跳到主要內容

Webhooks

從外部服務(GitHub、GitLab、JIRA、Stripe 等)接收事件,並自動觸發 Hermes Agent 運行。Webhook 適配器運行一個 HTTP 服務器,接收 POST 請求,驗證 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 密鑰。

通過環境變量

將以下內容添加到 ~/.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"])。如果為空,則接受所有事件。事件類型從 X-GitHub-EventX-GitLab-Event 或有效載荷中的 event_type 讀取。
secret用於簽名驗證的 HMAC 密鑰。如果路由未設置,則回退到全局 secret。僅用於測試時設置為 "INSECURE_NO_AUTH"(跳過驗證)。
prompt包含點號表示法有效載荷訪問的模板字符串(例如 {pull_request.title})。如果省略,則將完整 JSON 有效載荷轉儲到提示中。
skills為 Agent 運行加載的技能名稱列表。
deliver響應發送位置:github_commenttelegramdiscordslacksignalsmswhatsappmatrixmattermosthomeassistantemaildingtalkfeishuwecomweixinbluebubbleslog(默認)。
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}
Diff URL: {pull_request.diff_url}
Action: {action}
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 個字符)。適用於監控警報或通用 Webhook,其中 Agent 需要完整上下文。
  • 缺失的鍵將保留為字面量 {key}(無錯誤)
  • 嵌套字典和列表將被 JSON 序列化,並在 2000 個字符處截斷

你可以將 {__raw__} 與常規模板變量混合使用:

prompt: "PR #{pull_request.number} by {pull_request.user.login}: {__raw__}"

如果某個路由未配置 prompt 模板,則整個有效載荷將以縮進的 JSON 格式轉儲(截斷為 4000 個字符)。

相同的點號表示法模板也適用於 deliver_extra 值。

論壇主題交付

當向 Telegram 交付 Webhook 響應時,可以通過在 deliver_extra 中包含 message_thread_id(或 thread_id)來定位特定論壇主題:

webhooks:
routes:
alerts:
events: ["alert"]
prompt: "Alert: {__raw__}"
deliver: "telegram"
deliver_extra:
chat_id: "-1001234567890"
message_thread_id: "42"

如果 deliver_extra 中未提供 chat_id,交付將回退到目標平臺配置的主頻道。


GitHub PR 審查(逐步指南)

本指南將設置在每次拉取請求上自動進行代碼審查。

1. 在 GitHub 中創建 Webhook

  1. 進入你的倉庫 → 設置Webhooks添加 Webhook
  2. 設置 有效載荷 URLhttp://your-server:8644/webhooks/github-pr
  3. 設置 內容類型application/json
  4. 設置 密鑰 以匹配你的路由配置(例如 github-webhook-secret
  5. 哪些事件? 下,選擇 讓我選擇單個事件,並勾選 拉取請求
  6. 點擊 添加 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 以明文 X-Gitlab-Token 頭髮送密鑰(精確字符串匹配,非 HMAC)。

  1. 進入您的項目 → 設置Webhooks
  2. URL 設置為 http://your-server:8644/webhooks/gitlab-mr
  3. 輸入您的 密鑰令牌
  4. 選擇 合併請求事件(以及您想要的其他事件)
  5. 點擊 添加 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}
Action: {object_attributes.action}
deliver: "log"

交付選項

deliver 字段控制 Agent 在處理 Webhook 事件後,將響應發送到何處。

交付類型描述
log將響應記錄到網關日誌輸出中。這是默認選項,適用於測試。
github_comment通過 gh CLI 將響應作為 PR/問題評論發佈。需要 deliver_extra.repodeliver_extra.pr_numbergh CLI 必須在網關主機上安裝並已認證(gh auth login)。
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通過 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將響應路由至電子郵件。使用主頻道,或在 deliver_extra 中指定 chat_id
dingtalk將響應路由至釘釘。使用主頻道,或在 deliver_extra 中指定 chat_id
feishu將響應路由至飛書/飛書。使用主頻道,或在 deliver_extra 中指定 chat_id
wecom將響應路由至企業微信。使用主頻道,或在 deliver_extra 中指定 chat_id
weixin將響應路由至微信(WeChat)。使用主頻道,或在 deliver_extra 中指定 chat_id
bluebubbles將響應路由至 BlueBubbles(iMessage)。使用主頻道,或在 deliver_extra 中指定 chat_id

