mirror of
https://github.com/vercel/chat.git
synced 2026-09-14 18:32:29 +08:00
63515f2286
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
@chat-adapter/whatsapp
WhatsApp Business Cloud adapter for Chat SDK, using the WhatsApp Business Cloud API.
Installation
pnpm add @chat-adapter/whatsapp
Usage
import { Chat } from "chat";
import { createWhatsAppAdapter } from "@chat-adapter/whatsapp";
const bot = new Chat({
userName: "mybot",
adapters: {
whatsapp: createWhatsAppAdapter(),
},
});
bot.onNewMention(async (thread, message) => {
await thread.post("Hello from WhatsApp!");
});
When using createWhatsAppAdapter() without arguments, credentials are auto-detected from environment variables.
WhatsApp Business setup
1. Create a Meta app
- Go to developers.facebook.com/apps
- Click Create App, select Business type
- Add the WhatsApp product to your app
- Go to WhatsApp > API Setup and note your Phone Number ID and Access Token
2. Configure webhooks
- Go to WhatsApp > Configuration in your Meta app
- Set Callback URL to
https://your-domain.com/api/webhooks/whatsapp - Set Verify Token to a secret string of your choice (this becomes
WHATSAPP_VERIFY_TOKEN) - Subscribe to the
messageswebhook field
3. Get credentials
From your Meta app dashboard, copy:
- App Secret (under App Settings > Basic) as
WHATSAPP_APP_SECRET - Access Token (under WhatsApp > API Setup) as
WHATSAPP_ACCESS_TOKEN - Phone Number ID (under WhatsApp > API Setup) as
WHATSAPP_PHONE_NUMBER_ID
For production, generate a permanent System User Token instead of the temporary access token.
Configuration
All options are auto-detected from environment variables when not provided. You can call createWhatsAppAdapter() with no arguments if the env vars are set.
| Option | Required | Description |
|---|---|---|
accessToken |
No* | Meta access token. Auto-detected from WHATSAPP_ACCESS_TOKEN |
appSecret |
No* | App secret for webhook verification. Auto-detected from WHATSAPP_APP_SECRET |
phoneNumberId |
No* | Bot's phone number ID. Auto-detected from WHATSAPP_PHONE_NUMBER_ID |
verifyToken |
No* | Webhook verification secret. Auto-detected from WHATSAPP_VERIFY_TOKEN |
apiVersion |
No | Graph API version (defaults to v21.0) |
userName |
No | Bot username for self-message detection. Auto-detected from WHATSAPP_BOT_USERNAME (defaults to whatsapp-bot) |
logger |
No | Logger instance (defaults to ConsoleLogger("info")) |
*Required at runtime — either via config or environment variable.
Environment variables
WHATSAPP_ACCESS_TOKEN=... # Meta access token (permanent or system user token)
WHATSAPP_APP_SECRET=... # App secret for X-Hub-Signature-256 verification
WHATSAPP_PHONE_NUMBER_ID=... # Bot's phone number ID from Meta dashboard
WHATSAPP_VERIFY_TOKEN=... # User-defined secret for webhook verification
WHATSAPP_BOT_USERNAME=... # Optional, defaults to "whatsapp-bot"
Webhook setup
WhatsApp uses two webhook mechanisms:
- Verification handshake (GET) — Meta sends a
hub.verify_tokenchallenge that must match yourWHATSAPP_VERIFY_TOKEN. - Event delivery (POST) — incoming messages, reactions, and interactive responses, verified via
X-Hub-Signature-256.
// Next.js App Router example
import { bot } from "@/lib/bot";
export async function GET(request: Request) {
return bot.adapters.whatsapp.handleWebhook(request);
}
export async function POST(request: Request) {
return bot.adapters.whatsapp.handleWebhook(request);
}
Features
Messaging
| Feature | Supported |
|---|---|
| Post message | Yes |
| Edit message | No (WhatsApp limitation) |
| Delete message | No (WhatsApp limitation) |
| Streaming | Buffered (accumulates then sends) |
| Mark as read | Yes |
| Auto-chunking | Yes (splits at 4096 chars) |
Rich content
| Feature | Supported |
|---|---|
| Interactive buttons | Yes (up to 3) |
| Button title limit | 20 characters |
| List messages | Yes |
| Text fallback | Yes (for >3 buttons) |
Conversations
| Feature | Supported |
|---|---|
| Reactions | Yes (add and remove) |
| Typing indicator | No (not supported by Cloud API) |
| DMs | Yes |
| Open DM | Yes |
Incoming message types
| Type | Supported |
|---|---|
| Text | Yes |
| Images | Yes (with captions) |
| Documents | Yes (with captions) |
| Audio / Voice | Yes |
| Video | Yes (with captions) |
| Stickers | Yes |
| Locations | Yes (converted to map URL) |
| Interactive replies | Yes (button and list) |
| Reactions | Yes |
Message history
| Feature | Supported |
|---|---|
| Fetch messages | No (Cloud API limitation) |
| Fetch thread info | Yes |
Interactive messages
Card elements are automatically converted to WhatsApp interactive messages:
- 3 or fewer buttons — rendered as WhatsApp reply buttons (max 20 chars per title)
- More than 3 buttons — falls back to formatted text
- Max body text — 1024 characters
Thread ID format
whatsapp:{phoneNumberId}:{userWaId}
Example: whatsapp:1234567890:15551234567
Troubleshooting
Webhook verification failing
- Confirm
WHATSAPP_VERIFY_TOKENmatches the value you entered in the Meta dashboard - Ensure your endpoint returns the
hub.challengevalue for GET requests
Messages not arriving
- Check that you subscribed to the
messageswebhook field in Meta app settings - Verify
WHATSAPP_APP_SECRETis correct — signature verification silently rejects invalid payloads - Ensure your phone number is registered and verified in the WhatsApp Business dashboard
"Invalid signature" errors
- Double-check
WHATSAPP_APP_SECRETmatches the value under App Settings > Basic - The adapter uses HMAC-SHA256 to verify the
X-Hub-Signature-256header
Token expired
- Temporary tokens from the API Setup page expire after 24 hours
- For production, create a System User in Meta Business Suite and generate a permanent token
License
MIT