- JavaScript 100%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| bridges | ||
| .gitignore | ||
| PLUGIN_DEVELOPMENT.md | ||
| README.md | ||
| worker.js | ||
| wrangler.toml | ||
Worker RSS Bridge
Single-file Cloudflare Worker RSS bridge implemented in worker.js.
Bridge plugins live in bridges/. Add a new site by creating a new plugin file
that exports a standard bridge object, then register it in worker.js.
See PLUGIN_DEVELOPMENT.md for the full plugin interface, caching behavior,
development checklist, and validation commands.
Routes
/- HTML usage page/health- JSON health check/feed?bridge=nikkeiAsiaChina/feed/nikkeiAsiaChina?category=chinaTech&limit=15&fulltext=true/feed?bridge=bbcWorld/feed/bbcWorld?limit=20&fulltext=false/feed?bridge=apNews/feed/apNews?category=world&limit=20&fulltext=true/feed?bridge=abcNewsJustIn/feed/abcNewsJustIn?category=world&limit=20&fulltext=true/feed/linuxDo?limit=20&fulltext=true/feed/jin10Topics?category=middleEast&limit=30/feed/samsungMobileW24?limit=20/feed/innomad?limit=20&fulltext=true/feed/nessLabs?limit=20&fulltext=true/feed/foreverBlog?limit=30/feed/bokequan?limit=40/feed/hiKebaHost?limit=30&fulltext=true/feed/reutersMobile?category=world&limit=20/feed/pbcNews?limit=30/feed/ftChinese?limit=20&fulltext=false/feed/nytimesChinese?category=world&limit=20&fulltext=true/feed/politicoMobile?category=latestNews&limit=20&fulltext=true/feed/theAtlantic?limit=20&fulltext=true/feed/flyertDigest?limit=30/feed/bloombergMobile?category=latest&limit=20&fulltext=true/feed/scmpFullText?limit=20&fulltext=true/feed/morganStanleyGlobal?limit=20/feed/morganStanleyChina?limit=20/image?url=...- cached image proxy/telegram?chat_id=-1001234567890&limit=20- RSS from Telegram Bot API updates/telegram?channel=public_channel_name&limit=20- same feed, after the bot has received a post from the channel/telegram/webhook- Telegram Bot API webhook receiver
BBC World
BBC World News bridge:
/feed?bridge=bbcWorld
/feed/bbcWorld?limit=15&fulltext=true
Parameters:
category:worldlimit: 1-50, default 15fulltext: default true; use0orfalsefor summary mode
AP News
AP News bridge:
/feed?bridge=apNews
/feed/apNews?category=world&limit=15&fulltext=true
Parameters:
category:home,factCheck,us,world,investigationslimit: 1-50, default 15fulltext: default true; use0orfalsefor summary mode
ABC News
ABC News bridge:
/feed?bridge=abcNewsJustIn
/feed/abcNewsJustIn?limit=15&fulltext=true
/feed/abcNewsJustIn?category=world&limit=15&fulltext=true
/feed/abcNewsJustIn?category=world&limit=10&fulltext=false
Parameters:
category:justIn,worldlimit: 1-50, default 15fulltext: default true; use0orfalsefor summary mode
Nikkei Asia secret
Full logged-in article content can use a Worker Secret:
wrangler secret put NIKKEI_ASIA_COOKIE
Migrated PHP sources
linuxDofromquanwenrss.com_tjfZJ/linux.do/linux.do.phpjin10Topicsfromquanwenrss.com_tjfZJ/jin10/jin10.phpsamsungMobileW24fromquanwenrss.com_tjfZJ/blog/samsungmobile/samsungmobile.phpinnomadfromquanwenrss.com_tjfZJ/blog/innomad.io/generate_rss.phpnessLabsfromquanwenrss.com_tjfZJ/blog/nesslabs/nesslabs_rss.phpforeverBlogfromquanwenrss.com_tjfZJ/blog/foreverblog/fetch_rss.phpbokequanfromquanwenrss.com_tjfZJ/blog/bokequan/bokequan_rss.phphiKebaHostfromquanwenrss.com_tjfZJ/blog/keba.host/generate_hi_keba_rss.phpreutersMobilefromquanwenrss.com_tjfZJ/reuters/reuters_rss.phppbcNewsfromquanwenrss.com_tjfZJ/pbc/zhengcejiedu.phpftChinesefromquanwenrss.com_tjfZJ/ftchinese/ft_rss_gen.phpnytimesChinesefromquanwenrss.com_tjfZJ/nytimes/nytimes_rss.phppoliticoMobilefromquanwenrss.com_tjfZJ/politico/rss.phpand its category config inquanwenrss.com_tjfZJ/politico/config.phptheAtlanticfromquanwenrss.com_tjfZJ/Atlantic/rss.phpflyertDigestfromquanwenrss.com_tjfZJ/flyert/flyert-digest-rss.phpbloombergMobilefromquanwenrss.com_tjfZJ/bloomberg/bloomberg.phpscmpFullTextfromquanwenrss.com_tjfZJ/scmp/scmp.phpmorganStanleyGlobalfromquanwenrss.com_tjfZJ/morganstanley/morganstanley_global_rss.phpmorganStanleyChinafromquanwenrss.com_tjfZJ/morganstanley/morganstanley_rss.php
Excluded source artifacts
These old PHP files are intentionally not separate Worker plugins:
quanwenrss.com_tjfZJ/bloomberg/feeds/bilingual_rss.php- DeepL translation post-processor for generated RSS filesquanwenrss.com_tjfZJ/morganstanley/generate_all_rss.php- batch wrapper around the two Morgan Stanley generatorsquanwenrss.com_tjfZJ/reuters/reuters_api_scraper.php- older Reuterspf/api/v3generator; the endpoint returned 401 during migration, soreutersMobileuses the working mobile API insteadquanwenrss.com_tjfZJ/reuters/reuters_api_scraper_debug.php- diagnostic helper for the old Reuters APIquanwenrss.com_tjfZJ/scmp/fetch_articles.php- database population job;scmpFullTextfetches RSS and article pages directlyquanwenrss.com_tjfZJ/scmp/generate_atom.php- database-to-Atom generator;scmpFullTextrenders RSS in the Worker
Generated XML, caches, databases, translation post-processors, .env files,
and vendor/ files are source artifacts, not Worker plugins.
SCMP secret
SCMP full text can use a Worker Secret for article cookies:
wrangler secret put SCMP_COOKIES
Scheduled feed pre-generation
Slow full-text feeds can be pre-generated by Cron and served from KV. This keeps reader requests fast after the scheduled job has warmed the XML cache.
Create a KV namespace and bind it as FEED_CACHE:
npx wrangler kv namespace create FEED_CACHE
Add the returned namespace ID to wrangler.toml:
[[kv_namespaces]]
binding = "FEED_CACHE"
id = "your-kv-namespace-id"
Configure the public Worker URL and the feeds to pre-generate:
[vars]
FEED_BASE_URL = "https://your-worker-domain.example"
FEED_PREGENERATE_URLS = """
/feed/apNews?category=world&limit=15&fulltext=true
/feed/abcNewsJustIn?category=world&limit=15&fulltext=true
"""
FEED_CACHE_FRESH_SECONDS = "1800"
FEED_CACHE_STALE_SECONDS = "86400"
FEED_PREGENERATE_URLS accepts newline-separated paths, comma-separated paths,
or a JSON array. Absolute feed URLs also work and do not need FEED_BASE_URL.
Telegram Bot API feeds
The Telegram route is API-based and never scrapes t.me/s. It also supports
private and restricted channels, provided the bot can receive their posts.
Create a bot with BotFather, add it to each source channel as an administrator,
and bind a KV namespace as TELEGRAM_FEEDS (it may use the same namespace as
FEED_CACHE):
[[kv_namespaces]]
binding = "TELEGRAM_FEEDS"
id = "your-kv-namespace-id"
Set these Worker secrets:
wrangler secret put TELEGRAM_BOT_TOKEN
wrangler secret put TELEGRAM_WEBHOOK_SECRET
Register the webhook, replacing the placeholders with the deployed Worker URL, bot token, and the exact webhook secret:
curl "https://api.telegram.org/bot<BOT_TOKEN>/setWebhook?url=https%3A%2F%2Fyour-worker.example%2Ftelegram%2Fwebhook&secret_token=<WEBHOOK_SECRET>&allowed_updates=%5B%22channel_post%22%2C%22edited_channel_post%22%5D"
Telegram only delivers posts created after the bot is made an administrator and the webhook is registered; its Bot API cannot fetch a channel's earlier history. Once the first post is received, use the numeric chat id shown by the update or the channel username:
/telegram?chat_id=-1001234567890&limit=20
/telegram?channel=public_channel_name&limit=20
Channel photos are served through /telegram/media so the bot token remains a
Worker secret.
Deploy
npx wrangler deploy