- Update event formatter count 23 -> 28 (add ping, workflow_job, status, deployment, check_suite) - Document Telegram support end-to-end (routes, /gh commands, richheader, secrets) - Fix route schema to use targets array and group fields (owners, emoji) - Correct KV/D1 storage layout (msg:*, i18n:*, D1 links/send_logs) - Note GITHUB_APP_ID/GITHUB_PRIVATE_KEY are unused; drop legacy DISCORD_CHANNEL_ID/PORT/CONFIG_PATH - Remove stale Docker deployment section - Update color table, branch filter compatibility, admin API endpoints - AGENTS.md: add Documentation section requiring doc updates after functional changes
6.3 KiB
Deployment
Cloudflare Setup
1. Create KV Namespace
npx wrangler kv namespace create KV
This outputs a namespace ID. Update wrangler.jsonc with the ID:
{
"kv_namespaces": [
{
"binding": "KV",
"id": "your-namespace-id",
},
],
}
2. Set Secrets
npx wrangler secret put GITHUB_WEBHOOK_SECRET
npx wrangler secret put GITHUB_CLIENT_ID
npx wrangler secret put GITHUB_CLIENT_SECRET
npx wrangler secret put DISCORD_TOKEN
npx wrangler secret put DISCORD_PUBLIC_KEY # Discord app public key (Developer Portal) — required for interactions
npx wrangler secret put TELEGRAM_TOKEN # Telegram bot token (BotFather) — required for Telegram routes
npx wrangler secret put ADMIN_USER_IDS # comma-separated GitHub IDs/logins allowed into the Web UI
::: tip Target channels are configured per route
There is no global channel secret. Each route in the Web UI declares its own target channel (and optional thread), so DISCORD_CHANNEL_ID is not needed.
:::
::: tip GitHub App ID / private key are unused
GITHUB_APP_ID and GITHUB_PRIVATE_KEY are not currently used by the code — the
OAuth flow only needs GITHUB_CLIENT_ID / GITHUB_CLIENT_SECRET. You do not need to
set them (no PKCS#8 conversion required).
:::
Discord interactions arrive via the HTTPS Interactions Endpoint, so set DISCORD_PUBLIC_KEY and point the Interactions Endpoint URL at https://your-domain/discord/interactions. See Interactions Endpoint below.
3. Deploy
npx wrangler deploy
Your worker is now live at https://webhooker.<your-subdomain>.workers.dev.
4. Configure GitHub Webhook
- Go to your GitHub App settings
- Set Webhook URL to
https://webhooker.<your-subdomain>.workers.dev/webhook - Set Webhook secret to match
GITHUB_WEBHOOK_SECRET
GitHub App Setup
1. Create App
- Go to https://github.com/settings/apps/new
- Fill in:
- GitHub App name:
WebHooker(or your choice) - Homepage URL: your domain
- Webhook URL:
https://your-domain/webhook - Webhook secret: generate and copy to
GITHUB_WEBHOOK_SECRET
- GitHub App name:
- Set permissions:
- Repository permissions: Contents (read), Issues (write), Pull requests (write), Metadata (read), Checks (read), Deployments (read), Discussions (read), Code scanning alerts (read), Dependabot alerts (read)
- Organization permissions: Members (read) — if needed
- Subscribe to events (all 28 supported):
- Push, Pull request, Issues, Issue comment, Workflow run, Workflow job, Status, Deployment, Deployment status, Ping, Release, Create, Delete, Star, Fork, Check run, Check suite, Pull request review, Pull request review comment, Commit comment, Member, Label, Milestone, Discussion, Discussion comment, Repository, Code scanning alert, Dependabot alert
- Generate private key → save contents to
GITHUB_PRIVATE_KEYenv var
2. Install App
- After creation, go to the App settings page
- Click "Install App" → select org/user
- Choose repositories to monitor
3. Configure OAuth
- Go to App → OAuth settings
- Set Callback URL:
https://your-domain/auth/github/callback - Copy Client ID and Client Secret to env
Discord Bot Setup
-
Create a new application → go to Bot section
-
Copy the bot token to
DISCORD_TOKEN -
Invite the bot with the
botandapplications.commandsscopes and theView Channels+Send Messages+Send Messages in Threadspermissions (combined integer274877910016):https://discord.com/oauth2/authorize?client_id=YOUR_BOT_CLIENT_ID&permissions=274877910016&scope=bot+applications.commands -
Configure target channels per route in the Web UI (
/admin) — no global channel ID is required.
Interactions Endpoint
Messages are sent via the Discord REST API, so pushing works with just DISCORD_TOKEN. Interactions (slash commands, buttons, modals) arrive through the HTTPS Interactions Endpoint:
- Copy the application Public Key (Developer Portal → General Information) to
DISCORD_PUBLIC_KEY. - Set the Interactions Endpoint URL to
https://your-domain/discord/interactions. - Every interaction request is verified with Ed25519 signatures (
X-Signature-Ed25519overX-Signature-Timestamp + body).
The /gh slash command and the GitHub: 添加/编辑/删除评论 message commands are synced by the scheduled trigger (every 5 minutes): per-guild for instant availability, plus a global registration (24h dedup, ~1h propagation). The bot never connects to the Discord Gateway, so it shows as offline — messaging is unaffected (always REST).
Users run /gh login to link their GitHub account and can then comment on issues/PRs as themselves. See the README for the full command reference.
Telegram Bot Setup
- Create a bot with @BotFather and copy its token to
TELEGRAM_TOKEN. - (Optional) Set
TELEGRAM_WEBHOOK_SECRET; the webhook registration passes it to Telegram assecret_token, andPOST /telegram/webhookverifies it with a timing-safe compare. - The worker syncs the webhook from the scheduled trigger (
setWebhookto{BASE_URL}/telegram/webhook), so no manualsetWebhookcall is needed — just make sureBASE_URLis set. - Add the bot to a group (or enable topics) and route events to
chatId/topicIdin the route config.
In Telegram, /gh commands work by replying to a notification message:
/gh login— link your GitHub account (returns an OAuth link)/gh logout— unlink/gh comment <text>— reply to an issue/PR notification to comment as yourself/gh merge//gh close— reply to a PR notification to merge/close it
Avatars are rendered as a link-preview card using the built-in GET /api/richheader (overridable with TELEGRAM_RICH_HEADER_HOST).
Custom Domain (Optional)
To use a custom domain instead of *.workers.dev:
- Go to your Cloudflare Worker settings
- Add a custom domain or route
- Update
BASE_URLto match
Note
This project is a Cloudflare Worker. It requires the KV and D1 bindings declared in
wrangler.jsonc, so it cannot run as a standalone Node/container process.