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

FieldRequiredDescription
tokenYesWhatsApp Cloud API access token
phoneYesPhone number ID (phone_number_id) from Meta dashboard
handleYesKeyword used for mention detection in group chats

Getting WhatsApp Credentials

To get WhatsApp credentials:

  1. Create a Meta Developer account at developers.facebook.com
  2. Create a WhatsApp app in the Meta for Developers dashboard
  3. Generate a temporary or permanent access token
  4. 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.

Open ConfigurationWebhook 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

FeatureTelegramWhatsApp
Webhook SetupAutomaticManual (Meta dashboard)
Command SyncAutomaticNot supported
Mention Detection@usernameKeyword-based
Media SupportFullLimited (Cloud API)
Message FormatMarkdownV2Plain 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.