Webhook

Webhook は、RCS for Business プラットフォームが メッセージイベントを投稿する、パートナー指定の URL です。 この URL は、イベントに関するデータを含む HTTPS POST リクエストを受け取るエンドポイントとして機能します。つまり、データは HTTPS 経由でアプリケーションに安全に送信されます。

Webhook URL は https://[your company name].com/api/rbm-events のようになります。 Webhook を構成すると、メッセージとイベントの受信を開始できます。

パートナー Webhook とエージェント Webhook

Webhook は、パートナー単位またはエージェント単位で構成できます。

  • パートナー Webhook は、管理しているすべてのエージェントに適用されます。エージェントの動作が似ている場合や、エージェントが 1 つしかない場合は、パートナー Webhook を使用します。
  • エージェント Webhook は、個々のエージェントに適用されます。動作が異なる複数のエージェント を運用している場合は、エージェントごとに 異なる Webhook を設定できます

パートナー Webhook とエージェント Webhook の両方を構成している場合、エージェント Webhook は特定のエージェントで優先されますが、パートナー Webhook は独自に Webhook を持たないエージェントに適用されます。

エージェント Webhook を構成する

エージェントに送信されたメッセージは、パートナー Webhook で受信します。特定のエージェントのメッセージを別の Webhook に配信する場合は、エージェント Webhook を設定します。

  1. RCS for Business デベロッパー コンソール を開き、RCS for Business パートナーの Google アカウントでログインします。
  2. エージェントをクリックします。
  3. [Integrations] をクリックします。
  4. [Webhook] セクションで [構成] をクリックします。
    1. [Webhook endpoint] に、「https://」で始まる Webhook URL を入力します。
    2. [Client token] に、clientToken の値を指定します。受信したメッセージが Google から送信されたものであることを確認 するために必要です。
  5. 指定した clientToken パラメータを含む POST リクエストを受け取り、secret パラメータのプレーン テキスト値をレスポンス本文として含む 200 OK レスポンスを送信するように Webhook を構成します。

    たとえば、Webhook が次の本文コンテンツを含む POST リクエストを受信した場合、

    {
      "clientToken":"SJENCPGJESMGUFPY",
      "secret":"1234567890"
    }
    

    Webhook は clientToken の値を確認し、clientToken が正しい場合は、1234567890 をレスポンス本文として含む 200 OK レスポンスを返します。

    // clientToken from Configure
    const myClientToken = "SJENCPGJESMGUFPY";
    
    // Example endpoint
    app.post("/rbm-webhook", (req, res) => {
      // Use the X-Goog-Webhook-Type header to route requests
      const webhookType = req.header('X-Goog-Webhook-Type');
    
      if (webhookType === 'verification') {
        const msg = req.body;
        if (msg.clientToken === myClientToken) {
            res.status(200).send(msg.secret);
            return;
        }
      }
      res.send(400);
      // handle other webhook types
    });
    
  6. デベロッパー コンソールで、 [確認] をクリックします。RCS for Business が Webhook を確認すると、ダイアログが閉じます。

リクエスト タイプを識別する

Webhook に送信されるすべてのリクエストのリクエスト タイプを識別するには、X-Goog-Webhook-Type ヘッダーを使用します。

ヘッダーには次の値を指定できます。

  • verification: 初期エンドポイント検証プロセスで使用されます。
  • message_callback: メッセージ関連のイベント(入力通知や配信通知、ユーザーからの受信メッセージなど)で使用されます。
  • agent_callback: エージェント固有の管理イベント(エージェントの起動状態の変更など)で使用されます。

受信メッセージを確認する

Webhook は任意の送信者からメッセージを受信できるため、メッセージ コンテンツを処理する前に、受信メッセージが Google から送信されたものであることを確認する必要があります。

受信したメッセージが Google から送信されたものであることを確認する手順は次のとおりです。

  1. メッセージの X-Goog-Signature ヘッダーを抽出します。これは、メッセージ本文のペイロードのハッシュ化された base64 エンコード コピーです。
  2. リクエストの message.body 要素で、RCS for Business のペイロードを base64 デコードします。
  3. Webhook のクライアント トークン(Webhook の設定時に指定したトークン)をキーとして使用し、base64 デコードされたメッセージ ペイロードのバイトの SHA512 HMAC を作成して、結果を base64 エンコードします。
  4. X-Goog-Signature ハッシュと作成したハッシュを比較します。
    • ハッシュが一致する場合は、メッセージが Google から送信されたものであることを確認できます。
    • ハッシュが一致しない場合は、既知の正常なメッセージでハッシュ処理を確認してください。

      ハッシュ処理が正しく機能しているにもかかわらず、不正に送信されたと思われるメッセージを受信した場合は、 お問い合わせください

