instaPostsForge
Google Drive or Cloudflare R2 · GitHub Actions · AI agents

Built for photographers whose best shots stay stuck in the gallery.

Drop your handpicked photos in a Google Drive folder or a Cloudflare R2 bucket. Every evening instaPostsForge has its AI agents (Claude, OpenAI, Gemini or Ollama Cloud) choose one, write its caption and hashtags, and post it to Instagram. Plain code checks every word, and every token is accounted for.

Runs free on GitHub Actions in a public repo · Python 3.10+ · official Instagram API, no password

PostedSun 25 Oct · 19:00 IST
PostedMon 26 Oct · 19:00 IST
Today
SET 1/3
Why

Good photos don't post themselves.

You come back from a walk with forty frames and three keepers. Then the keepers sit in a folder, because posting well every day is its own job: pick one, don't repeat last week, write something true, choose the hashtags, remember to do it at all.

instaPostsForge does that job the way you would at a contact sheet. It looks at every frame in your photo folder once, circles the one for today, and writes the caption. It runs on GitHub Actions, so no server and no laptop need to stay on.

Prefer your phone? Postaday is its Android sibling and runs the same workflow with your own keys.

DRIVE FOLDER · 8 FRAMESPICK: FRAME 6 · TRAVEL · CALM
A day with instaPostsForge

One scheduled run, a few minutes, one post.

The Daily post workflow starts at 13:30 UTC (7:00 pm IST) once the AUTO_POST variable is on. Change the time in one cron line. The minutes below are typical, not fixed.

  1. ▸ 1FETCH19:00

    Learn from past posts

    Reads reach, likes, comments, saves and shares for the last 30 days of posts.

  2. ▸ 2PICK19:01

    Look, then choose

    New photos in the folder are described once. The planner picks today's photo, or a set of 2 to 5 from one outing.

  3. ▸ 3WRITE19:02

    Caption, tags, review

    A short caption, 3 to 5 hashtags, then a reviewer that can send back only the part it faults.

  4. ▸ 4POST19:03

    It goes out

    A 1080-wide JPEG is staged on the repo's media branch for about a minute, published through the official API, then deleted.

  5. ▸ 5RECORD19:04

    Remember and account

    The post is committed to state/ so it never goes out twice, and the run's token audit report is saved.

What it does

A folder in, a post out, and a receipt for every run.

Your folder is the library

Put handpicked photos in one link-shared Drive folder, or a private Cloudflare R2 bucket. Each is analysed once and remembered by its file ID, and a near-identical copy waits 30 days.

Look before it posts

Run it by hand in four modes: check the keys and folder, plan the next 7 days with reasons, preview the exact image and caption, or post. The schedule waits until you turn on AUTO_POST.

Sometimes a set

Code finds photos from one outing or place. The planner decides whether a set beats any single photo. Every photo in a set has the same shape, so none gets a border.

Short, and written with care

Captions stay under 150 characters, follow a playbook for each category and mood, and speak of deities and festivals as devotees do, ending with a greeting instead of a question.

A receipt for every run

Every AI call is logged with its tokens and estimated cost, and each run saves a token audit report you can download from the run page.

Safe in a public repo

Keys, tokens and even the folder link live in GitHub secrets. The repo only names them. The Instagram token renews itself every month.

How it works

Five AI agents, with code at every gate.

The AI decides what to post and what to say. Plain code does everything with a side effect (fetching, image preparation, hosting, publishing, records) and validates every answer before it can reach Instagram. Every agent runs on Claude Haiku 5.5 by default, or on OpenAI, Gemini or Ollama Cloud by setting one variable, with AI_MODEL to pick another model.

  1. analyst

    Describes each new photo once: category, mood, main subject, quality from 1 to 10, anything unsafe.

  2. planner

    Picks today's photo or set, balancing strong photos with variety and what has performed well.

  3. code: rules

    No explicit photos, screenshots or children. No near-duplicates, no subject twice in 3 days, no mood more than twice a week.

  4. caption_writer

    Writes the caption, a quote when one fits, and alt text. Code holds the text to 150 characters.

  5. hashtags

    Chooses 3 to 5 specific tags, rotating away from recent sets.

  6. reviewer

    Approves, or sends back only the part it faults, up to two times.

  7. code: checks

    At most 5 hashtags and 2,200 characters, JPEG, 4:5 to 1.91:1. A false claim or a doubtful quote author skips the day.

A workflow, not an agent

Prompt chaining with gates and an evaluator-optimizer review loop. The model gets no tools and chooses no steps.

It fails safe

If the planner fails, a random eligible photo is used. If the review still finds a real problem, the day is skipped. A broken post never goes out.

Never twice

A photo is recorded only after Instagram returns a media ID, keyed by a hash of its file ID, together with every photo of a set.

Token audit

Know exactly where the tokens go.

Every AI call is written to state/<profile>/usage/ as it happens, whether it succeeds or fails, with its model, input, output and cache tokens, time taken and estimated cost.

After every post, preview or plan run, scheduled or manual, the workflow saves a token audit report as a run artifact, kept for 90 days. It shows:

  • tokens, cache use, seconds, failures and cost per phase and per agent;
  • every call in order, so a revision or a shortening pass gets its own row;
  • the month so far, by phase.

forge usage -p main totals any month from the command line.

