Webhook を使用して変更通知を受信する

Webhook は、Microsoft Graph などのサービスから変更通知やイベントを受信するようにインフラストラクチャで設定できる HTTP ベースのユーザー定義コールバック API です。 既知でアクセス可能な HTTPS で保護されたエンドポイントを使用して Webhook を構成する必要があります。

Webhook を介して変更通知を受信するには、変更の通知を受け取るリソースへのサブスクリプションを作成する必要があります。 サブスクリプションが有効な間は、リソースで変更が検出されるたびに、Microsoft Graph からアプリに通知が送信されます。

この記事では、Microsoft Graph サブスクリプションを管理するプロセスと、Webhook を介して変更通知を受け取る方法について説明します。

サブスクリプションの作成

Microsoft Graph の変更通知を受け取る前に、まずサブスクリプションを作成する必要があります。 有効なサブスクリプションを設定するプロセスには、次のようにクライアント アプリと Microsoft Graph の両方が含まれます。

  1. クライアント アプリは、特定のリソースの変更をサブスクライブするサブスクリプション要求を送信します。

  2. Microsoft Graph が要求を確認します。

    • 要求が有効な場合、Microsoft Graph はクライアント アプリの通知 URL に検証トークンを送信して、通知 URL を検証します。
    • 要求が無効な場合、Microsoft Graph はエラー コードと詳細を含むエラー応答を送信します。
  3. クライアントが通知 URL 検証要求を受け取ると、この記事で後述するように、クライアントはプレーン テキストで検証トークンで応答します。

  4. Microsoft Graph は、クライアントの検証トークンの応答を検証し、検証トークンが有効な場合は、サブスクリプション ID で応答します。

サブスクリプション要求

クライアント アプリは、 エンドポイントに POST 要求を /subscriptions 送信します。 次の例は、サインインしているユーザーの代わりに特定のメール フォルダーへの変更をサブスクライブする要求を示しています。 変更通知をサポートする他の Microsoft Graph リソースの詳細については、「 サポートされているリソース」を参照してください。

POST https://graph.microsoft.com/v1.0/subscriptions
Content-Type: application/json

{
  "changeType": "created,updated",
  "notificationUrl": "https://webhook.azurewebsites.net/notificationClient",
  "resource": "/me/mailfolders('inbox')/messages",
  "expirationDateTime": "2016-03-20T11:00:00.0000000Z",
  "clientState": "SecretClientState"
}

clientState プロパティが必要です。 このプロパティを設定すると、サービスは、受信した変更通知が Microsoft Graph から発生していることを確認できます。 その理由で、このプロパティの値は機密として保たなければならず、使用はアプリケーションと Microsoft Graph サービスのためにのみ限るようにしてください。

処理が正常に終了すると、Microsoft Graph は 201 Created コードおよび本文内に サブスクリプション オブジェクトを返します。

各サブスクリプションには、同じリソースを監視し、同じ通知 URL を使用する複数のサブスクリプションがある場合でも、一意の subscriptionId があります。

注:

notificationUrl プロパティに含まれるクエリ文字列パラメーターは、通知がサービスに配信されるときに HTTP POST 要求に含まれます。

notificationUrl 検証

Webhook を介して変更通知を受け取るサブスクリプションを作成すると、Microsoft Graph はまず、サブスクリプション要求の notificationUrl プロパティで提供される通知エンドポイントを検証します。 検証プロセスは、次のようになります。

  1. Microsoft Graph は検証トークンをエンコードし、次のように通知 URL への POST 要求に含めます。

    Content-Type: text/plain; charset=utf-8
    POST https://{notificationUrl}?validationToken={opaqueTokenCreatedByMicrosoftGraph}
    
  2. クライアントは、Microsoft Graph からプレーン テキスト検証トークンを取得するために、URL を適切にデコードする必要があります。

    悪意のあるアクターはクロスサイト スクリプティングの種類の攻撃に通知エンドポイントを使用できるため、HTML または JavaScript をエスケープすることをお勧めします。 Microsoft Graph が HTML または JavaScript コードを含む値を送信することはありません。

    一般に、検証トークンの値は不透明として扱います。トークンの形式は予告なく変更される可能性があります。

  3. クライアントは、手順 1 から 10 秒以内に次の特性で応答する必要があります。

    • 状態コード HTTP 200 OK
    • コンテンツ タイプ text/plain
    • URL デコードされたプレーン テキスト検証トークンを含む本文。

    重要

    検証トークンはプレーン テキストで返す必要があります。 クライアントがエンコードされた検証トークンを返した場合、検証は失敗します。

