# bzzrt A Cloudflare Worker that polls RSS and Atom feeds for new entries and posts them to Discord channels via webhooks. ## Features - **Multi-format feed support** — Handles RSS, Atom, RDF, and JSON Feed via [feedsmith](https://github.com/macieklamberski/feedsmith) - **Multi-feed, multi-channel** — Monitor any number of feeds and route each to one or more Discord channels - **Deduplication** — Tracks the last-seen entry date per feed in Cloudflare KV to avoid reposting - **Cron-driven** — Runs automatically every 5 minutes via Cloudflare's cron triggers - **Manual trigger** — `GET /check` to trigger a feed check on demand - **Discord embeds** — Posts entries as rich embeds with title, link, summary, timestamp, and author ## Architecture ``` feeds.json — Feed URL → Discord channel mapping worker.js — Main worker: cron handler, fetch handler, feed checking, Discord posting wrangler.toml — Cloudflare Worker configuration .dev.vars — Local-only secrets (WEBHOOKS) ``` **Flow:** 1. Every 5 minutes (or on `GET /check`), the worker iterates over feeds defined in `feeds.json` 2. For each feed, it fetches the URL, parses it with `parseFeed()`, and normalizes entries into a common shape 3. It compares entry dates against the last-posted timestamp stored in Cloudflare KV 4. New entries are posted as embeds to the configured Discord webhook(s) 5. The latest entry date is saved back to KV ## Setup ### Prerequisites - Node.js - A Cloudflare account with Workers enabled - A Cloudflare KV namespace - One or more Discord webhook URLs ### Configuration **feeds.json** — Map feed URLs to Discord channel names: ```json { "https://example.com/feed.xml": ["general"], "https://example.com/blog/atom.xml": ["blog", "general"] } ``` **WEBHOOKS secret** — A JSON object mapping channel names to Discord webhook URLs. Set it as a Cloudflare secret: ```bash npx wrangler secret put WEBHOOKS # Paste: {"general":"https://discord.com/api/webhooks/...","blog":"https://discord.com/api/webhooks/..."} ``` For local development, put the same value in `.dev.vars`: ``` WEBHOOKS = {"general":"https://discord.com/api/webhooks/..."} ``` **wrangler.toml** — Update the KV namespace ID if creating a new one: ```bash npx wrangler kv namespace create KV # Update the id in wrangler.toml ``` ## Development ```bash npm install npx wrangler dev --test-scheduled ``` The worker runs locally at `http://localhost:8787`. Visit `/check` to trigger a feed check, or `/__scheduled` to simulate a cron trigger. ## Deployment ```bash npx wrangler deploy ``` Wrangler bundles the worker and deploys it to Cloudflare with the cron trigger active.