← 所有文章
教學

TikTok 資料可攜不等於即時私訊:建立客服真正需要的入站佇列

TikTok 的開發者介面越來越清楚,但文件更精準,不代表它剛好解決客服團隊眼前的問題。

6 月 4 日,TikTok 在 Data Portability API changelog 中說明,Data Types 文件已更新,用來反映目前支援的資料類別和欄位。Data Portability API 產品頁說明,這個 API 面向歐洲經濟區和英國的 TikTok 使用者,允許使用者授權把自己的資訊傳輸到另一個應用程式。現在的 data types 頁面 也列出 Direct Messages 作為可匯出的類別,欄位包含日期、傳送者和內容。

這對資料可攜、封存、備份和合規流程有價值。但它不是即時客服收件匣。

如果你的團隊做 TikTok Shop、創作者活動或直播銷售,真正需要的是另一件事:每一則新私訊都應該進入佇列,被去重,觸發 CRM 查詢,然後分配給同事或 AI 助理。使用者授權的歷史匯出無法提供這個事件循環。帶簽名的入站 webhook 可以。

先定義整合要完成的工作

選 API 之前,先把工作流程寫成普通語句:

  1. 客戶送出一則 TikTok 私訊。
  2. 後端在幾秒內收到這則訊息。
  3. 投遞帶簽名,伺服器可以確認來源可信。
  4. 訊息被儲存,因為錯過的事件之後無法補回。
  5. 同一個佇列未來還能接收 WhatsApp、LINE、Zalo、Telegram 或 X 訊息。

TikTok Data Portability API 並不是為這個順序設計。它是使用者授權的資料傳輸產品。申請方需要服務歐洲經濟區或英國使用者,通過隱私與安全審查,並請求明確的資料範圍。它的資料模型圍繞匯出:貼文與個人資料、活動、私訊或完整封存。

這不是客服需要的時間模型。客服問的不是「這個使用者能不能匯出昨天的封存」,而是「十秒前進來的那則訊息,我們能不能馬上處理」。

UnifyPort 的 webhook 結構

UnifyPort 的 TikTok 非官方接口面向第二種模型。你連接 TikTok 帳號,註冊 webhook endpoint,並訂閱 message.received。客戶訊息到達後,UnifyPort 會向你的後端送出一個標準事件包:

{
  "id": "evt_7a4d2c91b6",
  "type": "message.received",
  "provider": "tiktok",
  "account_id": "acc_8c21d0",
  "occurred_at": "2026-07-05T03:18:42Z",
  "data": {
    "conversation": { "id": "tt_conv_9172", "type": "user", "title": "Mai Nguyen" },
    "sender": { "id": "tt_user_4839", "name": "Mai Nguyen", "type": "user" },
    "message": {
      "id": "tt_msg_20260705_001",
      "type": "text",
      "text": "今晚直播前黑色托特包還有貨嗎?",
      "direction": "inbound",
      "sent_at": "2026-07-05T03:18:41Z"
    }
  }
}

關鍵是這個事件包:idtypeprovideraccount_idoccurred_atdata。同一個處理器今天可以處理 provider: "tiktok",明天可以處理 provider: "zalo"。路由層只在平台行為確實不同時再分支。

先註冊 endpoint

連接佇列之前,先建立 webhook。endpoint 會保存 URL、訂閱事件、簽名狀態和重試策略。設定 signing_secret 後,每次投遞都會帶上 X-Device-TimestampX-Device-Signature

curl -X POST https://api.unifyport.ai/v1/webhook-endpoints \
  -H "X-Api-Key: <YOUR_API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{
  "url": "https://example.com/webhook",
  "status": "active",
  "subscribed_events": ["message.received"],
  "signing_secret": "<WEBHOOK_SIGNING_SECRET>"
}'

UnifyPort 使用 HMAC-SHA256 對時間戳記、一個點和原始請求本文進行簽名。必須在解析 JSON 前用原始位元組驗證。不要先解析再重新序列化,因為那會改變被驗證的位元組。

import crypto from "crypto";
import express from "express";

const app = express();
const signingSecret = process.env.WEBHOOK_SIGNING_SECRET;

app.post("/webhook", express.raw({ type: "application/json" }), (req, res) => {
  const timestamp = req.get("X-Device-Timestamp");
  const signature = req.get("X-Device-Signature");

  const hmac = crypto.createHmac("sha256", signingSecret);
  hmac.update(timestamp);
  hmac.update(".");
  hmac.update(req.body);
  const expected = hmac.digest("hex");

  const valid =
    signature.length === expected.length &&
    crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));

  if (!valid) {
    res.status(401).end();
    return;
  }

  const event = JSON.parse(req.body.toString("utf8"));
  if (event.type === "message.received") {
    console.log(event.provider, event.data.sender.id, event.data.message.text);
  }

  res.status(200).end();
});

app.listen(3000);

這已經足夠作為入站邊界。正式環境可以把事件寫入佇列,但邊界不變:帶簽名的投遞進來,驗證後的事件出去。

先儲存,再路由

UnifyPort 文件明確說明,webhook 事件是入站流量的唯一記錄。沒有訊息讀取 API,也沒有錯過 payload 後的回補路徑。因此佇列設計要先圍繞儲存。

第一步寫入應按 id 保存事件,同時保存原始請求本文或解析後的 JSON、provider、account ID 和 occurred_at。寫入成功後,再非同步路由:

TikTok message
  -> UnifyPort message.received webhook
  -> Signature verification
  -> Event store keyed by id
  -> Routing queue
  -> CRM lookup, Slack alert, helpdesk ticket, or AI triage

這裡也能看清 Data Portability API 應該放在什麼位置。匯出適合使用者授權的資料移動。即時客服佇列適合營運處理。兩者可以共存,但不能混為一談。

只有需要回覆時再加入傳送流程

有些團隊只需要入站分流。有些團隊希望佇列在人工或 AI 助理決策後產生回覆。把回覆作為明確的第二步。

傳送訊息時,UnifyPort 使用 POST /v1/messages,並傳入帳號、接收者和標準訊息本文。入站事件會給你 provider、account、sender、conversation 和 message text;回覆流程再決定是否傳送。

curl -X POST https://api.unifyport.ai/v1/messages \
  -H "X-Api-Key: <YOUR_API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{
  "account_id": "acc_8c21d0",
  "to": { "id": "tt_user_4839", "type": "user" },
  "message": { "type": "text", "text": "黑色托特包還有貨,可以在今晚直播前下單。" }
}'

入站和出站應該在程式碼中保持分離。第一條路徑負責捕獲和保存客戶訊息。第二條路徑只在業務邏輯決定後傳送回應。

為什麼 2026 年 7 月要重新區分這件事

TikTok 6 月 4 日的文件更新提醒我們:平台 API 往往只服務某個政策或產品面。Data portability 是使用者控制的資料傳輸。Content Posting 是發布。Display API 是創作者內容展示。這些名稱都不自動等於「即時客服私訊收件匣」。

小團隊常見的時間浪費,是把每一個新文件化的 API 類別都當成客服事件流。更穩的做法是先命名工作流,再選擇符合它時間模型的接口。

如果工作流是匯出,就用匯出工具。如果工作流是客服,就用 webhook。如果工作流今天覆蓋 TikTok、下個月還要覆蓋 Zalo 或 LINE,就從一開始保持標準化事件包。

這就是實際分工:TikTok Data Portability 幫使用者移動自己的資料;UnifyPort 幫你的客服系統在訊息到達時收到它們。