さらに、Microsoft Graph Postman コレクションを使用して、エンドポイントが検証リクエストを適切に実装していることを確認できます。 Misc フォルダー内のサブスクリプションの検証リクエストは、エンドポイントによって提供される応答を検証する単体テストを提供します。

検証応答のテスト結果

通知を受信する

サブスクリプションは有効であり、サブスクライブしたリソースに変更がありますが、Microsoft Graph は、変更の詳細を含む要求を notificationUrl に送信POSTします。 このペイロードは 変更通知です。

ほとんどのサブスクリプションでは、Microsoft Graph は通知の送信を遅らせませんが、 サービスでインシデントが発生していない限り、SLA 内のすべての通知を配信します。

アプリに送信される変更通知ペイロードには、サブスクリプションに関連する変更通知のコレクションを含めることができます。

変更通知の例

ユーザーが電子メールを受信すると、次の例に示すように、Microsoft Graph は変更通知オブジェクトをクライアント アプリに送信します。 通知ペイロードの詳細については、 changeNotificationCollection と関連する changeNotification に関するページを参照してください。

変更が多数発生した場合は、Microsoft Graph は異なるサブスクリプションに対応する複数の通知を同一の POST 要求で送信する場合があります。

{
  "value": [
    {
      "id": "lsgTZMr9KwAAA",
      "subscriptionId":"{subscription_guid}",
      "subscriptionExpirationDateTime":"2016-03-19T22:11:09.952Z",
      "clientState":"secretClientValue",
      "changeType":"created",
      "resource":"users/{user_guid}@{tenant_guid}/messages/{long_id_string}",
      "tenantId": "84bd8158-6d4d-4958-8b9f-9d6445542f95",
      "resourceData":
      {
        "@odata.type":"#Microsoft.Graph.Message",
        "@odata.id":"Users/{user_guid}@{tenant_guid}/Messages/{long_id_string}",
        "@odata.etag":"W/\"CQAAABYAAADkrWGo7bouTKlsgTZMr9KwAAAUWRHf\"",
        "id":"{long_id_string}"
      }
    }
  ]
}

変更通知の処理

サービスは、受信したすべての変更通知を処理する必要があります。 変更通知を処理するためにアプリが実行する必要がある最小限のタスクは、次のようになります。

  1. 変更通知を受け取った後、2xx クラス コードを Microsoft Graph に送信します。 Microsoft Graph は、3 秒以内に 2xx クラス コードを受け取らない場合、変更通知を最大 4 時間、複数回再送信しようとします。 Microsoft Graph が期間内に 2xx コードを受信しない場合、変更通知は破棄されます。 クライアント アプリが 3 秒以内に一貫して応答しない場合、 通知は調整の影響を受ける可能性があります

    サービスで変更通知の処理に 3 秒以上かかる場合は、通知を保持し、Microsoft Graph への応答で状態コードを返 202 - Accepted してから、その容量で通知を処理する必要があります。 通知が永続化されない場合は、エラーを示す 5xx クラス コードを返して、Microsoft Graph が通知を再試行できるようにします。

    サービスに 3 秒未満かかると予想される場合は、通知を処理し、状態コードを 200 - OK Microsoft Graph に返す必要があります。 通知が正しく処理されない場合は、エラーを示す 5xx クラス コードを返して、Microsoft Graph が通知を再試行できるようにします。

  2. clientState プロパティを検証します。 これは、サブスクリプション作成要求で当初送られた値に一致していなければなりません。

    不一致がある場合は、変更通知を有効と見なさないでください。 変更通知が Microsoft Graph から発信されておらず、不正なアクターによって送信された可能性があります。 また、変更通知の送信元を調査し、適切なアクションを実行する必要があります。

  3. ビジネス ロジックに基づいてクライアント アプリを更新します。

