Skip to main content
Channel plugin · listing tai42/channel-whatsapp

Install

Permissions

Provides

whatsapp

Channel — Deliver ask_user questions to a human on WhatsApp via the Meta Cloud API and bridge the reply back. Bridge a WhatsApp number carried by the Meta Cloud API to an agent, or deliver ask_user questions into it. Unlike Twilio, this channel sends interactive controls, media, and pre-approved templates.

Enable it

manifest.yml

Configuration

The CHANNEL_WHATSAPP_ env group. CHANNEL_WHATSAPP_REDIS_URL (and the inherited connection-tuning fields) point the plugin-owned correlation store.

Point the webhook at the deployment

Meta uses a single webhook endpoint for verification, inbound messages, and delivery statuses (configured in the Meta App dashboard):
  • Callback URL → {public base URL}/api/channels/whatsapp/inbound
  • Verify token → the value of CHANNEL_WHATSAPP_VERIFY_TOKEN
On subscribe, Meta sends a GET with hub.challenge; the door echoes it only when the verify token matches. Inbound messages and delivery statuses then arrive as signed POSTs on the same URL.

Create a bridge route

our_identity is the number’s phone_number_id (from the Meta dashboard), not the display number:

Rich messages

  • Interactive select asks — when a select question is delivered, its options render as native WhatsApp controls: a short set becomes tappable reply buttons, a longer set a list message. Past WhatsApp’s row cap, or when an option’s text is too long for a button or row, the ask falls back to the numbered-text prompt so the person always sees every option in full. Either way the answer is the option text.
  • Media on a notificationnotify_user can attach media: an image sends as a WhatsApp image message from a public https URL with an optional caption (a data: URI is refused loudly); a link item is appended to the body. media and template are mutually exclusive on one send.

The 24-hour window and templates

WhatsApp delivers freeform messages only inside a 24-hour service window opened by the client’s last message. Outside it, a freeform reply is rejected (synchronously, or later via a failed delivery-status webhook), and the record ends failed rather than silently vanishing. Read failures with:
A pre-approved template is the one message delivered outside the window. Send one with notify_user’s template input (a name, a language, and positional body-text parameters). Because a template is billed and delivered cold, the channel fences who may receive one: the recipient must be on CHANNEL_WHATSAPP_ALLOWED_RECIPIENTS, or be a known contact — a number the inbound webhook received a message from within CHANNEL_WHATSAPP_TEMPLATE_CONTACT_WINDOW_DAYS. A template send to a cold, unlisted number is refused loudly.

See also