mirror of
https://github.com/ReCloudStudio/WebHooker.git
synced 2026-09-22 16:11:29 +00:00
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:
parent
f456c979f7
commit
d996dbe45d
8 changed files with 133 additions and 55 deletions
|
|
@ -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 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_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)。
|
||||
|
||||
## 自定义域名(可选)
|
||||
|
||||
|
|
|
|||
|
|
@ -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` | 构建文档站点 |
|
||||
|
|
|
|||
|
|
@ -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 API(Gateway 通过可选的 Durable Object 提供在线状态与 `/gh` 命令)
|
||||
- **Web UI**: Nuxt 3 静态 SPA,由 Worker 资源托管
|
||||
- **存储**: Cloudflare KV
|
||||
- **鉴权**: Web Crypto API (HMAC-SHA256)、jose (JWT)、octokit (GitHub API)
|
||||
- **语言**: TypeScript
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue