Chuyển tới nội dung chính

Trình nghe Webhook của Microsoft Graph

Nền tảng cổng msgraph_webhook là một trình xử lý sự kiện gửi đến. Đó là cách Hermes nhận được thông báo thay đổi từ Microsoft Graph — "một cuộc họp Teams đã kết thúc", "một tin nhắn mới đã đến trong cuộc trò chuyện này", "sự kiện lịch này đã được cập nhật". Khác với nền tảng team (là nền tảng mà người dùng sử dụng bot trò chuyện) - nền tảng này là M365 nói với Hermes điều gì đó đã xảy ra, không phải một người.

Hiện tại, đối tượng sử dụng chính là quy trình tóm tắt cuộc họp trên Teams: Graph thông báo khi cuộc họp tạo ra bản ghi, quy trình tìm nạp bản ghi đó và Hermes đăng bản tóm tắt trở lại Teams. Các tài nguyên Đồ thị khác (/chats/.../messages, /users/.../events) sử dụng cùng một trình nghe — người tiêu dùng quy trình tiếp cận với PR của riêng họ.

Điều kiện tiên quyết

  • Thông tin đăng nhập ứng dụng Microsoft Graph — Đăng ký ứng dụng Microsoft Graph
  • URL HTTPS công khai mà Microsoft Graph có thể tiếp cận (Graph không gọi điểm cuối riêng tư). Đường hầm dành cho nhà phát triển hoạt động để thử nghiệm; production cần một miền thực có chứng chỉ hợp lệ.
  • Một bí mật được chia sẻ mạnh mẽ để sử dụng làm giá trị clientState. Tạo bằng openssl rand -hex 32 và đặt nó vào ~/.hermes/.env dưới dạng MSGRAPH_WEBHOOK_CLIENT_STATE.

Bắt đầu nhanh

Tối thiểu ~/.hermes/config.yaml:

platforms:
msgraph_webhook:
enabled: true
extra:
port: 8646
client_state: "replace-with-a-strong-secret"
accepted_resources:
- "communications/onlineMeetings"

Hoặc thông qua env vars trong ~/.hermes/.env (tự động hợp nhất khi khởi động):

MSGRAPH_WEBHOOK_ENABLED=true
MSGRAPH_WEBHOOK_PORT=8646
MSGRAPH_WEBHOOK_CLIENT_STATE=<generate-with-openssl-rand-hex-32>
MSGRAPH_WEBHOOK_ACCEPTED_RESOURCES=communications/onlineMeetings

Khởi động cổng: hermes cổng chạy. Người nghe bộc bạch:

  • POST /msgraph/webhook — thay đổi thông báo từ Graph
  • GET /msgraph/webhook?validationToken=... — Bắt tay xác thực đăng ký biểu đồ
  • GET /health — thăm dò mức độ sẵn sàng với các bộ đếm được chấp nhận/trùng lặp

Hiển thị công khai người nghe (proxy ngược, đường hầm nhà phát triển, xâm nhập). URL thông báo cho các đăng ký Graph là nguồn gốc HTTPS công khai của bạn, theo sau là /msgraph/webhook:

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

Cấu hình

Tất cả cài đặt đều nằm trong platforms.msgraph_webhook.extra:

SettingDefaultDescription
host0.0.0.0Bind address for the HTTP listener.
port8646Bind port.
webhook_path/msgraph/webhookURL path Graph POSTs to.
health_path/healthReadiness endpoint.
client_stateShared secret Graph echoes in every notification. Compared with hmac.compare_digest — generate with openssl rand -hex 32.
accepted_resources[] (accept all)Allowlist of Graph resource paths/patterns. Trailing * acts as prefix match. Leading / is tolerated. Example: ["communications/onlineMeetings", "chats/*/messages"].
max_seen_receipts5000Dedupe cache size for notification IDs. Oldest entries evicted when the cap is hit.
allowed_source_cidrs[] (allow all)Optional source-IP allowlist. See below.

Mỗi cài đặt cũng có một biến env tương đương (MSGRAPH_WEBHOOK_*) hợp nhất vào cấu hình khi khởi động cổng — xem tham chiếu biến môi trường.

Tăng cường bảo mật

clientState là bước kiểm tra xác thực chính

Mọi thông báo của Biểu đồ đều bao gồm chuỗi clientState mà đăng ký của bạn đã đăng ký. Trình nghe từ chối bất kỳ thông báo nào có clientState không khớp, sử dụng so sánh an toàn về thời gian. Đây là cơ chế được ghi lại của Microsoft — coi giá trị là bí mật được chia sẻ mạnh mẽ.

Nếu client_state không được đặt, trình nghe sẽ chấp nhận mọi POST được định dạng đúng. Không chạy mà không có nó trong quá trình sản xuất.

Danh sách cho phép nguồn-IP (triển khai sản xuất)

Để sản xuất, hãy hạn chế trình nghe trong phạm vi IP nguồn webhook Graph đã xuất bản của Microsoft. Microsoft ghi lại các phạm vi đầu ra trong Dịch vụ web URL và địa chỉ IP Office 365. Cấu hình chúng như:

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

Hoặc dưới dạng một env var:

MSGRAPH_WEBHOOK_ALLOWED_SOURCE_CIDRS="52.96.0.0/14,52.104.0.0/14"

Danh sách cho phép trống = chấp nhận từ mọi nơi (mặc định; duy trì quy trình làm việc của đường hầm nhà phát triển). Chuỗi CIDR không hợp lệ ghi lại cảnh báo và bị bỏ qua. Xem lại danh sách IP của Microsoft hàng quý — danh sách này thay đổi.

Chấm dứt HTTPS

Người nghe nói HTTP đơn giản. Chấm dứt TLS tại proxy ngược của bạn (Caddy, Nginx, Cloudflare Tunnel, AWS ALB) và proxy cho người nghe qua mạng cục bộ. Graph từ chối phân phối đến các điểm cuối không phải HTTPS, do đó, không có đường dẫn nào cho lưu lượng truy cập không được mã hóa tiếp cận bạn từ chính Graph.

Vệ sinh ứng phó

Khi thành công, trình nghe trả về 202 Được chấp nhận với phần nội dung trống - các bộ đếm bên trong nằm ngoài phản hồi dây. Người vận hành có thể quan sát số lượng thông qua /health.

Bảng mã trạng thái:

OutcomeStatus
Notification(s) accepted or deduped202
Validation handshake (GET with validationToken)200 (echoes the token)
Every item in batch failed clientState403
Malformed JSON / missing value array / unknown resource400
Source IP not in allowlist403
Bare GET without validationToken400

Khắc phục sự cố

ProblemWhat to check
Graph subscription validation failsPublic URL is reachable, /msgraph/webhook path matches, GET with validationToken echoes the token verbatim as text/plain within 10 seconds.
Notifications POST but nothing ingestsclient_state matches what you registered the subscription with. Re-run openssl rand -hex 32 and create a new subscription if the value drifted. Check accepted_resources includes the resource path Graph is sending.
Every notification 403sclientState mismatch (forged, or subscription registered with a different value). Re-create the subscription with hermes teams-pipeline subscribe --client-state "$MSGRAPH_WEBHOOK_CLIENT_STATE" ... (ships with the pipeline runtime PR).
Listener starts but curl http://localhost:8646/health hangsPort binding collision. Check ss -tlnp | grep 8646 and change port: if needed.
Real Graph requests from Microsoft get 403'dSource IP allowlist is too narrow. Remove allowed_source_cidrs temporarily, confirm traffic flows, then widen the list to include the current Microsoft egress ranges.

Tài liệu liên quan