サブスクリプションを更新する

サブスクリプションを更新する必要がある理由は多数あります。 詳細については、「 ライフサイクル通知」を参照してください。

ライフサイクル通知をサブスクライブすると、サブスクリプションの有効期限が近づいているときに Microsoft Graph からアラートが表示され、更新する必要があります。 ライフサイクル通知をサブスクライブしない場合は、 subscriptionExpirationDateTime を使用して、アプリがサブスクリプションの更新要求を送信するタイミングを監視できます。

サブスクリプションを更新するには、 expirationDateTime プロパティが必要です。 サブスクリプションを時間内に更新しない場合、Microsoft Graph によってサブスクリプションが削除され、アプリはサブスクリプションの今後の変更通知を受け取りません。

サブスクリプションの更新要求

PATCH https://graph.microsoft.com/v1.0/subscriptions/{id}
Content-Type: application/json

{
  "expirationDateTime": "2016-03-22T11:00:00.0000000Z"
}

サブスクリプションの更新要求が成功した場合、応答コードとサブスクリプション オブジェクトが応答本文に返200 OKされます。 サブスクリプション オブジェクトには、新しい expirationDateTime 値が 含まれています。

サブスクリプションの削除

クライアント アプリが変更通知を不要にした場合は、次のように subscriptionId を 使用してサブスクリプションを削除できます。

DELETE https://graph.microsoft.com/v1.0/subscriptions/{id}

処理が正常に終了すると、Microsoft Graph は 204 No Content コードを返します。

調整

サブスクリプション通知 URL が遅いか応答に失敗し、Microsoft Graph が 3 秒以内に 2xx クラス コードを受け取らない場合、Microsoft Graph は最大 4 時間、変更通知を複数回再送信しようとします。 この場合、Microsoft Graph は、サブスクリプションに関連付けられている通知エンドポイントの通知を調整する可能性があります。

Microsoft Graph が Webhook を使用して変更通知の調整を処理する方法

通知は、3 秒のタイムアウトで HTTP クライアントを使用して発行されます。

  1. 発行時間が 2,900 ミリ秒を超える場合、応答は低速とみなされます。
  2. その後、変更通知サービスは、エンドポイントが 100 件の通知を受信した後の低速応答の割合を計算します。
  3. 低速応答の割合が 10% に達すると、通知 URL に関連付けられているエンドポイントに低速エンドポイントとしてフラグが設定されます。 エンドポイントに関連付けられているすべてのサブスクリプションに対するすべての通知は、調整の対象となります。
  4. 評価はリアルタイムで続行され、応答の蓄積は 10 分ごとにフラッシュされます。

Microsoft Graph がエンドポイントを調整すると、通知には 10 分の遅延が発生し、失敗した通知と調整された通知専用のワーカーにオフロードされます。 HTTP 呼び出しの失敗によって配信に失敗した通知は、10 分後にもう一度再試行されます。 調整されたエンドポイントの低速率が 15% 以上の場合、通知は削除されます。

ファイアウォール構成

通知 URL を保護するファイアウォールを構成して、Microsoft Graph からの受信接続のみを許可し、無効な変更通知に対するさらなる露出を減らすことができます。 Microsoft Graph が変更通知を配信するために使用する IP アドレスの完全なリストについては、「Microsoft 365 の追加のエンドポイント」をご覧ください。

注:

変更通知の配信に使用される一覧に記載されている IP アドレスは、予告なしにいつでも更新できます。

概要

この記事では、Webhook を使用して変更通知を受信する方法について説明しました。

  1. POST 要求をエンドポイントに送信してサブスクリプションを /subscriptions 作成します。
  2. Microsoft Graph は、サブスクリプションの作成プロセスを完了する前に Webhook 通知エンドポイントを検証します。 一意の subscriptionId がサブスクリプションにリンクされています。
  3. サブスクリプションがまだ有効であり、サブスクライブされたリソースに変更が発生する限り、Microsoft Graph は notificationUrl エンドポイントに変更通知を送信します。
  4. サブスクリプションを定期的に更新して、その有効性を維持し、サブスクライブされた変更に関する更新を引き続き受け取る。

関連項目