跳到主要内容

Webhooks 设置

从外部服务(GitHub、GitLab、JIRA、Stripe 等)接收事件并自动触发 Hermes agent 运行。Webhook 适配器运行一个接受 POST 请求的 HTTP 服务器,验证 HMAC 签名,将负载转换为 agent 提示词,并将响应路由回源或其他配置的平台上。

Agent 处理事件后可以通过在 PR 上发布评论、发送消息到 Telegram/Discord 或记录结果来响应。


快速开始

  1. 通过 hermes gateway setup 或环境变量启用
  2. config.yaml 中定义路由 使用 hermes webhook subscribe 动态创建
  3. 将你的服务指向 http://your-server:8644/webhooks/<route-name>

设置

有两种方式启用 webhook 适配器。

通过设置向导

hermes gateway setup

按照提示启用 webhooks、设置端口和设置全局 HMAC secret。

通过环境变量

添加到 ~/.hermes/.env

WEBHOOK_ENABLED=true
WEBHOOK_PORT=8644 # 默认
WEBHOOK_SECRET=your-global-secret

验证服务器

网关运行后:

curl http://localhost:8644/health

预期响应:

{"status": "ok", "platform": "webhook"}

配置路由

路由定义如何处理不同的 webhook 源。每个路由是你 config.yamlplatforms.webhook.extra.routes 下的命名条目。

路由属性

属性必填描述
events接受的事件类型列表(如 ["pull_request"])。如果为空,接受所有事件。
secret签名验证的 HMAC secret。如果路由未设置,回退到全局 secret。设为 "INSECURE_NO_AUTH" 仅用于测试(跳过验证)。
prompt带点号表示法的负载访问模板字符串(如 {pull_request.title})。如果省略,完整 JSON 负载被转储到提示词中。
skills为 agent 运行加载的 skill 名称列表
deliver响应发送到哪里:github_commenttelegramdiscord、slacksignalsmswhatsappmatrixmattermosthomeassistantemaildingtalkfeishuwecomweixinbluebubblesqqbotlog`(默认)。
deliver_extra附加投递配置 — 键取决于 deliver 类型(如 repopr_numberchat_id)。值支持与 prompt 相同的 {dot.notation} 模板。

完整示例

platforms:
webhook:
enabled: true
extra:
port: 8644
secret: "global-fallback-secret"
routes:
github-pr:
events: ["pull_request"]
secret: "github-webhook-secret"
prompt: |
Review this pull request:
Repository: {repository.full_name}
PR #{number}: {pull_request.title}
Author: {pull_request.user.login}
URL: {pull_request.html_url}
skills: ["github-code-review"]
deliver: "github_comment"
deliver_extra:
repo: "{repository.full_name}"
pr_number: "{number}"
deploy-notify:
events: ["push"]
secret: "deploy-secret"
prompt: "New push to {repository.full_name} branch {ref}: {head_commit.message}"
deliver: "telegram"

提示词模板

提示词使用点号表示法访问 webhook 负载中的嵌套字段:

  • {pull_request.title} 解析为 payload["pull_request"]["title"]
  • {repository.full_name} 解析为 payload["repository"]["full_name"]
  • {__raw__} — 转储整个负载为缩进 JSON 的特殊标记(截断至 4000 字符)
  • 缺失的键保留为字面 {key} 字符串(无错误)
  • 嵌套字典和列表被 JSON 序列化并截断至 2000 字符

投递选项

deliver 字段控制 agent 处理 webhook 事件后响应的去向:

投递类型描述
log将响应记录到网关日志输出。这是默认值,适合测试。
github_comment通过 gh CLI 将响应作为 PR/issue 评论发布。需要 deliver_extra.repodeliver_extra.pr_number
telegram将响应路由到 Telegram。使用主频道或在 deliver_extra 中指定 chat_id
discord将响应路由到 Discord。使用主频道或在 deliver_extra 中指定 chat_id
slack将响应路由到 Slack。使用主频道或在 deliver_extra 中指定 chat_id
signal将响应路由到 Signal。使用主频道或在 deliver_extra 中指定 chat_id
sms将响应路由到 SMS(通过 Twilio)。使用主频道或在 deliver_extra 中指定 chat_id
whatsapp将响应路由到 WhatsApp。使用主频道或在 deliver_extra 中指定 chat_id
matrix将响应路由到 Matrix。使用主频道或在 deliver_extra 中指定 chat_id
mattermost将响应路由到 Mattermost。使用主频道或在 deliver_extra 中指定 chat_id
homeassistant将响应路由到 Home Assistant。使用主频道或在 deliver_extra 中指定 chat_id
email将响应路由到 Email。使用主频道或在 deliver_extra 中指定 chat_id
dingtalk将响应路由到 DingTalk。使用主频道或在 deliver_extra 中指定 chat_id
feishu将响应路由到 Feishu/Lark。使用主频道或在 deliver_extra 中指定 chat_id
wecom将响应路由到 WeCom。使用主频道或在 deliver_extra 中指定 chat_id
weixin将响应路由到微信(WeChat)。使用主频道或在 deliver_extra 中指定 chat_id
bluebubbles将响应路由到 BlueBubbles(iMessage)。使用主频道或在 deliver_extra 中指定 chat_id

动态订阅(CLI)

除了 config.yaml 中的静态路由,你还可以使用 hermes webhook CLI 命令动态创建 webhook 订阅。当 agent 本身需要设置事件驱动触发器时,这特别有用。

创建订阅

hermes webhook subscribe github-issues \
--events "issues" \
--prompt "New issue #{issue.number}: {issue.title}\nBy: {issue.user.login}\n\n{issue.body}" \
--deliver telegram \
--deliver-chat-id "-100123456789" \
--description "Triage new GitHub issues"

列出订阅

hermes webhook list

移除订阅

hermes webhook remove github-issues

测试订阅

hermes webhook test github-issues
hermes webhook test github-issues --payload '{"issue": {"number": 42, "title": "Test"}}'

GitHub PR 审查(分步)

本指南设置每次拉取请求的自动代码审查。

1. 在 GitHub 中创建 webhook

  1. 进入你的仓库 → SettingsWebhooksAdd webhook
  2. 设置 Payload URLhttp://your-server:8644/webhooks/github-pr
  3. 设置 Content typeapplication/json
  4. 设置 Secret 以匹配你的路由配置
  5. Which events? 下,选择 Let me select individual events 并勾选 Pull requests
  6. 点击 Add webhook

2. 添加路由配置

github-pr 路由添加到你的 ~/.hermes/config.yaml(如上面的完整示例所示)。

3. 确保 gh CLI 已认证

github_comment 投递类型使用 GitHub CLI 发布评论:

gh auth login

4. 测试

在仓库上打开一个拉取请求。Webhook 触发,Hermes 处理事件,并在 PR 上发布审查评论。


GitLab Webhook 设置

GitLab webhook 工作方式类似但使用不同的认证机制。GitLab 将 secret 作为纯 X-Gitlab-Token 头发送(精确字符串匹配,非 HMAC)。

1. 在 GitLab 中创建 webhook

  1. 进入你的项目 → SettingsWebhooks
  2. 设置 URLhttp://your-server:8644/webhooks/gitlab-mr
  3. 输入你的 Secret token
  4. 选择 Merge request events(以及你需要的任何其他事件)
  5. 点击 Add webhook

2. 添加路由配置

platforms:
webhook:
enabled: true
extra:
routes:
gitlab-mr:
events: ["merge_request"]
secret: "your-gitlab-secret-token"
prompt: |
Review this merge request:
Project: {project.path_with_namespace}
MR !{object_attributes.iid}: {object_attributes.title}
Author: {object_attributes.last_commit.author.name}
URL: {object_attributes.url}
deliver: "log"

安全

Webhook 适配器包含多层安全保护:

HMAC 签名验证

适配器使用适用于每个源的方法验证入站 webhook 签名:

  • GitHubX-Hub-Signature-256 头 — 以 sha256= 为前缀的 HMAC-SHA256 十六进制摘要
  • GitLabX-Gitlab-Token 头 — 纯 secret 字符串匹配
  • 通用X-Webhook-Signature 头 — 原始 HMAC-SHA256 十六进制摘要

Secret 是必需的

每个路由必须有一个 secret — 要么直接在路由上设置,要么从全局 secret 继承。没有 secret 的路由会导致适配器启动失败并报错。对于开发/测试,你可以将 secret 设为 "INSECURE_NO_AUTH" 以完全跳过验证。

速率限制

每个路由默认限制为每分钟 30 请求(固定窗口)。全局配置:

platforms:
webhook:
extra:
rate_limit: 60 # 每分钟请求数

幂等性

投递 ID(来自 X-GitHub-DeliveryX-Request-ID 或时间戳备选)被缓存 1 小时。重复投递(例如 webhook 重试)会被静默跳过并返回 200 响应,防止重复 agent 运行。

负载大小限制

超过 1 MB 的负载在读取正文之前被拒绝。配置:

platforms:
webhook:
extra:
max_body_bytes: 2097152 # 2 MB
提示词注入风险

Webhook 负载包含攻击者控制的数据 — PR 标题、提交消息、issue 描述等都可以包含恶意指令。暴露在互联网时,在沙盒化环境(Docker、VM)中运行网关。考虑使用 Docker 或 SSH 终端后端进行隔离。


故障排除

Webhook 未到达

  • 验证端口已暴露且可从 webhook 源访问
  • 检查防火墙规则 — 端口 8644(或你配置的端口)必须开放
  • 验证 URL 路径匹配:http://your-server:8644/webhooks/<route-name>
  • 使用 /health 端点确认服务器正在运行

签名验证失败

  • 确保你的路由配置中的 secret 与 webhook 源中配置的 secret 完全匹配
  • 对于 GitHub,secret 是基于 HMAC 的 — 检查 X-Hub-Signature-256
  • 对于 GitLab,secret 是纯 token 匹配 — 检查 X-Gitlab-Token
  • 检查网关日志中的 Invalid signature 警告

事件被忽略

  • 检查事件类型是否在你的路由的 events 列表中
  • GitHub 事件使用如 pull_requestpushissues 这样的值(X-GitHub-Event 头值)
  • GitLab 事件使用如 merge_requestpush 这样的值(X-GitLab-Event 头值)
  • 如果 events 为空或未设置,接受所有事件

Agent 不响应

  • 在前台运行网关查看日志:hermes gateway run
  • 检查提示词模板是否正确渲染
  • 验证投递目标已配置并连接

重复响应

  • 幂等性缓存应该防止这种情况 — 检查 webhook 源是否发送了投递 ID 头(X-GitHub-DeliveryX-Request-ID
  • 投递 ID 被缓存 1 小时

gh CLI 错误(GitHub 评论投递)

  • 在网关上运行 gh auth login
  • 确保已认证的 GitHub 用户对仓库有写访问权限
  • 检查 gh 已安装并在 PATH 上

环境变量

变量描述默认值
WEBHOOK_ENABLED启用 webhook 平台适配器false
WEBHOOK_PORT用于接收 webhooks 的 HTTP 服务器端口8644
WEBHOOK_SECRET全局 HMAC secret(当路由未指定自己的 secret 时用作备选)(无)