Telegram bot

What
Telegram photo-sorting bot
Where it lives
Inside Telegram
Code
modern-solver/pickmypics (opens in a new tab)

PickMyPics

A Telegram bot: send a picdump, and it scores, ranks and captions the best shots for the platform you pick.

The source is public on GitHub.

The problem

A picdump is easy to make and slow to sort. Picking the best shots out of it is the chore.

What I decided

Build it inside a chat app people already use. There is no new app to install and nothing new to learn: you send the pictures to a Telegram bot.

Score every photo for the platform it is going to, then caption the picks, so what comes back is ready to post rather than a sorted folder.

How it works

  1. Send your picdump.
  2. It scores each photo out of 10 on clarity, face/scenery visibility, resolution and other factors.
  3. It returns the top 3 with scores (eval, tuned to the target platform).
  4. It captions each of the 3 and returns the final pick.

How it’s built

  • Step in the code
  • LLM or external API
  • Data store
  • Only some turns, or offline

Fig. 1 · PickMyPics, how it is built

PickMyPics, how it is builtThe same steps are listed in order below the diagram.User in Telegramthe whole flowstays in the chatBot handlerspython-telegram-botcurator/main.pycurator/bot/agent.pyPick the target platform(s)on /startInstagram, Facebook, Tinder,Bumble, Hinge, LinkedInParse the intentplatforms, vibe, constraintscurator/session/intent.pyReceive the picdumpsession store with timeoutcurator/session/Tier 1: technical checkslocal: resolution (Pillow), blur(OpenCV Laplacian), near-dupes(pHash), faces (Haar)grading/tier1.pyTier 2: platform fitlocal: weights per platform, aface gate for dating apps, aLinkedIn suitability flagconfig/platform_weights.ymlgrading/tier2.pyTier 3: vision scoringcomposition, lighting, subject,mood. External API: Groq(Llama 4 Scout vision). No key:deterministic fallback, skippedgrading/tier3.pyComposite scoreout of 10 per photograding/composite.pyRank for the target platform,keep the top 3ranking_agent.rankDescribe the sceneExternal API: Groq vision. Nokey: deterministic fallback,BLIP-2, local or Hugging Facescene.pyWrite caption variantsshort, long, haiku; no hashtags.External API: Groq (Llama 3.370B). No key: deterministicfallbackcaption/agent.pyconfig/prompts.ymlPresent scored cardswith captionsranking/card.pypresentation.pyOverrides/next /platform/retry /shorterPick the photo and caption→ final cardranking/selection.py/starteach photoscored cards + captionsfinal cardPython, deployed as a worker on Railway.
  • Step in the code
  • LLM or external API
  • Data store
  • Only some turns, or offline
Simplified from the code in modern-solver/pickmypics (opens in a new tab), branch claude/sub-agents-build-1k1fez. Python, deployed as a worker on Railway.
The same diagram, as a list
  1. A user in Telegram sends /start to the bot (python-telegram-bot handlers in curator/main.py and curator/bot/agent.py).
  2. They pick the target platform(s): Instagram, Facebook, Tinder, Bumble, Hinge or LinkedIn.
  3. The bot parses the intent: platforms, vibe and constraints (curator/session/intent.py).
  4. It receives the picdump into a session store with a timeout (curator/session/).
  5. Tier 1, local: technical checks for resolution (Pillow), blur (OpenCV Laplacian), near-duplicates (pHash) and faces (Haar).
  6. Tier 2, local: platform fit, with weights from config/platform_weights.yml, a face gate for dating apps and a LinkedIn suitability flag.
  7. Tier 3: vision scoring of composition, lighting, subject and mood through Groq (Llama 4 Scout vision). Without a key, it is skipped and the deterministic tiers stand.
  8. Each photo gets a composite score out of 10 (grading/composite.py).
  9. The photos are ranked for the target platform and the top 3 are kept (ranking_agent.rank).
  10. Each pick’s scene is described through Groq vision, or a BLIP-2 fallback, local or on Hugging Face (scene.py).
  11. Caption variants are written per photo: short, long and haiku, no hashtags, through Groq (Llama 3.3 70B), with prompts in config/prompts.yml.
  12. Scored cards with captions go back to the chat (ranking/card.py, presentation.py).
  13. The user picks the photo and caption, and gets a final card (ranking/selection.py).
  14. At any point /next, /platform, /retry and /shorter re-rank or re-caption.
  15. Python, deployed as a worker on Railway.

The result

A working Telegram bot that scores, ranks and captions a picdump. The source is public on GitHub.