NyawerXibox is a Telegram bot that provides donation notifications from Trakteer and Saweria, along with a donator leaderboard. Runs serverless on Cloudflare Workers with Upstash Redis.
- Real-time Donation Notifications: Sends incoming donation notifications from Trakteer and Saweria directly to the target Telegram group.
- Donator Leaderboard: Displays the top 10 donators based on cumulative donation amounts.
- Donation Statistics: Provides a quick summary of total donations, unique donators, transaction count, and the last donation time.
- Flexible Group Configuration: Group administrators configure the notification target via
/setgroup. - Notification Retry: Retries pending notifications every 5 minutes (cron), max 5 attempts, with admin alert on exhaustion.
- Secure Webhook Verification:
- Trakteer: constant-time token comparison via
X-Webhook-Tokenheader. - Saweria: constant-time secret comparison via
?secret=query parameter.
- Trakteer: constant-time token comparison via
Important
- Bot: @nyawerxibox_bot
- Community: t.me/xiboxcode_community
- Trakteer: https://trakteer.id/ikhsan3adi
- Saweria: https://saweria.co/xiboxann
- Bun - JavaScript runtime
- Cloudflare account (free tier)
- Upstash Redis database (free tier)
- Telegram bot token from @BotFather
git clone https://github.com/XiboxCode/NyawerXibox.git
cd NyawerXibox
bun installcp .env.example .dev.varsFill in all values in .dev.vars:
TELEGRAM_BOT_TOKEN- token from @BotFatherUPSTASH_REDIS_REST_URL+UPSTASH_REDIS_REST_TOKEN- from Upstash dashboardTRAKTEER_WEBHOOK_TOKEN- from Trakteer dashboard (Integrasi > Webhook)SAWERIA_SECRET- generate your own, e.g.openssl rand -hex 16
bun run deploy:fullThe script will prompt for CF_API_TOKEN (create at Cloudflare Dashboard - permission: Workers Edit), upload all secrets, and deploy the worker.
bun run webhook:set -- https://nyawer-xibox.<subdomain>.workers.dev| Platform | Webhook URL |
|---|---|
| Trakteer | https://nyawer-xibox.<subdomain>.workers.dev/webhook/trakteer |
| Saweria | https://nyawer-xibox.<subdomain>.workers.dev/webhook/saweria?secret=<SAWERIA_SECRET> |
- @BotFather >
/setprivacy> select bot > Disable - Add bot to your Telegram group
- Send
/setgroupin the group
- Runtime: Cloudflare Workers
- Framework: Elysia.js
- Database: Upstash Redis
- Local Runtime: Bun
- Testing: Vitest
- Validation: @sinclair/typebox
4-layer: Route > Service > Repository > Utils.
- Routes (
src/routes/): HTTP endpoints (webhooks, health check). No controllers or middleware. - Services (
src/services/): Business logic (donation processing, leaderboard, stats, commands). - Repositories (
src/repositories/): Data access layer (Redis via @upstash/redis). - Utils (
src/utils/): Helpers (formatRupiah,escapeMarkdown,generateDonationId,error-response,security). - Validators (
src/validators/): TypeBox schemas for webhook payload validation. - Parsers (
src/services/parsers/): Platform-specific payload parsers. Register new platforms here.
Dependency injection via Elysia .derive() lazy singleton in src/index.ts.
Copy .env.example to .dev.vars for local development, or use wrangler secret put <KEY> for production.
| Variable | Required | Description |
|---|---|---|
TELEGRAM_BOT_TOKEN |
Yes | Telegram Bot API token (from @BotFather) |
UPSTASH_REDIS_REST_URL |
Yes | Upstash Redis REST URL |
UPSTASH_REDIS_REST_TOKEN |
Yes | Upstash Redis REST token |
TRAKTEER_WEBHOOK_TOKEN |
Yes | Webhook token from Trakteer integration settings |
SAWERIA_SECRET |
Yes | Your own secret string. Must match the ?secret= query param in Saweria webhook URL |
TRAKTEER_URL |
No | Profile link for /donasi command |
SAWERIA_URL |
No | Profile link for /donasi command |
ADMIN_CHAT_ID |
No | Telegram chat ID for cron retry failure alerts |
ENVIRONMENT |
No | development or production |
bun run dev- Start local dev server (Wrangler)bun run test- Run unit tests (Vitest)bun run typecheck- TypeScript type check (tsc --noEmit)bun run deploy- Deploy to Cloudflare Workersbun run deploy:full- Upload secrets + deploybun run webhook:set -- <url>- Set Telegram webhook