hermes-agent/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/user-guide/messaging/msgraph-webhook.md
Teknium 76135b329d
docs(i18n): translate all docs into Simplified Chinese (zh-Hans) (#31942)
Translates the full English docs corpus (335 files) into Simplified
Chinese under website/i18n/zh-Hans/. Combined with PR #31895 (cross-
locale link fix), the 简体中文 locale toggle now serves a complete
Chinese site with working cross-page navigation.

Pipeline:
- Claude Sonnet 4.6 via OpenRouter, 8-way concurrent
- Preserves frontmatter keys, code blocks, MDX/JSX, link URLs, brand
  names, and technical jargon (prompt/token/hook/MCP/ACP/etc.)
- Translates only frontmatter title/description and prose
- Two largest files (configuration.md 93KB, research-paper-writing.md
  107KB) retried with 64K max_tokens after initial fence-drift
- 3 manual post-fixes for MDX edge cases the model didn't escape:
  < in optional-skills-catalog table, double-quotes in an alt= tag,
  and a bare URL adjacent to a full-width period

Cost: ~$30 total (Sonnet 4.6 input $3/M + output $15/M).

Verified `npm run build` succeeds for both en and zh-Hans locales,
no double-prefixed /docs/zh-Hans/docs/ URLs in rendered output,
all in-page navigation resolves correctly.

Translations are machine-generated and may need human review on
specific pages — but they're an enormous improvement over the
previous state (3 zh-Hans pages out of 335).
2026-05-25 01:47:38 -07:00

7.1 KiB
Raw Blame History

sidebar_position title description
23 Microsoft Graph Webhook 监听器 在 Hermes 中接收 Microsoft Graph 变更通知(会议、日历、聊天等)

Microsoft Graph Webhook 监听器

msgraph_webhook gateway 平台是一个入站事件监听器。它是 Hermes 接收来自 Microsoft Graph 的变更通知的方式——"一个 Teams 会议已结束"、"此聊天中收到了一条新消息"、"此日历事件已更新"。与 teams 平台(用户向其发送消息的聊天机器人)不同——此平台是 M365 告知 Hermes 某事已发生,而非来自用户的消息。

目前主要的消费者是 Teams 会议摘要流水线Graph 在会议产生转录文本时发出通知流水线获取该内容Hermes 将摘要发回 Teams。其他 Graph 资源(/chats/.../messages/users/.../events)使用同一监听器——流水线消费者通过各自的 PR 接入。

前提条件

  • Microsoft Graph 应用凭据——注册 Microsoft Graph 应用程序
  • 一个 Microsoft Graph 可访问的公开 HTTPS URLGraph 不会调用私有端点)。测试时可使用 dev tunnel生产环境需要具有有效证书的真实域名。
  • 一个强共享密钥,用作 clientState 的值。使用 openssl rand -hex 32 生成,并以 MSGRAPH_WEBHOOK_CLIENT_STATE 写入 ~/.hermes/.env

快速开始

最小化 ~/.hermes/config.yaml

platforms:
  msgraph_webhook:
    enabled: true
    extra:
      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

启动 gatewayhermes gateway run。监听器暴露以下端点:

  • POST /msgraph/webhook — 来自 Graph 的变更通知
  • GET /msgraph/webhook?validationToken=... — Graph 订阅验证握手
  • GET /health — 就绪探针,包含已接受/重复计数器

将监听器公开暴露反向代理、dev tunnel、ingress。Graph 订阅的通知 URL 为你的公开 HTTPS 源地址加上 /msgraph/webhook

https://ops.example.com/msgraph/webhook

配置

所有设置位于 platforms.msgraph_webhook.extra 下:

设置 默认值 说明
host 0.0.0.0 HTTP 监听器的绑定地址。
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 [](允许全部) 可选的源 IP 白名单。见下文。

每个设置也有对应的环境变量(MSGRAPH_WEBHOOK_*),在 gateway 启动时合并到配置中——参见环境变量参考

安全加固

clientState 是主要的认证检查

每条 Graph 通知都包含你在订阅时注册的 clientState 字符串。监听器使用时序安全比较拒绝任何 clientState 不匹配的通知。这是 Microsoft 的官方机制——请将该值视为强共享密钥。

如果未设置 client_state,监听器将接受所有格式正确的 POST 请求。生产环境中请勿在未设置的情况下运行。

源 IP 白名单(生产部署)

在生产环境中,将监听器限制为 Microsoft 公布的 Graph webhook 源 IP 范围。Microsoft 在 Office 365 IP 地址和 URL Web 服务中记录了出口范围。配置方式如下:

platforms:
  msgraph_webhook:
    enabled: true
    extra:
      client_state: "..."
      allowed_source_cidrs:
        - "52.96.0.0/14"
        - "52.104.0.0/14"
        # ...添加当前 Microsoft 365 "Common" + "Teams" 类别的出口范围

或通过环境变量:

MSGRAPH_WEBHOOK_ALLOWED_SOURCE_CIDRS="52.96.0.0/14,52.104.0.0/14"

空白名单 = 接受来自任何地址的请求(默认;保留 dev tunnel 工作流)。无效的 CIDR 字符串会记录警告并被忽略。请每季度审查 Microsoft IP 列表——它会变更。

HTTPS 终止

监听器使用纯 HTTP。在你的反向代理Caddy、Nginx、Cloudflare Tunnel、AWS ALB处终止 TLS并通过本地网络代理到监听器。Graph 拒绝向非 HTTPS 端点投递,因此来自 Graph 的未加密流量不存在可达路径。

响应规范

成功时,监听器返回 202 Accepted 且响应体为空——内部计数器不会出现在响应中。运维人员可通过 /health 观察计数。

状态码说明:

结果 状态码
通知已接受或已去重 202
验证握手(带 validationToken 的 GET 200原样回传 token
批次中所有条目的 clientState 均失败 403
JSON 格式错误 / 缺少 value 数组 / 未知资源 400
源 IP 不在白名单中 403
不带 validationToken 的裸 GET 400

故障排查

问题 检查项
Graph 订阅验证失败 公开 URL 可访问,/msgraph/webhook 路径匹配,带 validationToken 的 GET 在 10 秒内以 text/plain 原样回传 token。
通知 POST 成功但无内容被摄取 client_state 与订阅时注册的值一致。如值已漂移,重新运行 openssl rand -hex 32 并创建新订阅。检查 accepted_resources 是否包含 Graph 发送的资源路径。
每条通知均返回 403 clientState 不匹配(伪造,或订阅时使用了不同的值)。使用 hermes teams-pipeline subscribe --client-state "$MSGRAPH_WEBHOOK_CLIENT_STATE" ... 重新创建订阅(随流水线运行时 PR 一同发布)。
监听器已启动,但 curl http://localhost:8646/health 挂起 端口绑定冲突。检查 ss -tlnp | grep 8646,如有需要更改 port:
来自 Microsoft 的真实 Graph 请求返回 403 源 IP 白名单范围过窄。临时移除 allowed_source_cidrs,确认流量正常后,将列表扩展至包含当前 Microsoft 出口范围。

相关文档