Channel plugin · listing tai42/channel-whatsappInstall
Permissions
Provides
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
TheCHANNEL_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
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
selectquestion 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 notification —
notify_usercan attach media: an image sends as a WhatsApp image message from a publichttpsURL with an optional caption (adata:URI is refused loudly); a link item is appended to the body.mediaandtemplateare 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 afailed delivery-status webhook), and the record
ends failed rather than silently vanishing. Read failures 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
- Client conversations — the bridge model and delivery outcomes.
- Interactions — the answer contract for a delivered question.
- Conversation bridge — every setting and the authorization model.

