← Tất cả bài viết
Hướng dẫn

Sau khi tạo UnifyPort API key: checklist kiểm tra Webhook đầu tiên

Sau khi có UnifyPort API key đầu tiên, đừng vội kết nối messaging account ngay. Thứ tự an toàn hơn là: kiểm tra key bằng GET /v1/workspace, tạo signed webhook endpoint, subscribe message.received hoặc ["*"], lưu event khi nhận được, rồi mới authorize WhatsApp, Telegram, LINE, TikTok, Zalo hoặc X. Với đội ngũ ở Việt Nam, cách này đặc biệt hữu ích khi bạn cần nhận cả WhatsApp và Zalo trong cùng một hàng đợi.

Điểm chính

  • API key xác thực qua header X-Api-Key; không đặt trong browser code và không commit vào repository.
  • Secret đầy đủ của key mới chỉ được trả về một lần trong field api_key; các list response sau đó chỉ hiển thị key_prefix.
  • Nên tạo webhook trước account authorization, vì tiến trình authorization và inbound messages đều đến qua webhook events.
  • Bật signing_secret và xác thực X-Device-Signature bằng raw request body trước khi tin payload.
  • Hãy xem message.received là production contract đầu tiên, không phải event demo tạm thời.

Nếu bạn đã có live key và cần thay thế, hãy dùng zero-downtime API key rotation runbook. Nếu bạn đang thiết kế inbound architecture từ đầu, hãy đọc cùng webhook-first integration checklist.

1. Xác nhận key thuộc workspace nào

UnifyPort hiện khả dụng cho một nhóm khách hàng được chọn; tài liệu công khai hướng dẫn liên hệ team để lấy workspace access và API key đầu tiên. Sau khi có key, request đầu tiên nên là kiểm tra workspace dạng read-only, không phải gửi 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 thành công xác nhận key map tới một workspace. Introduction docs cũng nêu rằng mọi /v1 endpoint xác thực bằng X-Api-Key request header, và JSON success/error response có top-level request_id để hỗ trợ debug và reconciliation.

2. Tạo key có tên và lưu secret đầy đủ một lần

Nếu workspace cho phép tạo thêm key, hãy đặt tên thể hiện runtime sử dụng nó, ví dụ production inbound worker. Theo Create API key reference, record của key nằm trong key, còn secret đầy đủ chỉ được trả về một lần trong 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"
  }'

Quy tắc vận hành: đưa api_key vừa nhận vào secrets manager ngay, không dán vào issue, chat log hoặc client-side environment variable. OWASP Secrets Management Cheat Sheet chính thức cũng xem API keys là secrets và quản lý tạo, lưu trữ, rotation, revocation, auditing như một lifecycle thống nhất.

3. Register webhook trước khi kết nối account

Hãy làm bước này trước QR, code hoặc session authorization. UnifyPort không đảm bảo replay đầy đủ các webhook delivery đã bỏ lỡ, vì vậy record bền vững của inbound traffic nên nằm trong receiver và database của bạn.

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 cho phép dùng public standard event names chính xác hoặc ["*"] để nhận toàn bộ public standard events. Nếu bạn xây account state machine đầy đủ, dùng ["*"]; nếu milestone đầu tiên là nhận inbound messages từ WhatsApp hoặc Zalo, bắt đầu với message.received sẽ dễ kiểm tra hơn.

4. Xác thực webhook signature bằng raw body

Delivery docs định nghĩa các header quan trọng: X-Device-Event-Id, X-Device-Delivery-Id, X-Device-TimestampX-Device-Signature. Signature là hex-encoded HMAC-SHA256 của:

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

Điểm quan trọng là raw body. Nếu framework parse JSON trước rồi serialize lại, bytes có thể thay đổi và signature verification sẽ fail.

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();
});

Tham khảo sâu hơn tại Webhook delivery & signature verification. Trang này cũng giải thích retries, idempotency, stale timestamp checks và quy tắc rằng bất kỳ 2xx response nào cũng xác nhận delivery.

5. Lưu message.received envelope làm contract đầu tiên

Một inbound message thông thường có envelope ổn định gồm id, type, provider, account_id, occurred_atdata. standard event payload reference cho thấy những field nên dùng để thiết kế model:

{
  "id": "evt_2f9c1a4b7e",
  "type": "message.received",
  "provider": "zalo",
  "account_id": "acc_8c21d0",
  "occurred_at": "2026-06-08T12:34:56Z",
  "data": {
    "conversation": { "id": "zalo_user_8842", "type": "user" },
    "sender": { "id": "zalo_user_8842", "type": "user", "name": "Jordan Lee" },
    "message": {
      "id": "msg_10472",
      "text": "Đơn hàng của tôi đã gửi chưa?",
      "direction": "inbound",
      "sent_at": "2026-06-08T12:34:55Z"
    }
  }
}

Lưu top-level event id cho idempotency, provideraccount_id cho routing, data.conversation.id cho queue grouping, data.sender.id cho identity, và data.message.id cho message-level actions. Khi shape này đã ổn định, cùng một receiver có thể nhận Zalo hoặc WhatsApp trước, rồi thêm LINE, Telegram, TikTok hoặc X sau. Nếu muốn xem phiên bản có AI coding agent hỗ trợ tạo implementation, đọc AI coding agent auto-reply bot tutorial.

Lỗi thường gặp trong ngày đầu

LỗiTác hạiCách an toàn hơn
Tạo account trướcAuth events có thể đến trước khi receiver sẵn sàngTạo webhook endpoint trước
Tắt signingNgười biết URL có thể gửi JSON trông giống thậtĐặt signing_secret và xác thực raw-body HMAC
Deduplicate theo delivery attemptRetry có thể gửi lại cùng một eventDeduplicate bằng X-Device-Event-Id hoặc event id
Ghi API key vào logsSecrets lan sang hệ thống khó audit hằng ngàyLưu trong secrets manager và redact trong logs
Xem message.received là WhatsApp-onlyĐây là normalized event cho các providers được hỗ trợLưu provider/account fields thay vì giả định một platform

FAQ

Có thể lấy lại API key đầy đủ sau này không?

Không. Create response trả secret đầy đủ một lần trong api_key. List và detail responses chỉ trả metadata an toàn để hiển thị như key_prefix, không trả lại secret đầy đủ.

Nên subscribe message.received hay ["*"]?

Dùng message.received cho inbound test đầu tiên gọn nhất. Dùng ["*"] nếu một receiver cần xử lý auth, runtime, message, receipt, conversation hoặc group events.

Có cần webhook endpoint trước khi tạo account không?

Để first run đáng tin cậy, nên có. Account authorization progress và live inbound messages được gửi qua webhook events, và UnifyPort không hứa replay đầy đủ các payload đã bỏ lỡ.

Có cần official business account trên mọi platform không?

Không. UnifyPort cung cấp unofficial interface cho WhatsApp, Telegram, LINE, TikTok, Zalo và X, đồng thời có thể kết nối personal hoặc ordinary messaging accounts trong mô hình phù hợp.

Bước tiếp theo

Mở Quickstart, lưu API key trong secrets manager, tạo webhook endpoint trước và dùng delivery verification docs làm chuẩn cho receiver implementation.

Sources checked on 2026-09-01

UnifyPort API

Biến tích hợp nhắn tin thành một pipeline sản phẩm ổn định.

Bắt đầu bằng cách gửi qua một API, rồi đưa mọi tin nhắn inbound trở lại hệ thống kinh doanh bằng sự kiện chuẩn.