WhatsApp Adapter
Integrate your bot with WhatsApp using the WhatsApp Cloud API adapter.
The WhatsApp adapter connects your bot to WhatsApp's massive user base through Meta's WhatsApp Cloud API. Unlike Telegram, WhatsApp requires a bit more setup—you'll need to configure webhooks manually in Meta's dashboard and handle verification requests. But once it's set up, you can reach billions of WhatsApp users with the same bot code you use for Telegram.
Configuration
Before you can start sending and receiving WhatsApp messages, you need to set up your credentials with Meta's WhatsApp Cloud API. This involves creating a Meta Developer account, setting up a WhatsApp app, and getting your access token and phone number ID. Once you have these, configuration is straightforward:
import { whatsapp } from '@igniter-js/bot'
const whatsappAdapter = whatsapp({
token: process.env.WHATSAPP_TOKEN!,
phone: process.env.WHATSAPP_PHONE_ID!,
handle: 'mybot' // Keyword for mention detection in groups
})Configuration Options
| Field | Required | Description |
|---|---|---|
token | Yes | WhatsApp Cloud API access token |
phone | Yes | Phone number ID (phone_number_id) from Meta dashboard |
handle | Yes | Keyword used for mention detection in group chats |
Getting WhatsApp Credentials
To get WhatsApp credentials:
- Create a Meta Developer account at developers.facebook.com
- Create a WhatsApp app in the Meta for Developers dashboard
- Generate a temporary or permanent access token
- Note your phone number ID from the app dashboard
Webhook Setup
WhatsApp's webhook setup is different from Telegram—you need to configure it manually in Meta's dashboard. This is because WhatsApp requires webhook verification, where Meta sends a challenge request that your endpoint must respond to correctly. While this adds an extra step, it provides better security and control over your webhook configuration.
When you're ready to set up webhooks, follow these steps in Meta's dashboard:
Access Your WhatsApp App
Go to your WhatsApp app in the Meta for Developers dashboard.
Navigate to Webhook Configuration
Open Configuration → Webhook in your app settings.
Configure the Webhook URL
Set the callback URL to your webhook endpoint (e.g., https://your-domain.com/api/whatsapp).
Set the Verify Token
Set the verify token (use the same value in your route handler). This token is used to verify that webhook requests are coming from Meta.
Subscribe to Events
Subscribe to messages events so WhatsApp sends you incoming messages.
Webhook Verification
Your webhook endpoint must handle verification requests:
// Next.js App Router example
export async function GET(req: Request) {
const { searchParams } = new URL(req.url)
const mode = searchParams.get('hub.mode')
const token = searchParams.get('hub.verify_token')
const challenge = searchParams.get('hub.challenge')
if (mode === 'subscribe' && token === process.env.WHATSAPP_VERIFY_TOKEN) {
return new Response(challenge, { status: 200 })
}
return new Response('Forbidden', { status: 403 })
}Message Types Supported
The WhatsApp adapter handles various message types that users can send through WhatsApp. Each type is normalized into Igniter.js's unified message format, making it easy to process different content types without worrying about WhatsApp-specific structures. This unified interface means your bot code works the same way regardless of whether messages come from WhatsApp or other platforms.
Sending Messages
Send text messages using the bot's send method:
await ctx.bot.send({
provider: 'whatsapp',
channel: ctx.channel.id, // WhatsApp phone number
content: {
type: 'text',
content: 'Hello from WhatsApp!'
}
})Channel ID Format
The channel parameter should be the recipient's WhatsApp phone number in international format (e.g., 5511999999999).
Group Mentions
In WhatsApp group chats, mention detection works differently than Telegram. The handle option specifies a keyword that triggers the bot:
whatsapp({
handle: 'mybot', // Bot responds when this keyword appears in group messages
// ...
})In private chats: The bot always responds.
In group chats: The bot responds when the handle keyword appears in the message (case-insensitive).
bot.on('message', async (ctx) => {
if (ctx.message.isMentioned) {
// Bot was mentioned (keyword detected in group chat)
await ctx.bot.send({
provider: ctx.provider,
channel: ctx.channel.id,
content: {
type: 'text',
content: 'Hey! You mentioned me!'
}
})
}
})Complete Example
Here's a complete example that brings together everything we've covered: configuration, webhook setup, command handling, and message processing. This example shows how all the pieces fit together in a real-world WhatsApp bot. You can use this as a starting point for your own WhatsApp integration, adapting it to your specific needs.
This example demonstrates:
- Adapter Configuration: Setting up the WhatsApp adapter with token, phone number ID, and handle
- Webhook Handling: Implementing both GET (verification) and POST (messages) endpoints
- Command Handling: Creating commands that work seamlessly with WhatsApp
- Message Processing: Reacting to incoming messages and sending responses
Bot Configuration:
import { Bot, whatsapp } from '@igniter-js/bot'
const bot = Bot.create({
id: 'whatsapp-bot',
name: 'WhatsApp Bot',
adapters: {
whatsapp: whatsapp({
token: process.env.WHATSAPP_TOKEN!,
phone: process.env.WHATSAPP_PHONE_ID!,
handle: 'mybot'
})
},
commands: {
start: {
name: 'start',
aliases: ['hello'],
description: 'Start the bot',
help: 'Use /start to begin',
async handle(ctx) {
await ctx.bot.send({
provider: ctx.provider,
channel: ctx.channel.id,
content: {
type: 'text',
content: `👋 Hello! Welcome to ${ctx.bot.name}`
}
})
}
}
},
on: {
message: async (ctx) => {
// Log all text messages
if (ctx.message.content?.type === 'text') {
console.log(`Text from ${ctx.message.author.name}: ${ctx.message.content.content}`)
}
}
}
})
await bot.start()Webhook Handler:
// src/app/api/whatsapp/route.ts
import { bot } from '@/bot'
export async function GET(req: Request) {
// Handle webhook verification
const { searchParams } = new URL(req.url)
const mode = searchParams.get('hub.mode')
const token = searchParams.get('hub.verify_token')
const challenge = searchParams.get('hub.challenge')
if (mode === 'subscribe' && token === process.env.WHATSAPP_VERIFY_TOKEN) {
return new Response(challenge, { status: 200 })
}
return new Response('Forbidden', { status: 403 })
}
export async function POST(req: Request) {
return bot.handle('whatsapp', req)
}Differences from Telegram
| Feature | Telegram | |
|---|---|---|
| Webhook Setup | Automatic | Manual (Meta dashboard) |
| Command Sync | Automatic | Not supported |
| Mention Detection | @username | Keyword-based |
| Media Support | Full | Limited (Cloud API) |
| Message Format | MarkdownV2 | Plain text |
Limitations
The WhatsApp adapter is continuously improving, but it currently has some limitations compared to what WhatsApp's Cloud API offers. Understanding these limitations helps you plan your bot's features and set realistic expectations for what's possible today.