A serverless Telegram bot that delivers the latest technology news from The Guardian and Hacker News — deployed on Cloudflare Workers with fully automated CI/CD via GitHub Actions.
This bot fetches fresh technology headlines and sends them directly to any Telegram chat on demand. Each news item is formatted with a bold title and a linked source name at the end, so the article is one tap away.
*Apple unveils new M4 chip lineup at WWDC 2025*
[The Guardian](https://theguardian.com/...)
*Show HN: I built a local-first SQLite sync engine*
[Hacker News](https://news.ycombinator.com/...)
The entire infrastructure runs 100 % free:
| Layer | Service | Cost |
|---|---|---|
| Runtime | Cloudflare Workers (free tier) | Free |
| CI/CD | GitHub Actions | Free |
| News: tech | The Guardian Open API | Free |
| News: community | Hacker News Firebase API | Free, no key |
- Serverless — no server to manage, scales to zero when idle
- Zero local tooling — no Node.js, npm, or Wrangler needed on your machine
- Parallel fetching — Guardian and Hacker News are fetched with
Promise.all - MarkdownV2 safe — all special characters are escaped correctly for Telegram
- Auto-deploy — every
git pushtomaintriggers a new deployment - Encrypted secrets — API keys are stored as Cloudflare Worker secrets, never in code
| Component | Technology |
|---|---|
| Language | TypeScript |
| Runtime | Cloudflare Workers (V8 isolates) |
| Build & deploy tool | Wrangler (runs in CI only) |
| CI/CD | GitHub Actions + cloudflare/wrangler-action |
| News source 1 | The Guardian Open Platform |
| News source 2 | Hacker News Firebase API |
| Telegram integration | Webhook (HTTP POST from Telegram → Worker) |
telegram-news-bot/
├── src/
│ └── index.ts # Bot logic (fetch, format, send)
├── .github/
│ └── workflows/
│ └── deploy.yml # CI/CD pipeline
├── wrangler.toml # Cloudflare Worker config
├── package.json # Dependencies (wrangler, ts types)
├── tsconfig.json # TypeScript config
├── .gitignore
├── README.md # This file
└── README.FA.md # Persian documentation
| Tool | Purpose |
|---|---|
| A browser | Creating accounts, collecting keys |
| Git | Only for git push — or upload files directly on GitHub.com |
All build steps, dependency installation, and deployment run inside GitHub Actions on GitHub's servers. Nothing runs on your machine.
- Open @BotFather in Telegram
- Send
/newbot - Choose a display name (e.g.
Tech News Bot) - Choose a username ending in
bot(e.g.my_technews_bot) - BotFather replies with a token like:
7123456789:AAFxxxxxxxxxxxxxxxxxxxxxxxxxxxx - Save it as →
TELEGRAM_BOT_TOKEN
- Go to https://open-platform.theguardian.com/access/
- Click "Register for a developer key"
- Fill in the free registration form
- An API key arrives in your email:
a1b2c3d4-e5f6-7890-abcd-ef1234567890 - Save it as →
GUARDIAN_API_KEY
- Sign up at https://dash.cloudflare.com/sign-up (free plan is enough)
- Verify your email
- Navigate to Workers & Pages → Overview
- Find Account ID in the right-hand sidebar — copy it
- Save it as →
CLOUDFLARE_ACCOUNT_ID
- Go to https://dash.cloudflare.com/profile/api-tokens
- Click "Create Token"
- Select the "Edit Cloudflare Workers" template
- Set:
- Account Resources → Include → All accounts
- Zone Resources → Include → All zones
- Click "Continue to summary" → "Create Token"
- Copy the token immediately — it is shown only once
- Save it as →
CLOUDFLARE_API_TOKEN
- Go to https://github.com/new
- Name it
telegram-news-bot - Set it to Private
- Click "Create repository"
Navigate to: Settings → Secrets and variables → Actions → New repository secret
Add all four secrets:
| Secret name | Value |
|---|---|
CLOUDFLARE_API_TOKEN |
From step 1.4 |
CLOUDFLARE_ACCOUNT_ID |
From step 1.3 |
TELEGRAM_BOT_TOKEN |
From step 1.1 |
GUARDIAN_API_KEY |
From step 1.2 |
For each file click Add file → Create new file inside the repository.
Tip: To create nested files, type the full path in the filename field.
Example: typesrc/index.ts— GitHub creates thesrc/folder automatically.
Create these files in any order:
src/index.ts
wrangler.toml
package.json
tsconfig.json
.gitignore
.github/workflows/deploy.yml ← triggers deployment
After committing the last file GitHub Actions starts automatically.
git clone https://github.com/YOUR_USERNAME/telegram-news-bot.git
cd telegram-news-bot
# Copy all project files into this directory
git add .
git commit -m "feat: Telegram tech news bot"
git push origin main- Open your repository → Actions tab
- Find the "Deploy to Cloudflare Workers" run
- Wait ~30–60 seconds
- ✅ Green checkmark = deployed successfully
What happens inside GitHub Actions:
git push
│
▼
actions/checkout@v4 pulls your code onto the GitHub runner
│
▼
npm install installs wrangler & TypeScript (on GitHub's server)
│
▼
wrangler deploy compiles TypeScript → uploads Worker to Cloudflare
│
▼
secrets inject encrypts TELEGRAM_BOT_TOKEN & GUARDIAN_API_KEY
into the Worker environment on Cloudflare
│
▼
✅ Bot is live at https://telegram-news-bot.YOUR_SUBDOMAIN.workers.dev
Go to Cloudflare Dashboard → Workers & Pages → telegram-news-bot
The URL shown there looks like:
https://telegram-news-bot.johndoe.workers.dev
Open this URL in your browser (replace both values):
https://api.telegram.org/botTELEGRAM_BOT_TOKEN/setWebhook?url=WORKER_URL
Real example:
https://api.telegram.org/bot7123456789:AAFxxx/setWebhook?url=https://telegram-news-bot.johndoe.workers.dev
A successful response looks like:
{ "ok": true, "result": true, "description": "Webhook was set" }Open Telegram, find your bot by its @username, and send:
| Command | Result |
|---|---|
/start |
Welcome message and help |
/guardian |
5 latest articles from The Guardian |
/hackernews |
5 top stories from Hacker News |
/all |
Both sources together |
Every future change deploys automatically:
git add .
git commit -m "update: your change description"
git push origin main
# ✅ GitHub Actions re-deploys in ~30 seconds — no manual steps needed| Command | Description |
|---|---|
/start |
Show help message |
/help |
Show help message |
/guardian |
Latest 5 tech articles from The Guardian |
/hackernews |
Top 5 stories from Hacker News |
/all |
All news from both sources |
| Secret | Where to get it |
|---|---|
CLOUDFLARE_API_TOKEN |
https://dash.cloudflare.com/profile/api-tokens |
CLOUDFLARE_ACCOUNT_ID |
Workers & Pages → Overview → right sidebar |
TELEGRAM_BOT_TOKEN |
@BotFather in Telegram |
GUARDIAN_API_KEY |
https://open-platform.theguardian.com/access/ |
Check that the webhook is correctly registered by opening this URL:
https://api.telegram.org/botTOKEN/getWebhookInfo
The url field must match your Worker URL exactly.
- Click the failed run → read the log
- Most common cause: a secret was pasted with an extra space or newline
- Go to Settings → Secrets → delete and re-add the affected secret
Your CLOUDFLARE_API_TOKEN has expired or was entered incorrectly.
Create a new token in the Cloudflare dashboard and update the GitHub secret.
A news title contains unescaped MarkdownV2 characters.
The esc() function in src/index.ts handles this — ensure it wraps every dynamic string.
MIT — free to use, modify, and distribute.