A Cloudflare Worker that aggregates gaming news from RSS feeds and GitHub releases, transforming them into GameHub's API format with custom HTML styling.
- 🎮 RSS Feed Support: Fetches and parses gaming news from RSS feeds
- 📦 GitHub Releases: Tracks 14 emulation/gaming projects
- 🎨 Custom HTML Styling: Mobile-optimized articles with GameHub theming
- đź’ľ Smart Caching: 1-hour cache with KV storage (auto-refresh)
- đź“„ Pagination: Lazy loading support (4 items per page)
- 🖼️ Image Control: Hides inline images while keeping header images
- 🔄 Auto-Refresh: Cache expires and rebuilds automatically
- Rock Paper Shotgun - PC gaming news
- URL:
https://www.rockpapershotgun.com/feed/news
- URL:
- FEX-Emu/FEX - x86/x86-64 emulator
- ptitSeb/box64 - x86-64 Linux emulator for ARM64
- ptitSeb/box86 - x86 Linux emulator for ARM
- GloriousEggroll/wine-ge-custom - Wine with gaming patches
- doitsujin/dxvk - DirectX to Vulkan translation
- HansKristian-Work/vkd3d-proton - Direct3D 12 to Vulkan
- ValveSoftware/Proton - Steam Play compatibility tool
- bottlesdevs/Bottles - Wine prefix manager
- lutris/lutris - Open gaming platform
- Heroic-Games-Launcher/HeroicGamesLauncher - Epic/GOG launcher
- flathub/flathub - Linux app distribution
- Kron4ek/Wine-Builds - Wine packages
- fastfetch-cli/fastfetch - System info tool
- FeralInteractive/gamemode - Game performance optimizer
cd news-aggregator-worker
npm installnpx wrangler kv:namespace create NEWS_CACHECopy the namespace ID and update wrangler.toml:
[[kv_namespaces]]
binding = "NEWS_CACHE"
id = "your_namespace_id_here"npm run deployGet paginated news list in GameHub format
Query Parameters:
page(optional): Page number (default: 1)page_size(optional): Items per page (default: 30)
Example:
curl "https://gamehub-news-aggregator.secureflex.workers.dev/api/news/list?page=1&page_size=4"Response:
{
"code": 200,
"msg": "",
"time": "1760032301",
"data": {
"title": "Gaming News & Updates",
"total": 28,
"page": 1,
"page_size": 4,
"card_list": [
{
"id": 1,
"cover_image": "https://...",
"title": "New game release...",
"time": "2025-10-09",
"source": "rps"
}
]
}
}Get full article with custom HTML styling
Example:
curl "https://gamehub-news-aggregator.secureflex.workers.dev/api/news/detail/1"Response:
{
"code": 200,
"msg": "",
"time": "1760032301",
"data": {
"cover_image": "https://...",
"title": "Article Title",
"content": "<html>...</html>",
"time": "2025-10-09"
}
}Force cache refresh (fetches fresh data from all sources)
Example:
curl -X GET "https://gamehub-news-aggregator.secureflex.workers.dev/api/news/refresh"View current news sources configuration
Articles are rendered with custom CSS for mobile reading:
- White text on dark background (#FFFFFF)
- Clean typography (16px base, 1.6 line height)
- Header image at top (full width, auto height)
- Hidden inline images (only header visible)
- Responsive layout (20px padding)
- Links styled in light blue (#4A9EFF)Storage: Cloudflare KV TTL: 1 hour (3600 seconds) Keys:
news:list- Main aggregated news listnews:detail:{id}- Individual article HTML content
Auto-Refresh: Cache expires after 1 hour, next request triggers rebuild
Edit src/config.js to modify news sources:
export const NEWS_SOURCES = {
rss: [
{
id: 'unique-id',
url: 'https://example.com/feed',
title: 'News Source',
subtitle: 'Gaming News'
}
]
};export const NEWS_SOURCES = {
github: [
{
id: 'unique-id',
owner: 'username',
repo: 'repository',
subtitle: 'Project Name'
}
]
};The main GameHub API worker forwards news requests:
// Forward news list requests
if (url.pathname === '/card/getNewsList' && request.method === 'POST') {
const body = await request.json();
const page = body.page || 1;
const pageSize = body.page_size || 4;
const newsResponse = await fetch(
`${NEWS_AGGREGATOR_URL}/api/news/list?page=${page}&page_size=${pageSize}`
);
return new Response(await newsResponse.text(), {
headers: { 'Content-Type': 'application/json' }
});
}
// Forward news detail requests
if (url.pathname === '/card/getNewsGuideDetail' && request.method === 'POST') {
const body = await request.json();
const newsId = body.id;
const newsDetailResponse = await fetch(
`${NEWS_AGGREGATOR_URL}/api/news/detail/${newsId}`
);
return new Response(await newsDetailResponse.text(), {
headers: { 'Content-Type': 'application/json' }
});
}Run locally:
npm run devVisit: http://localhost:8787/api/news/list
View logs:
npm run tail- Cold Start: ~200ms
- Cached Response: <50ms
- Cache Rebuild: ~2-3 seconds (fetches all sources)
- Memory: <10MB
- Cost: Free tier (< 100k requests/day)
Some sites block Cloudflare Workers. Try:
- Use alternative RSS feeds
- Check if site has a
/feed/rssor/feed.xmlendpoint
- Unauthenticated: 60 requests/hour
- Solution: Using
.atomfeeds instead of API (no rate limits)
# Manual refresh
curl -X GET "https://your-worker.workers.dev/api/news/refresh"
# Check KV storage
npx wrangler kv:key list --binding=NEWS_CACHE- Articles automatically styled for mobile (GameHub WebView)
- Images are lazily loaded (header image visible, inline images hidden)
- GitHub releases use RSS feeds to avoid API rate limits
- All timestamps converted to Unix epoch for GameHub compatibility
- News is sorted by date (newest first)