如何以 TypeScript 建立 WhatsApp 互動按鈕及清單訊息處理器
Building a WhatsApp Interactive Button & List Message Handler in TypeScript
教學示範以 TypeScript 建立 WhatsApp 互動訊息處理器,解析按鈕及清單回覆的 webhook payload,並按 action ID 分流至對話流程。清單選單最多支援 10 個選項,範例亦展示如何將回覆分派至 CRM、人工客服或 AI 知識庫處理。
Interactive messaging is one of the most effective ways to increase user engagement and eliminate typing friction on WhatsApp. Rather than forcing users to type out responses like "1", "YES", or "MENU", the official Meta WhatsApp Cloud API supports interactive buttons (quick replies, call-to-action buttons) and scrollable list menus (up to 10 options).
In this tutorial, we will build a production-ready, type-safe interactive message handler in TypeScript that parses incoming interactive payloads and routes them into conversational flows.
Understanding WhatsApp Interactive Payloads
When a recipient taps an interactive button or list item, Meta delivers an inbound webhook payload where the message type is set to "interactive".
Inside the interactive object, you will receive either:
-
button_reply: Contains theidandtitleof the clicked quick-reply button. -
list_reply: Contains theid,title, and optionaldescriptionof the chosen list row.
Step 1: Defining TypeScript Interfaces
Let's define the strict typings for incoming interactive webhook events:
export interface WhatsAppInteractiveButtonReply {
id: string;
title: string;
}
export interface WhatsAppInteractiveListReply {
id: string;
title: string;
description?: string;
}
export interface WhatsAppInteractiveMessage {
from: string;
id: string;
timestamp: string;
type: 'interactive';
interactive: {
type: 'button_reply' | 'list_reply';
button_reply?: WhatsAppInteractiveButtonReply;
list_reply?: WhatsAppInteractiveListReply;
};
}
Step 2: Sending Interactive Quick-Reply Buttons
Here is how to construct and send an interactive button message using Axios and TypeScript:
import axios from 'axios';
interface ButtonPayload {
to: string;
bodyText: string;
buttons: Array<{ id: string; title: string }>;
}
export async function sendInteractiveButtons({ to, bodyText, buttons }: ButtonPayload) {
const url = `https://graph.facebook.com/v21.0/${process.env.WHATSAPP_PHONE_NUMBER_ID}/messages`;
const payload = {
messaging_product: 'whatsapp',
recipient_type: 'individual',
to,
type: 'interactive',
interactive: {
type: 'button',
body: { text: bodyText },
action: {
buttons: buttons.map(btn => ({
type: 'reply',
reply: { id: btn.id, title: btn.title }
}))
}
}
};
const response = await axios.post(url, payload, {
headers: {
Authorization: `Bearer ${process.env.WHATSAPP_CLOUD_API_TOKEN}`,
'Content-Type': 'application/json'
}
});
return response.data;
}
Step 3: Dispatching to Conversational CRM and AI Handlers
Once the interactive webhook arrives at your server, you should route it based on the action ID:
export async function handleInteractiveReply(msg: WhatsAppInteractiveMessage) {
const customerPhone = msg.from;
const replyType = msg.interactive.type;
const actionId = replyType === 'button_reply'
? msg.interactive.button_reply?.id
: msg.interactive.list_reply?.id;
console.log(`Received action ${actionId} from ${customerPhone}`);
switch (actionId) {
case 'ACTION_BOOK_DEMO':
// Move customer into 'Demo Scheduled' stage in CRM
break;
case 'ACTION_TALK_HUMAN':
// Trigger human agent assignment
break;
case 'ACTION_FAQ':
// Pass inquiry to AI Knowledge Base
break;
default:
console.warn('Unhandled interactive ID:', actionId);
}
}
Enterprise Production Considerations
Managing raw button schemas, translation dictionaries, and state machines across hundreds of concurrent chats can quickly become complex.
Platforms like AI Soul provide a visual drag-and-drop conversational designer where interactive buttons, list menus, and AI fallbacks can be configured with zero boilerplate code. Incoming selections are automatically reflected inside the Conversational CRM and can trigger automated WhatsApp Drip Campaigns or AI Chatbot Solutions.
Conclusion
Interactive WhatsApp messages drastically improve completion rates compared to plain text replies. By modeling strict TypeScript contracts and decoupling interactive events from business logic, your integration remains reliable and maintainable.
來源:DEV Community · dev.to