Lazy Blogging with Telegram and Cloudflare Workers
I wanted to post to this blog from my phone without fighting a git workflow on Android. The solution I landed on was a Telegram bot that accepts a message and opens a GitHub draft PR containing the post, ready to merge from the GitHub mobile app.
Rationale
The standard Zola workflow — branch, write, commit, push, PR — is fine at a desk. On a phone it’s friction enough that posts don’t happen. The gap between thought and published needs to be close to zero, or the habit won’t stick.
The requirements were simple: no new third-party dependencies beyond what I already trusted, content lands in git immediately, and the publish step stays deliberate rather than automatic.
Tech choices
Telegram was the obvious input layer. Creating a bot takes about two minutes via BotFather, the Android app is excellent, and sending a message to a bot is as low-friction as it gets. The alternative was a secret-URL endpoint or email-to-draft, but Telegram felt more natural for the use case.
Cloudflare Workers handles the integration layer. I was already on Cloudflare for Pages, so a Worker is a natural extension — a small JS function that receives Telegram’s webhook POST, parses the message, calls the GitHub Contents API to create the file and branch, and opens a draft PR. No Actions required, no additional services.
The message format is minimal: first line is the title, subsequent lines are the body. The Worker slugifies the title, creates content/blog/{slug}/index.md with Zola front matter, and fires back a PR URL via Telegram.
Source is in the blog-bot repo.
Environment setup
Wrangler requires Node 16.17 or later. I used nvm to manage this:
nvm install 22
nvm use 22
npm install -g wrangler
Wrangler setup and deploy
Authenticate against your Cloudflare account:
wrangler login
Set the required secrets — Wrangler will prompt for each value:
wrangler secret put TELEGRAM_SECRET # random string: openssl rand -hex 32
wrangler secret put TELEGRAM_TOKEN # from BotFather
wrangler secret put GITHUB_TOKEN # fine-grained PAT: contents + PRs write
wrangler secret put GITHUB_OWNER
wrangler secret put GITHUB_REPO
Deploy:
wrangler deploy
Then register the webhook with Telegram once, substituting your Worker URL and secrets:
curl "https://api.telegram.org/bot${TELEGRAM_TOKEN}/setWebhook" \
-d "url=${WORKER_URL}/${TELEGRAM_SECRET}"
After that, messages sent to the bot create draft PRs. Merging from GitHub mobile or desktop triggers a Cloudflare Pages build in the usual way.