🔥 Generated by this AI Agent → Blog · Substack · Telegram
Stateless pipeline: reads your Telegram channels, LLM curates a digest, publishes to Telegram, Ghost, and Substack.
- Collect — Reads all subscribed broadcast channels →
/tmp/telegram_messages.json - Curate — Two parallel LLM calls generate platform-specific digests:
- Messenger digest (short, emoji, links) for Telegram
- Blog digest (long-form HTML) for Ghost and Substack
- Publish — Posts to all platforms in parallel:
- Ghost (main blog) — Lexical format, newsletter emails via Mailgun
- Telegram — plain text to channel
- Substack (secondary) — ProseMirror format
Runs daily at 6:00 UTC via GitHub Actions. No persistent state.
- Go to https://my.telegram.org → API development tools
- Create a new application, copy
api_idandapi_hash - Generate a session string:
pip install telethon
export TELEGRAM_API_ID="your_api_id"
export TELEGRAM_API_HASH="your_api_hash"
export TELEGRAM_PHONE="+your_phone_number"
python agent/integrations/telegram/setup_session.py- Create a target channel: Menu → New Channel → make it Public → set a username
- Deploy Ghost using
infra/ghost/deploy-ghost.sh(Docker Compose on any Linux server) - Create an admin account at
https://your-domain/ghost - Settings → Integrations → Add custom integration → copy the Admin API key
- (Optional) Settings → Mailgun → configure for newsletter emails
See agent/integrations/substack/README.md for how to get your connect.sid cookie.
Secrets:
| Secret | Description |
|---|---|
TELEGRAM_API_ID |
Numeric API ID from my.telegram.org |
TELEGRAM_API_HASH |
API hash string from my.telegram.org |
TELEGRAM_SESSION_STRING |
Output from setup_session.py |
CLAUDE_CODE_OAUTH_TOKEN |
Claude Code OAuth token (primary LLM auth) |
ANTHROPIC_API_KEY |
Claude API key (fallback LLM auth) |
GHOST_ADMIN_API_KEY |
Ghost Admin API key (format: {id}:{secret}) |
SUBSTACK_COOKIE |
Substack connect.sid cookie value |
Variables:
| Variable | Description |
|---|---|
TELEGRAM_PUBLISH_CHANNEL |
Target Telegram channel (e.g. @my_ai_digest) |
GHOST_URL |
Ghost domain without https:// (e.g. aicmo.blog) |
SUBSTACK_PUBLICATION_URL |
Substack publication URL (e.g. https://howai.substack.com) |
LLM_PROVIDER |
LLM provider: claude, openai, gemini, vertex (default: claude) |
LLM_MODEL |
Model name (default: claude-sonnet-4-6) |
LLM_MAX_TOKENS |
Max tokens (default: 12288) |
Daily digest: Runs automatically at 4:00 UTC. Manual: Actions → "Generate Daily Digest" → Run workflow.
Supports workflow dispatch inputs: start_date, end_date, and per-platform publish toggles.
Weekly digest: Runs automatically Saturday at 6:00 UTC. Manual: Actions → "Generate Weekly Digest" → Run workflow.
Reads published daily digests from the publish channel, resolves t.me source links, and synthesizes a thematic weekly roundup. Supports start_date, end_date, and per-platform publish toggles.
To backfill past digests one day at a time:
.github/scripts/backfill-digests.sh 2026-02-08 2026-03-09agent/integrations/
telegram/
telegram.py # Telegram I/O (--read, --post, --list-channels)
setup_session.py # one-time auth → StringSession
requirements.txt # telethon, cryptg
ghost/
ghost.py # Ghost publisher (--post, --draft, HTML→Lexical)
requirements.txt # requests
substack/
substack.py # Substack publisher (--post, --draft, HTML→ProseMirror)
requirements.txt # requests
README.md # Substack auth setup guide
infra/
hetzner-setup.sh # one-click VPS setup (see below)
ghost/
deploy-ghost.sh # deploy Ghost (Docker Compose)
docker-compose.yml # Caddy + Ghost + MySQL
ubuntu_security_hardening.sh # server hardening (SSH, UFW, fail2ban, sysctl)
.github/
scripts/
backfill-digests.sh # backfill past digests sequentially
prompts/
generate-digest-daily-messenger.md # Daily Telegram prompt (short, emoji, links)
generate-digest-daily-blog.md # Daily blog prompt (long-form HTML)
generate-digest-weekly-messenger.md # Weekly Telegram prompt (thematic roundup)
generate-digest-weekly-blog.md # Weekly blog prompt (thematic HTML, source links)
workflows/
generate-digest-daily.yml # daily pipeline (4:00 UTC)
generate-digest-weekly.yml # weekly pipeline (Saturday 6:00 UTC)
test-ghost.yml # manual Ghost test
test-substack.yml # manual Substack test
One-click hardened VPS setup with infra/hetzner-setup.sh:
export HCLOUD_TOKEN="..."
export TAILSCALE_API_KEY="..."
bash infra/hetzner-setup.sh my-serverConnection stack: Tailscale + Mosh/SSH + Termius + sshid.io hardware keys
- Provisions Ubuntu 24.04 on Hetzner Cloud via API + cloud-init
- No public SSH — all access through Tailscale mesh VPN
- Cloudflare-only HTTP/S, Docker + Compose, fail2ban, unattended upgrades
- Server auto-appears in Tailscale and
~/.ssh/config - Connect from any device:
mosh evios@my-serveror via Termius