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

สร้าง n8n WhatsApp AI Agent จาก inbound webhook ที่มีลายเซ็น

วิธีที่เร็วที่สุดในการสร้าง WhatsApp AI Agent ในปี 2026 มักไม่ใช่การเริ่มจากตัว agent แต่ควรเริ่มจาก inbound edge ก่อน

ปัญหานี้เห็นได้ชัดใน public community ใน n8n Reddit thread ล่าสุด มี builder คนหนึ่งต้องการทำ WhatsApp automation กับ DeepSeek รองรับ media และ production stability แต่ไม่อยากติดอยู่กับ Meta Business verification และ Cloud API setup ส่วน thread อื่น ๆ ก็พูดถึงปัญหาใกล้กัน เช่น WhatsApp trigger ทำงานครั้งเดียว ทำงานเฉพาะ test mode หรือ webhook delivery กับ workflow response ไม่ตรงจังหวะ

สำหรับทีมเล็ก ลำดับที่ถูกต้องคือ รับข้อความให้เชื่อถือได้ ตอบ acknowledgement ให้เร็ว เก็บ event ก่อน แล้วค่อยให้ AI Agent ตัดสินใจว่าจะตอบหรือไม่

UnifyPort ให้ส่วน inbound เป็น event message.received ที่มีลายเซ็น ส่วน n8n ให้ workflow canvas เมื่อนำ edge verifier ขนาดเล็กมาวางตรงกลาง จะได้ path ที่เหมาะกับ production:

WhatsApp customer message
  -> UnifyPort signed message.received webhook
  -> Edge verifier for X-Device-Signature
  -> n8n production Webhook URL
  -> AI triage, CRM lookup, Slack alert, or reply via POST /v1/messages

ในประเทศไทย LINE มักเป็นช่องทางหลักพอ ๆ กับ WhatsApp ในหลายทีม support ข้อดีของโครงสร้างนี้คือคุณเริ่มจาก WhatsApp วันนี้ แล้วเพิ่ม LINE ภายหลังได้โดยไม่ต้องออกแบบ inbound workflow ใหม่ทั้งหมด

ทำไม n8n webhook URL จึงสำคัญ

เอกสารทางการของ n8n สำหรับ Webhook node ระบุชัดว่า Webhook node มีสอง URL คือ test URL และ production URL โดย test URL ใช้สำหรับ manual run ตอน editor กำลัง listen ส่วน production URL คือ URL ที่ควรใช้หลัง workflow active แล้ว

สำหรับ customer-message pipeline ให้ design โดยยึด production URL เป็นหลัก ลูกค้าจะไม่ส่งข้อความซ้ำเพียงเพราะ editor ของคุณไม่ได้ listen อยู่ inbound path ควร active เสถียร และตอบ 2xx ได้เร็ว

Respond to Webhook node ของ n8n มีประโยชน์เมื่อ workflow ต้องควบคุม HTTP response เอง สำหรับ inbound messaging response ควรเรียบง่าย: รับ event, enqueue หรือ store, แล้วตอบ 200 ส่วน AI reasoning ที่ใช้เวลานาน การเขียน CRM และ outbound replies ควรทำหลัง delivery ถูก acknowledge แล้ว

ลงทะเบียน UnifyPort webhook

สร้าง webhook endpoint ใน UnifyPort และ subscribe message.received ตั้งค่า signing_secret เพื่อให้แต่ละ delivery มี X-Device-Timestamp และ X-Device-Signature

curl -X POST https://api.unifyport.ai/v1/webhook-endpoints \
  -H "X-Api-Key: <YOUR_API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{
  "url": "https://edge.example.com/unifyport/n8n",
  "status": "active",
  "subscribed_events": ["message.received"],
  "signing_secret": "<WEBHOOK_SIGNING_SECRET>"
}'

URL นี้ไม่ได้ชี้ไปที่ n8n โดยตรง แต่ชี้ไปที่ edge verifier ขนาดเล็ก วิธีนี้ทำให้ signature verification เข้มงวด เพราะ UnifyPort เซ็น raw request body ด้วย HMAC-SHA256 string ที่ถูกเซ็นมีรูปแบบ:

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

ถ้า n8n deployment ของคุณเข้าถึง raw request bytes ก่อน JSON parsing ได้ ก็สามารถ verify ใน n8n ได้ แต่หลายทีมเลือก verify ใน service เล็ก ๆ แล้ว forward เฉพาะ trusted event ไปยัง n8n production webhook พร้อม internal token เพื่อให้ boundary ชัดเจน

เพิ่ม edge verifier

นี่คือ Node.js verifier แบบครบถ้วน มัน verify ลายเซ็นของ UnifyPort, parse event, ตรวจ event type และ forward trusted payload ไปที่ n8n

import crypto from "crypto";
import express from "express";

const app = express();
const signingSecret = process.env.WEBHOOK_SIGNING_SECRET;
const n8nWebhookUrl = process.env.N8N_PRODUCTION_WEBHOOK_URL;
const internalToken = process.env.N8N_INTERNAL_TOKEN;

