Skip to content
Chethan Yadav
Work

Engineering/2024/Active

Tech Updates Bot

Sends daily tech updates to a Telegram channel.

TypeScript

Overview

tech-updates is a Cloudflare Worker that polls two news sources — TechCrunch and the Times of India's tech section — on a cron schedule, and pushes anything new to a public Telegram channel and any Discord server that's subscribed. It's the kind of small always-on bot that trades a dedicated server for a scheduled edge function: no process to keep alive, just a worker that wakes up, checks for new articles, and goes back to sleep.

The Telegram side is public and passive — anyone can join @dailytechneuz and get every update. The Discord side is opt-in per server: an admin runs a slash command to pick a channel, and the bot posts there from then on.

Key Features

  • Dual-source polling — fetches from a TechCrunch API endpoint and a Times of India tech-news API endpoint on every run, tracked in separate tables (tc_article / toi_article) so each source is deduplicated independently
  • Dedup by article ID — every fetched article ID is checked against Postgres (via Prisma) before it's sent; already-seen articles are silently skipped, so a cron re-run never double-posts
  • Telegram channel delivery — new articles get pushed to @dailytechneuz via the Telegram Bot API
  • Per-server Discord subscriptions/subscribe #channel and /unsubscribe slash commands (admin-only) let a server opt in or out; subscriptions are stored per-guild in a subs table, and every subscribed server gets the same articles posted to its chosen channel
  • Heartbeat webhook — after each run, a Discord webhook gets a Data updated at <timestamp> ping, a cheap way to confirm the cron job actually fired
  • Manual trigger — hitting /update on the deployed worker re-runs the fetch-and-post cycle on demand, outside the cron schedule

Setup

git clone https://github.com/chethanyadav456/tech-updates
cd tech-updates
npm install
cp example.wrangler.toml wrangler.toml

Fill in wrangler.toml:

account_id = ""            # Cloudflare account ID
 
[vars]
DATABASE_URL = ""          # Prisma Accelerate connection string
DIRECT_DATABASE_URL = ""   # Direct Postgres connection string
TELEGRAM_BOT_TOKEN = ""
TECHCRUNCH_API_URL = ""
DISCORD_BOT_TOKEN = ""
DISCORD_WEBHOOK_URL = ""
APPLICATION_ID = ""        # Discord application ID
PUBLIC_KEY = ""             # Discord interactions public key
npm run deploy   # wrangler deploy -e build

Deploying registers the worker's scheduled handler (the cron trigger that runs the fetch-and-post job) and its fetch handler, which serves a health check at /, a manual trigger at /update, and Discord's interaction webhook everywhere else.

How It Works

The worker's scheduled export is the entry point on a cron trigger. Each run:

  1. Connects to Postgres through Prisma's edge client with the Accelerate extension (Workers can't hold a normal TCP connection pool, so Accelerate proxies it)
  2. Fetches the latest items from both the TechCrunch and Times of India endpoints
  3. Diffs each article's ID against what's already stored — new IDs are written to the database first, then sent, so a crash mid-send can't cause a re-send loop on the next run
  4. Posts new articles to the Telegram channel and to every guild in the subs table, one Discord message per subscribed channel
  5. Pings a Discord webhook to confirm the run completed

Discord slash commands are handled by the same worker, using cf-workers-discord to verify interaction signatures against PUBLIC_KEY and dispatch to command handlers (/subscribe, /unsubscribe, plus /ping and /help). /subscribe and /unsubscribe both require Administrator permission on the guild and just write or delete a row keyed by guildId in Postgres — there's no separate admin dashboard; the subscription state is the database.

View on GitHub ↗ · Telegram channel ↗