الأكاديمية ← قنوات المراسلةتوثيق رسمي · إرشاد عربي

مستقبل أحداث Microsoft Graph

Microsoft Graph Webhook Listener

متوسط6 دقائق قراءةالدرس 274 أسئلة✓ 2026-08-18
قبل أن تقرأ

ما هذه الصفحة، وماذا تحتوي.

الخطافات: أن تربط كودك بلحظة معيّنة: قبل تشغيل أداة، بعد انتهاء مهمة، عند وصول رسالة. تضيف تحقّقاتك وقيودك من دون تعديل Hermes نفسه. ستستعمل هنا hermes gateway run، والقراءة نحو 6 دقائق. انتبه: الخطاف يعمل في كل مرة يقع فيها الحدث. اجعله سريعًا، وتعامل مع فشله بوضوح.

6أقسام
5أمثلة برمجية
3جداول
1أوامر
983كلمة من المصدر
الوصف الرسمي في سطر

Receive Microsoft Graph change notifications (meetings, calendar, chat, etc.) in Hermes

ماذا ستستطيع بعدها

نتائج مأخوذة من هذه الصفحة، لا من قالب.

  • تعرف ما الخطافات ولماذا قد تحتاجه.
  • تنفّذ hermes gateway run وتفهم ما يحدث بعدها.
  • تقرأ الجدول وتأخذ منه السطر الذي يخصّك فقط.
  • تضبط MSGRAPH_WEBHOOK_CLIENT_STATE في المكان الصحيح.
ما ستقابله من أسماء

كما تظهر تمامًا داخل Hermes.

الأوامر
  • hermes gateway run
متغيرات البيئة
  • MSGRAPH_WEBHOOK_CLIENT_STATE
  • MSGRAPH_WEBHOOK_ENABLED
  • MSGRAPH_WEBHOOK_PORT
  • MSGRAPH_WEBHOOK_ACCEPTED_RESOURCES
  • MSGRAPH_WEBHOOK_HOST
  • MSGRAPH_WEBHOOK_ALLOWED_SOURCE_CIDRS
خريطة الصفحة

انتقل مباشرة إلى ما تحتاجه.

  1. 01Prerequisites
  2. 02Quick Start
  3. 03Configuration
  4. 04Security Hardening
  5. 05Troubleshooting
  6. 06Related Docs
الصفحة الرسمية كاملة

بلا اختصار أو حذف.

النص أدناه منقول من المصدر الرسمي بالإنجليزية حتى تبقى الأوامر والأسماء دقيقة كما هي. قبل كل قسم شرح عربي يوضّح ما بداخله.

The msgraph_webhook gateway platform is an inbound event listener. It's how Hermes receives change notifications from Microsoft Graph — "a Teams meeting ended," "a new message landed in this chat," "this calendar event was updated." Different from the teams platform (which is a chat bot users type to) — this one is M365 telling Hermes something happened, not a person.

Right now the primary consumer is the Teams meeting summary pipeline: Graph notifies when a meeting produces a transcript, the pipeline fetches it, and Hermes posts a summary back into Teams. Other Graph resources (/chats/.../messages, /users/.../events) use the same listener — the pipeline consumers land with their own PRs.

Prerequisites

إعدادات تضبطها مرة وتنساها. غيّر واحدًا في كل مرة حتى تعرف أثر كل تغيير. تضبط MSGRAPH_WEBHOOK_CLIENT_STATE خارج المحادثة، في بيئة التشغيل.

  • Microsoft Graph application credentials — Register a Microsoft Graph Application
  • A public HTTPS URL that Microsoft Graph can reach (Graph does not call private endpoints). A dev tunnel works for testing; production needs a real domain with a valid certificate.
  • A strong shared secret to use as the clientState value. Generate with openssl rand -hex 32 and put it in ~/.hermes/.env as MSGRAPH_WEBHOOK_CLIENT_STATE.

Quick Start

خطوات عملية بالترتيب. نفّذ خطوة وتأكد أنها نجحت قبل الانتقال للتالية. الأوامر هنا: hermes gateway run.

Minimum ~/.hermes/config.yaml:

YAML9 أسطر
platforms:
  msgraph_webhook:
    enabled: true
    extra:
      host: 127.0.0.1
      port: 8646
      client_state: "replace-with-a-strong-secret"
      accepted_resources:
        - "communications/onlineMeetings"

Or via env vars in ~/.hermes/.env (auto-merged on startup):