app.post("/unifyport/n8n", express.raw({ type: "application/json" }), async (req, res) => {
  const timestamp = req.get("X-Device-Timestamp") || "";
  const signature = req.get("X-Device-Signature") || "";

  const hmac = crypto.createHmac("sha256", signingSecret);
  hmac.update(timestamp);
  hmac.update(".");
  hmac.update(req.body);
  const expected = hmac.digest("hex");

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

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

  const event = JSON.parse(req.body.toString("utf8"));
  if (event.type !== "message.received") {
    res.status(202).end();
    return;
  }

  await fetch(n8nWebhookUrl, {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "X-Internal-Token": internalToken
    },
    body: JSON.stringify(event)
  });

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

app.listen(3000);

service นี้ไม่เก็บ credentials ของ WhatsApp account และไม่ตัดสินใจว่า agent ควรตอบอย่างไร หน้าที่เดียวคือพิสูจน์ว่า event มาจาก UnifyPort endpoint ของคุณ แล้วส่ง trusted event เข้า n8n

สร้าง n8n workflow

ใน n8n ให้สร้าง active workflow พร้อม Webhook trigger ที่ใช้ production URL JSON ที่เข้ามาเป็น standard UnifyPort event อยู่แล้ว:

{
  "id": "evt_2f9c1a4b7e",
  "type": "message.received",
  "provider": "whatsapp",
  "account_id": "acc_8c21d0",
  "occurred_at": "2026-07-08T02:30:00Z",
  "data": {
    "conversation": { "id": "8613912345678", "type": "user", "title": "Jordan Lee" },
    "sender": { "id": "8613912345678", "name": "Jordan Lee", "type": "user" },
    "message": {
      "id": "wamid.HBgM",
      "type": "text",
      "text": "Can I change the delivery address?",
      "direction": "inbound",
      "sent_at": "2026-07-08T02:29:59Z"
    },
    "event": { "kind": "message_received" }
  }
}

workflow รุ่นแรกที่ใช้งานได้จริงควรมีห้า node:

  1. Webhook: รับ event ที่ forward มา
  2. IF: ตรวจว่า type เป็น message.received และ provider เป็น whatsapp
  3. Data store, Postgres, Airtable หรือ CRM: เก็บ id, account_id, provider, data.conversation.id, data.sender.id, และ data.message.text
  4. AI Agent หรือ HTTP Request ไปยัง model gateway: จัดประเภท message เป็น sales, support, billing หรือ human handoff
  5. HTTP Request: ตอบกลับผ่าน UnifyPort เมื่อจำเป็น

ให้ store ก่อน เอกสาร webhook ของ UnifyPort มอง events เป็น record ของ inbound traffic ไม่มี message-history read API ให้ดึง missed payloads ภายหลัง ดังนั้น workflow ควร persist event ก่อน AI step ที่ใช้เวลานานอาจ fail

ตอบกลับเมื่อ workflow ตัดสินใจแล้วเท่านั้น

ถ้า agent ต้องตอบ ให้ใช้ POST /v1/messages เอา recipient จาก inbound event และทำให้ reply เป็น action ที่ชัดเจน

curl -X POST https://api.unifyport.ai/v1/messages \
  -H "X-Api-Key: <YOUR_API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{
  "account_id": "acc_8c21d0",
  "to": { "id": "8613912345678", "type": "user" },
  "message": {
    "type": "text",
    "text": "Yes. Send us the new delivery address and we will update the order note."
  }
}'

ใน n8n นี่คือ HTTP Request node map account_id จาก {{$json.account_id}}, recipient id จาก {{$json.data.sender.id}}, และ message.text จาก output ของ AI node

ทำไม agent ไม่ควรเป็น first hop

AI Agent ไม่ควรเป็นระบบแรกที่แตะ customer message ระบบแรกควรเรียบง่าย: verify, acknowledge, store, route แบบนี้ operational contract จะยังเสถียร แม้ model, prompt หรือ escalation policy เปลี่ยน

โครงสร้างนี้ยังทำให้ n8n workflow เดียวขยายออกนอก WhatsApp ได้ envelope ใช้ provider, account_id, occurred_at, และ data เมื่อคุณเชื่อม Telegram, LINE, Zalo, TikTok หรือ X ในอนาคต workflow สามารถ branch ตาม provider โดยไม่ต้องเรียนรู้ webhook formats หกแบบ

WhatsApp Business Developer Hub อย่างเป็นทางการยังเป็นที่ที่ถูกต้องสำหรับการเรียนรู้ Meta Cloud API, webhooks, pricing และ policy surface ใช้มันเมื่อคุณ build บน official platform แต่ถ้าทีมของคุณต้องการ inbound WhatsApp support agent ใน n8n โดยไม่อยากนำ official setup steps ทั้งหมดเข้ามาใน workflow, unofficial interface ของ UnifyPort ทำให้งานแคบลง: รับ customer messages ที่มีลายเซ็น และส่งต่อไปยังเครื่องมือที่ทีมใช้อยู่แล้ว

เริ่มจาก edge ให้เสถียรก่อน เมื่อ edge เชื่อถือได้ agent ก็เป็นเพียง node ถัดไป