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

หลังสร้าง UnifyPort API key: เช็กลิสต์ทดสอบ Webhook แรก

หลังจากได้ UnifyPort API key แรก อย่าเพิ่งรีบเชื่อมต่อ messaging account ทันที ลำดับที่ปลอดภัยกว่าคือ ตรวจ key ด้วย GET /v1/workspace, สร้าง signed webhook endpoint, subscribe message.received หรือ ["*"], เก็บ event ที่เข้ามา แล้วค่อย authorize WhatsApp, Telegram, LINE, TikTok, Zalo หรือ X สำหรับทีมในไทยที่ใช้ LINE เป็นช่องทางหลัก ลำดับนี้ช่วยให้ไม่พลาด event ตั้งแต่ต้น

สรุปสำคัญ

  • API key ใช้ยืนยันตัวตนผ่าน header X-Api-Key; อย่าใส่ไว้ใน browser code หรือ commit ลง repository
  • key ที่สร้างใหม่จะคืนค่า secret เต็มเพียงครั้งเดียวใน field api_key; response สำหรับ list ภายหลังจะแสดงเฉพาะ key_prefix
  • ควรสร้าง webhook ก่อน account authorization เพราะสถานะการ authorize และ inbound messages จะถูกส่งเป็น webhook events
  • เปิดใช้ signing_secret และตรวจ X-Device-Signature ด้วย raw request body ก่อนเชื่อถือ payload
  • ให้ถือ message.received เป็น production contract แรก ไม่ใช่แค่ event สำหรับ demo

ถ้าคุณมี key ที่ใช้งานจริงแล้วและต้องการเปลี่ยนโดยไม่ทำให้ระบบหยุด ดู zero-downtime API key rotation runbook ก่อน หากคุณกำลังเริ่มออกแบบ inbound architecture ตั้งแต่ศูนย์ ให้อ่านคู่กับ webhook-first integration checklist

1. ตรวจว่า key ผูกกับ workspace ใด

UnifyPort เปิดให้ใช้งานกับลูกค้าที่ได้รับการคัดเลือกในปัจจุบัน เอกสารสาธารณะระบุให้ติดต่อทีมเพื่อรับ workspace access และ API key แรก เมื่อได้ key แล้ว request แรกควรเป็นการตรวจ workspace แบบ read-only ไม่ใช่การส่ง message

export UNIFYPORT_API_KEY="set-this-in-your-secret-manager"

curl https://api.unifyport.ai/v1/workspace \
  -H "X-Api-Key: $UNIFYPORT_API_KEY"

response สำเร็จหมายความว่า key นี้ map ไปยัง workspace ได้ Introduction docs ยังระบุว่า endpoint /v1 ทุกตัวใช้ X-Api-Key request header และ JSON success/error response จะมี top-level request_id สำหรับ support และ reconciliation

2. สร้าง key ที่มีชื่อ และเก็บ secret เต็มเพียงครั้งเดียว

ถ้า workspace อนุญาตให้สร้าง key เพิ่ม ให้ตั้งชื่อที่บอก runtime ที่จะใช้งาน เช่น production inbound worker ตาม Create API key reference record ของ key จะอยู่ใต้ key และ secret เต็มจะถูกส่งกลับใต้ api_key เพียงครั้งเดียว

curl -X POST https://api.unifyport.ai/v1/api-keys \
  -H "X-Api-Key: $UNIFYPORT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Production inbound worker",
    "prefix": "dk_live"
  }'

กฎการใช้งานคือ นำค่า api_key ที่ได้ไปเก็บใน secrets manager ทันที อย่าวางไว้ใน issue, chat log หรือ client-side environment variable OWASP Secrets Management Cheat Sheet อย่างเป็นทางการก็จัด API keys เป็น secrets และอธิบาย lifecycle เดียวกันตั้งแต่การสร้าง การเก็บ การ rotate การ revoke และการ audit

3. Register webhook ก่อนเชื่อมต่อ account

ทำขั้นตอนนี้ก่อน QR, code หรือ session authorization เพราะ UnifyPort ไม่รับประกัน replay แบบครบถ้วนสำหรับ webhook delivery ที่พลาดไป ดังนั้น record ถาวรของ inbound traffic ควรอยู่ที่ receiver และ database ของคุณ

export WEBHOOK_SIGNING_SECRET="generate-a-long-random-secret"

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/webhook",
    "status": "active",
    "subscribed_events": ["message.received"],
    "signing_secret": "'"$WEBHOOK_SIGNING_SECRET"'"
  }'

Create webhook endpoint reference รองรับ public standard event names แบบเจาะจง หรือ ["*"] สำหรับ public standard events ทั้งหมด ถ้าจะสร้าง account state machine ครบชุด ใช้ ["*"]; ถ้า milestone แรกคือรับข้อความจาก LINE หรือช่องทางอื่น ให้เริ่มจาก message.received จะตรวจง่ายกว่า

4. ตรวจ webhook signature จาก raw body

Delivery docs กำหนด header สำคัญ ได้แก่ X-Device-Event-Id, X-Device-Delivery-Id, X-Device-Timestamp และ X-Device-Signature โดย signature คือ hex-encoded HMAC-SHA256 ของค่า:

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

จุดสำคัญคือ raw body ถ้า framework parse JSON ก่อนแล้ว serialize ใหม่ bytes อาจเปลี่ยนและ signature verification จะล้มเหลว

import crypto from 'crypto';
import express from 'express';

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

app.post('/unifyport/webhook', 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');

  const valid = signature.length === expected.length &&
    crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));

  if (!valid) return res.status(401).end();

  const event = JSON.parse(req.body.toString('utf8'));
  if (event.type === 'message.received') {
    console.log(event.provider, event.data.conversation.id, event.data.message.text);
  }

  res.status(200).end();
});

ดูรายละเอียดเพิ่มเติมที่ Webhook delivery & signature verification ซึ่งครอบคลุม retries, idempotency, การตรวจ stale timestamp และกฎว่า response 2xx ใด ๆ ถือเป็น acknowledgement ของ delivery

5. เก็บ message.received envelope เป็น contract แรก

Inbound message ปกติจะมาพร้อม envelope ที่คงที่ ได้แก่ id, type, provider, account_id, occurred_at และ data standard event payload reference แสดง fields ที่ควรใช้เป็นฐานของ model:

{
  "id": "evt_2f9c1a4b7e",
  "type": "message.received",
  "provider": "line",
  "account_id": "acc_8c21d0",
  "occurred_at": "2026-06-08T12:34:56Z",
  "data": {
    "conversation": { "id": "u1234567890", "type": "user" },
    "sender": { "id": "u1234567890", "type": "user", "name": "Jordan Lee" },
    "message": {
      "id": "msg_10472",
      "text": "ขอเช็กสถานะจัดส่งครับ",
      "direction": "inbound",
      "sent_at": "2026-06-08T12:34:55Z"
    }
  }
}

เก็บ top-level event id สำหรับ idempotency, provider และ account_id สำหรับ routing, data.conversation.id สำหรับจัดกลุ่ม queue, data.sender.id สำหรับ identity และ data.message.id สำหรับ message-level actions เมื่อ shape นี้นิ่ง receiver เดียวกันสามารถรับ LINE ก่อน แล้วเพิ่ม WhatsApp, Telegram, Zalo, TikTok หรือ X ได้ภายหลัง ถ้าต้องการ workflow ที่มี AI coding agent ช่วยสร้าง implementation ดู AI coding agent auto-reply bot tutorial

ข้อผิดพลาดที่พบบ่อยในวันแรก

ข้อผิดพลาดผลกระทบวิธีที่ปลอดภัยกว่า
สร้าง account ก่อน webhookauth events อาจมาถึงก่อน receiver พร้อมสร้าง webhook endpoint ก่อน
ปิด signingผู้ที่รู้ URL อาจส่ง JSON คล้ายของจริงได้ตั้ง signing_secret และตรวจ raw-body HMAC
deduplicate เฉพาะ delivery attemptretry อาจส่ง event เดิมซ้ำdeduplicate ด้วย X-Device-Event-Id หรือ event id
log API keysecret กระจายไปยังระบบ log ที่ตรวจยากเก็บใน secrets manager และ redact ใน logs
มอง message.received เป็นของ WhatsApp เท่านั้นevent นี้เป็น normalized event ข้าม providersเก็บ provider/account fields และไม่ผูกกับ platform เดียว

FAQ

ดึง API key เต็มกลับมาในภายหลังได้ไหม?

ไม่ได้ response ตอนสร้าง key จะคืนค่า secret เต็มใน api_key เพียงครั้งเดียว ส่วน list และ detail response จะแสดง metadata ที่ปลอดภัย เช่น key_prefix

ควร subscribe message.received หรือ ["*"]?

ถ้าเป็น inbound test แรก ใช้ message.received ถ้าระบบต้องการ auth, runtime, message, receipt, conversation หรือ group events ใน receiver เดียว ใช้ ["*"]

ต้องมี webhook endpoint ก่อนสร้าง account ไหม?

สำหรับ first run ที่เชื่อถือได้ ควรมี เพราะ account authorization progress และ live inbound messages ถูกส่งเป็น webhook events และ UnifyPort ไม่รับประกัน replay ครบทุก payload ที่พลาด

ต้องมี official business account ทุก platform หรือไม่?

ไม่จำเป็น UnifyPort มี unofficial interface สำหรับ WhatsApp, Telegram, LINE, TikTok, Zalo และ X และสามารถเชื่อมต่อ personal หรือ ordinary messaging account ได้ในโมเดลที่เหมาะสม

ขั้นตอนถัดไป

เปิด Quickstart เก็บ API key ใน secrets manager สร้าง webhook endpoint ก่อน แล้วใช้ delivery verification docs เป็นคู่มือสำหรับ receiver implementation

Sources checked on 2026-09-01

UnifyPort API

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

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