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

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

変更の通知を受け取るリソースへのサブスクリプションを作成できます。 サブスクリプションは有効ですが、Microsoft Graph は、リソースの変更を検出するたびに、エンドポイントに通知を送信します。

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

変更通知を作成する方法の詳細については、「Microsoft Graph API変更通知」を参照してください。

Webhook エンドポイントに関する考慮事項

Webhook を介して通知を受け取る前に、URL を介してアドレス指定可能なパブリックにアクセス可能な HTTPS で保護されたエンドポイントを作成する必要があります。 エンドポイントにパブリックにアクセスできない場合、Microsoft Graph はエンドポイントに通知を送信しません。

通知を確実に受信するには、エンドポイントが正しく、一貫性があり、タイムリーな HTTP 応答を提供する必要があります。 エンドポイントがタイムリーに応答しない場合、変更通知サービスが通知の削除を開始する可能性があります。 削除された通知は回復できません。

また、サブスクリプションを継続的に更新するか、ライフサイクル通知に応答することで、エンドポイントは引き続き Microsoft Graph に対する認証を維持する必要があります。

HTTP コードと再試行ロジック

Microsoft Graph 変更通知サービスがエンドポイントから 2xx クラス コードを受け取ると、通知は送信されたと見なされます。 変更通知サービスが 10 秒以内に他の HTML 応答 (エラー コードでも) を受け取る限り、サービスは最大 4 時間通知を配信し続けます。

  • 3 秒のウィンドウ内で通知を処理できる場合は、状態コードを 200 - OK Microsoft Graph に返す必要があります
  • サービスで通知の処理に 10 秒以上かかる場合は、エンドポイントのキューに通知を保持し、状態コードを Microsoft Graph に返 202 - Accepted します。
  • 通知が処理またはキューに入っていない場合は、エラーを示す 5xx クラス コードを返して、Microsoft Graph が通知を再試行できるようにします。

配信に失敗した通知は、指数バックオフ間隔で再試行されます。 通知が見つからなかった場合、エンドポイントがオンラインになると、再送信に最大で 4 時間かかることがあります。

調整

セキュリティとパフォーマンス上の理由から、Microsoft Graph は、低速または応答しなくなるエンドポイントに送信される通知を調整します。 回復できない方法で通知を削除することが含まれる場合があります。

  1. エンドポイントは、10 分のウィンドウで応答の 10% を超える時間が 10 秒を超えると"低速" とマークされます。

    • エンドポイントが "低速" とマークされると、新しい通知は 10 秒の遅延で送信されます。
    • エンドポイントは、応答の 10% 未満が 10 分のウィンドウで 10 秒より長くかかる "低速" 状態を終了します。
  2. エンドポイントは、10 分のウィンドウで 15% を超える応答に 10 秒を超えると"ドロップ" とマークされます。

    • エンドポイントが "drop" とマークされると、新しい通知は最大 10 分間ドロップされます
    • エンドポイントは、応答の 15% 未満に 1 回 "ドロップ" 状態を終了し、10 分のウィンドウで 10 秒を超える時間がかかります。

エンドポイントがこれらのパフォーマンス特性を満たすことができない場合は、通知を受信するためのターゲットとして Event Hubs または Event Grid を使用することを検討してください。

認証

サブスクリプションを作成すると、アクセス トークンがエンドポイントに送信されます。 このアクセス トークンは、エンドポイントの有効性をチェックするためにのみ使用され、変更通知サブスクリプションとは異なるライフサイクルを持ちます。 通常、このアクセス トークンの有効期限は 1 時間以内です。

Microsoft Graph が引き続きエンドポイントに通知を配信できるように、Microsoft Graph によって定期的に再認証されるようにエンドポイントを準備する必要があります。

アクセス トークンの有効期限が切れた場合、通知は配信されません。 ただし、エンドポイントの調整動作はトリガーされません。Microsoft Graph は最大 4 時間、各通知の送信を再試行し続けます。 そのため、有効期限が切れた 4 時間以内にアクセス トークンが更新されると、未送信の通知が配信されます。

