docs: align VitePress site with REST send, optional gateway and slash commands

- deployment: drop DISCORD_CHANNEL_ID, add ADMIN_USER_IDS, PKCS#8 key note,
  applications.commands invite scope, and an optional Gateway section
- getting-started: PKCS#8 .dev.vars example, remove channel ID
- introduction: REST delivery, optional DiscordGateway DO, delivery dedup,
  /admin Web UI in architecture and data flow
- index: refresh Workers feature, add Web UI & slash commands feature
This commit is contained in:
RhenCloud 2026-08-02 07:02:40 +08:00
parent f456c979f7
commit d996dbe45d
No known key found for this signature in database
GPG key ID: A574A617378C4E0B
8 changed files with 133 additions and 55 deletions

View file

@ -26,13 +26,30 @@ npx wrangler kv namespace create KV
```bash
npx wrangler secret put GITHUB_WEBHOOK_SECRET
npx wrangler secret put GITHUB_APP_ID
npx wrangler secret put GITHUB_PRIVATE_KEY
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_CHANNEL_ID
npx wrangler secret put ADMIN_USER_IDS # 逗号分隔的 GitHub ID/登录名,允许进入 Web UI
```
::: tip 目标频道按路由配置
不存在全局频道密钥。每条路由在 [Web 控制台](/zh/guide/configuration#web-控制台) 中声明各自的目标频道(及可选的子区/thread因此不需要 `DISCORD_CHANNEL_ID`
:::
::: warning GitHub App 私钥必须是 PKCS#8
GitHub 下发的私钥为 PKCS#1 格式(`BEGIN RSA PRIVATE KEY`。Cloudflare Workers 的 JWT 签名要求 PKCS#8,需先转换:
```bash
openssl pkcs8 -topk8 -inform PEM -outform PEM -nocrypt \
-in your-app.private-key.pem -out gh_pk_pkcs8.pem
```
然后将 `gh_pk_pkcs8.pem` 作为 `GITHUB_PRIVATE_KEY` 上传。
:::
Discord Gateway 是可选的。在 `wrangler.jsonc``vars` 中设置 `DISCORD_GATEWAY_ENABLED`(默认为 `"false"`)。参见下方 [Gateway可选](#gateway可选)。
### 3. 部署
```bash
@ -81,8 +98,22 @@ Worker 现在可通过 `https://webhooker.<your-subdomain>.workers.dev` 访问
1. 打开 <https://discord.com/developers/applications>
2. 创建新应用 → 进入 Bot 部分
3. 将 Bot Token 复制到 `DISCORD_TOKEN`
4. 使用 `bot` 权限范围邀请 Bot 到你的服务器,并勾选 `Send Messages` 权限
5. 将目标频道 ID 复制到 `DISCORD_CHANNEL_ID`
4. 使用 `bot``applications.commands` 两个 scope 邀请 Bot并勾选 `View Channels` + `Send Messages` + `Send Messages in Threads` 权限(组合整数 `274877910016`
```text
https://discord.com/oauth2/authorize?client_id=YOUR_BOT_CLIENT_ID&permissions=274877910016&scope=bot+applications.commands
```
5. 在 Web UI`/admin`)中**按路由**配置目标频道——无需全局频道 ID。
### Gateway可选
消息通过 Discord **REST API** 发送,因此仅凭 `DISCORD_TOKEN` 即可推送。Gateway 连接仅用于:(a) 让 Bot 显示为**在线**(b) 启用 Discord 内的斜杠 / 右键菜单命令。
- `DISCORD_GATEWAY_ENABLED=false`(默认):仅 REST不建立 Gateway 连接。
- `DISCORD_GATEWAY_ENABLED=true`:由一个 Durable Object 持有 Gateway 连接,并按服务器注册 `/gh` 斜杠命令以及 `GitHub: 添加/编辑/删除评论` 消息命令。
启用后,用户运行 `/gh login` 绑定自己的 GitHub 账号,即可以本人身份评论 issue/PR。完整命令说明见 [README](https://github.com/ReCloudStudio/WebHooker#bot-commands-comment-on-github-as-yourself)。
## 自定义域名(可选)

View file

@ -30,14 +30,18 @@ cp .env.example .dev.vars
```bash
GITHUB_WEBHOOK_SECRET=your-webhook-secret
GITHUB_APP_ID=your-app-id
GITHUB_PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----\n...\n-----END RSA PRIVATE KEY-----"
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_CHANNEL_ID=your-channel-id
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`
:::
::: warning
`.dev.vars` 已被 gitignore包含敏感信息请勿提交。
:::
@ -59,14 +63,14 @@ curl http://localhost:8787/health
## 可用脚本
| 脚本 | 说明 |
| --- | --- |
| `npm run dev` | 启动本地开发服务器 (wrangler) |
| `npm run deploy` | 部署到 Cloudflare |
| `npm run typecheck` | TypeScript 类型检查 |
| `npm run lint` | ESLint |
| `npm run lint:md` | Markdownlint |
| `npm run format` | 使用 Prettier 格式化 |
| `npm run format:check` | 检查 Prettier 格式 |
| `npm run docs:dev` | 启动文档开发服务器 |
| `npm run docs:build` | 构建文档站点 |
| 脚本 | 说明 |
| ---------------------- | ----------------------------- |
| `npm run dev` | 启动本地开发服务器 (wrangler) |
| `npm run deploy` | 部署到 Cloudflare |
| `npm run typecheck` | TypeScript 类型检查 |
| `npm run lint` | ESLint |
| `npm run lint:md` | Markdownlint |
| `npm run format` | 使用 Prettier 格式化 |
| `npm run format:check` | 检查 Prettier 格式 |
| `npm run docs:dev` | 启动文档开发服务器 |
| `npm run docs:build` | 构建文档站点 |

View file

@ -1,40 +1,44 @@
# 简介
WebHooker 是一个基于 Cloudflare Workers 构建的 GitHub webhook 调度器。它接收 GitHub webhook 事件,应用可配置的过滤器,将事件格式化为丰富的 Discord 嵌入消息,并通过 Durable Object 维护的 Gateway 连接将消息路由到 Discord 频道或帖子
WebHooker 是一个基于 Cloudflare Workers 构建的 GitHub webhook 调度器。它接收 GitHub webhook 事件,应用可配置的过滤器,将事件格式化为丰富的 Discord 嵌入消息,并通过 Discord REST API 投递到 Discord 频道或帖子。一个可选的 Durable Object 持有 Gateway 连接,用于让 Bot 保持在线并支持 Discord 内的 `/gh` 命令。路由通过内置的 Web UI 管理
## 架构
```text
GitHub Webhook → Cloudflare Worker (Hono)
├── POST /webhook → 验证 → 过滤 → 格式化 → DO (Discord Gateway) → Discord
├── POST /webhook → 验证 → 去重 → 过滤 → 格式化 → Discord (REST API)
├── GET /auth/github → OAuth 流程
├── POST /api/* → 用户操作 (Bearer Token 鉴权)
├── /admin → 路由与发送日志 Web UI管理员会话
└── GET /health → 健康检查
可选Durable Object ⇄ Discord Gateway → Bot 在线 + /gh 斜杠与右键命令
```
### 组件
| 组件 | 职责 |
| --- | --- |
| **Cloudflare Worker** | HTTP 入口、签名验证、事件解析、路由匹配 |
| **Durable Object (DiscordGateway)** | 持久 WebSocket 连接 Discord Gateway、频道缓存、带重试的消息分发 |
| **KV** | Token 存储 (`token:{userId}`)、OAuth 状态 (`state:{hex}`)、路由配置 (`config:routes`) |
| 组件 | 职责 |
| ----------------------------------- | --------------------------------------------------------------------------------------------------------- |
| **Cloudflare Worker** | HTTP 入口、签名验证、投递去重、事件解析、路由匹配、REST 发送 |
| **Durable Object (DiscordGateway)** | _可选。_ 保持 Gateway 连接Bot 在线)并处理 `/gh` 交互 |
| **KV** | Token 存储 (`token:{userId}`)、OAuth 状态 (`state:{hex}`)、路由配置 (`config:routes`)、发送日志、投递去重 |
### 数据流
1. GitHub 发送 webhook 到 `POST /webhook`
2. Worker 验证 HMAC-SHA256 签名
3. Worker 解析事件类型和载荷
4. 根据过滤器评估路由event、repo、actor、action、branch、keyword
5. 匹配的路由触发格式化器函数生成 Discord 嵌入消息
6. 消息被分发到 Durable Object由其维护 Gateway 连接
7. DO 通过 REST API 将消息发送到 Discord并处理速率限制重试
3. Worker `X-GitHub-Delivery` 去重KV短 TTL丢弃重复投递
4. Worker 解析事件类型和载荷
5. 根据过滤器评估路由event、repo、actor、action、branch、keyword
6. 匹配的路由触发格式化器函数生成 Discord 嵌入消息
7. 每条消息通过 Discord REST API 发送到对应路由的目标频道/帖子,并处理速率限制重试,结果记录到发送日志
## 技术栈
- **运行时**: Cloudflare Workers
- **HTTP 框架**: Hono
- **Discord Gateway**: Durable Object (持久 WebSocket + 频道缓存)
- **Discord 投递**: Discord REST APIGateway 通过可选的 Durable Object 提供在线状态与 `/gh` 命令)
- **Web UI**: Nuxt 3 静态 SPA由 Worker 资源托管
- **存储**: Cloudflare KV
- **鉴权**: Web Crypto API (HMAC-SHA256)、jose (JWT)、octokit (GitHub API)
- **语言**: TypeScript