用 GitHub Copilot 建一個 TikTok DM Webhook 接收器
做 TikTok 私訊客服,第一步唔應該係叫 AI 估 payload,而係將真實 API 契約放入 GitHub Copilot 上下文。UnifyPort 會將 TikTok 入站訊息整理成統一 message.received 事件,並用 X-Device-Signature 對 raw request body 做 HMAC-SHA256 簽名。
重點
- TikTok 官方開發者文件入面,Direct Messages 主要出現喺 Data Portability scope 同 data types,唔係通用即時客服 webhook。
- Copilot 要依據 UnifyPort reference 寫:
POST /v1/webhook-endpoints、subscribed_events、signing_secret、X-Device-Timestamp、X-Device-Signature。 - 驗簽一定要用 raw body;先 parse JSON 再 stringify 會改變 bytes。
- 對香港或東南亞營運團隊,最好先存事件,再將 inbound message 分流去 Slack、CRM 或 AI worker。
如果你仍然研究 TikTok DM API 是否適合,先睇 TikTok DM API:點解冇官方通用端點。如果你已經需要 live intake,可以接住睇 TikTok Data Portability vs live DMs。
最終 demo
Demo 係一個 Node.js 服務,只有 /webhook route。它收 UnifyPort event,驗證 X-Device-Timestamp 同 X-Device-Signature,解析 message.received,保存必要欄位,然後回 200。
開發時請對住 webhook delivery and signature verification 文件。呢頁描述咗簽名字串、headers、retry 同 idempotency,是 Copilot 生成代碼嘅依據。
Prompt 1:先寫 receiver
Build a minimal Express service for a UnifyPort webhook receiver.
Use express.raw({ type: 'application/json' }). Verify X-Device-Signature as hex HMAC-SHA256 over X-Device-Timestamp + '.' + raw request body using WEBHOOK_SIGNING_SECRET.
Only process event.type === 'message.received'. Store provider, account_id, conversation.id, sender.id, message.id, message.text, message.direction, and occurred_at.
Return 200 after storing; return 401 on invalid signature.
核心代碼應該保留 raw body:
import crypto from 'crypto';
import express from 'express';
const app = express();
const secret = process.env.WEBHOOK_SIGNING_SECRET;
const queue = [];
function verifySignature(req) {
const timestamp = req.get('X-Device-Timestamp') || '';
const signature = req.get('X-Device-Signature') || '';
const expected = crypto.createHmac('sha256', secret)
.update(timestamp + '.')
.update(req.body)
.digest('hex');
return signature.length === expected.length &&
crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
}
app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
if (!verifySignature(req)) return res.status(401).end();
const event = JSON.parse(req.body.toString('utf8'));
if (event.type !== 'message.received') return res.status(200).end();
queue.push({ provider: event.provider, account_id: event.account_id,
conversation_id: event.data.conversation.id, sender_id: event.data.sender.id,
message_id: event.data.message.id, text: event.data.message.text || '',
direction: event.data.message.direction, occurred_at: event.occurred_at });
res.status(200).end();
});
註冊 webhook endpoint
部署 HTTPS 後,呼叫 POST /v1/webhook-endpoints。subscribed_events 設為 message.received,signing_secret 會啟用簽名。
curl -X POST https://api.unifyport.ai/v1/webhook-endpoints \
-H "X-Api-Key: dk_live_example" \
-H "Content-Type: application/json" \
-d '{
"url": "https://inbox.example.com/webhook",
"status": "active",
"subscribed_events": ["message.received"],
"signing_secret": "whsec_6f5b1c9d4e7a2b8c"
}'
想睇同類 AI coding 流程,可參考 AI coding agent 自動回覆 bot 教程。
加上可靠性
第二個 prompt 可要求 Copilot 使用 X-Device-Event-Id 做 retry 去重,保存 raw event,並只將 direction === 'inbound' 嘅訊息送入 triage queue。之後才接 Slack、CRM 或 AI 分類。
限制
如產品需要官方內容發布、登入、研究工具或資料匯出,應使用 TikTok 官方 API。UnifyPort 的非官方接口適合現有帳號嘅即時入站訊息;它提供可驗證事件流,不代表 TikTok 官方 product scope。
FAQ
Copilot 可唔可以做晒整個 inbox?
可幫你生成 receiver、測試同隊列代碼,但驗簽、secret 管理、部署同 storage 行為仍要人手 review。
Data Portability 係咪 live DMs?
唔係。官方文件描述資料導出範圍;客服通常需要即時 event stream。
應該訂閱邊個 event?
只做入站訊息就用 message.received;全量收集先用 ["*"]。
Sources checked on 2026-08-29
令訊息接入變成一條穩定嘅產品管線。
先用統一嘅 API 跑通發送,再用標準事件將所有入站訊息接返去業務系統。