← 全記事
チュートリアル

QR認可でTikTokアカウントを署名付きWebhookに接続する

UnifyPortでTikTokメッセージを受けるなら、最初に作るべきものはQR画面ではなくwebhookです。署名付きwebhook endpointを登録し、auth_mode: "qrcode" のTikTokアカウントを作成し、QR認可を開始して状態をポーリングします。アカウント所有者がQRをスキャンしたら、届いた message.received イベントをまず保存し、その後でSlack、CRM、AI処理、有人対応に流します。

日本チームの場合、LINEを主チャネル、TikTokを獲得・問い合わせチャネルとして併用することも多くあります。UnifyPortの利点は、TikTokだけでなくLINEなどのチャネルも同じ受信形状に寄せられる点です。LINE側の設計は LINEサービスメッセージとwebhookの使い分け も参考になります。

要点

  • 認可より先にwebhookを作る。認可進行と後続のインバウンドメッセージはどちらもイベントで届きます。
  • UnifyPortのTikTok認可は標準のaccount / QR auth endpointを使います。最初のstart responseにQR URLがない場合があるため、QR checkをポーリングします。
  • X-Device-SignatureX-Device-Timestamp + "." + raw body に対するHMAC-SHA256です。JSONをparseする前に検証します。
  • 受信イベントはまず永続化し、その後でルーティングします。
  • TikTok公式のLogin Kit QR認可とは別物です。公式Login Kitはアプリログインとprofile/scope認可のためのフローです。

TikTokに一般公開DM APIがあるかを確認している段階なら、先に TikTok DM APIの解説 を読んでください。この記事は、UnifyPortのunofficial interfaceを選んだ後の具体的な接続手順に絞っています。受信側の全体設計は webhook-first inbound checklist と合わせて確認すると安全です。

接続の順番

  1. HTTPSのwebhook endpointを作成し、signing_secretを設定する。
  2. 最初は message.received だけを購読する。
  3. TikTok accountを作成し、auth_modeqrcodeにする。
  4. QR認可を開始する。
  5. QR check endpointをポーリングし、QR情報、成功状態、失敗状態のいずれかを待つ。
  6. TikTokアカウント所有者にQRをスキャンしてもらう。
  7. 認可/runtimeイベントを確認し、テストメッセージで message.received を受ける。

UnifyPortのドキュメントでは、webhookはインバウンドトラフィックの耐久的な記録になる層です。後から完全に取り戻せる前提で、先にアカウントだけ接続しないでください。

1. 署名付き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 のほうが原因を切り分けやすくなります。

2. TikTok accountを作成する

UnifyPortでは、1つのチャネルログインが1つのaccountです。TikTok provider guideでは、このチャネルがQR認可を使うことが説明されています。

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を保存します。以降の例では、本番IDをチャットやログに貼らないよう $ACCOUNT_ID としています。

3. QR認可を開始してポーリングする

QRフローを開始します。

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では、最初のstart responseにQR URLがまだ含まれない場合があります。次のendpointをポーリングします。

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 '{}'

QR情報が出たら、そのTikTokアカウントを接続する本人だけに表示します。スキャンと承認の後、webhookに認可/runtimeイベントが届き、続いて message.received を確認できます。

4. JSONをparseする前に署名を検証する

Webhook delivery and signature verification が署名契約の一次資料です。署名が有効なendpointでは、deliveryに X-Device-TimestampX-Device-Signature が含まれます。署名対象は次の文字列とraw bodyです。

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

Expressではraw 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, account_id, occurred_at, dataを保存してからルーティングする
  }

  res.sendStatus(202);
});

署名が合わない場合は、webhook HMAC replay protection のraw body、timestamp、secret、middleware順序を確認してください。多くのミスマッチは、JSONをparseまたは整形した後で検証していることが原因です。

message.received の形

標準event envelopeは idtypeprovideraccount_idoccurred_atdata を持ちます。TikTok専用schemaではなく、この共通形状を保存してください。

{
  "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更新、担当者割り当ては、イベントが耐久的に受理された後に実行してください。

制限とトレードオフ

  • TikTokアカウント所有者によるQRスキャンと承認が必要です。
  • チャネル能力と上流の利用可否は、アカウントや地域によって変わる可能性があります。
  • Webhook deliveryはat-least-onceです。event.id または X-Device-Event-Id で冪等化します。
  • HMACは送信元と完全性を検証しますが、ログ、queue、databaseを暗号化するものではありません。
  • TikTok公式のapp-login scopeやprofile APIが必要な場合は、TikTok公式Developer Platformを使います。ここでのUnifyPortはインバウンドメッセージイベント流のための層です。

FAQ

このUnifyPortフローにTikTok developer appは必要ですか?

不要です。UnifyPortのaccountとQR認可endpointを使います。TikTok公式Login Kitは、app-loginとscope認可のための別フローです。

なぜ最初のstart responseにQR URLがないのですか?

TikTok provider guideでは、初回responseにQR URLが含まれない場合があるとされています。QR checkをポーリングし、QR情報、成功、失敗のいずれかを待ちます。

["*"]message.received のどちらを使うべきですか?

最初のテストでは message.received だけを推奨します。auth、runtime、receiptなどを処理できるようになったら、必要なイベントを増やします。

次のステップ

TikTok authorization provider guideWebhook delivery guide を並べて確認してください。LINEを含む複数チャネルの受信設計に広げる場合は、LINE inbound handlerの構築ログ も参考になります。

Sources

Official sources checked on 2026-09-03:

UnifyPort API

メッセージ連携を安定したプロダクトパイプラインへ。

まずは 1 つの API で送信を始め、標準イベントですべての inbound メッセージを業務システムへ戻しましょう。