← 所有文章
教程

用二维码授权把 TikTok 账号接入签名 Webhook

要通过 UnifyPort 接收 TikTok 消息,不要从二维码页面开始,而要先建 webhook。正确顺序是:注册带 signing_secret 的 webhook endpoint,创建 auth_mode: "qrcode" 的 TikTok 账号,启动二维码授权,轮询二维码状态,账号主人扫码确认,然后把送达的 message.received 事件先写入队列或数据库。

要点

  • 先建 webhook,再做授权;授权进度和后续入站消息都会以事件形式送达。
  • UnifyPort 的 TikTok 授权走标准账号与二维码授权端点;首次启动响应可能还没有二维码 URL,所以要继续轮询 QR check。
  • 收到请求后,先用 X-Device-Timestamp + "." + raw body 验证 X-Device-Signature,再解析 JSON。
  • 入站事件先存储,再分发到 Slack、客服系统、AI worker 或内部队列。
  • 这不是 TikTok 官方 Login Kit 的二维码登录;后者用于应用登录、基础资料和授权 scope。

如果你还在判断 TikTok 是否有通用 DM API,请先看 TikTok DM API 可用性说明。本文只讲你已经选择 UnifyPort 非官方接口后,如何把 TikTok 账号接到一个签名入站流。通用的接收端设计可以配合 webhook-first 入站集成清单 一起看。

接入顺序

建议按这个顺序做:

  1. 创建一个 HTTPS webhook endpoint,并设置 signing_secret
  2. 开发阶段先订阅 message.received;等 handler 准备好后再扩展到更多事件。
  3. 创建 TikTok account,auth_mode 设为 qrcode
  4. 启动二维码授权。
  5. 轮询 QR check endpoint,直到拿到可展示的二维码材料、成功状态或失败状态。
  6. 让 TikTok 账号主人扫码确认。
  7. 观察授权 / runtime 事件,再发送测试消息,确认 message.received 到达。

第一步最重要。UnifyPort 文档明确把 webhook 作为入站流量的持久记录;不要假设漏掉的消息之后还能完整重建。

第一步:注册签名 webhook endpoint

生产环境应使用你自己控制的稳定 HTTPS URL。开发时可以先用 tunnel,但验签逻辑要和生产一致。

curl -X POST https://api.unifyport.ai/v1/webhook-endpoints \
  -H "X-Api-Key: $UNIFYPORT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "url": "https://inbox.example.com/unifyport/tiktok",
  "status": "active",
  "subscribed_events": ["message.received"],
  "signing_secret": "sea-support-tiktok-2026"
}'

Create webhook endpoint 文档说明了 urlstatussubscribed_eventssigning_secretretry_policy.max_attempts。如果你需要所有公开标准事件,可以用 ["*"];如果只是先验证 TikTok 入站,保持 message.received 更清晰。

第二步:创建 TikTok 账号

创建一个 TikTok 连接账号。UnifyPort 把一次渠道登录视为一个 account,TikTok provider guide 说明该渠道使用二维码授权。

curl -X POST https://api.unifyport.ai/v1/accounts \
  -H "X-Api-Key: $UNIFYPORT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "TikTok Support Inbox",
  "provider": "tiktok",
  "region": "global",
  "status": "active",
  "auth_mode": "qrcode",
  "capabilities": ["receive_message"],
  "provider_data": {},
  "metadata": { "workflow": "support-intake" }
}'

保存返回的 account ID。下面用 $ACCOUNT_ID 表示,避免把真实生产标识贴进日志或聊天工具。

第三步:启动二维码授权并轮询

先启动二维码流程:

curl -X POST "https://api.unifyport.ai/v1/accounts/$ACCOUNT_ID/auth/qr/start" \
  -H "X-Api-Key: $UNIFYPORT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'

TikTok 的首次启动响应可能还没有 QR URL。继续轮询:

curl -X POST "https://api.unifyport.ai/v1/accounts/$ACCOUNT_ID/auth/qr/check" \
  -H "X-Api-Key: $UNIFYPORT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'

拿到二维码材料后,只展示给需要连接该 TikTok 账号的人。扫码确认后,等待 webhook 收到授权和 runtime 事件,再观察第一条 message.received

第四步:先验签,再解析事件

Webhook delivery 与签名验证文档定义了签名规则。启用签名后,请求会包含 X-Device-TimestampX-Device-Signature,签名内容是:

<X-Device-Timestamp>.<raw request body>

Node.js 接收端应保留原始 body:

import crypto from 'node:crypto';
import express from 'express';

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

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

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

  if (signature.length !== expected.length) return res.sendStatus(401);
  if (!crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected))) {
    return res.sendStatus(401);
  }

  const event = JSON.parse(req.body.toString('utf8'));
  if (event.type === 'message.received' && event.provider === 'tiktok') {
    // 先存 event.id、event.account_id、event.occurred_at 和 event.data,再分发
  }

  res.sendStatus(202);
});

如果验签失败,对照 webhook HMAC 防重放指南检查 raw body、时间戳、secret 和中间件顺序。最常见错误是先解析 / 重新格式化 JSON 再验签。

message.received 的形状

标准事件 envelope 始终包含 idtypeprovideraccount_idoccurred_atdata。handler 不应依赖 TikTok 专属结构,而应按标准 envelope 处理:

{
  "id": "evt_2f9c1a4b7e",
  "type": "message.received",
  "provider": "tiktok",
  "account_id": "acc_8c21d0",
  "occurred_at": "2026-06-08T12:34:56Z",
  "data": {
    "conversation": { "id": "5005", "type": "user" },
    "sender": { "id": "4004", "type": "user", "name": "Jordan Lee" },
    "message": {
      "id": "3003",
      "text": "Hi - is this item still available?",
      "direction": "inbound",
      "sent_at": "2026-06-08T12:34:55Z"
    }
  }
}

收到后先写入持久存储,再做 AI 分类、CRM 补充或人工分配。2xx 响应表示你已经接受该 delivery,不能在事件还没落库时就提前确认。

限制与取舍

  • TikTok 账号仍需要真实账号主人扫码授权。
  • 渠道能力和上游可用性可能受账号或地区影响;界面要能展示授权失败和重新授权状态。
  • Webhook 是 at-least-once delivery,需要用 event.idX-Device-Event-Id 做幂等。
  • HMAC 证明请求来源和内容完整性,但不会保护日志、队列和数据库中的明文。
  • 如果你需要 TikTok 官方应用登录 scope 或资料 API,应使用 TikTok 官方开发者平台;这里的 UnifyPort 流程用于入站消息事件流。

FAQ

这个流程需要 TikTok developer app 吗?

不需要。UnifyPort 账号连接使用 UnifyPort 的 account 与二维码授权端点。TikTok 官方 Login Kit 是另一个用于应用登录和授权 scope 的路径。

为什么首次启动没有二维码 URL?

TikTok provider guide 说明首次 start 响应可能暂时没有 QR URL。继续轮询 QR check,直到出现二维码材料、成功状态或失败状态。

订阅 ["*"] 还是只订阅 message.received

第一次验证 TikTok 入站时,建议只订阅 message.received。等你准备好处理授权、runtime、receipt 等事件,再扩展到 ["*"]

下一步

TikTok authorization provider guideWebhook delivery guide 并排打开。如果还在设计队列,可以继续看 TikTok live-DM queue 教程

来源

官方来源核对日期:2026-09-03:

UnifyPort API

让消息接入变成一条稳定的产品管线。

先用统一 API 跑通发送,再用标准事件把所有入站消息接回业务系统。