mirror of
https://github.com/ReCloudStudio/WebHooker.git
synced 2026-09-22 16:11:29 +00:00
docs: sync documentation with current codebase
- 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
This commit is contained in:
parent
68cda9f178
commit
afe19795b1
25 changed files with 621 additions and 398 deletions
154
README.zh.md
154
README.zh.md
|
|
@ -1,34 +1,40 @@
|
|||
# WebHooker
|
||||
|
||||
GitHub webhook → Discord 分发服务。通过 Cloudflare Workers 接收 webhook 事件,应用过滤器,将格式化消息路由到 Discord 频道或子区。
|
||||
GitHub webhook → Discord / Telegram 分发服务。通过 Cloudflare Workers 接收 webhook 事件,应用过滤器,将格式化消息路由到 Discord 频道/子区与 Telegram 群组/话题。
|
||||
|
||||
## 功能特性
|
||||
|
||||
- **23 种事件格式化** — push、pull_request、issues、issue_comment、workflow_run、release、create、delete、star、fork、check_run、pull_request_review、pull_request_review_comment、commit_comment、deployment_status、member、label、milestone、discussion、discussion_comment、repository、code_scanning_alert、dependabot_alert(+ 通用回退)
|
||||
- **28 种事件格式化** — push、pull_request、issues、issue_comment、workflow_run、workflow_job、status、deployment、deployment_status、check_run、check_suite、ping、release、create、delete、star、fork、pull_request_review、pull_request_review_comment、commit_comment、member、label、milestone、discussion、discussion_comment、repository、code_scanning_alert、dependabot_alert(+ 通用回退)
|
||||
- HMAC-SHA256 签名验证(Web Crypto API)
|
||||
- 按事件类型、仓库、操作人、操作、分支(含 PR)、关键词(支持正则)过滤
|
||||
- 富 Discord embed:颜色编码、作者头像、字段、时间戳
|
||||
- 路由到频道或子区
|
||||
- GitHub App OAuth 用户授权(评论、合并、反应)
|
||||
- **Web 配置控制台**(`/admin`)— 通过 GitHub OAuth + 管理员白名单管理路由
|
||||
- 按事件类型、仓库、操作人、操作、分支、关键词(支持正则)过滤
|
||||
- 富消息:颜色编码、作者头像、字段、时间戳——渲染为 Discord embed 与 Telegram HTML
|
||||
- 路由到 Discord 频道/子区与 Telegram 群组/话题(一条路由可多目标)
|
||||
- `workflow_run` 进度**原地编辑**同一条消息(工作流推进时更新),两个平台均支持
|
||||
- GitHub OAuth 用户授权(评论、编辑评论、删除评论、合并、关闭、反应)
|
||||
- **Web 配置控制台**(`/admin`)— 通过 GitHub OAuth + 管理员白名单管理路由与分组、查看发送日志
|
||||
- **Discord Interactions Endpoint**(Ed25519 验签)支持 `/gh` 斜杠命令、消息右键菜单命令、PR 合并/关闭按钮与评论 modal
|
||||
- Cloudflare KV 存储 token/状态/配置
|
||||
- **Telegram `/gh` 命令**(login/logout/comment/merge/close),通过 Telegram webhook 接收,头像以链接预览卡片呈现
|
||||
- Cloudflare KV 存储 token/状态/配置/会话 + D1 存储发送日志与平台账号绑定
|
||||
- 优雅降级(Discord 不可用时仅 webhook 模式)
|
||||
|
||||
## 架构
|
||||
|
||||
```text
|
||||
GitHub Webhook → Cloudflare Worker (Hono)
|
||||
├── POST /webhook → 验证 → 过滤 → 格式化 → Discord (REST)
|
||||
├── POST /webhook → 验证 → 去重 → 过滤 → 格式化 → Discord (REST) / Telegram (Bot API)
|
||||
├── POST /discord/interactions → 验证 (Ed25519) → 处理命令/按钮/modal
|
||||
├── POST /telegram/webhook → 验证 (secret token) → 处理 /gh 命令
|
||||
├── GET /auth/github → OAuth 流程
|
||||
├── GET /api/richheader → Telegram 头像链接预览卡片
|
||||
├── POST /api/* → 用户操作(Bearer token 鉴权)
|
||||
├── /admin → 路由、分组与发送日志 Web UI
|
||||
└── GET /health → 健康检查
|
||||
```
|
||||
|
||||
- **Cloudflare Worker** — HTTP 入口、签名验证、路由分发
|
||||
- **Interactions Endpoint** — HTTPS 回调(无 Discord Gateway 连接、无 Durable Object);bot 保持离线,命令通过 API 注册
|
||||
- **KV** — Token 存储(`token:{userId}`)、OAuth state(`state:{hex}`)、路由配置(`config:routes`)
|
||||
- **KV** — Token 存储(`token:{userId}`)、OAuth state(`state:{hex}`)、路由配置(`config:routes`)、分组配置(`config:groups`)、管理员会话(`session:{id}`)、投递去重(`delivery:{id}`)、消息更新追踪(`msg:*`)
|
||||
- **D1** — 发送日志(`send_logs`)、Discord↔GitHub 绑定(`discord_links`)、Telegram↔GitHub 绑定(`telegram_links`)
|
||||
|
||||
## 快速开始
|
||||
|
||||
|
|
@ -42,22 +48,28 @@ npx wrangler dev # 启动本地开发服务器
|
|||
|
||||
### 密钥(本地用 `.dev.vars`,生产用 Worker Secrets)
|
||||
|
||||
| 变量 | 说明 |
|
||||
| ------------------------ | --------------------------------------------------------------------------- |
|
||||
| `GITHUB_WEBHOOK_SECRET` | GitHub webhook 密钥 |
|
||||
| `GITHUB_APP_ID` | GitHub App ID |
|
||||
| `GITHUB_PRIVATE_KEY` | App 私钥(PEM) |
|
||||
| `GITHUB_CLIENT_ID` | OAuth Client ID |
|
||||
| `GITHUB_CLIENT_SECRET` | OAuth Client Secret |
|
||||
| `DISCORD_TOKEN` | 机器人 token |
|
||||
| `DISCORD_PUBLIC_KEY` | Discord 应用的公钥(开发者门户获取)—— 交互功能必需 |
|
||||
| `DISCORD_APPLICATION_ID` | Discord 应用 ID(可选;省略时通过 `GET /oauth2/applications/@me` 自动获取) |
|
||||
| `BASE_URL` | 公网地址(用于 OAuth 回调) |
|
||||
| `ADMIN_USER_IDS` | 允许访问 `/admin` 的 GitHub 用户 ID(或登录名),逗号分隔 |
|
||||
| 变量 | 说明 |
|
||||
| --------------------------- | --------------------------------------------------------------------------- |
|
||||
| `GITHUB_WEBHOOK_SECRET` | GitHub webhook 密钥 |
|
||||
| `GITHUB_APP_ID` | GitHub App ID(当前代码未使用,为兼容保留) |
|
||||
| `GITHUB_PRIVATE_KEY` | App 私钥(PKCS#8 PEM;当前代码未使用,为兼容保留) |
|
||||
| `GITHUB_CLIENT_ID` | OAuth Client ID |
|
||||
| `GITHUB_CLIENT_SECRET` | OAuth Client Secret |
|
||||
| `DISCORD_TOKEN` | 机器人 token |
|
||||
| `DISCORD_PUBLIC_KEY` | Discord 应用的公钥(开发者门户获取)—— 交互功能必需 |
|
||||
| `DISCORD_APPLICATION_ID` | Discord 应用 ID(可选;省略时通过 `GET /oauth2/applications/@me` 自动获取) |
|
||||
| `TELEGRAM_TOKEN` | Telegram Bot Token(BotFather 获取)—— Telegram 路由必需 |
|
||||
| `TELEGRAM_WEBHOOK_SECRET` | 可选;`POST /telegram/webhook` 的验签密钥 |
|
||||
| `TELEGRAM_RICH_HEADER_HOST` | 可选;覆盖内置 `GET /api/richheader` 的 Telegram 头像卡片地址 |
|
||||
| `BASE_URL` | 公网地址(用于 OAuth 回调与 Telegram webhook 同步) |
|
||||
| `ADMIN_USER_IDS` | 允许访问 `/admin` 的 GitHub 用户 ID(或登录名),逗号分隔 |
|
||||
| `DOCS_URL` | 可选;落地页使用的文档站点 URL |
|
||||
| `GITHUB_REPO_URL` | 可选;落地页使用的 GitHub 仓库 URL |
|
||||
| `LEGAL_CONTACT` | 可选;`/terms` 与 `/privacy` 页面展示的联系方式 |
|
||||
|
||||
### 路由配置
|
||||
|
||||
路由存储在 KV(`config:routes`,JSON 格式)。**没有默认路由**——每条路由(包括目标)都必须显式定义,可通过 Web 控制台(`/admin`)或直接向 KV 存储 JSON 数组:
|
||||
路由存储在 KV(`config:routes`,JSON 格式)。**没有默认路由**——每条路由(包括目标)都必须显式定义,可通过 Web 控制台(`/admin`)或直接向 KV 存储 JSON 数组。一条路由可携带多个 `targets`,因此一个规则可以同时转发到多个频道:
|
||||
|
||||
```json
|
||||
[
|
||||
|
|
@ -65,28 +77,27 @@ npx wrangler dev # 启动本地开发服务器
|
|||
"id": "all-push",
|
||||
"name": "Push 事件",
|
||||
"enabled": true,
|
||||
"groupId": "default",
|
||||
"filters": [{ "type": "event", "match": "push" }],
|
||||
"target": { "platform": "discord", "channelId": "频道ID" }
|
||||
},
|
||||
{
|
||||
"id": "telegram-issues",
|
||||
"name": "Issue 推送 Telegram",
|
||||
"enabled": true,
|
||||
"filters": [{ "type": "event", "match": "issues" }],
|
||||
"target": { "platform": "telegram", "chatId": "-1001234567890" }
|
||||
"targets": [
|
||||
{ "platform": "discord", "channelId": "频道ID" },
|
||||
{ "platform": "telegram", "chatId": "-1001234567890" }
|
||||
]
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
`target.platform` 选择推送目标:`discord`(默认)或 `telegram`。Discord 路由需 `target.channelId`(可选 `threadId` 指向子区);Telegram 路由需 `target.chatId`(群组聊天 ID,可选 `topicId` 指向话题)。不存在默认频道回退。
|
||||
`target.platform` 选择推送目标:`discord`(默认)或 `telegram`。Discord 目标需 `target.channelId`(可选 `threadId` 指向子区);Telegram 目标需 `target.chatId`(可选 `topicId` 指向话题)。旧的单数 `target` 字段仍会被自动迁移。不存在默认频道回退。
|
||||
|
||||
路由隶属于**分组**(KV `config:groups`),分组用于限定管理权限,并可限制哪些组织/用户的事件流入。完整模式见 `config.example.yaml` 与 `docs/zh/guide/configuration.md`。
|
||||
|
||||
### Web 控制台(`/admin`)
|
||||
|
||||
内置的配置控制台让你在浏览器中管理路由(新增 / 编辑 / 删除 / 开关),无需操作 KV:
|
||||
内置的配置控制台让你在浏览器中管理路由与分组(新增 / 编辑 / 删除 / 开关 / 排序),并查看发送日志——无需操作 KV:
|
||||
|
||||
1. 设置 `ADMIN_USER_IDS` 为允许管理控制台的 GitHub 用户 ID(或登录名),例如 `ADMIN_USER_IDS=12345,RhenCloud`。
|
||||
2. 访问 `/admin` 并用 GitHub 登录,仅白名单内用户可进入。
|
||||
3. 修改会立即写入 KV `config:routes`,webhook 管线随即生效。
|
||||
3. 修改会立即写入 KV,webhook 管线随即生效。
|
||||
|
||||
在 `/admin/logout` 退出登录。
|
||||
|
||||
|
|
@ -94,14 +105,14 @@ npx wrangler dev # 启动本地开发服务器
|
|||
|
||||
### 过滤器类型
|
||||
|
||||
| 类型 | 匹配内容 | 备注 |
|
||||
| --------- | ----------------------------------- | --------------------------------------------------------------- |
|
||||
| `event` | `push`、`pull_request`、`issues` 等 | GitHub 事件名 |
|
||||
| `repo` | `org/repo` 全名 | |
|
||||
| `actor` | 发送者登录名 | |
|
||||
| `action` | `opened`、`closed`、`published` 等 | |
|
||||
| `branch` | 分支名 | 支持 push、PR、create/delete、workflow_run、code_scanning_alert |
|
||||
| `keyword` | payload 中的文本 | 支持正则表达式;无效正则回退为子串匹配 |
|
||||
| 类型 | 匹配内容 | 备注 |
|
||||
| --------- | ----------------------------------- | ------------------------------------------------------------------------------------------------------------- |
|
||||
| `event` | `push`、`pull_request`、`issues` 等 | GitHub 事件名 |
|
||||
| `repo` | `org/repo` 全名 | |
|
||||
| `actor` | 发送者登录名 | |
|
||||
| `action` | `opened`、`closed`、`published` 等 | |
|
||||
| `branch` | 分支名 | 支持 push、PR/review、create/delete、workflow_run、workflow_job、check_suite、deployment、code_scanning_alert |
|
||||
| `keyword` | payload 中的文本 | 支持正则表达式;无效正则回退为子串匹配 |
|
||||
|
||||
设置 `exclude: true` 可取反过滤器。
|
||||
|
||||
|
|
@ -114,13 +125,14 @@ npx wrangler dev # 启动本地开发服务器
|
|||
### OAuth
|
||||
|
||||
- `GET /auth/github` — 发起 GitHub OAuth 授权(重定向到 GitHub)
|
||||
- `GET /auth/github/callback` — OAuth 回调(交换 code 为 token)
|
||||
- `GET /auth/github/callback` — OAuth 回调(交换 code 为 token;管理员会话 / Discord 绑定 / Telegram 绑定)
|
||||
- `DELETE /auth/token/:userId` — 撤销用户 token
|
||||
|
||||
### 操作接口(需要 `Authorization: Bearer <token>` 头)
|
||||
|
||||
- `POST /api/comment` — 创建 issue 评论
|
||||
- `POST /api/merge` — 合并 PR
|
||||
- `POST /api/close` — 关闭 PR
|
||||
- `POST /api/react` — 添加 issue 反应
|
||||
|
||||
### 管理接口(需要管理员 OAuth 会话)
|
||||
|
|
@ -130,6 +142,13 @@ npx wrangler dev # 启动本地开发服务器
|
|||
- `GET /admin/logout` — 退出登录
|
||||
- `GET /admin/api/routes` — 列出路由
|
||||
- `PUT /admin/api/routes` — 替换路由
|
||||
- `GET /admin/api/groups` — 列出分组(按权限过滤)
|
||||
- `PUT /admin/api/groups` — 替换分组(仅超级管理员)
|
||||
- `GET /admin/api/groups/:groupId/routes` — 列出某分组的路由
|
||||
- `PUT /admin/api/groups/:groupId/routes` — 替换某分组的路由
|
||||
- `GET /admin/api/me` — 当前会话 / 权限范围
|
||||
- `GET /admin/api/logs` — 发送日志(按权限过滤)
|
||||
- `GET /admin/api/logs/:id` — 单条发送日志
|
||||
|
||||
## GitHub App 配置教程
|
||||
|
||||
|
|
@ -142,10 +161,10 @@ npx wrangler dev # 启动本地开发服务器
|
|||
- **Webhook URL**:`https://your-domain/webhook`
|
||||
- **Webhook secret**:生成并复制到 `GITHUB_WEBHOOK_SECRET`
|
||||
3. 设置权限:
|
||||
- **Repository permissions**:Contents (read)、Issues (write)、Pull requests (write)、Metadata (read)
|
||||
- **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) — 如需要
|
||||
4. 订阅事件:Push、Pull request、Issues、Issue comment、Workflow run、Release、Create、Delete、Star、Fork、Check run、Pull request review、Pull request review comment、Commit comment、Deployment status、Member、Label、Milestone、Discussion、Discussion comment、Repository、Code scanning alert、Dependabot alert
|
||||
5. 生成私钥 → 将内容保存到 `GITHUB_PRIVATE_KEY` 环境变量
|
||||
4. 订阅事件: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
|
||||
5. 生成私钥 — `GITHUB_PRIVATE_KEY` 当前未被代码使用(OAuth 流程只用到 Client ID/Secret),因此为可选;若日后启用 GitHub App 认证可再配置。
|
||||
|
||||
### 2. 安装 App
|
||||
|
||||
|
|
@ -224,24 +243,45 @@ bot 通过定时任务(每 5 分钟)同步注册原生的**斜杠命令**与
|
|||
| OAuth | 已配置 `GITHUB_CLIENT_ID` / `GITHUB_CLIENT_SECRET` 与 `BASE_URL` |
|
||||
| 用户绑定 | 每个用户先执行 `/gh login` |
|
||||
|
||||
## Telegram 机器人配置
|
||||
|
||||
1. 用 [@BotFather](https://t.me/BotFather) 创建机器人,将 Token 复制到 `TELEGRAM_TOKEN`。
|
||||
2. (可选)设置 `TELEGRAM_WEBHOOK_SECRET`;webhook 注册时会作为 `secret_token` 传给 Telegram,`POST /telegram/webhook` 使用时间安全比较校验。
|
||||
3. Worker 会在定时任务中自动同步 webhook(`setWebhook` 指向 `{BASE_URL}/telegram/webhook`),因此无需手动调用 `setWebhook`——只需确保 `BASE_URL` 已设置。
|
||||
4. 将机器人加入群组(或启用话题),在路由配置中用 `chatId` / `topicId` 指定目标。
|
||||
|
||||
在 Telegram 中,`/gh` 命令通过在通知消息上**回复**来使用:
|
||||
|
||||
- `/gh login` — 绑定你的 GitHub 账号(返回 OAuth 链接)
|
||||
- `/gh logout` — 解除绑定
|
||||
- `/gh comment <内容>` — 回复一条 issue/PR 通知,以本人身份评论
|
||||
- `/gh merge` / `/gh close` — 回复一条 PR 通知,合并/关闭该 PR
|
||||
|
||||
头像使用内置 `GET /api/richheader` 渲染为链接预览卡片(可用 `TELEGRAM_RICH_HEADER_HOST` 覆盖)。
|
||||
|
||||
## 部署
|
||||
|
||||
```bash
|
||||
# 在 Cloudflare 设置密钥
|
||||
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_CLIENT_ID
|
||||
npx wrangler secret put GITHUB_CLIENT_SECRET
|
||||
npx wrangler secret put DISCORD_TOKEN
|
||||
npx wrangler secret put DISCORD_PUBLIC_KEY
|
||||
npx wrangler secret put DISCORD_CHANNEL_ID
|
||||
npx wrangler secret put TELEGRAM_TOKEN
|
||||
npx wrangler secret put ADMIN_USER_IDS
|
||||
|
||||
# 创建 KV 命名空间
|
||||
npx wrangler kv namespace create KV
|
||||
|
||||
# 更新 wrangler.jsonc 中的 KV namespace ID
|
||||
|
||||
# 创建 D1 数据库并执行迁移
|
||||
npx wrangler d1 create webhooker
|
||||
# 更新 wrangler.jsonc d1_databases 中的数据库 ID
|
||||
npx wrangler d1 execute webhooker --remote --file ./migrations/0001_init.sql
|
||||
npx wrangler d1 execute webhooker --remote --file ./migrations/0002_log_detail.sql
|
||||
npx wrangler d1 execute webhooker --remote --file ./migrations/0003_telegram_links.sql
|
||||
|
||||
# 部署
|
||||
npx wrangler deploy
|
||||
```
|
||||
|
|
@ -252,6 +292,7 @@ npx wrangler deploy
|
|||
npx wrangler dev # 本地开发服务器(Miniflare)
|
||||
npm run typecheck # 类型检查
|
||||
npm run lint # ESLint
|
||||
npm test # 单元测试(bun test)
|
||||
```
|
||||
|
||||
## 支持的事件
|
||||
|
|
@ -262,16 +303,21 @@ npm run lint # ESLint
|
|||
| `pull_request` | PR 标题、分支、差异统计 |
|
||||
| `issues` | Issue 标题、标签、指派人 |
|
||||
| `issue_comment` | 评论内容、Issue 引用 |
|
||||
| `workflow_run` | 工作流状态、结论、耗时 |
|
||||
| `workflow_run` | 工作流状态、结论、耗时(原地更新) |
|
||||
| `workflow_job` | 作业名、状态、结论 |
|
||||
| `status` | 提交状态、上下文、状态值 |
|
||||
| `deployment` | 环境、引用、任务 |
|
||||
| `deployment_status` | 环境、状态、commit ref |
|
||||
| `check_run` | 状态、结论、详情链接 |
|
||||
| `check_suite` | 套件结论、head 分支、提交 |
|
||||
| `ping` | Webhook 确认 |
|
||||
| `release` | Tag、内容、资产 |
|
||||
| `create` / `delete` | 分支/tag 创建或删除 |
|
||||
| `star` | Star 数量、仓库 |
|
||||
| `fork` | Fork 来源 → 目标 |
|
||||
| `check_run` | 状态、结论、详情链接 |
|
||||
| `pull_request_review` | 审查状态、内容预览 |
|
||||
| `pull_request_review_comment` | 行内代码评论、文件路径、行号 |
|
||||
| `commit_comment` | Commit SHA、评论内容 |
|
||||
| `deployment_status` | 环境、状态、commit ref |
|
||||
| `member` | 协作者添加/移除 |
|
||||
| `label` | 标签名、颜色、描述 |
|
||||
| `milestone` | 进度条、open/closed 计数、截止日期 |
|
||||
|
|
@ -281,6 +327,8 @@ npm run lint # ESLint
|
|||
| `code_scanning_alert` | 严重程度、规则 ID、文件路径 |
|
||||
| `dependabot_alert` | 严重程度、包名、受影响范围、修复版本 |
|
||||
|
||||
任何其他事件类型回退到通用格式化器(事件类型、操作、操作人、仓库、原始载荷)。
|
||||
|
||||
## 许可证
|
||||
|
||||
MIT
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue