← บทความทั้งหมด
บทช่วยสอน

สร้างตัวรับ TikTok DM Webhook ด้วย GitHub Copilot

ถ้าทีมต้องรับข้อความ TikTok DM เข้า workflow ซัพพอร์ต อย่าให้ AI เดา payload เอง ให้เริ่มจากสัญญา API จริงก่อน: UnifyPort ส่งข้อความขาเข้าจาก TikTok เป็น event มาตรฐาน message.received แบบเดียวกับ WhatsApp, Telegram, LINE, Zalo และ X พร้อมลายเซ็น HMAC-SHA256 บน raw body

สรุปสั้น

  • เอกสารทางการของ TikTok ระบุ Direct Messages ในบริบท Data Portability scopes และ data types ไม่ใช่ webhook สดสำหรับ customer support ทั่วไป
  • Prompt ให้ Copilot ด้วยชื่อจริงจากเอกสาร UnifyPort: POST /v1/webhook-endpoints, subscribed_events, signing_secret, X-Device-Timestamp, X-Device-Signature
  • ต้อง verify raw body ก่อน parse JSON เพราะการ serialize ใหม่ทำให้ bytes เปลี่ยน
  • สำหรับทีมไทยที่ใช้ LINE เป็นช่องหลัก คุณสามารถใช้ receiver เดียวกันนี้ต่อ LINE เพิ่มภายหลังได้ เพราะ schema ถูก normalize แล้ว

ถ้ายังไม่แน่ใจเรื่อง TikTok DM API ให้อ่าน ทำไม TikTok DM API ไม่มี endpoint ทางการทั่วไป ก่อน แล้วค่อยดู TikTok Data Portability vs live DMs เพื่อแยก export workflow ออกจาก live support intake

Demo ที่จะได้

เราจะได้ Node.js service เล็ก ๆ ที่มี route /webhook รับ UnifyPort events ตรวจ X-Device-Timestamp และ X-Device-Signature parse เฉพาะ message.received เก็บฟิลด์สำคัญ แล้วตอบ 200

เปิด webhook delivery and signature verification ไว้ขณะเขียน เพราะหน้านี้คือ source of truth ของ signature, headers, retries และ idempotency

Prompt แรกสำหรับ Copilot

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

หลัง deploy ด้วย HTTPS ให้สร้าง endpoint ด้วย POST /v1/webhook-endpoints และ subscribe เฉพาะ message.received

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

ถ้าต้องการตัวอย่าง workflow แนว AI coding เพิ่มเติม ดู tutorial auto-reply bot ด้วย AI coding agent

เพิ่มความทนทาน

Prompt ถัดไปควรให้ Copilot เพิ่ม idempotency ด้วย X-Device-Event-Id เก็บ raw event และ route เฉพาะ data.message.direction === 'inbound' ไปยัง triage queue จากนั้นค่อยต่อ Slack, CRM หรือ AI classifier

ข้อจำกัด

ถ้าต้องการ publishing, login, research tools หรือ data export อย่างเป็นทางการ ให้ใช้ TikTok official APIs ส่วน UnifyPort เป็น unofficial interface สำหรับรับ live inbound messages จากบัญชีที่มีอยู่ พร้อม event stream ที่ตรวจสอบได้

FAQ

Copilot ทำ inbox ทั้งหมดแทนเราได้ไหม?

ช่วย scaffold receiver, tests และ queue code ได้ แต่ทีมต้อง review signature verification, secret management และ storage behavior เอง

Data Portability คือ live DM หรือไม่?

ไม่ใช่ เอกสารทางการพูดถึง export scopes และ data types ส่วนงานซัพพอร์ตต้องการ live event stream

ควร subscribe event ไหน?

ใช้ message.received สำหรับ inbound messages และใช้ ["*"] เฉพาะกรณีสร้าง collector ทุก event

Sources checked on 2026-08-29

UnifyPort API

เปลี่ยนการเชื่อมต่อข้อความให้เป็น pipeline ผลิตภัณฑ์ที่เสถียร

เริ่มจากการส่งผ่าน API เดียว แล้วส่งข้อความขาเข้าทั้งหมดกลับสู่ระบบธุรกิจของคุณด้วย event มาตรฐาน