refactor: replace Discord Gateway DO with Interaction Endpoint

This commit is contained in:
RhenCloud 2026-08-03 03:02:42 +08:00
parent 9bb9cb1444
commit d540d465d1
No known key found for this signature in database
GPG key ID: A574A617378C4E0B
27 changed files with 834 additions and 964 deletions

View file

@ -14,6 +14,7 @@ https://your-worker.workers.dev
| -------- | ------------------------------ | -------------- | ------------------------ |
| `GET` | `/health` | None | Health check |
| `POST` | `/webhook` | HMAC signature | GitHub webhook ingestion |
| `POST` | `/discord/interactions` | Ed25519 signature | Discord interactions (slash commands, buttons, modals) |
| `GET` | `/auth/github` | None | Start GitHub OAuth flow |
| `GET` | `/auth/github/callback` | None | OAuth callback |
| `DELETE` | `/auth/token/:userId` | None | Revoke user token |

View file

@ -14,14 +14,14 @@ npm run dev # Start local dev server
```text
src/
├── index.ts # CF Workers entry (fetch + scheduled), exports DiscordGateway DO
├── index.ts # CF Workers entry (fetch + scheduled), scheduled = command sync
├── types.ts # Env, Config, Route, Filter, WebhookEvent, FormattedMessage
├── config.ts # Loads routes from KV (returns [] if unset), builds Config from env
├── server.ts # Hono app: /health, /webhook, mounts /auth, /admin + /
├── server.ts # Hono app: /health, /webhook, /discord/interactions, mounts /auth, /admin + /
├── webhook.ts # HMAC verify (Web Crypto), parseEvent, extractBranch, matchRoute
├── discord.ts # Dispatch via Discord REST (DO RPC when gateway enabled), initGateway (scheduled)
├── discord.ts # Dispatch to Discord via REST (sendMessage)
├── discord-rest.ts # Discord REST sendMessage with retry + rate-limit handling
├── discord-gateway.ts # Durable Object: Discord Gateway WS, heartbeat, channel cache, send
├── discord-interactions.ts # Ed25519 verify + interaction handlers (/gh, buttons, modals) + command registration
├── formatter.ts # 23 event formatters + generic fallback
├── github-oauth.ts # OAuth URL, callback token exchange, getUserOctokit
├── oauth-routes.ts # GET /auth/github, callback, DELETE /token/:userId (KV state)

View file

@ -19,9 +19,10 @@ WebHooker requires several secrets to function. For local development, store the
| Variable | Description | Default |
| ------------------------- | ----------------------------------------------------------------------------------------------------- | ----------------------- |
| `DISCORD_PUBLIC_KEY` | Discord application public key (Developer Portal) — required for interactions | Unset → interactions return `401` |
| `DISCORD_APPLICATION_ID` | Discord application id; auto-resolved when omitted | Auto-resolved |
| `BASE_URL` | Public URL for OAuth callbacks | `http://localhost:8787` |
| `ADMIN_USER_IDS` | Comma-separated GitHub user IDs (or logins) allowed to access the Web UI | Disabled |
| `DISCORD_GATEWAY_ENABLED` | Set to `true` to connect the Discord Gateway (bot online status); messaging works without it via REST | `false` |
## Web UI
@ -180,4 +181,7 @@ Filters accept either a single string or an array of strings:
| `discord-link:{userId}` | GitHub user id linked to a Discord user | Permanent |
| `state:{hex}` | `{ redirectTo, expiresAt, discordUserId? }` | 600 seconds |
| `delivery:{id}` | Webhook delivery id (dedup marker) | 300 seconds |
| `cmd:guild:{id}` | Guild id whose commands were registered (dedup) | Permanent |
| `cmd:registered:global` | Global command registration marker (dedup) | 1 day |
| `config:discord-app-id` | Cached Discord application id | Permanent |
| `logs:send:{ts}-{hex}` | Send record | 1 hour |

View file

@ -30,6 +30,7 @@ npx wrangler secret put GITHUB_PRIVATE_KEY # PKCS#8 PEM (BEGIN PRIVATE KEY)
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 ADMIN_USER_IDS # comma-separated GitHub IDs/logins allowed into the Web UI
```
@ -48,7 +49,7 @@ openssl pkcs8 -topk8 -inform PEM -outform PEM -nocrypt \
Then upload `gh_pk_pkcs8.pem` as `GITHUB_PRIVATE_KEY`.
:::
The Discord Gateway is optional. Set `DISCORD_GATEWAY_ENABLED` in `wrangler.jsonc` `vars` (`"false"` by default). See [Gateway (optional)](#gateway-optional) below.
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](#interactions-endpoint) below.
### 3. Deploy
@ -106,14 +107,17 @@ Your worker is now live at `https://webhooker.<your-subdomain>.workers.dev`.
5. Configure target channels **per route** in the Web UI (`/admin`) — no global channel ID is required.
### Gateway (optional)
### Interactions Endpoint
Messages are sent via the Discord **REST API**, so pushing works with just `DISCORD_TOKEN`. The Gateway connection is only needed to (a) show the bot as **online** and (b) enable the in-Discord slash / context-menu commands.
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:
- `DISCORD_GATEWAY_ENABLED=false` (default): REST-only, no Gateway connection.
- `DISCORD_GATEWAY_ENABLED=true`: a Durable Object holds the Gateway connection and registers the `/gh` slash command plus the `GitHub: 添加/编辑/删除评论` message commands per guild.
1. Copy the application **Public Key** (Developer Portal → General Information) to `DISCORD_PUBLIC_KEY`.
2. Set the **Interactions Endpoint URL** to `https://your-domain/discord/interactions`.
3. Every interaction request is verified with Ed25519 signatures (`X-Signature-Ed25519` over `X-Signature-Timestamp + body`).
When enabled, users run `/gh login` to link their GitHub account and can then comment on issues/PRs as themselves. See the [README](https://github.com/ReCloudStudio/WebHooker#bot-commands-comment-on-github-as-yourself) for the full command reference.
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](https://github.com/ReCloudStudio/WebHooker#bot-commands-comment-on-github-as-yourself) for the full command reference.
## Custom Domain (Optional)
@ -132,4 +136,4 @@ docker build -t webhooker .
docker run -p 8787:8787 --env-file .env webhooker
```
Note: Docker mode runs without Durable Objects and KV. Use Cloudflare deployment for full functionality.
Note: Docker mode runs without KV and other Cloudflare storage. Use Cloudflare deployment for full functionality.

View file

@ -34,12 +34,13 @@ GITHUB_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----"
GITHUB_CLIENT_ID=your-client-id
GITHUB_CLIENT_SECRET=your-client-secret
DISCORD_TOKEN=your-bot-token
DISCORD_PUBLIC_KEY=your-public-key
ADMIN_USER_IDS=your-github-id,your-github-login
BASE_URL=http://localhost:8787
```
::: tip
`GITHUB_PRIVATE_KEY` must be in **PKCS#8** format (`BEGIN PRIVATE KEY`). Convert a GitHub-issued PKCS#1 key with `openssl pkcs8 -topk8 -nocrypt -in app.pem -out pkcs8.pem`. Target channels are set per route in the Web UI, so no `DISCORD_CHANNEL_ID` is needed. To keep the bot online and enable `/gh` slash commands locally, also set `DISCORD_GATEWAY_ENABLED=true`.
`GITHUB_PRIVATE_KEY` must be in **PKCS#8** format (`BEGIN PRIVATE KEY`). Convert a GitHub-issued PKCS#1 key with `openssl pkcs8 -nocrypt -in app.pem -out pkcs8.pem`. Target channels are set per route in the Web UI, so no `DISCORD_CHANNEL_ID` is needed. To enable `/gh` commands locally, copy the **Public Key** from the Developer Portal into `DISCORD_PUBLIC_KEY` and set the Interactions Endpoint URL to `http://localhost:8787/discord/interactions`.
:::
::: warning

View file

@ -1,6 +1,6 @@
# Introduction
WebHooker is a GitHub webhook dispatcher built on Cloudflare Workers. It receives GitHub webhook events, applies configurable filters, formats them into rich Discord embeds, and delivers them to Discord channels or threads through the Discord REST API. An optional Durable Object holds a Gateway connection to keep the bot online and power the in-Discord `/gh` commands. Routes are managed through a built-in Web UI.
WebHooker is a GitHub webhook dispatcher built on Cloudflare Workers. It receives GitHub webhook events, applies configurable filters, formats them into rich Discord embeds, and delivers them to Discord channels or threads through the Discord REST API. In-Discord `/gh` interactions arrive via an HTTPS Interactions Endpoint (Ed25519-verified). Routes are managed through a built-in Web UI.
## Architecture
@ -10,9 +10,9 @@ GitHub Webhook → Cloudflare Worker (Hono)
├── GET /auth/github → OAuth flow
├── POST /api/* → user actions (Bearer token auth)
├── /admin → routes & send-log Web UI (admin session)
└── GET /health → status check
└── GET /health → status check
(optional) Durable Object ⇄ Discord Gateway → bot online + /gh slash & context commands
POST /discord/interactions → verify (Ed25519) → handle /gh slash & context commands
```
### Components
@ -20,7 +20,7 @@ GitHub Webhook → Cloudflare Worker (Hono)
| Component | Role |
| ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| **Cloudflare Worker** | HTTP ingress, signature verification, delivery dedup, event parsing, route matching, REST send |
| **Durable Object (DiscordGateway)** | _Optional._ Keeps the Gateway connection alive (bot online) and handles `/gh` interactions |
| **Interactions Endpoint** | Verifies Ed25519 signatures and handles `/gh` interactions (slash commands, context-menu commands, buttons, modals) |
| **KV** | Token storage (`token:{userId}`), OAuth state (`state:{hex}`), route config (`config:routes`), send logs, delivery dedup |
### Data Flow
@ -37,7 +37,7 @@ GitHub Webhook → Cloudflare Worker (Hono)
- **Runtime**: Cloudflare Workers
- **HTTP Framework**: Hono
- **Discord delivery**: Discord REST API (Gateway via optional Durable Object for online status + `/gh` commands)
- **Discord delivery**: Discord REST API (interactions via an Ed25519-verified HTTPS Interactions Endpoint)
- **Web UI**: Nuxt 3 static SPA served from Worker assets
- **Storage**: Cloudflare KV
- **Auth**: Web Crypto API (HMAC-SHA256), jose (JWT), octokit (GitHub API)

View file

@ -19,11 +19,11 @@ features:
- title: Flexible Filtering
details: Filter by event type, repo, actor, action, branch (including PRs), and keyword (with regex support). Exclude patterns with a flag.
- title: Cloudflare Workers
details: Runs on Cloudflare's edge network. Sends via the Discord REST API, with an optional Durable Object Gateway connection for online status and slash commands.
details: Runs on Cloudflare's edge network. Sends via the Discord REST API, with an Ed25519-verified Interactions Endpoint for `/gh` slash commands and buttons.
- title: Web UI & Slash Commands
details: "Manage routes and view send logs from a built-in admin console. Link your GitHub account and comment on issues/PRs as yourself via /gh commands."
- title: Signature Verification
details: HMAC-SHA256 webhook signature verification using the Web Crypto API with timing-safe comparison.
details: HMAC-SHA256 webhook signature verification and Ed25519 interaction signature verification using the Web Crypto API with timing-safe comparison.
- title: Graceful Degradation
details: Runs in webhook-only mode if Discord token is unavailable. Health endpoint for monitoring.
---

View file

@ -14,6 +14,7 @@ https://your-worker.workers.dev
| -------- | ------------------------------ | ------------ | ------------------------ |
| `GET` | `/health` | 无 | 健康检查 |
| `POST` | `/webhook` | HMAC 签名 | GitHub webhook 接入 |
| `POST` | `/discord/interactions` | Ed25519 签名 | Discord 交互斜杠命令、按钮、modal |
| `GET` | `/auth/github` | 无 | 启动 GitHub OAuth 流程 |
| `GET` | `/auth/github/callback` | 无 | OAuth 回调 |
| `DELETE` | `/auth/token/:userId` | 无 | 撤销用户 Token |

View file

@ -14,14 +14,14 @@ npm run dev # 启动本地开发服务器
```text
src/
├── index.ts # CF Workers 入口 (fetch + scheduled)导出 DiscordGateway DO
├── index.ts # CF Workers 入口 (fetch + scheduled)scheduled = 命令同步
├── types.ts # Env、Config、Route、Filter、WebhookEvent、FormattedMessage
├── config.ts # 从 KV 加载路由(未设置时返回 []),从 env 构建 Config
├── server.ts # Hono 应用: /health、/webhook挂载 /auth、/admin + /
├── server.ts # Hono 应用: /health、/webhook、/discord/interactions,挂载 /auth、/admin + /
├── webhook.ts # HMAC 验证 (Web Crypto)、parseEvent、extractBranch、matchRoute
├── discord.ts # 通过 Discord REST 分发(启用 Gateway 时走 DO RPC、initGateway (scheduled)
├── discord.ts # 通过 Discord REST 分发 (sendMessage)
├── discord-rest.ts # Discord REST sendMessage带重试和限流处理
├── discord-gateway.ts # Durable Object: Discord Gateway WS、心跳、频道缓存、发送
├── discord-interactions.ts # Ed25519 验签 + 交互处理 (/gh、按钮、modal) + 命令注册
├── formatter.ts # 23 种事件格式化器 + 通用回退
├── github-oauth.ts # OAuth URL、回调 Token 交换、getUserOctokit
├── oauth-routes.ts # GET /auth/github、回调、DELETE /token/:userId (KV 状态)

View file

@ -17,11 +17,12 @@ WebHooker 需要多个密钥才能运行。本地开发时存储在 `.dev.vars`
### 可选密钥
| 变量 | 说明 | 默认值 |
| ------------------------- | -------------------------------------------------------------------------- | ----------------------- |
| `BASE_URL` | OAuth 回调的公开 URL | `http://localhost:8787` |
| `ADMIN_USER_IDS` | 允许访问 WebUI 的 GitHub 用户 ID或登录名逗号分隔 | 未设置时 WebUI 关闭 |
| `DISCORD_GATEWAY_ENABLED` | 设为 `true` 连接 Discord Gatewaybot 在线状态);不启用也能通过 REST 推送 | `false` |
| 变量 | 说明 | 默认值 |
| ------------------------ | ------------------------------------------------------ | ----------------------- |
| `BASE_URL` | OAuth 回调的公开 URL | `http://localhost:8787` |
| `ADMIN_USER_IDS` | 允许访问 WebUI 的 GitHub 用户 ID或登录名逗号分隔 | 未设置时 WebUI 关闭 |
| `DISCORD_PUBLIC_KEY` | Discord 应用的公钥(开发者门户获取),交互功能必需 | 未设置时交互返回 401 |
| `DISCORD_APPLICATION_ID` | Discord 应用 ID省略时自动获取 | 自动获取 |
## Web 控制台
@ -181,3 +182,6 @@ WebHooker 内置了位于 `/admin` 的配置控制台,可在浏览器中管理
| `state:{hex}` | `{ redirectTo, expiresAt, discordUserId? }` | 600 秒 |
| `delivery:{id}` | Webhook 投递 id去重标记 | 300 秒 |
| `logs:send:{ts}-{hex}` | 发送记录 | 1 小时 |
| `cmd:guild:{id}` | 已注册命令的服务器 id去重标记 | 永久 |
| `cmd:registered:global` | 全局命令已注册标记24h 去重) | 1 天 |
| `config:discord-app-id` | Discord 应用 id 缓存 | 永久 |

View file

@ -30,6 +30,7 @@ npx wrangler secret put GITHUB_PRIVATE_KEY # PKCS#8 PEMBEGIN PRIVATE KEY
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 应用的公钥(开发者门户获取),交互功能必需
npx wrangler secret put ADMIN_USER_IDS # 逗号分隔的 GitHub ID/登录名,允许进入 Web UI
```
@ -48,7 +49,7 @@ openssl pkcs8 -topk8 -inform PEM -outform PEM -nocrypt \
然后将 `gh_pk_pkcs8.pem` 作为 `GITHUB_PRIVATE_KEY` 上传。
:::
Discord Gateway 是可选的。在 `wrangler.jsonc``vars` 中设置 `DISCORD_GATEWAY_ENABLED`(默认为 `"false"`)。参见下方 [Gateway可选](#gateway可选)。
Discord 交互通过 HTTPS Interactions Endpoint 送达,需要设置 `DISCORD_PUBLIC_KEY` 并把 **Interactions Endpoint URL** 指向 `https://your-domain/discord/interactions`。参见下方 [Interactions Endpoint](#interactions-endpoint)。
### 3. 部署
@ -106,14 +107,17 @@ Worker 现在可通过 `https://webhooker.<your-subdomain>.workers.dev` 访问
5. 在 Web UI`/admin`)中**按路由**配置目标频道——无需全局频道 ID。
### Gateway可选
### Interactions Endpoint
消息通过 Discord **REST API** 发送,因此仅凭 `DISCORD_TOKEN` 即可推送。Gateway 连接仅用于:(a) 让 Bot 显示为**在线**(b) 启用 Discord 内的斜杠 / 右键菜单命令。
消息通过 Discord **REST API** 发送,因此仅凭 `DISCORD_TOKEN` 即可推送。交互斜杠命令、按钮、modal则通过 HTTPS Interactions Endpoint 送达:
- `DISCORD_GATEWAY_ENABLED=false`(默认):仅 REST不建立 Gateway 连接。
- `DISCORD_GATEWAY_ENABLED=true`:由一个 Durable Object 持有 Gateway 连接,并按服务器注册 `/gh` 斜杠命令以及 `GitHub: 添加/编辑/删除评论` 消息命令。
1. 在 Discord 开发者门户 → General Information 复制应用的 **Public Key**,填入 `DISCORD_PUBLIC_KEY`
2. 将 **Interactions Endpoint URL** 设为 `https://your-domain/discord/interactions`
3. 所有交互请求都使用 Ed25519 签名验证(`X-Signature-Ed25519` 覆盖 `X-Signature-Timestamp + body`)。
启用后,用户运行 `/gh login` 绑定自己的 GitHub 账号,即可以本人身份评论 issue/PR。完整命令说明见 [README](https://github.com/ReCloudStudio/WebHooker#bot-commands-comment-on-github-as-yourself)。
`/gh` 斜杠命令与 `GitHub: 添加/编辑/删除评论` 消息命令由定时任务(每 5 分钟同步注册按服务器即时可用同时全局注册24h 去重,约 1 小时传播。Bot 从不连接 Discord Gateway因此显示为**离线**——消息推送不受影响(始终走 REST
用户运行 `/gh login` 绑定自己的 GitHub 账号,即可以本人身份评论 issue/PR。完整命令说明见 [README](https://github.com/ReCloudStudio/WebHooker#bot-commands-comment-on-github-as-yourself)。
## 自定义域名(可选)
@ -132,4 +136,4 @@ docker build -t webhooker .
docker run -p 8787:8787 --env-file .env webhooker
```
注意Docker 模式下不包含 Durable Objects 和 KV。完整功能请使用 Cloudflare 部署。
注意Docker 模式下不包含 KV 等 Cloudflare 存储。完整功能请使用 Cloudflare 部署。

View file

@ -34,12 +34,13 @@ GITHUB_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----"
GITHUB_CLIENT_ID=your-client-id
GITHUB_CLIENT_SECRET=your-client-secret
DISCORD_TOKEN=your-bot-token
DISCORD_PUBLIC_KEY=your-public-key
ADMIN_USER_IDS=your-github-id,your-github-login
BASE_URL=http://localhost:8787
```
::: tip
`GITHUB_PRIVATE_KEY` 必须是 **PKCS#8** 格式(`BEGIN PRIVATE KEY`)。用 `openssl pkcs8 -topk8 -nocrypt -in app.pem -out pkcs8.pem` 转换 GitHub 下发的 PKCS#1 私钥。目标频道在 Web UI 中按路由设置,因此不需要 `DISCORD_CHANNEL_ID`。若要让 Bot 保持在线并在本地启用 `/gh` 斜杠命令,可额外设置 `DISCORD_GATEWAY_ENABLED=true`。
`GITHUB_PRIVATE_KEY` 必须是 **PKCS#8** 格式(`BEGIN PRIVATE KEY`)。用 `openssl pkcs8 -nocrypt -in app.pem -out pkcs8.pem` 转换 GitHub 下发的 PKCS#1 私钥。目标频道在 Web UI 中按路由设置,因此不需要 `DISCORD_CHANNEL_ID`。若要在本地启用 `/gh` 命令,请在开发者门户复制 **Public Key** 填入 `DISCORD_PUBLIC_KEY`,并把 Interactions Endpoint URL 设为 `http://localhost:8787/discord/interactions`。
:::
::: warning

View file

@ -1,6 +1,6 @@
# 简介
WebHooker 是一个基于 Cloudflare Workers 构建的 GitHub webhook 调度器。它接收 GitHub webhook 事件,应用可配置的过滤器,将事件格式化为丰富的 Discord 嵌入消息,并通过 Discord REST API 投递到 Discord 频道或帖子。一个可选的 Durable Object 持有 Gateway 连接,用于让 Bot 保持在线并支持 Discord 内的 `/gh` 命令。路由通过内置的 Web UI 管理。
WebHooker 是一个基于 Cloudflare Workers 构建的 GitHub webhook 调度器。它接收 GitHub webhook 事件,应用可配置的过滤器,将事件格式化为丰富的 Discord 嵌入消息,并通过 Discord REST API 投递到 Discord 频道或帖子。Discord 内的 `/gh` 交互通过 HTTPS Interactions EndpointEd25519 验签)送达。路由通过内置的 Web UI 管理。
## 架构
@ -12,7 +12,7 @@ GitHub Webhook → Cloudflare Worker (Hono)
├── /admin → 路由与发送日志 Web UI管理员会话
└── GET /health → 健康检查
可选Durable Object ⇄ Discord Gateway → Bot 在线 + /gh 斜杠与右键命令
POST /discord/interactions → 验证 (Ed25519) → 处理 /gh 斜杠与右键命令
```
### 组件
@ -20,7 +20,7 @@ GitHub Webhook → Cloudflare Worker (Hono)
| 组件 | 职责 |
| ----------------------------------- | --------------------------------------------------------------------------------------------------------- |
| **Cloudflare Worker** | HTTP 入口、签名验证、投递去重、事件解析、路由匹配、REST 发送 |
| **Durable Object (DiscordGateway)** | _可选。_ 保持 Gateway 连接Bot 在线)并处理 `/gh` 交互 |
| **Interactions Endpoint** | 验证 Ed25519 签名并处理 `/gh` 交互斜杠命令、右键菜单、按钮、modal |
| **KV** | Token 存储 (`token:{userId}`)、OAuth 状态 (`state:{hex}`)、路由配置 (`config:routes`)、发送日志、投递去重 |
### 数据流
@ -37,7 +37,7 @@ GitHub Webhook → Cloudflare Worker (Hono)
- **运行时**: Cloudflare Workers
- **HTTP 框架**: Hono
- **Discord 投递**: Discord REST APIGateway 通过可选的 Durable Object 提供在线状态与 `/gh` 命令
- **Discord 投递**: Discord REST API交互通过 Ed25519 验签的 HTTPS Interactions Endpoint
- **Web UI**: Nuxt 3 静态 SPA由 Worker 资源托管
- **存储**: Cloudflare KV
- **鉴权**: Web Crypto API (HMAC-SHA256)、jose (JWT)、octokit (GitHub API)

View file

@ -19,11 +19,11 @@ features:
- title: 灵活的过滤器
details: 支持按事件类型、仓库、参与者、操作、分支(含 PR和关键字支持正则过滤。支持排除模式。
- title: Cloudflare Workers
details: 运行在 Cloudflare 边缘网络上。通过 Discord REST API 发送消息,并可选地用 Durable Object 维持 Gateway 连接以提供在线状态与斜杠命令。
details: 运行在 Cloudflare 边缘网络上。通过 Discord REST API 发送消息,并通过 Ed25519 验签的 Interactions Endpoint 支持 `/gh` 命令。
- title: Web UI 与斜杠命令
details: "在内置管理控制台中管理路由、查看发送日志。绑定你的 GitHub 账号,通过 /gh 命令以本人身份评论 issue/PR。"
- title: 签名验证
details: 使用 Web Crypto API 进行 HMAC-SHA256 webhook 签名验证,支持时间安全比较。
details: 使用 Web Crypto API 进行 HMAC-SHA256 webhook 签名验证与 Ed25519 交互签名验证,支持时间安全比较。
- title: 优雅降级
details: 当 Discord Token 不可用时以 webhook-only 模式运行。提供健康检查端点用于监控。
---