← 所有文章
教學

WhatsApp 聊天跨標籤交接:安全的 API 操作流程

透過 UnifyPort 將 WhatsApp 聊天從一個工作流程標籤移至另一個,需要兩次成員關係操作:先新增目標標籤,確認結果,再移除來源標籤。公開文件沒有承諾原子轉移。請保留無關標籤,讓未完成的交接持續可見;不要刪除整個標籤,也不要把請求逾時當作「一定沒有變更」。

重點

  • action: "remove" 是替選定對話移除標籤;刪除標籤是另一項操作。
  • 多個標籤可以並存,不能強制唯一負責人或唯一工作階段。
  • 先新增再移除有助於維持可見性,但中途會暫時保留兩個標籤。
  • 正式的指派紀錄與交接進度應存於應用程式,不宜僅從標籤推斷。

定義交接,不是取代全部標籤

WhatsApp 的標籤說明介紹以標籤整理聊天,以及為同一聊天套用多個標籤。頁面也指出標籤正逐步轉換為清單。這項介面用語變化不代表 UnifyPort 的 label_id 欄位已更名,也不保證應用程式內每種清單都有對應 API。

以下是假設情境:聊天已有「待處理」與「VIP」,客服希望移至「處理中」。預期操作是新增「處理中」、移除「待處理」,保留「VIP」,而非將全部標籤替換成「處理中」。

六月 API 更新介紹過標籤端點。交接時,請先分清操作對象:

意圖操作對象
建立或重新命名分類建立或更新標籤標籤定義
新增目標標籤成員關係 action: "add"該標籤下選定的對話
移除來源標籤成員關係 action: "remove"該標籤下選定的對話
停用一個分類刪除標籤標籤本身,不是單一對話的歸屬

不要用刪除標籤代替替單一對話移除標籤;其他聊天可能還在使用這個分類。

準備兩次操作

在選定訊息帳號下讀取標籤目錄,取得來源及目標 ID,並完成分頁。名稱是顯示文字,不是穩定的識別鍵。若需要建立目標標籤,使用建立或更新標籤,保留回傳的 data.id。

在同一帳號下確認聊天的 conversation_id。不要把標籤名稱、聯絡人顯示名稱或訊息 ID 當作對話 ID。先查看操作支援矩陣:這些標籤操作目前支援 whatsapp,不支援 LINE、Telegram、Zalo,亦不支援獨立的 whatsapp-protocol 渠道。

標籤成員關係參考定義 POST /v1/accounts/{account_id}/conversations/labels,請求包含 label_id、action 及非空的 conversation_ids 陣列。

以下伺服器端 JavaScript 函式只執行一次操作,不會自動完成整個交接。請傳入後端實際選取的 ID 與安全保存的 API key。這是示意程式碼,不是已驗證的正式環境用戶端。

async function changeLabelMembership({
  apiKey, accountId, labelId, conversationIds, action
}) {
  const validId = value => typeof value === 'string' && value.trim() !== '';
  if (!validId(accountId) || !validId(labelId) ||
      !Array.isArray(conversationIds) || conversationIds.length === 0 ||
      !conversationIds.every(validId) || !['add', 'remove'].includes(action)) {
    throw new Error('Select an account, label, conversations, and action');
  }
  const response = await fetch(
    `https://api.unifyport.ai/v1/accounts/${encodeURIComponent(accountId)}/conversations/labels`,
    {
      method: 'POST',
      headers: { 'X-Api-Key': apiKey, 'Content-Type': 'application/json' },
      body: JSON.stringify({
        label_id: labelId,
        action,
        conversation_ids: [...new Set(conversationIds)]
      })
    }
  );
  const result = await response.json();
  return { httpStatus: response.status, result };
}

第一次呼叫使用目標 ID 與 add;後續呼叫改用來源 ID 與 remove,對話保持相同。在本地拒絕來源和目標 ID 相同的交接。請檢查 HTTP 狀態及回應內容;fetch 正常回傳未必代表成功。文件中的成功回應會標識受影響的 label_id、action 和 conversation_ids。

在新增與移除之間加入確認關卡

以下是應用程式設計建議,不是 UnifyPort 提供的交易保證:

  1. 在本地儲存預定帳號、對話、來源及目標標籤,確認操作人員有權變更指派。
  2. 新增目標標籤,記錄回應與 request_id,不記錄 API key。
  3. 使用明確的 label_id 呼叫對話清單,讀取目標標籤檢視。確認選定聊天出現後,再移除來源標籤。
  4. 只移除來源成員關係,保留 VIP 等獨立標籤。
  5. 核對兩個檢視;觀察結果不符預期時,顯示尚未完成的工作。

不要用未指定標籤的清單驗證目標。文件規定,WhatsApp 省略 label_id 時只回傳特別關注的對話。聊天缺漏與標籤篩選排查說明了這項邊界與分頁方式。第一頁找不到某聊天,不代表它不存在;讀取失敗也不等於空結果。即時分頁讀取沒有不可變快照的保證。

觀察到的歸屬本次交接的解讀建議動作
只有來源尚未觀察到目標保留來源,調查新增操作
來源與目標皆有中間狀態,或其他編輯者的變更確認目前意圖,再移除來源
只有目標已觀察到預期歸屬模式本地指派仍一致時記錄完成
皆無,或讀取不完整狀態未釐清保留本地工作並調查,不猜測完成

復原時避免重送過期意圖

在應用程式中循序處理同一對話的變更,送出前拒絕過期的佇列工作。如果其他客服已修改指派,不要盲目完成舊交接。本地循序處理無法鎖住所有連結的用戶端,因此必須核對外部變更,不能宣稱獨占控制。

新增逾時時,保留來源,先查看目標再決定下一步。移除結果不確定時,先確認兩個檢視再考慮重送。不要自動移除目標來「回復」:其他人可能已經依賴該標籤。

公開參考未承諾兩次呼叫之間的原子性、整批全部成功或失敗、版本前置條件,或專用的標籤變更 webhook。批次處理請逐對話保留進度,不要把整批當成一個已完成的指派。set_label_members_failed 對應文件所述的伺服器端或上游失敗;unsupported_by_provider 是功能支援邊界,不應無限重試。

常見問題

新增標籤會自動移除舊標籤嗎?

不會。API 分別提供新增與移除動作,請獨立處理各個標籤成員關係。

標籤能強制只有一位客服負責嗎?

此契約沒有這種保證。負責人與權限應存於應用程式,標籤只是渠道端的投影。

conversation.updated 能確認交接嗎?

不要如此假設。文件中的設定包括靜音、封存、置頂及已讀狀態,並非保證提供標籤歸屬回執。

這是 WhatsApp Cloud API 的官方操作嗎?

不是。這些是 UnifyPort 面向已連結帳號的非官方介面端點。WhatsApp 應用程式說明僅解釋使用者端概念,不定義這份 API 契約。

下一步與參考資料

先閱讀為對話新增或移除標籤。在受控帳號測試正常交接、新增失敗、移除逾時、競爭編輯、分頁及保留無關標籤,再啟用批次轉移。這些是建議驗收項目,不是已執行的測試成果。

資料核對日期:2026-10-14。

UnifyPort API

讓訊息接入變成一條穩定的產品管線。

先用統一 API 跑通傳送,再用標準事件把所有入站訊息接回業務系統。