WebHooker/README.zh.md
RhenCloud f456c979f7
docs: replace !gh command with slash/context-menu commands
Document the /gh login, /gh logout and /gh comment add|edit|del
commands plus the right-click message context-menu equivalents, and
require the applications.commands invite scope. Comments are posted as
the linked user's own GitHub account, so the old GitHub App identity,
Message Content intent and Read Message History requirements are gone.
2026-08-02 06:55:48 +08:00

14 KiB
Raw Blame History

WebHooker

GitHub webhook → Discord 分发服务。通过 Cloudflare Workers 接收 webhook 事件,应用过滤器,将格式化消息路由到 Discord 频道或子区。

功能特性

  • 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+ 通用回退)
  • HMAC-SHA256 签名验证Web Crypto API
  • 按事件类型、仓库、操作人、操作、分支(含 PR、关键词支持正则过滤
  • 富 Discord embed颜色编码、作者头像、字段、时间戳
  • 路由到频道或子区
  • GitHub App OAuth 用户授权(评论、合并、反应)
  • Web 配置控制台/admin)— 通过 GitHub OAuth + 管理员白名单管理路由
  • Durable Object 维持 Discord Gateway WebSocket 连接 + 频道缓存
  • Cloudflare KV 存储 token/状态/配置
  • 优雅降级Discord 不可用时仅 webhook 模式)

架构

