mirror of
https://github.com/ReCloudStudio/WebHooker.git
synced 2026-09-22 16:11:29 +00:00
71 lines
5.9 KiB
Markdown
71 lines
5.9 KiB
Markdown
# Webhook 接入与租户隔离
|
||
|
||
## Webhook 提供方
|
||
|
||
WebHooker 通过同一个 `POST /webhook` 端点接收多个 forge 的 webhook,按请求头自动识别来源;只需把各 forge 的 webhook 指向 `{BASE_URL}/webhook` 即可。
|
||
|
||
| 提供方 | 事件请求头 | 签名请求头 | 签名格式 | 密钥 |
|
||
| ------ | ---------------- | --------------------- | -------------------------- | ----------------------- |
|
||
| GitHub | `X-GitHub-Event` | `X-Hub-Signature-256` | `sha256=<hex>` HMAC-SHA256 | `GITHUB_WEBHOOK_SECRET` |
|
||
| Gitea | `X-Gitea-Event` | `X-Gitea-Signature` | 纯 hex HMAC-SHA256 | `GITEA_WEBHOOK_SECRET` |
|
||
|
||
投递 id 去重使用 `X-GitHub-Delivery`(GitHub)或 `X-Gitea-Delivery`(Gitea)请求头(存在时)。
|
||
|
||
Gitea 载荷会被归一化为与 GitHub 事件相同的内部结构,因此路由、过滤器与 28 个格式化器无需改动即可工作。未知或未映射的 Gitea 事件回退到通用格式化器。仓库/提交/用户链接取自载荷中的 `repository.html_url`,因此指向你的 Gitea 实例。
|
||
|
||
## 全局端点(`POST /webhook`)
|
||
|
||
全局端点使用运营者的全局密钥(`GITHUB_WEBHOOK_SECRET`、`GITEA_WEBHOOK_SECRET`)验签,并分发到**所有**路由。GitHub App 安装的事件都在此送达;在分组上设置 `installationId` 可保持租户隔离。
|
||
|
||
## 分组端点(`POST /webhook/{groupId}`)
|
||
|
||
每个分组都可以选择接入自己的 webhook 入口,使用独立的密钥(在分组页面的 _Webhook 端点_ 面板生成,owner 角色)。载荷使用**分组**的密钥验签,而不是全局密钥,并且只有该分组的路由会被触发。SaaS 用户以此配置 Gitea、经典 GitHub 或自定义 webhook,而无需共享(或知道)运营者的密钥。
|
||
|
||
- 支持任意提供方:GitHub(`X-Hub-Signature-256`)、Gitea(`X-Gitea-Signature`)、自定义(`X-WebHooker-Signature`)
|
||
- 密钥为 64 位 hex 字符串;在控制台重新生成会立即失效旧密钥
|
||
- 投递 id 去重键按租户隔离(`delivery:{groupId}:{id}`)
|
||
- 分组没有密钥(或已不存在)时端点返回 `404`
|
||
|
||
## 自定义 Webhook
|
||
|
||
向 `POST /webhook/{groupId}`(或全局端点)POST 任意 JSON,并使用分组密钥将原始 body 的 HMAC-SHA256 以 `X-WebHooker-Signature: sha256=<hex>` 签名。载荷会变成 `custom` 事件,走正常的路由管线——创建一条 `event: custom` 的路由(控制台有模板),即可分发到该路由的目标、记录 `send_logs`,并出现在分组的 webhook 日志频道中。
|
||
|
||
载荷模式:
|
||
|
||
```json
|
||
{
|
||
"title": "Deploy failed",
|
||
"description": "Prod rollout failed at 12:03 UTC",
|
||
"color": "red",
|
||
"url": "https://ci.example.com/runs/42",
|
||
"repo": "acme/widget",
|
||
"author": {
|
||
"name": "alice",
|
||
"iconUrl": "https://…/alice.png",
|
||
"url": "https://github.com/alice"
|
||
},
|
||
"fields": [{ "name": "Env", "value": "prod", "inline": true }],
|
||
"footer": "my-monitor",
|
||
"deliveryId": "alert-123"
|
||
}
|
||
```
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
| ------------- | -------- | -------------------------------------------------------------------------------------------------------- |
|
||
| `title` | string | 消息标题(缺省时为 "Custom message") |
|
||
| `description` | string | 可选消息正文 |
|
||
| `color` | string | 可选嵌入颜色:颜色词(`red`、`green`、`yellow`、`blue`、`purple`、`orange`、`cyan`、`gray`)或 `#rrggbb` |
|
||
| `url` | string | 可选的标题链接 |
|
||
| `repo` | string | 可选 `owner/repo`;作为标题前缀并用作页脚 |
|
||
| `author` | object | 可选 `{ name, iconUrl, url }` |
|
||
| `fields` | object[] | 可选嵌入字段 `{ name, value, inline }` |
|
||
| `footer` | string | 可选页脚覆盖 |
|
||
| `deliveryId` | string | 可选的发送方去重 id(重试) |
|
||
|
||
## GitHub App 租户隔离
|
||
|
||
GitHub App 安装后,**所有**安装方的事件都会到达全局端点。要让租户互相隔离,请把每个分组绑定到应当为其提供事件的安装 ID:`"installationId": 12345678`。该 ID 可从 App 安装 webhook 载荷(`installation.id`)或 GitHub App 安装页 URL 看到。即使分组的 `owners` 为空,来自其它安装的事件也会被拒绝。未设置 `installationId` 的分组保持旧行为(`owners` 过滤)。
|
||
|
||
绑定是**自动配置**的 —— 将 GitHub App 的 _Setup URL_ 指向 `{BASE_URL}/auth/github/install`。用户安装 App 后浏览器立即跳转到该页面(页面需要已登录的管理员会话——未登录用户会先被重定向走 OAuth 流程),可选择将安装绑定到:**新分组**(`inst-{installationId}`,默认)或任意**自己拥有 owner 权限的已有分组**(提交时再次校验角色;由 `POST /auth/github/install/bind` 完成配置)。无需手动填写 ID。作为兜底(例如未配置 Setup URL 时),`installation.created` webhook 事件也会自动创建/绑定分组 —— `owners` 匹配安装账号的现有分组会被绑定,否则创建独立的 `inst-{installationId}` 分组。之后在控制台为分组添加路由和成员即可。
|
||
|
||
要在选择页显示安装所属账号的登录名,请设置 `GITHUB_APP_ID` 与 `GITHUB_PRIVATE_KEY`——见[密钥](./configuration#密钥)。
|