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

@ -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)