Automates Threads posts by selecting a random PNG from an OCI Object Storage bucket, uploading it through the official Threads Graph API, and deleting the image from the bucket after a successful post.
- Python 3.10+
- OCI credentials (via
~/.oci/config) with access toTHREADS_BUCKET - Threads Graph API access token with publish permissions
- Claude API key with access to the latest vision-capable model (default:
claude-sonnet-4-5-20250929)
- Install dependencies:
python -m venv .venv . .venv/bin/activate pip install -r requirements.txt - Copy the sample environment file and fill in your values:
cp .env.example .env
- Ensure your OCI profile can list objects, create pre-authenticated requests, and delete objects in the target bucket.
- Provide your Anthropic Claude API key in the environment so captions can be generated automatically.
Run the poster manually:
python -m threads_posterThe script:
- Loads configuration and credentials from the environment
- Lists all PNG files in the configured OCI bucket/prefix
- Picks a random image and creates a pre-authenticated URL
- Sends the image to Claude Vision to craft a one-line caption that reflects the quote
- Creates and publishes the Threads post with the generated caption
- Deletes the posted image from OCI once the upload succeeds
Logs are printed to stdout with timestamps to simplify automation and alerting.
cron/threads_poster.cron contains a ready-to-import crontab entry that runs the script every hour from 09:30 to 21:30 IST (04:00-16:00 UTC):
crontab cron/threads_poster.cronAdjust the repository path or Python interpreter in that file to match your environment before loading it.
The following variables are required (see .env.example):
THREADS_ACCESS_TOKENTHREADS_USER_IDTHREADS_BUCKETOCI_NAMESPACEOCI_REGION(falls back to the region in~/.oci/configif omitted)ANTHROPIC_API_KEY(required whenTHREADS_ENABLE_CAPTIONINGistrue)
Optional variables:
THREADS_PREFIXto limit selection to a subfolderTHREADS_ENABLE_CAPTIONINGto toggle Claude caption generation (set tofalsefor silent posts)OCI_PROFILEto select a non-default profile from~/.oci/configTHREADS_CLAUDE_MODELto target a different Claude vision modelTHREADS_CLAUDE_MAX_TOKENSto adjust the caption response limitTHREADS_CAPTION_FALLBACKto set fallback text if Claude succeeds but returns no textTHREADS_MEDIA_WAIT_SECONDSto adjust the media processing waitTHREADS_PRESIGN_EXPIRATION_SECONDSto tweak presigned URL validity