mirror of
https://github.com/ReCloudStudio/WebHooker.git
synced 2026-09-22 16:11:29 +00:00
chore: auto-fix lint & formatting [skip ci]
This commit is contained in:
parent
6f1a334150
commit
811f8646e0
26 changed files with 304 additions and 306 deletions
|
|
@ -6,12 +6,12 @@
|
|||
|
||||
使用任何命令前,需先绑定一次 GitHub 账号:
|
||||
|
||||
| 平台 | 命令 | 效果 |
|
||||
|----------|----------------------------------|-------------------------------------------------------------|
|
||||
| Discord | `/gh login` | 返回一条仅你可见的 OAuth 链接,用于授权 GitHub 账号 |
|
||||
| Discord | `/gh logout` | 解除绑定 |
|
||||
| Telegram | `/gh login`(引用一条消息) | 返回 OAuth 链接 |
|
||||
| Telegram | `/gh logout`(引用一条消息) | 解除绑定 |
|
||||
| 平台 | 命令 | 效果 |
|
||||
| -------- | ---------------------------- | --------------------------------------------------- |
|
||||
| Discord | `/gh login` | 返回一条仅你可见的 OAuth 链接,用于授权 GitHub 账号 |
|
||||
| Discord | `/gh logout` | 解除绑定 |
|
||||
| Telegram | `/gh login`(引用一条消息) | 返回 OAuth 链接 |
|
||||
| Telegram | `/gh logout`(引用一条消息) | 解除绑定 |
|
||||
|
||||
链接保存在服务端(KV),并在 D1 中映射到你的 Discord/Telegram 用户 ID。
|
||||
|
||||
|
|
@ -43,12 +43,12 @@ Discord 命令为**斜杠命令**与**消息右键菜单命令**,由定时任
|
|||
|
||||
### 前置条件
|
||||
|
||||
| 项目 | 如何满足 |
|
||||
|--------------|-----------------------------------------------------------------------------------------------------|
|
||||
| 公钥 | 设置 `DISCORD_PUBLIC_KEY` 并配置 Interactions Endpoint URL |
|
||||
| 邀请 scope | 机器人以 `applications.commands` scope 邀请(见 [Discord Bot 设置](./deployment#discord-bot-设置)) |
|
||||
| OAuth | 配置 `GITHUB_CLIENT_ID` / `GITHUB_CLIENT_SECRET` 与 `BASE_URL` |
|
||||
| 绑定账号 | 每位用户先执行 `/gh login` |
|
||||
| 项目 | 如何满足 |
|
||||
| ---------- | --------------------------------------------------------------------------------------------------- |
|
||||
| 公钥 | 设置 `DISCORD_PUBLIC_KEY` 并配置 Interactions Endpoint URL |
|
||||
| 邀请 scope | 机器人以 `applications.commands` scope 邀请(见 [Discord Bot 设置](./deployment#discord-bot-设置)) |
|
||||
| OAuth | 配置 `GITHUB_CLIENT_ID` / `GITHUB_CLIENT_SECRET` 与 `BASE_URL` |
|
||||
| 绑定账号 | 每位用户先执行 `/gh login` |
|
||||
|
||||
## Telegram
|
||||
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ curl http://localhost:8787/health
|
|||
## 可用脚本
|
||||
|
||||
| 脚本 | 说明 |
|
||||
|------------------------|--------------------------------------|
|
||||
| ---------------------- | ------------------------------------ |
|
||||
| `bun run dev` | 启动 Nuxt 开发服务器 (HMR) |
|
||||
| `bun run build` | 生产构建(cloudflare_module preset) |
|
||||
| `bun run deploy` | 部署到 Cloudflare |
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
```
|
||||
|
||||
| 字段 | 类型 | 必需 | 说明 |
|
||||
|------------------|----------|------|--------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| ---------------- | -------- | ---- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `id` | string | 是 | 小写 id(`a-z0-9`、`-`);被每条路由的 `groupId` 引用。可编辑:重命名分组会同步其路由、分组 webhook secret 与待处理邀请 |
|
||||
| `name` | string | 是 | 人类可读的分组名 |
|
||||
| `members` | object[] | 否 | `{ login, role }` 条目;角色为 `owner`、`admin` 或 `viewer` |
|
||||
|
|
@ -38,7 +38,7 @@
|
|||
每个分组成员拥有三种角色之一。超级管理员(`ADMIN_USER_IDS`)始终绕过这些限制。
|
||||
|
||||
| 角色 | 查看路由/日志 | 编辑路由 | 管理成员与邀请 | 编辑分组设置 |
|
||||
|----------|---------------|----------|----------------|------------------|
|
||||
| -------- | ------------- | -------- | -------------- | ---------------- |
|
||||
| `owner` | ✓ | ✓ | ✓ | ✓(除 `owners`) |
|
||||
| `admin` | ✓ | ✓ | ✗ | ✗ |
|
||||
| `viewer` | ✓(只读) | ✗ | ✗ | ✗ |
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
```jsonc
|
||||
// KV 键:i18n:zh
|
||||
{
|
||||
"events.push.title": "{repo}: 推送了 {count} 个提交到 {ref}"
|
||||
"events.push.title": "{repo}: 推送了 {count} 个提交到 {ref}",
|
||||
}
|
||||
```
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
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` |
|
||||
|
||||
|
|
@ -51,7 +51,7 @@ Gitea 载荷会被归一化为与 GitHub 事件相同的内部结构,因此路
|
|||
```
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|---------------|----------|----------------------------------------------------------------------------------------------------------|
|
||||
| ------------- | -------- | -------------------------------------------------------------------------------------------------------- |
|
||||
| `title` | string | 消息标题(缺省时为 "Custom message") |
|
||||
| `description` | string | 可选消息正文 |
|
||||
| `color` | string | 可选嵌入颜色:颜色词(`red`、`green`、`yellow`、`blue`、`purple`、`orange`、`cyan`、`gray`)或 `#rrggbb` |
|
||||
|
|
|
|||
|
|
@ -4,25 +4,25 @@
|
|||
|
||||
每次分发尝试都会记录到 D1 `send_logs` 表,并可在控制台(**日志**标签页)查看。字段:
|
||||
|
||||
| 字段 | 含义 |
|
||||
|--------------|-------------------------------------------------------------|
|
||||
| `routeId` | 匹配的路由 |
|
||||
| `groupId` | 路由所属分组 |
|
||||
| `event` | 事件类型(如 `push`、`pull_request`、`custom`) |
|
||||
| `repo` | 仓库全名(存在时) |
|
||||
| `target` | 消息发送到的目标 id |
|
||||
| `platform` | `discord` 或 `telegram` |
|
||||
| `ok` | 发送是否成功 |
|
||||
| `status` | 平台 API 的 HTTP 状态码(适用时) |
|
||||
| `error` | 失败时的错误信息 |
|
||||
| `errorCode` | 稳定错误码(如 `NO_TARGET`、`NO_TOKEN`、`RATE_LIMITED`) |
|
||||
| `attempts` | 含重试在内的发送次数 |
|
||||
| `durationMs` | 发送耗时 |
|
||||
| `deliveryId` | Webhook 投递 id(提供时) |
|
||||
| `messageId` | 平台消息 id(用于原地编辑) |
|
||||
| `actor` | 发送者登录名 |
|
||||
| `action` | 事件动作(存在时) |
|
||||
| `detail` | 附加 JSON 详情(存在时) |
|
||||
| 字段 | 含义 |
|
||||
| ------------ | -------------------------------------------------------- |
|
||||
| `routeId` | 匹配的路由 |
|
||||
| `groupId` | 路由所属分组 |
|
||||
| `event` | 事件类型(如 `push`、`pull_request`、`custom`) |
|
||||
| `repo` | 仓库全名(存在时) |
|
||||
| `target` | 消息发送到的目标 id |
|
||||
| `platform` | `discord` 或 `telegram` |
|
||||
| `ok` | 发送是否成功 |
|
||||
| `status` | 平台 API 的 HTTP 状态码(适用时) |
|
||||
| `error` | 失败时的错误信息 |
|
||||
| `errorCode` | 稳定错误码(如 `NO_TARGET`、`NO_TOKEN`、`RATE_LIMITED`) |
|
||||
| `attempts` | 含重试在内的发送次数 |
|
||||
| `durationMs` | 发送耗时 |
|
||||
| `deliveryId` | Webhook 投递 id(提供时) |
|
||||
| `messageId` | 平台消息 id(用于原地编辑) |
|
||||
| `actor` | 发送者登录名 |
|
||||
| `action` | 事件动作(存在时) |
|
||||
| `detail` | 附加 JSON 详情(存在时) |
|
||||
|
||||
控制台的**日志**标签页列出最近记录(可按分组过滤),并可查看单条完整详情。写入为尽力而为——插入失败不会中断分发。
|
||||
|
||||
|
|
|
|||
|
|
@ -31,12 +31,12 @@
|
|||
|
||||
`targets` 的每一项都是一个推送目标,因此一条路由可同时转发到多个频道(例如一个 Discord 频道**和**一个 Telegram 群组)。`target.platform` 选择平台:`discord`(默认)或 `telegram`。**Discord** 目标要求 `target.channelId`(可选 `target.threadId` 指定子区);**Telegram** 目标要求 `target.chatId`(群组/超级群组 id,如 `-1001234567890`),可选 `target.topicId`(话题的 `message_thread_id`,相当于 Discord 子区)。没有默认频道回退。
|
||||
|
||||
| 字段 | 类型 | 必需 | 说明 |
|
||||
|------------------|----------|------|-----------------------------------------------------------------------------|
|
||||
| `groupId` | string | 是 | 路由所属[分组](./groups)的 id |
|
||||
| `fallback` | boolean | 否 | 为 `true` 时仅在没有其他非 fallback 路由匹配时才触发;其自身过滤器被忽略 |
|
||||
| `stop` | boolean | 否 | 为 `true` 且该路由匹配时,不再评估后续路由 |
|
||||
| `discordRoleIds` | string[] | 否 | 路由触发时要提醒的 Discord 身份组 id;仅对 Discord 目标生效 |
|
||||
| 字段 | 类型 | 必需 | 说明 |
|
||||
| ---------------- | -------- | ---- | ------------------------------------------------------------------------ |
|
||||
| `groupId` | string | 是 | 路由所属[分组](./groups)的 id |
|
||||
| `fallback` | boolean | 否 | 为 `true` 时仅在没有其他非 fallback 路由匹配时才触发;其自身过滤器被忽略 |
|
||||
| `stop` | boolean | 否 | 为 `true` 且该路由匹配时,不再评估后续路由 |
|
||||
| `discordRoleIds` | string[] | 否 | 路由触发时要提醒的 Discord 身份组 id;仅对 Discord 目标生效 |
|
||||
|
||||
## Discord 身份组提醒
|
||||
|
||||
|
|
|
|||
|
|
@ -2,34 +2,34 @@
|
|||
|
||||
## KV 存储布局
|
||||
|
||||
| 键模式 | 值 | TTL |
|
||||
|---------------------------------|--------------------------------------------------------------------------------|--------------------|
|
||||
| `config:routes` | 路由 JSON 数组 | 永久 |
|
||||
| `config:groups` | 分组 JSON 数组 | 永久 |
|
||||
| `session:{id}` | 管理员会话 `{ userId, login }` | 7 天 |
|
||||
| `token:{userId}` | `{ userId, accessToken, expiresAt, refreshToken? }` | 0.9 × Token 有效期 |
|
||||
| `token-reverse:{sha256}` | 用于按 Token 反查的用户 id | 0.9 × Token 有效期 |
|
||||
| `state:{hex}` | `{ redirectTo, expiresAt, discordUserId?, telegramUserId?, telegramChatId? }` | 600 秒 |
|
||||
| `invite:{token}` | `{ groupId, role, expiresAt, createdBy, note? }` | 7 天 |
|
||||
| `invite:group:{id}` | 每组的 Token 索引(保证邀请列表一致性) | 永久 |
|
||||
| `delivery:{id}` | Webhook 投递 id(去重标记) | 300 秒 |
|
||||
| `delivery:{groupId}:{id}` | 分组级 webhook 入口的租户级投递去重 | 300 秒 |
|
||||
| `tenant:{groupId}` | 分组 webhook secret(64 位 hex,控制台生成) | 永久 |
|
||||
| `msg:{routeId}:{key}:{target}` | 原地更新用消息 id 追踪(如 `workflow_run` / `check_run`) | 7 天 |
|
||||
| `cmd:guild:{id}` | 已注册命令的服务器 id(去重) | 永久 |
|
||||
| `cmd:registered:global` | 全局命令注册标记(去重) | 1 天 |
|
||||
| `config:discord-app-id` | 缓存的 Discord 应用 id | 永久 |
|
||||
| `i18n:{lang}` | 叠加在英文之上的翻译覆盖 | 永久 |
|
||||
| 键模式 | 值 | TTL |
|
||||
| ------------------------------ | ----------------------------------------------------------------------------- | ------------------ |
|
||||
| `config:routes` | 路由 JSON 数组 | 永久 |
|
||||
| `config:groups` | 分组 JSON 数组 | 永久 |
|
||||
| `session:{id}` | 管理员会话 `{ userId, login }` | 7 天 |
|
||||
| `token:{userId}` | `{ userId, accessToken, expiresAt, refreshToken? }` | 0.9 × Token 有效期 |
|
||||
| `token-reverse:{sha256}` | 用于按 Token 反查的用户 id | 0.9 × Token 有效期 |
|
||||
| `state:{hex}` | `{ redirectTo, expiresAt, discordUserId?, telegramUserId?, telegramChatId? }` | 600 秒 |
|
||||
| `invite:{token}` | `{ groupId, role, expiresAt, createdBy, note? }` | 7 天 |
|
||||
| `invite:group:{id}` | 每组的 Token 索引(保证邀请列表一致性) | 永久 |
|
||||
| `delivery:{id}` | Webhook 投递 id(去重标记) | 300 秒 |
|
||||
| `delivery:{groupId}:{id}` | 分组级 webhook 入口的租户级投递去重 | 300 秒 |
|
||||
| `tenant:{groupId}` | 分组 webhook secret(64 位 hex,控制台生成) | 永久 |
|
||||
| `msg:{routeId}:{key}:{target}` | 原地更新用消息 id 追踪(如 `workflow_run` / `check_run`) | 7 天 |
|
||||
| `cmd:guild:{id}` | 已注册命令的服务器 id(去重) | 永久 |
|
||||
| `cmd:registered:global` | 全局命令注册标记(去重) | 1 天 |
|
||||
| `config:discord-app-id` | 缓存的 Discord 应用 id | 永久 |
|
||||
| `i18n:{lang}` | 叠加在英文之上的翻译覆盖 | 永久 |
|
||||
|
||||
## D1 存储布局
|
||||
|
||||
D1 数据库(`DB` 绑定,数据库 `webhooker`)包含四张表:
|
||||
|
||||
| 表 | 用途 |
|
||||
|-------------------|--------------------------------------------------------------------------------------------------|
|
||||
| `send_logs` | 每次分发尝试一行(路由 id、事件、目标、ok/error、耗时、错误码、详情) |
|
||||
| `audit_logs` | 每次管理员操作一行(登录/登出、分组/路由/成员/邀请变更) |
|
||||
| `discord_links` | 映射 `discord_user_id` → `github_user_id`,供 `/gh` Discord 命令使用 |
|
||||
| `telegram_links` | 映射 `telegram_user_id` → `github_user_id`,供 `/gh` Telegram 命令使用 |
|
||||
| 表 | 用途 |
|
||||
| ---------------- | ---------------------------------------------------------------------- |
|
||||
| `send_logs` | 每次分发尝试一行(路由 id、事件、目标、ok/error、耗时、错误码、详情) |
|
||||
| `audit_logs` | 每次管理员操作一行(登录/登出、分组/路由/成员/邀请变更) |
|
||||
| `discord_links` | 映射 `discord_user_id` → `github_user_id`,供 `/gh` Discord 命令使用 |
|
||||
| `telegram_links` | 映射 `telegram_user_id` → `github_user_id`,供 `/gh` Telegram 命令使用 |
|
||||
|
||||
`audit_logs` 由定时任务在 `AUDIT_RETENTION_DAYS`(默认 90)后自动清理。行字段说明见[日志](./logs)。
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
WebHooker 通过定时触发器(`*/5 * * * *`,每 5 分钟)运行三个维护任务。它们只在部署后的 Worker 上运行(Cloudflare cron);本地 `wrangler dev` 可用 `wrangler dev --test-scheduled` 触发。
|
||||
|
||||
| 任务 | 用途 |
|
||||
|-----------------|---------------------------------------------------------------------------------------------------------------------|
|
||||
| --------------- | ------------------------------------------------------------------------------------------------------------------- |
|
||||
| `discord-sync` | 注册 Discord 斜杠/右键菜单命令:按服务器即时注册,并全局注册(24h 去重,约 1 小时传播) |
|
||||
| `telegram-sync` | 调用 `setWebhook` 指向 `{BASE_URL}/telegram/webhook`(设置了 `TELEGRAM_WEBHOOK_SECRET` 时作为 `secret_token` 传入) |
|
||||
| `audit-prune` | 删除早于 `AUDIT_RETENTION_DAYS`(默认 90)天的 `audit_logs` 记录 |
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue