สร้างตัวรับ 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
เปลี่ยนการเชื่อมต่อข้อความให้เป็น pipeline ผลิตภัณฑ์ที่เสถียร
เริ่มจากการส่งผ่าน API เดียว แล้วส่งข้อความขาเข้าทั้งหมดกลับสู่ระบบธุรกิจของคุณด้วย event มาตรฐาน