聊天平台 API 整合指南

本指南說明如何使用 Apps API 建構伺服器端 Chat 整合。完成後,整合作業將能:

  • 向 Apps API 驗證。

  • 建立或更新使用者。

  • 為該使用者發起即時通訊。

  • 接收並驗證來自 Contact Center AI 平台的 Webhook 事件。

  • 在聊天室中傳送訊息。

  • 處理選用分支,例如匯入即時通訊前轉錄稿、虛擬服務專員轉送佇列選取、升級偏轉和媒體附件。

  • 對話結束後,請關閉即時通訊。

本指南適用於建構後端服務的開發人員,該服務可將客戶擁有的即時通訊體驗連結至 CCAI 平台。本教學課程假設您可以在 CCAI Platform 中建立 API 憑證、託管 HTTPS Webhook 端點、安全儲存密鑰,以及從伺服器發出 HTTP 要求。

本指南是 Apps API Chat 端點的補充說明。請參閱 API 參考資料,瞭解完整的請求和回覆結構定義,並按照本指南建議的端對端導入流程操作。

術語

本文件適用下列定義:

  • 客戶:在自家軟體中導入即時通訊整合功能的 CCAI 平台客戶。

  • Consumer:客戶擁有的伺服器端應用程式,會向 Apps API 發出要求,並接收 CCAI 平台 Webhook 事件。

  • 使用者:使用客戶軟體與服務專員或虛擬服務專員展開或繼續對話的人。

  • Chat:Apps API 建立的 CCAI 平台對話資源。

  • Webhook 端點:消費者應用程式中的 HTTPS 端點,用於接收 CCAI Platform 的即時通訊事件。

事前準備

開始前,請確認您具備以下項目:

  • 應用程式 API 憑證

    • 在 CCAI 平台中,依序前往「Settings」(設定) >「Developer Settings」(開發人員設定) >「API Credentials」(API 憑證),建立 API 憑證。

    • 請妥善儲存憑證密鑰。請勿在瀏覽器或行動用戶端程式碼中公開。

  • 用戶群網址詳細資料

    • 找出 CCAI 平台子網域和網域。

    • Apps API 基準網址如下: https://YOUR_SUBDOMAIN.YOUR_DOMAIN/apps/api/v1

  • Webhook 端點

    • 託管可接收 CCAI Platform POST 要求的公開 HTTPS 端點。

    • 在 CCAI Platform 開發人員設定中設定端點。

    • 生成並儲存 Webhook 主要和次要密鑰。

  • 佇列或選單設定

    • 找出新即時通訊進入的佇列或選單。

    • 如果您使用佇列選取虛擬服務專員,請先設定該虛擬服務專員並指派給入口佇列,再透過 API 建立即時通訊。

  • 使用者身分

    • 決定系統要為每位使用者使用哪種固定 ID。

    • 儲存 Apps API 傳回的 CCAI Platform 使用者 ID。

  • 頻率限制處理

    • CCAI 平台會限制 Apps API 的頻率。在整合中加入重試和輪詢機制,並避免針對單一租戶傳送大量要求。

驗證和 Webhook 安全性

整合功能會使用兩種驗證路徑:

  • Apps API 驗證:驗證從伺服器傳送至 CCAI Platform 的要求。

  • 驗證從 CCAI 平台傳送至伺服器的要求 Webhook 簽章。

驗證 Apps API 要求

要求會使用 HTTP 基本驗證。在 CCAI 平台中,依序前往「Settings」 >「Developer Settings」 >「API Credentials」建立 API 權杖,然後在 password 欄位中傳遞該權杖 (建議做法)。如果租戶使用舊版驗證路徑,您可以改為將公司金鑰做為使用者名稱,並將公司密鑰做為密碼。如需完整的驗證設定,請參閱 Apps API 參考資料。以下範例說明如何使用基本驗證,驗證 Apps API 要求:

curl -X GET \
  https://YOUR_SUBDOMAIN.YOUR_DOMAIN/apps/api/v1/chats/{chat_id} \
  -u "YOUR_SUBDOMAIN:YOUR_API_TOKEN" \
  -H "Accept: application/json"

將憑證儲存在伺服器端密鑰儲存庫中,並根據安全性政策輪替憑證,切勿在瀏覽器或行動應用程式中傳送憑證。

驗證 Webhook 要求

CCAI 平台會將即時通訊事件傳送至 Webhook 端點。每個 Webhook 要求都包含:

  • X-Signature

  • X-Signature-Timestamp

X-Signature 標頭可包含主要簽章、次要簽章,或兩者皆有:

primary=<primary_signature> secondary=<secondary_signature>

每個簽章都是以 Base64 編碼的 HMAC-SHA256 摘要。簽署值是時間戳記標頭與原始 JSON 要求主體串連而成的結果:

X-Signature-Timestamp + raw_request_body

在 Webhook 處理常式中:

  1. 請參閱「X-Signature」和「X-Signature-Timestamp」。

  2. 如果缺少任一標頭,則拒絕要求。

  3. 拒絕過時的時間戳記,降低重播風險。

  4. 剖析 JSON 前,請先讀取原始要求主體。

  5. 使用每個有效的 Webhook 密鑰,計算預期簽章。

  6. 使用固定時間比較法,比較收到的簽章和預期簽章。

  7. 如果與任何有效密鑰相符,則接受要求。

以下 Ruby 實作範例示範如何驗證 UJET Webhook 簽章:

require "base64"
require "openssl"
require "active_support/security_utils"

def parse_ujet_signature(header)
  header.to_s.split(/\s+/).each_with_object({}) do |part, result|
    key, value = part.split("=", 2)
    result[key] = value if key && value
  end
end

def expected_signature(secret, timestamp, raw_body)
  Base64.strict_encode64(
    OpenSSL::HMAC.digest(
      OpenSSL::Digest.new("sha256"),
      secret,
      "#{timestamp}#{raw_body}"
    )
  )
end

def secure_match?(received, expected)
  return false if received.nil? || expected.nil?
  return false unless received.bytesize == expected.bytesize

  ActiveSupport::SecurityUtils.secure_compare(received, expected)
end

def verify_ujet_webhook!(request, primary_secret:, secondary_secret:)
  signature_header = request.headers["X-Signature"]
  timestamp = request.headers["X-Signature-Timestamp"]

  return false if signature_header.nil? || timestamp.nil?

  # Optional but recommended: reject stale requests.
  return false if (Time.now.utc - Time.at(timestamp.to_i).utc).abs > 5.minutes

  raw_body = request.body.read
  signatures = parse_ujet_signature(signature_header)

  expected = [
    expected_signature(primary_secret, timestamp, raw_body),
    expected_signature(secondary_secret, timestamp, raw_body)
  ].compact

  received = [
    signatures["primary"],
    signatures["secondary"]
  ].compact

  received.any? do |received_signature|
    expected.any? do |expected_signature_value|
      secure_match?(received_signature, expected_signature_value)
    end
  end
end

如果驗證成功,請快速傳回成功回應,並以冪等方式處理事件。Webhook 傳送和 API 回應的抵達順序可能不同,因此請建構整合作業,容許接收相同的狀態變更多次,而不建立重複記錄。

整合流程

下列流程會建立使用者、發起即時通訊、接收 CCAI Platform 事件、交換訊息,以及結束即時通訊。

建立或更新使用者

目標:確保 CCAI Platform 在建立即時通訊前,已有使用者記錄。

端點

使用下列端點建立或更新使用者:

POST /apps/api/v1/end_users

要求範例

以下範例說明建立或更新使用者時的要求主體:

{
  "identifier": "customer-user-12345",
  "email": "customer.user@example.com",
  "name": "Customer User",
  "phone": "+15551234567"
}

儲存內容

將回應中的 CCAI Platform 使用者 ID 儲存在系統中。建立即時通訊時,請使用該 ID。

注意事項

  • 如果使用者不存在,CCAI Platform 會建立新記錄。

  • 如果已有相同 ID 的使用者,CCAI 平台會更新記錄,並傳回現有使用者的資訊。

建立對話

目標:為使用者發起新的 CCAI 平台即時通訊。

端點

使用下列端點發起新對話:

POST /apps/api/v1/chats

要求範例

以下範例說明建立對話的要求主體:

{
  "chat": {
    "menu_id": 123,
    "end_user_id": 456,
    "lang": "en"
  }
}

虛擬服務專員轉送的選用情境

如果佇列選取虛擬服務專員需要應用程式的背景資訊,請在建立即時通訊時加入背景資訊酬載,如以下範例所示:

{
  "chat": {
    "menu_id": 123,
    "end_user_id": 456,
    "lang": "en",
    "context": {
      "value": {
        "customer_tier": "gold",
        "issue_type": "billing"
      }
    }
  }
}

虛擬服務專員可以根據該情境中的值,決定由哪個佇列接收即時通訊。

注意事項

  • Apps API 會傳回 Chat 資源。

  • CCAI 平台會將 chat_created Webhook 事件傳送至您設定的 Webhook 端點。

  • API 回應和 Webhook 事件的抵達順序不一定。將兩者視為對同一聊天記錄的更新,並以聊天 ID 為索引鍵。

