The HoYoLAB feed integration in this repository is implemented with reference/adaptation from hoyolab-discord-worker by GamerYuan.
That reference applies to the HoYoLAB RSS/feed handling part only, not the full system architecture.
This project is a self-hosted feed distribution service that sends social/game updates to Discord webhooks.
It is designed as a standalone notification engine (separate from your Discord bot), with dashboard management, dedupe/state tracking, and delivery retry/rate-limit handling.
-
Multi-source feed polling:
twitter,youtube,hoyolab -
Multi-webhook fan-out:
1 event -> N webhooks -
SQLite persistence for dedupe, queue state, subscriptions, and logs
-
Rate-limit aware dispatcher with retry/backoff
-
Dashboard backend (REST API) + React dashboard frontend
-
Per-feed HoYoLAB language selection
-
Post age policy to avoid posting old content
-
TOTP dashboard authentication (Google Authenticator compatible)
Scheduler (cron tick) -> Source Adapter (Twitter / YouTube / HoYoLAB) -> Normalize Post -> Dedupe (events) -> Fan-out (subscriptions) -> Deliveries queue (pending/retry/sent/dead) -> Discord webhook dispatcher
- Node.js
22.xrecommended (.nvmrc) - npm
- SQLite via
better-sqlite3
Node 24.x can be used in production, but better-sqlite3 must match your runtime ABI. If no prebuilt binary is available for your OS/arch, native build tools are required.
Typical Linux build dependencies:
sudo apt update
sudo apt install -y build-essential python3 make g++After switching Node version:
npm rebuild better-sqlite3Copy environment file:
cp .env.example .envInstall dependencies:
npm i
npm --prefix dashboard iBuild and type-check:
npm run check
npm run build
npm run dashboard:buildStart backend:
npm run devStart dashboard:
npm run dashboard:devDefault URLs:
- API:
http://localhost:8080 - Dashboard:
http://localhost:3000
Core runtime:
PORT=8080ROLE=all(all,api,worker)DB_PATH=./data/feed-engine.dbSCHEDULER_TICK_CRON=*/30 * * * * *DISPATCH_CONCURRENCY=5MAX_RETRY_ATTEMPTS=6MAX_POST_AGE_HOURS=24SUBSCRIPTION_BACKFILL_COUNT=1
Source credentials:
TWITTER_BEARER_TOKEN=...YOUTUBE_API_KEY=...HOYOLAB_ENDPOINT=https://bbs-api-os.hoyolab.com/community/post/wapi/userPost(or custom endpoint)
HoYoLAB-specific implementation supports:
- Polling by HoYoLAB UID
- Per-feed language code
- Pinned post filtering (
is_user_top) for better dedupe stability - Custom Discord embed output (title, description, read-more link, image, timestamp)
- Author profile URL mapping to
https://www.hoyolab.com/accountCenter/postList?id=<uid>
Supported language codes:
en-us, zh-cn, zh-tw, de-de, es-es, fr-fr, id-id, it-it,
ja-jp, ko-kr, pt-pt, ru-ru, th-th, tr-tr, vi-vn
twitter: link-only withhttps://fxtwitter.com/...(Discord handles embed preview)youtube: link-only withhttps://www.youtube.com/watch?v=...hoyolab: custom embed payload from normalized article data
Google Authenticator-compatible login is available for the dashboard.
Required env values:
DASHBOARD_AUTH_ENABLED=trueDASHBOARD_SETUP_KEY=<setup-key>DASHBOARD_AUTH_ISSUER=Hoyo Feed EngineDASHBOARD_AUTH_ACCOUNT=dashboard-adminDASHBOARD_SESSION_SECRET=<long-random-secret>DASHBOARD_SESSION_TTL_HOURS=24
Flow:
- First setup requires
DASHBOARD_SETUP_KEYto generate QR. - Scan QR in authenticator app and verify a 6-digit code.
- After setup is complete, new clients see login only (no QR setup screen).
Health:
GET /health
Feed CRUD:
GET /feedsPOST /feedsPUT /feeds/:idDELETE /feeds/:id
Webhook CRUD:
GET /webhooksPOST /webhooksPUT /webhooks/:idDELETE /webhooks/:id
Subscription CRUD:
GET /subscriptionsPOST /subscriptionsPUT /subscriptions/:idDELETE /subscriptions/:id
Operations and status:
POST /ops/tickGET /status/deliveriesGET /status/rate-limitsGET /logs?limit=200DELETE /logs
Auth:
GET /auth/statusPOST /auth/setup/startPOST /auth/setup/verifyPOST /auth/loginGET /auth/sessionPOST /auth/logout
Use ecosystem.config.cjs to split processes:
feed-engine-apiwithROLE=apifeed-engine-workerwithROLE=worker
pm2 start ecosystem.config.cjs
pm2 saveMain tables:
feedswebhookssubscriptionseventsdeliverieslogsauth_stateauth_sessions
Important constraints:
UNIQUE(events.source, events.external_post_id)UNIQUE(deliveries.event_id, deliveries.webhook_id)
- Timestamps are stored in UTC.
- Dashboard displays timestamps in
Asia/SEA (UTC+7). - Cooldown and retry behavior is applied automatically when upstream returns temporary/rate-limit errors.
- Upstream API quotas (Twitter/YouTube/HoYoLAB) may affect polling frequency.
- Discord webhook rate limits may delay sends.
better-sqlite3is a native module and requires ABI-compatible binaries/build tools on some environments.
- HoYoLAB feed reference/adaptation: GamerYuan/hoyolab-discord-worker
- Upstream project credited by that repo: UnluckyNinja/worker-bilibili-discord