Webhook

Webhook 是合作夥伴指定的網址,RCS for Business 平台會將訊息事件發布至該網址。這個網址會做為端點,接收含有事件資料的 HTTPS POST 要求。這表示資料會透過 HTTPS 安全地傳送至應用程式。

Webhook 網址可能如下所示: https://[your company name].com/api/rbm-events。 設定 Webhook 後,即可開始接收訊息和事件。

合作夥伴 Webhook 和代理 Webhook

你可以在合作夥伴層級或服務專員層級設定 Webhook。

  • 合作夥伴 Webhook 會套用至您維護的每個代理程式。如果代理程式的行為類似,或只有一個代理程式,請使用合作夥伴 Webhook
  • 服務專員 Webhook 適用於個別服務專員。如果您經營多個行為不同的代理程式,可以為每個代理程式設定不同的 Webhook

如果您同時設定了合作夥伴 Webhook 和服務專員 Webhook,服務專員 Webhook 會優先用於特定服務專員,而合作夥伴 Webhook 則會套用至沒有專屬 Webhook 的服務專員。

設定代理程式 Webhook

您會在合作夥伴 Webhook 收到傳送給代理程式的訊息。如要讓特定代理的訊息傳送至其他 Webhook,請設定代理 Webhook。

  1. 開啟 RCS for Business Developer Console,然後使用 RCS for Business 合作夥伴 Google 帳戶登入。
  2. 按一下代理程式。
  3. 點選 [Integrations] (整合)。
  4. 在「Webhook」部分,按一下「設定」

    1. 在「Webhook 端點」中,輸入開頭為「https://」的 Webhook 網址。
    2. 在「Client token」(用戶端權杖) 中,指定 clientToken 值。您需要這項資訊驗證收到的訊息是否來自 Google。
  5. 將 Webhook 設為接受含有 clientTokensecret 參數的 JSON 酬載 POST 要求。

    {
      "clientToken":"YOURCLIENTTOKEN",
      "secret":"YOURSECRET"
    }
    

    如要驗證要求,端點必須傳回 HTTP 200 OK 狀態碼,並在回應主體中提供 secret 參數的原始字串值。

    Webhook 設定範例

    舉例來說,如果 Webhook 收到 POST 要求,且主體內容如下:

      {
      "clientToken":"YOURCLIENTTOKEN",
      "secret":"YOURSECRET"
      }
      

    接著,Webhook 應確認 clientToken 值,如果 clientToken 正確,則傳回 200 OK 回應,並將 YOURSECRET 做為回應主體:

      // clientToken from Configure
      const myClientToken = "YOURCLIENTTOKEN";
    
      // 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. 開發人員控制台中,按一下「驗證」。按一下「驗證」後,Google 會將 POST 要求傳送到你的 Webhook,並在要求內文中加入 clientTokensecret 參數。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 元素中,以 Base64 解碼 RCS for Business 酬載。
  3. 使用網路鉤子的用戶端權杖 (設定網路鉤子時指定) 做為金鑰,建立以 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

傳送失敗時的行為

如果網路鉤子傳回的狀態不是 200 OK,RCS 企業通訊平台會使用退避和重試機制,重新傳送資料。也就是說,系統會逐步增加每次嘗試傳送之間的延遲時間,最終達到每隔 10 分鐘重試傳送每則待處理訊息的頻率上限。系統會持續重試七天,之後就會永久刪除郵件。

服務專員層級 Webhook 的影響

RCS for Business 會將合作夥伴的訊息排入一個佇列。單一合作夥伴帳戶的所有服務專員共用一個佇列。因此,如果其中一個 Webhook 失敗,整個佇列就會遭到封鎖,導致所有代理商的使用者事件都無法傳送給合作夥伴。

如果有多則未確認的訊息,可能會導致重試事件大幅增加。舉例來說,如果服務專員未確認 1,600 筆送達收據,且重試頻率達到 10 分鐘的上限,則每天可能會產生約 230,000 個潛在錯誤:

每天 1,600 封郵件 × 每小時 6 次重試 × 每天 24 小時 = 每天約 230,000 個錯誤

重試次數過多可能會導致共用的 Pub/Sub 佇列遭到封鎖,合作夥伴所有廣告活動的使用者事件接收作業也會大幅延遲。

最佳做法

如要確保正式版流量的穩定性並避免佇列阻斷,請採用下列最佳做法:

  • 立即傳回 200 OK:Webhook 應接收訊息、儲存在本機佇列,並在五秒內傳回 200 OK 回應。
  • 處理程序分離:使用個別的背景工作站,處理本機佇列中的訊息邏輯。
  • 監控測試代理:將開發代理視為正式代理,因為如果開發代理失敗,也會封鎖共用合作夥伴佇列。
  • 專門用於測試的帳戶:建議使用一個開發人員帳戶來管理正式版代理程式,並使用另一個開發人員帳戶來管理測試版代理程式。
  • 驗證 Google 流量:使用反向 DNS 或 X-Goog-Signature 標頭,而非固定 IP 允許清單,因為 Google 使用動態任播 IP。如要進一步瞭解如何手動驗證及找出 Google IP 範圍,請參閱「驗證 Google 要求」文件,以及使用者觸發的擷取器Google 使用者觸發的擷取器的 JSON 檔案。

後續步驟

設定 Webhook 後,代理程式就能接收測試裝置傳送的訊息。傳送訊息來驗證設定。