處理 Chat Webhook 事件

目標:讓消費者應用程式與 CCAI 平台即時通訊狀態保持同步。

您的 Webhook 端點會處理 CCAI 平台的即時通訊生命週期和訊息事件。至少儲存:

  • Chat ID。

  • 事件類型。

  • 事件時間戳記。

  • 如果事件包含訊息,則會顯示訊息寄件者、訊息類型和訊息內容。

  • 事件描述轉送行為時,任何提報或轉移資料。

建議行為

  • 處理事件前,請先驗證每個 Webhook 簽章。

  • 儲存已處理的事件 ID 或確定性事件金鑰,避免重試時產生重複項目。

  • 接受事件後,傳回 2xx 回應。

  • 盡可能以非同步方式處理下游副作用。

注意事項

當 CCAI Platform 傳送事件 (例如建立即時通訊、收到的訊息、服務專員訊息、提報變更和即時通訊完成) 時,應用程式會更新即時通訊狀態。

傳送簡訊

目標:將使用者訊息從消費者應用程式傳送至 CCAI Platform 即時通訊。

端點

使用下列端點將文字訊息傳送至對話:

POST /apps/api/v1/chats/{chat_id}/message

要求範例

以下範例說明如何傳送簡訊的要求主體:

{
  "from_user_id": 456,
  "message": {
    "type": "text",
    "content": "Hello, I need help with my order."
  }
}

注意事項

  • CCAI 平台接受訊息。

  • 訊息會顯示在服務專員或虛擬服務專員對話中。

  • Webhook 端點會收到訊息的訊息事件,包括應用程式透過 Apps API 傳送的訊息。

接收並顯示 CCAI 平台的訊息

目標:在客戶擁有的即時通訊體驗中,顯示服務專員或虛擬服務專員的訊息。

Webhook 端點收到訊息事件時:

  1. 驗證 Webhook 簽章。

  2. 檢查事件是否為新事件。

  3. 依對話 ID 找出對話。

  4. 辨識寄件者和訊息類型。

  5. 在客戶擁有的即時通訊 UI 中顯示訊息。

  6. 保留事件,以免重新整理或重試時遺失對話記錄。

注意事項

客戶擁有的即時通訊 UI 會依正確順序,顯示服務專員、虛擬服務專員和使用者傳送的訊息。如果事件未依序送達,請使用事件時間戳記和自己的持續性層,調整顯示順序。

從虛擬服務專員轉接至真人服務專員

目標:當使用者需要服務專員協助時,將即時通訊從虛擬服務專員處理轉移至真人服務專員佇列。

如果整合項目使用佇列選取虛擬代理,請設定虛擬代理,將即時通訊轉送至目標佇列。如果伺服器直接啟動提報,請使用 Apps API 提報端點。

端點

使用下列端點,將即時通訊從虛擬服務專員提報給真人服務專員:

POST /apps/api/v1/chats/{chat_id}/escalations

要求範例

以下範例說明如何透過要求主體提報即時通訊:

{
  "reason": "by_end_user_ask",
  "force_escalate": false
}

注意事項

  • 如果目標佇列可用,即時通訊就會轉由服務專員處理。

  • 如果佇列無法接受即時通訊,且已設定轉移替代方案,CCAI Platform 會保留與虛擬服務專員的即時通訊,並傳送 escalation_deflected Webhook 事件,其中包含可供使用者選擇的替代方案。替代方案不會出現在提報回覆中。

  • 整合項目會向使用者顯示可用的轉移選項。

記錄提報偏離選項

目標:告知 CCAI Platform 使用者選取的轉移選項。

當 CCAI Platform 提供提報偏離選項時,請使用提報更新端點記錄使用者的選擇。

端點

使用下列端點,以轉移選項更新提報記錄:

PATCH /apps/api/v1/chats/{chat_id}/escalations/{escalation_id}

支援的 deflection_channel 值:

  • email:使用者選擇電子郵件轉移選項。

  • virtual_agent:使用者選擇繼續與虛擬服務專員對話。

  • human_agent:使用者選擇繼續等待真人服務專員。這個值僅適用於超出容量的偏轉。

要求範例

以下範例顯示記錄轉移選擇的要求主體:

{
  "deflection_channel": "email"
}

請只將支援的 deflection_channel 值傳送至這個端點。external_link 不是提報更新端點的有效值;當使用者點選外部轉移連結時,即會結束即時通訊。

注意事項

CCAI 平台會記錄提報選項。記錄選項不會轉送即時通訊,整合功能會根據選項採取行動,例如關閉即時通訊以轉移電子郵件,或傳送新的提報,並附上 force_escalate: true 以表示繼續等待。