Node.js

  if ((requestBody.hasOwnProperty('message')) && (requestBody.message.hasOwnProperty('data'))) {
    // Validate the received hash to ensure the message came from Google RBM
    const headerHash = req.header('X-Goog-Signature');
    const userEventString = Buffer.from(requestBody.message.data, 'base64');
    const hmac = crypto.createHmac('sha512', myClientToken);
    const genHash = hmac.update(userEventString).digest('base64');

    if (headerHash === genHash) {
      const userEvent = JSON.parse(userEventString);
      const webhookType = req.header('X-Goog-Webhook-Type');

      // Route based on the header type
      if (webhookType === 'message_callback') {
        handleMessage(userEvent);
      } else if (webhookType === 'agent_callback') {
        handleAgentEvent(userEvent);
      }
    } else {
      console.log('Hash mismatch - ignoring message');
      res.sendStatus(401);
      return;
    }
  }

  res.sendStatus(200);
  

メッセージ処理

Webhook から 200 OK 以外のものが返された場合は、配信失敗とみなされます。

デベロッパーは、メッセージを高いレートで送信すると、Webhook 通知が頻繁に生成されることに注意し、想定されるレートで通知を処理するようにコードを設計する必要があります。デベロッパーは、ウェブ コンテナからの 500 レスポンス、タイムアウト、アップストリームの障害など、エラー レスポンスが発生する可能性のある状況を考慮することが重要です。考慮すべき事項は次のとおりです。

  • DDoS 保護が、想定されるレートの Webhook 通知を処理するように構成されていることを確認します。
  • データベース接続プールなどのリソースが不足してタイムアウトや 500 レスポンスが発生しないことを確認します。

デベロッパーは、RBM イベントの処理が非同期で行われ、Webhook が 200 OK を返せないようにシステムを設計する必要があります。

非同期の Webhook 処理

Webhook 自体で RBM イベントを処理しない ことが重要です。処理中にエラーや遅延が発生すると、Webhook のリターンコードに影響する可能性があります。

同期 Webhook 処理

配信失敗時の動作

Webhook が 200 OK ステータス以外のものを返した場合、RCS for Business プラットフォームはバックオフと再試行のメカニズムを使用してデータを再配信します。つまり、システムは各配信試行の間隔を徐々に増やし、最終的には保留中のメッセージごとに 10 分ごとに 1 回の再試行頻度に達します。再試行サイクルは 7 日間続き、その後メッセージは完全に削除されます。

エージェント単位の Webhook の影響

RCS for Business は、パートナーのメッセージを 1 つのキューにキューイングします。1 つのパートナー アカウントのすべてのエージェントが 1 つのキューを共有します。そのため、1 つの Webhook で障害が発生すると、キュー全体がブロックされ、すべてのエージェントのユーザー イベントがパートナーに届かなくなる可能性があります。

確認応答のないメッセージが複数あると、再試行イベントが大幅に増加する可能性があります。たとえば、エージェントが 1,600 件の配信確認応答を送信せず、再試行頻度が 10 分の上限に達した場合、1 日あたり約 230,000 件のエラーが発生する可能性があります。

1,600 メッセージ × 1 時間あたり 6 回の再試行 × 1 日あたり 24 時間 = 1 日あたり約 230,000 件のエラー

この再試行の量により、共有 Pub/Sub キューがブロックされ、パートナーのすべてのキャンペーンのユーザー イベントの受信が大幅に遅れる可能性があります。

ベスト プラクティス

本番環境のトラフィックの信頼性を確保し、キューのブロッキングを回避するには、次のおすすめの方法を参考にしてください。

  • すぐに 200 OK を返す: Webhook はメッセージを受信し、 ローカル キューに保存して、5 秒以内に 200 OK レスポンスを返す必要があります。
  • 処理を分離する: 別のバックグラウンド ワーカーを使用して、 ローカル キューからメッセージ ロジックを処理します。
  • テスト エージェントをモニタリングする: 開発エージェントは、本番環境のエージェントとして扱います。 失敗すると共有パートナー キューをブロックする可能性があるためです。
  • テスト専用のアカウント: 本番環境のエージェントには 1 つのデベロッパー アカウント を使用し、テスト エージェントには専用のデベロッパー アカウントを使用することをおすすめします。
  • Google トラフィックを確認する: Google は動的エニーキャスト IP を使用するため、固定 IP 許可リストではなく、リバース DNS または X-Goog-Signature ヘッダー を使用します。手動検証と Google IP 範囲の特定について詳しくは、Google リクエストの検証と、ユーザー トリガー フェッチャーGoogle ユーザー トリガー フェッチャーの JSON ファイルをご覧ください。

次のステップ

Webhook を構成すると、エージェントは メッセージを テストデバイスから 受信できるようになりますメッセージを送信 して設定を検証します。