This run, by phase · example figures
PhaseCallsInputOutputEst. USD
Photo scanninganalyst11,840410$0.0004
Choosing the photoplanner13,200520$0.0006
Caption, quote and alt textcaption_writer24,100980$0.0009
Hashtagshashtags11,150160$0.0002
Reviewreviewer12,600300$0.0004
Total612,8902,370$0.0025
CLAUDE HAIKU 5.5 · $0.10 IN / $0.50 OUT PER MILLIONQUOTE IS PART OF THE CAPTION CALL
Post styles

The same photo, laid out many ways.

Every post is laid out in a designed style. By default the AI picks the style that suits each day's photos; you can also pick a style, a mood and a genre when you run the workflow, or post the photo plain. Code lays the post out from templates, the AI chooses the photos and writes the few words on the image, and those words go through the same checks as the caption. The photos themselves are never redrawn by an image model. Every slide is 1080×1350.

Poster

The photo as a large print on paper, with a title in spaced capitals, a quiet line and a handwritten note. The layout follows the photo's shape, and each post gets its own finish (border, tape, a slight tilt) and paper tone, so no two look alike.

Poster: a wide sky photo with a white border, the title and note under it
Wide photo, words under it
Poster: the title above a taped wide photo of hills
Wide photo, taped, words above
Poster: a sea photo spanning the full width
Edge to edge
Poster: a tall street photo on the left, handwritten note in the margin
Tall photo, note beside it
Poster: a tall photo on the right with a border and tape
Tall photo, border and tape
Poster: a square moon photo with a border
Square photo

Gallery, grid and story

A gallery frame gives one photo a museum-style label with its place and month. A grid tiles 2 to 9 photos from one outing, then shows each on its own slide. A story opens on the cover with a title and closes with a line on paper.

Gallery frame: a sky photo on an off-white margin with a small label
Gallery frame
Grid: nine photos in a 3 by 3 grid with a title across the middle
Grid of 9
Story cover: a full-bleed photo with the title at the bottom
Story cover
Story closing slide: one line of italic text on paper
Story closing slide

Panorama

A wide photo cut into 2 or 3 slides that join up as you swipe.

Panorama: one sea photo split across three slides
Three slides, one view

Backgrounds that match the photo

Behind a poster or gallery print, code draws a background from the photo's own colours: tinted paper, a blurred copy of the photo, a row of colour swatches, two tones, a soft sun, or kraft, linen, slate or night-navy paper. Text colour is checked for contrast, and flag or party colours never appear side by side.

Poster on a blurred, darkened copy of the same photo
Blurred echo
Poster on a two-tone background taken from the photo's colours
Two tones
Gallery print with a row of the photo's colours as dots under the label
Colour swatches
Poster with a soft sun shape behind the words
Sun shape
Poster on kraft paper
Kraft paper
Moon photo on night-navy paper
Night navy

Frames

A gallery post can take a frame that suits its kind of photo: a postcard with a postmark for travel, a ticket stub, a film strip for street and night, a magazine page, instant prints for a small set, or a soft festive border for devotional photos. The place and month come from code, and no frame copies a real brand, ticket or stamp.

Postcard: the sea photo on the front, a handwritten line and a stamp with a postmark
Postcard
Ticket stub: hill photo on the ticket, title and place, month and number on the stub
Ticket stub
Film strip: a street photo between sprocket holes with a frame number
Film strip
Magazine page: issue line, the photo large, a headline and a standfirst
Magazine page
Three instant prints scattered on kraft paper with a handwritten title
Instant prints
Festive border of marigold and maroon dots around a sky photo
Festive border

Notes: drawn on top, photo untouched

A notes post shows the photo exactly as shot, then the same photo with a hand-drawn layer: short notes with arrows, doodles in plain sky, a star map joining bright points, an old film date stamp, viewfinder marks, rule-of-thirds lines, a tape label or a magazine cover. The AI only names what is in the photo and writes the few notes; code places every mark clear of the subject, never on a person, and never on a devotional photo.

The sea photo as shot, the first slide of a notes post
Slide 1: as shot
The same sea photo with handwritten notes
Slide 2: field notes
A night sky with bright points joined into a small star map
Star map
Street photo with an orange film date stamp and a note
Film date stamp
Sky photo with small white sparkles, stars and swirls
Doodles
Sea photo set as a magazine cover with a masthead
Magazine cover
Hill photo with viewfinder corner marks and the time
Viewfinder
Hill photo with rule-of-thirds lines and a note
Photographer's notes
Sea photo with a strip of tape in the corner naming the place
Tape label

The sky is from the author's account; the other scenes are placeholders drawn for these examples. The AI avoids repeating the last post's style, and code never repeats the last post's look.

Privacy and safety

A public repo that holds nothing private.

Instagram

Official API only. It uses an access token you create and can revoke. It never asks for your Instagram password.

Secrets

Only in GitHub secrets. Keys, tokens, the Drive folder link and the R2 bucket name are passed only to the step that runs forge, never to installs or third-party actions.

Photos

No EXIF, no GPS. Published JPEGs carry only the colour profile. GPS is compared in memory to group outings and never saved. Photos are recorded by a one-way hash of their file ID.

Content

Rules in code. Explicit photos, screenshots, photos with children and photos about politics or conflict are skipped. Addresses and number plates stay out of the text, and every caption, hashtag and word on the image is checked against a list of blocked topics: politics, caste, religious debate, war and sexual content.

Built with
PythonClaude · Anthropic Python SDKOpenAI and Gemini SDKsOllama Cloud APIPydanticPillowGoogle Drive APICloudflare R2 · boto3Instagram APIGitHub ActionsGitHub Pagespytest