對於跨平臺交付,目標平臺也必須在網關中啟用並已連接。如果 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"

此命令將返回 Webhook URL 和自動生成的 HMAC 密鑰。請配置您的服務向該 URL 發送 POST 請求。

列出訂閱

hermes webhook list

刪除訂閱

hermes webhook remove github-issues

測試訂閱

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

動態訂閱的工作原理

  • 訂閱信息存儲在 ~/.hermes/webhook_subscriptions.json
  • Webhook 適配器在每次接收到請求時熱重載該文件(基於修改時間,開銷可忽略)
  • config.yaml 中的靜態路由始終優先於同名的動態路由
  • 動態訂閱使用與靜態路由相同的路由格式和功能(事件、提示模板、技能、交付)
  • 無需重啟網關 —— 訂閱後立即生效

Agent 驅動的訂閱

Agent 可通過終端工具在 webhook-subscriptions 技能的引導下創建訂閱。例如,讓 Agent“為 GitHub 問題設置 Webhook”,它將自動執行相應的 hermes webhook subscribe 命令。


安全性

Webhook 適配器包含多層安全機制:

HMAC 簽名驗證

適配器使用每個源對應的適當方法驗證傳入的 Webhook 簽名:

  • GitHubX-Hub-Signature-256 頭 —— HMAC-SHA256 十六進制摘要,前綴為 sha256=
  • GitLabX-Gitlab-Token 頭 —— 純密鑰字符串匹配
  • 通用X-Webhook-Signature 頭 —— 原始 HMAC-SHA256 十六進制摘要

如果配置了密鑰但未檢測到可識別的簽名頭,請求將被拒絕。

密鑰為必需項

每個路由都必須設置密鑰 —— 要麼直接在路由中設置,要麼從全局 secret 繼承。未設置密鑰的路由會導致適配器在啟動時失敗並報錯。僅用於開發/測試時,可將密鑰設為 "INSECURE_NO_AUTH" 以完全跳過驗證。

速率限制

每個路由默認限制為 每分鐘 30 次請求(固定窗口)。可全局配置:

platforms:
webhook:
extra:
rate_limit: 60 # 每分鐘請求數

超過限制的請求將收到 429 Too Many Requests 響應。

冪等性

交付 ID(來自 X-GitHub-DeliveryX-Request-ID 或時間戳回退)會被緩存 1 小時。重複的交付(例如 Webhook 重試)將被靜默跳過,並返回 200 響應,從而防止重複執行 Agent。

請求體大小限制

超過 1 MB 的負載在讀取請求體之前即被拒絕。可進行如下配置:

platforms:
webhook:
extra:
max_body_bytes: 2097152 # 2MB

提示注入風險

注意

Webhook 負載包含攻擊者控制的數據——PR 標題、提交信息、問題描述等都可能包含惡意指令。當網關暴露在互聯網時,建議在沙箱環境(如 Docker、虛擬機)中運行。考慮使用 Docker 或 SSH 終端後端以實現隔離。


故障排除

Webhook 未到達

  • 確認端口已暴露且可從 Webhook 源訪問
  • 檢查防火牆規則——端口 8644(或您配置的端口)必須開放
  • 確認 URL 路徑匹配:http://your-server:8644/webhooks/<route-name>
  • 使用 /health 端點確認服務器正在運行

簽名驗證失敗

  • 確保路由配置中的密鑰與 Webhook 源中配置的密鑰完全一致
  • 對於 GitHub,密鑰基於 HMAC —— 檢查 X-Hub-Signature-256
  • 對於 GitLab,密鑰為明文令牌匹配 —— 檢查 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接收 Webhook 的 HTTP 服務器端口8644
WEBHOOK_SECRET全局 HMAC 密鑰(當路由未指定自身密鑰時作為回退)(無)