結束對話

目標:在對話完成後關閉即時通訊。

端點

使用下列端點結束進行中的對話:

PATCH /apps/api/v1/chats/{chat_id}/end

要求範例

以下範例顯示結束即時通訊的要求主體:

{
  "ended_by_user_id": 456
}

注意事項

  • CCAI 平台會結束即時通訊。

  • Webhook 端點會收到最終的即時通訊狀態事件。

  • 應用程式會將即時通訊標示為完成,並停止接受該即時通訊的新使用者訊息。

如果對話結束是因為使用者選取了轉移選項,請勿使用這個端點,而是記錄該選項。請先記錄提報選項,或使用 PATCH /apps/api/v1/chats/{chat_id} 記錄選項並關閉即時通訊,同時提供 escalation_id 和 deflection_channel 以及狀態。如果即時通訊結束時未記錄選擇,則提報時不會記錄選擇,且不會顯示在轉移結果報表中。

進階工作流程

以下分支版本為選用。請只實作適用於您整合項目的流程。

匯入即時通訊前轉錄稿

如果使用者在您建立 CCAI Platform 即時通訊之前,已在系統中進行過對話 (例如聊天機器人對話),請使用這個流程。

建立即時通訊時,請新增轉錄稿酬載。轉錄稿可提供代理背景資訊,因此使用者不必重複提供資訊。

Apps API 參考資料包含確切的轉錄稿結構定義。

使用佇列選取虛擬服務專員轉接即時通訊

如果應用程式將所有新即時通訊傳送至項目佇列,並讓虛擬服務專員決定最終目標佇列,請使用這個流程。

  1. 建立虛擬服務專員,用於選取佇列。

  2. 將虛擬代理指派給入口佇列。

  3. 建立即時通訊時,請提供背景資訊。

  4. 設定虛擬服務專員,檢查對話內容並將即時通訊轉接至正確的佇列。

  5. 如果目標佇列無法使用,請處理轉移選項。

傳送相片或影片附件

當使用者從客戶擁有的即時通訊 UI 傳送媒體時,請使用這個流程。

媒體流程分為四個階段。

階段 1:要求預先簽署的上傳網址

請使用下列端點,要求預先簽署的網址,以便上傳相片或影片:

POST /apps/api/v1/chats/{chat_id}/photos/upload
POST /apps/api/v1/chats/{chat_id}/videos/upload

階段 2:將檔案上傳至傳回的儲存空間網址

請加入檔案,以及 CCAI 平台在預先簽署上傳回應中傳回的所有欄位。

階段 3:將上傳的檔案新增至對話

使用下列端點,將上傳的相片或影片新增至對話:

POST /apps/api/v1/chats/{chat_id}/photos
POST /apps/api/v1/chats/{chat_id}/videos

儲存 CCAI 平台傳回的 media_id。即時通訊訊息酬載會依媒體 ID 參照媒體。

階段 4:以訊息形式傳送媒體

使用下列端點,將媒體訊息傳送至對話:

POST /apps/api/v1/chats/{chat_id}/message

要求範例

以下範例說明傳送相片附件的要求主體:

{
  "from_user_id": 456,
  "message": {
    "type": "photo",
    "content": "Photo of the damaged item",
    "media_id": 789
  }
}

端點接受 type、content 和 media_id 做為平面值;在 content 中提供的巢狀物件會遭到捨棄,媒體參照也會遺失。請使用 video 訊息類型和影片 media_id 傳送影片訊息。media_id 是 content 的同層元素。

在即時通訊期間傳送自訂資料

如果整合項目需要將客戶定義的背景資訊附加至進行中的即時通訊,請使用下列端點:

POST /apps/api/v1/chats/{chat_id}/custom_data

Apps API 參考資料定義了確切的酬載形狀和保留金鑰行為。

在對話期間更新使用者身分

如果使用者身分在即時通訊開始後變更或已知,請使用下列端點:

POST /apps/api/v1/chats/{chat_id}/end_user

舉例來說,如果匿名使用者在即時通訊期間登入,且整合功能需要 CCAI Platform 將即時通訊與更新後的使用者身分建立關聯,請使用這個端點。

收集顧客滿意度或評分資料

如果整合服務負責即時通訊後的評分體驗,請使用下列即時通訊 CSAT 和評分端點:

GET /apps/api/v1/chats/{chat_id}/csat
GET /apps/api/v1/chats/{chat_id}/rating
PATCH /apps/api/v1/chats/{chat_id}/rating

如要瞭解確切的資格規則和評分酬載,請參閱 Apps API 參考資料。