Shell4 أسطر
MSGRAPH_WEBHOOK_ENABLED=true
MSGRAPH_WEBHOOK_PORT=8646
MSGRAPH_WEBHOOK_CLIENT_STATE=<generate-with-openssl-rand-hex-32>
MSGRAPH_WEBHOOK_ACCEPTED_RESOURCES=communications/onlineMeetings

Note: the bind host is read from extra.host in config.yaml (see the example above); there is no MSGRAPH_WEBHOOK_HOST env-var override.

Start the gateway: hermes gateway run. The listener exposes:

  • POST /msgraph/webhook — change notifications from Graph
  • GET /msgraph/webhook?validationToken=... — Graph subscription validation handshake
  • GET /health — readiness probe with accepted/duplicate counters

Expose the listener publicly (reverse proxy, dev tunnel, ingress). Your notification URL for Graph subscriptions is your public HTTPS origin followed by /msgraph/webhook:

Textسطر واحد
https://ops.example.com/msgraph/webhook

Configuration

جدول مرجعي. لا تقرأه كله، ابحث عن السطر الذي يخصّك فقط.

All settings go under platforms.msgraph_webhook.extra:

SettingDefaultDescription
hostunset (dual-stack: all interfaces, IPv4+IPv6)Bind address for the HTTP listener. Non-loopback binds require allowed_source_cidrs; loopback (127.0.0.1 / ::1) is the easiest dev-tunnel / reverse-proxy setup.
port8646Bind port.
webhook_path/msgraph/webhookURL path Graph POSTs to.
health_path/healthReadiness endpoint.
client_state—Shared 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[]Required for non-loopback binds. Leave empty only when the listener is bound to loopback and fronted by a local tunnel / reverse proxy.

Most settings also have an equivalent env var (MSGRAPH_WEBHOOK_*) that merges into the config at gateway startup (the exception is host, which is config-only — see the note above) — see the environment variables reference.

Security Hardening

جدول مرجعي. لا تقرأه كله، ابحث عن السطر الذي يخصّك فقط.

clientState is the primary auth check

Every Graph notification includes the clientState string your subscription registered with. The listener rejects any notification whose clientState doesn't match, using timing-safe comparison. This is Microsoft's documented mechanism — treat the value as a strong shared secret.

If client_state is unset, the listener refuses to start.

Source-IP allowlisting (production deployments)

For production, restrict the listener to Microsoft's published Graph webhook source IP ranges. Microsoft documents the egress ranges under the Office 365 IP Address and URL Web service ↗. Configure them as:

YAML10 أسطر
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

Or as an env var:

Shellسطر واحد
MSGRAPH_WEBHOOK_ALLOWED_SOURCE_CIDRS="52.96.0.0/14,52.104.0.0/14"

Binding a non-loopback host such as 0.0.0.0, ::, or a LAN IP without allowed_source_cidrs is refused at startup. If you're using a dev tunnel or reverse proxy on the same machine, bind Hermes to 127.0.0.1 or ::1 and leave the allowlist empty there. Invalid CIDR strings log a warning and are ignored. Review the Microsoft IP list quarterly — it changes.

HTTPS termination

The listener speaks plain HTTP. Terminate TLS at your reverse proxy (Caddy, Nginx, Cloudflare Tunnel, AWS ALB) and proxy to the listener over the local network. Graph refuses to deliver to non-HTTPS endpoints, so there's no path for unencrypted traffic to reach you from Graph itself.

Response hygiene

On success the listener returns 202 Accepted with an empty body — internal counters stay out of the wire response. Operators can observe counts via /health, which is guarded by the same source-IP rules as the webhook path.

Status code table:

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

Troubleshooting

قسم لحل المشكلات. ابحث فيه عن العطل الذي يشبه حالتك بدل قراءته كاملًا.

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 refuses to start on 0.0.0.0Set allowed_source_cidrs to Microsoft's current webhook egress ranges, or bind Hermes to 127.0.0.1 / ::1 behind your tunnel or reverse proxy.
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. Widen the list to include the current Microsoft egress ranges. If you're still validating the tunnel path, bind Hermes to loopback and let the tunnel handle public exposure.
اختبار الفهم

4 أسئلة إجاباتها كلها في هذه الصفحة.

كل خيار اسم حقيقي من توثيق Hermes. حتى الخيارات الخاطئة حقيقية، لكنها من صفحات أخرى.

1. في جدول هذا الدرس، ما «Default» المقابل لـ«port»؟
2. أي متغير بيئة من التالي يظهر فعليًا في هذا الدرس؟
3. أي عنوان من التالي لا يظهر في هذا الدرس؟
4. أي مفتاح إعداد يظهر في أمثلة هذا الدرس؟