エンドポイントをタイムリーに再認証できるように、 ライフサイクル通知 をサブスクリプションに追加してトークンの有効期限に関する警告を受け取るようにすることをお勧めします。

サブスクリプションを更新すると、アクセス トークンも更新されます。

ファイアウォール構成

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

注:

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

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

重要

Microsoft Graph 変更通知サービスとエンドポイントの間でセキュリティで保護された通信チャネルが確立され、維持されるようにするには、複数の手順が必要です。

Microsoft Graph の変更通知の受信を開始するには、エンドポイントの URL (通知 URL) を使用してサブスクリプションを作成してサブスクリプションを確立する必要があります。 サブスクリプションを確立するパターンは次のとおりです。

  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",
  "lifecycleNotificationUrl": "https://webhook.azurewebsites.net/api/lifecycleNotifications",
  "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 要求に含まれます。

重複するサブスクリプションは許可されません。 サブスクリプション要求に、既存のサブスクリプションと同じ 値 changeTypeリソース が含まれている場合、要求は HTTP エラー コード 409 Conflict、およびエラー メッセージ Subscription Id <> already exists for the requested combinationで失敗します。

notificationUrl 検証

Webhook を介して変更通知を取得するサブスクリプションを作成する要求を送信すると、サブスクリプション サービスは、サブスクリプション要求の notificationUrl プロパティが有効かどうかを確認します。 検証プロセスは次のように機能します。

注:

ライフサイクル通知もサブスクライブしている場合は、サブスクリプション サービスによって lifecycleNotificationUrl も検証されます。

  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 デコードされたプレーン テキスト検証トークンを含む本文。

    重要

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

  4. エンドポイントの検証が失敗した場合、Microsoft Graph はサブスクリプションを作成しません。

通知を受信する

サブスクリプションは有効であり、サブスクライブしたリソースに変更がありますが、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. clientState プロパティを検証します。 これは、サブスクリプション作成要求で当初送られた値に一致していなければなりません。

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

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

サブスクリプションのライフサイクル

不要になると、サブスクリプションが削除されたり、有効期限が切れたりすることがあります。 サブスクリプションを作成するときは、 expirationDateTime プロパティを使用して有効期限を設定します。 この時間が経過すると、Microsoft Graph はサブスクリプションを削除し、エンドポイントに通知を送信しません。 サブスクリプションを明示的に削除することもできます。

通知を受け取り続ける最も簡単な方法は、サブスクリプション要求の更新を続行することです。 各通知には、 subscriptionExpirationDateTime プロパティが 含まれています。 これを使用して、サブスクリプションを更新するタイミングをガイドできます。

各サブスクリプションには、エンドポイントに付与されたアクセス トークンも含まれます。 このアクセス トークンの有効期限は、サブスクリプションの有効期限が切れる前に発生する可能性があります。 サブスクリプションのライフサイクル通知を使用して、アクセス トークンの有効期限を管理できます。

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

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 コードを返します。

サブスクリプションのライフサイクル通知

柔軟性と信頼性を高めるために、サブスクリプションを作成するときに、ライフサイクル通知を受信、処理、応答する lifecycleNotificationUrl エンドポイントを提供することで、そのサブスクリプションのライフサイクル通知をサブスクライブすることもできます。

ライフサイクル通知をサブスクライブすると、Microsoft Graph によって次の警告が表示されます。

  • アクセス トークンの有効期限が切れようとしている場合。
  • サブスクリプションの有効期限が切れようとしている場合。
  • テナント管理者がリソースを読み取るアプリのアクセス許可を取り消したとき。

注:

アクセス トークンの有効期限が切れた場合、通知はエンドポイントに配信されません。 ただし、Microsoft Graph は最大 4 時間、各通知の送信を再試行し続けます。 そのため、有効期限が切れた 4 時間以内にアクセス トークンが更新されると、未送信の通知が配信されます。

サブスクリプションのライフサイクル通知を利用する方法の詳細については、「 ライフサイクル通知」を参照してください。

概要

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

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