An automated pipeline that generates, renders, schedules, and manages 600+ pieces of Facebook content per week across 3 brand pages — using AI for copy, Remotion for video, Playwright for graphics, and the Facebook Graph API for publishing and engagement.
| Page | Niche | Audience |
|---|---|---|
| MEA (Engage MEA) | Social media strategy | Creators & marketers |
| A2B (Runnin' From A2B) | Career pivots | Professionals changing careers |
| ATU (After The Uniform) | Veteran benefits | Veterans navigating VA systems |
Each page publishes 200 posts/week (175 static graphics + 25 text-only) and 7 reels/week.
| Page | Niche | URL |
|---|---|---|
| MEA | Social media strategy | facebook.com/EngageMEA1 |
| After the Uniform | Veteran benefits | facebook.com/AfterTheUniform |
| Runnin From A2B | Career pivots | facebook.com/RunninFromA2B |
Posts generated, rendered, and scheduled entirely by this pipeline
| MEA | After the Uniform | Runnin From A2B |
|---|---|---|
![]() |
![]() |
![]() |
- 1,638 posts/week across 3 pages, fully automated
- 1080×1080 PNG graphics rendered from branded HTML templates via headless Chromium
- Short-form MP4 reels with AI voiceover (ElevenLabs), AI music (Suno), and Remotion animations
- Animated micro-posts — 7-second MP4 versions of static graphics (66/page/week)
- Scheduled publishing via Facebook Graph API with crash-safe SQLite idempotency
- Automated first comments posted via cron every 15 minutes after each post goes live
- Cross-page engagement — each page comments on the other two pages daily
- Smart auto-replies using template banks or live Claude API calls
- Weekly engagement reports with failure profile diagnosis and pillar-level analytics
- Content optimization — 70/20/10 redistribution of next week's topics based on performance
Brand Config (page_brand.json + topic_bank_week.json)
│
▼
Claude API Copy Generation (generate_copy.js)
│
├──▶ HTML Templates → PNG (Playwright render)
│
└──▶ Remotion → MP4 (Reels + MicroPosts)
│
▼
QA Validation (qa_check.js)
│
▼
Facebook Scheduler (facebook_poster.html + fb_poster.js + Graph API)
│
├──▶ Cron: First Comments (every 15 min, 5AM–11PM CT)
├──▶ Cron: Auto-Reply + Cross-Engage + Group Posts (9PM CT daily)
└──▶ Analytics → Engagement Report → Optimize Mix → Next Week
| Database | Purpose |
|---|---|
poster.db |
SHA-256 keyed post ledger — crash recovery and scheduling idempotency |
engagement.db |
Deduplication for replies, cross-comments, and group posts |
tools/brand_intake.js runs a 10-minute CLI survey (mission, audience, tone, colors, content pillars) and outputs:
page_brand.json— complete brand DNAtopic_bank_week.json— 200 curated topics across 10 content pillars (P1–P6 branded graphics, P7 tweet-style, P8 text-only, P9 memes, P10 hot takes)
generate_copy.js calls Claude API once per topic (200 calls/week) with a sliding anti-repetition window of the last 5 outputs. Each call returns: copyText, firstComment, headline, subline, emWord, strongPhrase.
Cost: ~$0.60/page/week
generate_week.js injects copy fields into 9 branded HTML templates per page (CSS variables from page_brand.json). Outputs ~120 HTML files + 7 batch copy files in Mon_Batch1_Copy.txt through Sun_Batch3_Copy.txt format.
render_all.js spawns tools/render.py --batch which uses Playwright headless Chromium to screenshot each HTML file at 540×540 @ 2× = 1080×1080 PNG. Output: ~120 PNGs/page/week.
produce_reels.js orchestrates three steps per reel:
- Voiceover — ElevenLabs API → MP3
- Music — Suno API → MP3
- Video — Remotion → MP4
Six reel archetypes rotate Mon–Sun: FactReveal, StepSequence, QuoteZoom, DataBars, ExplainerCard, PollReveal.
Cost: ~$2.50/page/week
build_micro_manifest.js maps P1–P6 posts to 6 Remotion compositions and renders 66 animated 1080×1080 MP4s (7 seconds, no audio) per page. The HTML poster's "Media Preference" dropdown toggles between PNG and MP4 per post.
qa_check.js blocks scheduling on: placeholder text, copy under 50 chars, missing images, duplicate captions, missing hashtags, missing first comments. Exit code 0 = pass, 1 = block.
HTML Poster (tools/facebook_poster.html) — browser-based interface for selecting content directory, previewing all posts, and clicking "Schedule All."
Engine (fb_poster.js):
- Uploads images as unpublished photos via
POST /{pageId}/photos - Creates scheduled posts via
POST /{pageId}/feed - Records all actions to
poster.dbfor idempotency - Rate-limits at 250ms between API calls
- Schedule: 6AM, 11AM, 3PM, 7PM CT + 12PM reel
cron_comments.sh runs via macOS crontab every 15 minutes (5AM–11PM CT). post_comments.js matches published posts to copy files by 80-char prefix + overlap scoring, then posts the stored firstComment via POST /{postId}/comments. Tracked in engagement.db to prevent duplicates.
cron_engagement.js runs daily at 9PM CT:
| Tool | What It Does |
|---|---|
auto_reply.js |
Replies to new comments using 12+ template variants per pillar, or live Claude API for substantive replies |
cross_engage.js |
Each page comments on the other 2 pages' latest posts (1/pair/day) |
group_poster.js |
Posts discussion starters to owned Facebook Groups |
top_performer.js |
Scores posts (likes + 2×comments + 3×shares) and writes boost recommendations |
engagement_report.js diagnoses one of five failure profiles per page:
| Profile | Meaning |
|---|---|
| Ghost | Low reach — content isn't being shown |
| Salesman | High reach, low engagement — people see it but don't care |
| Robot | Flat/generic engagement — no emotional response |
| Builder | Growing but not yet strong |
| Healthy | Strong engagement across pillars |
optimize_mix.js applies a 70/20/10 redistribution: 70% to proven top-performing pillars, 20% to underperforming pillars with new angles, 10% experimental — then overwrites topic_bank_week.json for the next week.
content_recycler.js identifies posts at 1.5× average engagement and recycles with variation prefixes ("ICYMI:", "Worth repeating:") — max 2 recycles/post, 7-day minimum gap.
| Layer | Technology |
|---|---|
| Copy generation | Anthropic Claude API (claude-sonnet-4-6) |
| Image rendering | Playwright + headless Chromium (Python) |
| Video production | Remotion + TypeScript |
| Voiceover | ElevenLabs API |
| Music | Suno API |
| Publishing | Facebook Graph API |
| State / idempotency | SQLite (better-sqlite3) |
| Automation | macOS crontab |
| Runtime | Node.js + Python 3 |
fb-content-system/
├── mea/ a2b/ atu/ ← Brand config (page_brand.json, topic banks)
├── mea-week1/ a2b-week1/ ... ← Generated content (HTML, PNG, MP4, copy files)
├── templates/mea/ a2b/ atu/ ← 9 HTML templates per page (P1–P10)
├── reels/src/ ← Remotion compositions (6 reel + 6 micro)
├── reels/scripts/ ← Render + TTS + music generation scripts
├── tools/ ← All 26 production tools (Node.js)
├── skills/ ← Claude Code skill definitions
├── docs/ ← Planning docs, calendars, guides
├── reports/ ← Generated engagement reports
└── logs/ ← Cron execution logs
| Service | Per Page/Week | All 3 Pages/Month |
|---|---|---|
| Claude API (200 posts) | $0.60 | $7.20 |
| ElevenLabs (7 reels) | $0.14 | $1.68 |
| Suno (7 tracks) | $0.35 | $4.20 |
| Playwright rendering | $0.00 | $0.00 |
| Total variable | $1.09 | $13.08 |
All-in with fixed subscriptions: ~$71.94/month for all 3 pages.
- Node.js 22+ (current LTS — download)
- Python 3.9+
- macOS (cron scheduling uses macOS crontab)
- Facebook Developer App with Graph API access
- API keys: Anthropic, ElevenLabs, Suno
git clone https://github.com/design1-software/fb-content-system.git
cd fb-content-system
npm install
pip3 install playwright
playwright install chromium
cp tools/.env.example tools/.env
# Add your API keys to tools/.envnode tools/brand_intake.js --output mea/# Generate copy
node tools/generate_copy.js --page mea
# Generate HTML + batch files
node mea/generate_week.js
# Render PNGs
node tools/render_all.js --dir mea-week1
# QA check
node tools/qa_check.js mea-week1
# Open scheduler in browser
open tools/facebook_poster.html# Add to crontab (runs every 15 min, 5AM-11PM)
*/15 5-23 * * * /path/to/fb-content-system/tools/cron_comments.sh
# Daily engagement (9PM CT)
0 21 * * * node /path/to/fb-content-system/tools/cron_engagement.js| Variable | Type | Scope |
|---|---|---|
MEA_TOKEN |
User | Manages MEA page (never expires) |
A2B_TOKEN |
Page | Manages A2B page (never expires) |
ATU_TOKEN |
Page | Manages ATU page (never expires) |
tools/resolve_token.js auto-resolves which token to use from page_brand.json → .env.
MIT