GitHub Webhook → Cloudflare Worker (Hono)
                 ├── POST /webhook → 验证 → 过滤 → 格式化 → DO (Discord Gateway) → Discord
                 ├── GET  /auth/github → OAuth 流程
                 ├── POST /api/* → 用户操作Bearer token 鉴权)
                 └── GET  /health → 健康检查
  • Cloudflare Worker — HTTP 入口、签名验证、路由分发
  • Durable Object (DiscordGateway) — 持久 WebSocket 连接 Discord Gateway、频道缓存、消息发送含重试
  • KV — Token 存储(token:{userId}、OAuth statestate:{hex})、路由配置(config:routes

快速开始

npm install          # 或 bun install
cp .env.example .dev.vars   # 填写本地开发密钥
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
BASE_URL 公网地址(用于 OAuth 回调)
ADMIN_USER_IDS 允许访问 /admin 的 GitHub 用户 ID或登录名逗号分隔
DISCORD_GATEWAY_ENABLED 设为 true 启用 Discord Gatewaybot 在线状态);不启用也能通过 REST 推送

路由配置

路由存储在 KVconfig:routesJSON 格式)。没有默认路由——每条路由(包括目标 channelId / threadId)都必须显式定义,可通过 Web 控制台(/admin)或直接向 KV 存储 JSON 数组:

[
  {
    "id": "all-push",
    "name": "Push 事件",
    "enabled": true,
    "filters": [{ "type": "event", "match": "push" }],
    "target": { "channelId": "频道ID" }
  }
]

target.channelId 必填且按原样使用,不存在默认频道回退。

Web 控制台(/admin

内置的配置控制台让你在浏览器中管理路由(新增 / 编辑 / 删除 / 开关),无需操作 KV

  1. 设置 ADMIN_USER_IDS 为允许管理控制台的 GitHub 用户 ID或登录名例如 ADMIN_USER_IDS=12345,RhenCloud
  2. 访问 /admin 并用 GitHub 登录,仅白名单内用户可进入。
  3. 修改会立即写入 KV config:routeswebhook 管线随即生效。

/admin/logout 退出登录。

完整语法示例见 config.example.yaml

过滤器类型

类型 匹配内容 备注
event pushpull_requestissues GitHub 事件名
repo org/repo 全名
actor 发送者登录名
action openedclosedpublished
branch 分支名 支持 push、PR、create/delete、workflow_run、code_scanning_alert
keyword payload 中的文本 支持正则表达式;无效正则回退为子串匹配

设置 exclude: true 可取反过滤器。

API

健康检查

  • GET /health — 返回 {"status": "ok"}

OAuth

  • GET /auth/github — 发起 GitHub OAuth 授权(重定向到 GitHub
  • GET /auth/github/callback — OAuth 回调(交换 code 为 token
  • DELETE /auth/token/:userId — 撤销用户 token

操作接口(需要 Authorization: Bearer <token> 头)

  • POST /api/comment — 创建 issue 评论
  • POST /api/merge — 合并 PR
  • POST /api/react — 添加 issue 反应

管理接口(需要管理员 OAuth 会话)

  • GET /admin — 配置控制台页面
  • GET /admin/login — 开始管理员登录GitHub OAuth
  • GET /admin/logout — 退出登录
  • GET /admin/api/routes — 列出路由
  • PUT /admin/api/routes — 替换路由

GitHub App 配置教程

1. 创建 App

  1. 访问 https://github.com/settings/apps/new
  2. 填写信息:
    • GitHub App nameWebHooker(或自定义名称)
    • Homepage URL:你的域名
    • Webhook URLhttps://your-domain/webhook
    • Webhook secret:生成并复制到 GITHUB_WEBHOOK_SECRET
  3. 设置权限:
    • Repository permissionsContents (read)、Issues (write)、Pull requests (write)、Metadata (read)
    • Organization permissionsMembers (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 环境变量

2. 安装 App

  1. 创建后进入 App 设置页
  2. 点击 "Install App" → 选择组织/用户
  3. 选择要监控的仓库

3. 配置 OAuth

  1. 进入 App → OAuth settings
  2. 设置 Callback URLhttps://your-domain/auth/github/callback
  3. 复制 Client ID 和 Client Secret 到环境变量

Discord 机器人配置

https://discord.com/developers/applications 创建机器人,将 Token 复制到 DISCORD_TOKEN

OAuth2 邀请

使用 bot scope 将机器人加入服务器,需要以下权限:

权限 数值 用途
查看频道 (View Channels) 1024 查看目标频道以发送消息
发送消息 (Send Messages) 2048 向频道发送 embed/消息
在线程中发送消息 (Send Messages in Threads) 274877906944 当路由配置了 threadId 时向线程发送消息

权限组合整数值:274877910016

邀请链接(将 CLIENT_ID 替换为机器人的 Client ID。需要 applications.commands scope否则无法注册斜杠 / 右键菜单命令:

https://discord.com/oauth2/authorize?client_id=你的机器人CLIENT_ID&permissions=274877910016&scope=bot+applications.commands

Intents

Gateway 连接仅使用 GUILDS intent1 << 0)。无需特权 intent如 Message Content

Gateway可选

Discord Gateway 连接仅用于让 bot 显示为在线——发送消息不需要它。消息通过 Discord REST API 发送,因此只要有 DISCORD_TOKEN 即可推送。

  • DISCORD_GATEWAY_ENABLED=false(默认):直接通过 REST 发送消息,不建立 Gateway 连接。
  • DISCORD_GATEWAY_ENABLED=true:由 Durable Object 连接 Gateway 以维持 bot 在线状态;消息仍走 REST。

Bot 指令(以本人身份评论 GitHub

启用 Gateway 后bot 会在连接时为每个服务器注册原生的斜杠命令消息右键菜单命令。评论以你本人绑定的 GitHub 账号OAuth发出权限交由 GitHub 判定——若 GitHub 拒绝例如去修改他人评论bot 会提示你无权限。所有回复均为 ephemeral仅你可见

1. 绑定账号(一次即可):

/gh login     → 返回一个 ephemeral 授权链接,用于绑定你的 GitHub 账号
/gh logout    → 解除绑定

2. 添加 / 编辑 / 删除评论 —— 两种等价方式:

  • 右键点击通知(推荐):右键一条 bot 推送的 issue / PR / 评论通知 → 应用AppsGitHub: 添加评论 / 编辑评论 / 删除评论。目标会从通知 embed 中自动提取,无需粘贴链接。

  • 斜杠命令 + 链接

    /gh comment add  link:<issue 或 PR 链接>          例如 https://github.com/owner/repo/issues/123
    /gh comment edit link:<评论链接>                  链接需包含 #issuecomment-<id>
    /gh comment del  link:<评论链接>                  链接需包含 #issuecomment-<id>
    

    edit / del 需要具体的评论链接(在 GitHub 上:评论 ⋯ 菜单 → Copy link)。add / edit 会弹出 modal 让你输入 / 修改评论内容(编辑时预填原文)。

要求:

项目 说明
启用 Gateway DISCORD_GATEWAY_ENABLED=true(交互通过 Gateway 送达)
邀请 scope 邀请时带上 applications.commands(见上方邀请链接)
OAuth 已配置 GITHUB_CLIENT_ID / GITHUB_CLIENT_SECRETBASE_URL
用户绑定 每个用户先执行 /gh login

部署

# 在 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_CHANNEL_ID

# 创建 KV 命名空间
npx wrangler kv namespace create KV

# 更新 wrangler.jsonc 中的 KV namespace ID

# 部署
npx wrangler deploy

开发命令

npx wrangler dev      # 本地开发服务器Miniflare
npm run typecheck     # 类型检查
npm run lint          # ESLint

支持的事件

事件 格式化内容
push 提交列表、分支、作者
pull_request PR 标题、分支、差异统计
issues Issue 标题、标签、指派人
issue_comment 评论内容、Issue 引用
workflow_run 工作流状态、结论、耗时
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 计数、截止日期
discussion 讨论标题、分类、操作
discussion_comment 评论内容、讨论引用
repository 仓库重命名/转移详情
code_scanning_alert 严重程度、规则 ID、文件路径
dependabot_alert 严重程度、包名、受影响范围、修复版本

许可证

MIT