Back to projects

Flagship · AI/ML · Completed

ContentEngine

A Telegram-driven pipeline that picks a de-duplicated content angle across 4 niches, writes on-brand copy, generates a photorealistic image and 4 branded slides, and — once approved from Telegram — auto-publishes to Facebook and Instagram via Make.com.

Timeline
2026-05 – Present
Status
Completed
end-to-end run time (idea → 4 rendered slides + caption, ready for approval)
~5 min
content niches + live news-signal filter covered
4
est. manual time for equivalent output
~3 hrs (estimated)

Stack

Built with

Core

n8n
Google Gemini API
Telegram Bot API
Make.com

Supporting

Gemini 2.5 Flash Image
Supabase
Browserless
Tavily API
RSS
01

The problem

Posting consistently across Fintech, HR-tech, and SaaS content meant picking a genuinely new angle every time (not a repeat of the last 30 posts), writing copy that didn't read like every other 'thought leadership' account, producing an on-brand image, turning that into a branded multi-slide carousel, and actually getting it onto Facebook and Instagram. Doing all of that by hand, per post, per niche, doesn't scale past a few posts a week.

Constraints

  • No budget for a human designer or stock photography, so every image is generated (Gemini 2.5 Flash Image) and every social-card slide is built as HTML/CSS and rendered to PNG, not designed by hand
  • Had to guarantee no repeated topic — dedup logic checks the last 30 posts per niche for subtopic word overlap, topic_key-dimension matches, and shared-tag clusters before a strategy is accepted
  • Kept a human in the loop on purpose: nothing reaches Facebook or Instagram without an explicit Approve tap in Telegram, so a bad generation never auto-publishes

Architecture

How it's built

A Telegram bot is the entire interface: a Router node classifies every incoming update (niche button tap, approve/reject callback, plain text) and a Switch fans it out. Picking a niche pulls the last 30 Supabase posts for that niche and feeds them to a Gemini 'Strategy' call carrying a full taxonomy (5 content pillars × multiple subtopics per niche) plus explicit dedup rules; a code node re-checks the chosen subtopic against history (word overlap, topic_key match, tag-cluster overlap) and loops back to Gemini if it's too close to something already posted. A second Gemini call turns the approved strategy into a structured insight payload (before/after stat, a 4-point breakdown, a one-line takeaway) under strict sourcing rules — real named sources only, no fabricated numbers, nothing older than 2022. A third Gemini call writes a platform-specific caption against a banned-word list and hard character limits. In parallel, a fourth Gemini call generates a photorealistic B2B photo from a niche-aware, cinematically-varied prompt, and four separate HTML/CSS templates (cover, before/after, 4-point breakdown, closing statement) get rendered to 1080×1080 PNGs via Browserless and uploaded to Supabase storage. Every stage — strategy, insight, image, caption — has its own validation node and a bounded 3-attempt retry loop before it's allowed to fail loudly to Telegram instead of going quiet. The finished 4-slide carousel and caption go back as a Telegram media group with Approve/Reject buttons; Approve marks the Supabase record and POSTs the caption plus image URLs to a Make.com webhook, which is what actually publishes the post to Facebook and Instagram. A separate 'HSF' news-signal branch runs alongside it: pulls Bloomberg/MarketWatch, RBI, and TechCrunch RSS, deduplicates by normalized title, enriches the top story via Tavily, and runs it through a strict Gemini filter acting as a market strategist instructed to SKIP roughly 80% of headlines and only pass genuine structural shifts — the ones that pass get their own institutional-style slide and the same Telegram approval gate before publishing.

Telegram trigger → dedup-aware Gemini strategy → insight + image generation → 4 HTML-rendered slides → Telegram approval → Make.com auto-publish to Facebook/Instagram
Telegram trigger → dedup-aware Gemini strategy → insight + image generation → 4 HTML-rendered slides → Telegram approval → Make.com auto-publish to Facebook/Instagram

Decisions

Alternatives considered

Auto-publish straight to Facebook/Instagram with no review step

An unreviewed bad generation going out on a public brand account is worse than a slower pipeline, so every post stops at a Telegram Approve/Reject gate before Make.com ever sees it.

Decisions

Tradeoffs

  • Chose Telegram as the entire control surface instead of a proper dashboard — zero UI to build or host, but every interaction (niche pick, approve, reject) has to be squeezed into button taps and callback_data strings, which is why the Router/Switch layer up front is doing real routing work, not just passing messages through.
  • Render each social-card slide as HTML/CSS through Browserless rather than compositing images programmatically — slower and adds an external dependency, but on-brand typography and layout are exact and easy to restyle per niche by touching CSS, not by editing raster templates.

Honesty check

What failed

  • Early versions let a single bad Gemini response (malformed JSON, a missing required field) kill the whole run silently. Every stage now has a dedicated Validate node plus a 3-attempt retry counter that clears the error and loops back to the same Gemini node — only after 3 failures does it give up and post a specific error message to Telegram instead of just going quiet.

Lessons

  • A dedup check that only looks at the current batch isn't enough — it has to look at real history (the last 30 posts per niche), or the model will happily suggest something it already covered two weeks ago.
  • Strict, falsifiable content rules (real named sources only, no invented numbers, banned-word lists, hard character limits) work far better as instructions to the model than as post-hoc filters — cheaper to prevent than to catch.

Future improvements

  • Extend the same Approve/Reject/Make.com publish path to platforms beyond Facebook and Instagram.
  • Feed published-post performance back into the Strategy prompt so pillar/topic selection is informed by what actually worked, not just by what hasn't been posted recently.