Microsoft Graph Webhook 監聽器
msgraph_webhook 網關平臺是一個入站事件監聽器。Hermes 通過它接收來自 Microsoft Graph 的變更通知——例如“Teams 會議已結束”、“此聊天中收到新消息”、“此日曆事件已更新”。這與 teams 平臺(用戶向其發送消息的聊天機器人)不同——後者是 M365 告知 Hermes 發生了某事,而非由人發起。
目前的主要消費者是 Teams 會議摘要流水線:當會議生成轉錄文本時,Graph 會發出通知,流水線獲取該文本,然後 Hermes 將摘要發佈回 Teams。其他 Graph 資源(/chats/.../messages、/users/.../events)也使用相同的監聽器——流水線消費者會通過各自的 PR 接入。
前提條件
- Microsoft Graph 應用程序憑據 — 註冊 Microsoft Graph 應用程序
- 一個 Microsoft Graph 可以訪問的公共 HTTPS URL(Graph 不會調用私有端點)。測試時使用開發隧道即可;生產環境需要具有有效證書的真實域名。
- 一個強共享密鑰,用作
clientState值。使用openssl rand -hex 32生成,並將其放入~/.hermes/.env中,設置為MSGRAPH_WEBHOOK_CLIENT_STATE。
快速開始
最小的 ~/.hermes/config.yaml:
platforms:
msgraph_webhook:
enabled: true
extra:
host: 127.0.0.1
port: 8646
client_state: "replace-with-a-strong-secret"
accepted_resources:
- "communications/onlineMeetings"
或者通過 ~/.hermes/.env 中的環境變量(啟動時自動合併):
MSGRAPH_WEBHOOK_ENABLED=true
MSGRAPH_WEBHOOK_PORT=8646
MSGRAPH_WEBHOOK_CLIENT_STATE=<generate-with-openssl-rand-hex-32>
MSGRAPH_WEBHOOK_ACCEPTED_RESOURCES=communications/onlineMeetings
注意:綁定主機從 config.yaml 中的 extra.host 讀取(參見上面的示例);沒有 MSGRAPH_WEBHOOK_HOST 環境變量覆蓋。
啟動網關:hermes gateway run。監聽器暴露以下端點:
POST /msgraph/webhook— 來自 Graph 的變更通知GET /msgraph/webhook?validationToken=...— Graph 訂閱驗證握手GET /health— 就緒探針,包含已接受/重複計數器
公開暴露監聽器(通過反向代理、開發隧道或入口控制器)。用於 Graph 訂閱的通知 URL 是你的公共 HTTPS 源地址後跟 /msgraph/webhook:
https://ops.example.com/msgraph/webhook
配置
所有設置均位於 platforms.msgraph_webhook.extra 下:
| 設置 | 默認值 | 描述 |
|---|---|---|
host | 0.0.0.0 | HTTP 監聽器的綁定地址。非環回綁定需要 allowed_source_cidrs;環回(127.0.0.1 / ::1)是最簡單的開發隧道/反向代理設置。 |
port | 8646 | 綁定端口。 |
webhook_path | /msgraph/webhook | Graph POST 請求的 URL 路徑。 |
health_path | /health | 就緒端點。 |
client_state | — | 共享密鑰,Graph 會在每個通知中回顯該值。使用 hmac.compare_digest 進行比較 — 使用 openssl rand -hex 32 生成。 |
accepted_resources | [](接受所有) Graph 資源路徑/模式的允許列表。尾隨 * 作為前綴匹配。前導 / 是被容忍的。示例:["communications/onlineMeetings", "chats/*/messages"]。 | |
max_seen_receipts | 5000 | 通知 ID 的去重緩存大小。達到上限時驅逐最舊的條目。 |
allowed_source_cidrs | [] | 非環回綁定必需。僅當監聽器綁定到環回地址並由本地隧道/反向代理前置時,才留空。 |
大多數設置也有等效的環境變量(MSGRAPH_WEBHOOK_*),它們在網關啟動時合併到配置中(例外是 host,僅限配置—見上文說明)— 請參閱環境變量參考。
安全加固
clientState 是主要的身份驗證檢查
每個 Graph 通知都包含你註冊訂閱時提供的 clientState 字符串。如果通知的 clientState 不匹配,監聽器將使用計時安全比較予以拒絕。這是微軟記錄的機制—請將該值視為強共享秘密。
如果未設置 client_state,監聽器將拒絕啟動。
源 IP 允許列表(生產部署)
對於生產環境,將監聽器限制為微軟發佈的 Graph webhook 源 IP 範圍。微軟在 Office 365 IP 地址和 URL Web 服務 下記錄了出站範圍。配置如下:
platforms:
msgraph_webhook:
enabled: true
extra:
host: 0.0.0.0
client_state: "..."
allowed_source_cidrs:
- "52.96.0.0/14"
- "52.104.0.0/14"
# ...add the current Microsoft 365 "Common" + "Teams" category egress ranges
或者作為環境變量:
MSGRAPH_WEBHOOK_ALLOWED_SOURCE_CIDRS="52.96.0.0/14,52.104.0.0/14"
如果在沒有 allowed_source_cidrs 的情況下綁定非環回主機(如 0.0.0.0、:: 或 LAN IP),啟動時將被拒絕。如果你在同一臺機器上使用開發隧道或反向代理,請將 Hermes 綁定到 127.0.0.1 或 ::1,並將允許列表留空。無效的 CIDR 字符串會記錄警告並被忽略。每季度審查微軟 IP 列表—它會發生變化。
HTTPS 終止
監聽器使用純 HTTP 通信。在反向代理(Caddy、Nginx、Cloudflare Tunnel、AWS ALB)處終止 TLS,並通過本地網絡代理到監聽器。Graph 拒絕交付到非 HTTPS 端點,因此來自 Graph 本身的未加密流量無法到達你。
響應衛生
成功時,監聽器返回 202 Accepted 且響應體為空——內部計數器不會出現在網絡響應中。操作員可以通過 /health 端點觀察計數,該端點受與 webhook 路徑相同的源 IP 規則保護。
狀態碼錶:
| 結果 | 狀態碼 |
|---|---|
| 通知已接受或去重 | 202 |
驗證握手(帶有 validationToken 的 GET 請求) | 200(回顯令牌) |
| 批次中的每個項目均因 clientState 失敗 | 403 |
JSON 格式錯誤 / 缺少 value 數組 / 未知資源 | 400 |
| 源 IP 不在允許列表中 | 403 |
不帶 validationToken 的普通 GET 請求 | 400 |
故障排除
| 問題 | 檢查事項 |
|---|---|
| Graph 訂閱驗證失敗 | 公共 URL 可訪問,/msgraph/webhook 路徑匹配,帶有 validationToken 的 GET 請求在 10 秒內以 text/plain 原樣回顯令牌。 |
| 通知已 POST 但未被攝入 | client_state 與你註冊訂閱時使用的值匹配。如果值發生漂移,請重新運行 openssl rand -hex 32 並創建新訂閱。檢查 accepted_resources 是否包含 Graph 發送的資源路徑。 |
| 每個通知都返回 403 | clientState 不匹配(被偽造,或訂閱註冊時使用了不同的值)。使用 hermes teams-pipeline subscribe --client-state "$MSGRAPH_WEBHOOK_CLIENT_STATE" ... 重新創建訂閱(隨管道運行時 PR 提供)。 |
監聽器拒絕在 0.0.0.0 上啟動 | 將 allowed_source_cidrs 設置為 Microsoft 當前的 webhook 出口範圍,或者將 Hermes 綁定到隧道或反向代理背後的 127.0.0.1 / ::1。 |
監聽器已啟動,但 curl http://localhost:8646/health 掛起 | 端口綁定衝突。檢查 ss -tlnp | grep 8646 並在必要時更改 port:。 |
| 來自 Microsoft 的真實 Graph 請求被返回 403 | 源 IP 允許列表過窄。擴大列表以包含當前的 Microsoft 出口範圍。如果你仍在驗證隧道路徑,請將 Hermes 綁定到環回接口,讓隧道處理公共暴露。 |
相關文檔
- 註冊 Microsoft Graph 應用程序 — Azure 應用註冊前提條件
- 環境變量 → Microsoft Graph — 完整的環境變量列表
- Microsoft Teams 機器人設置 — 不同的平臺,允許用戶在 Teams 中與 Hermes 聊天