@cool-ai/beach-channel-whatsapp
v0.3.1
Published
WhatsApp edge for Beach applications — webhook inbound and Cloud-API outbound, gated by Delivery Manifests.
Readme
@cool-ai/beach-channel-whatsapp
The WhatsApp channel adaptor: webhook-driven inbound, Cloud-API outbound. It implements core's ChannelAdaptor, so the channel-router routes its inbound messages and delivers its replies like any other channel. The webhook, signature, parser, and Cloud-API wire layers live here too — this package folds in what used to be @cool-ai/beach-transport-whatsapp.
Home: cool-ai.org · Documentation: cool-ai.org/docs
Install
pnpm add @cool-ai/beach-channel-whatsappUse
import { WhatsAppChannelAdaptor } from '@cool-ai/beach-channel-whatsapp';
import { renderText } from '@cool-ai/beach-a2ui-renderer-text';
const whatsapp = new WhatsAppChannelAdaptor({
transport: { phoneNumberId, appSecret, verifyToken, tokenProvider },
inbound: (req) => channelRouter.inbound(req),
render: (parts) => ({ text: renderText(parts) }),
});
app.use('/webhooks/whatsapp', whatsapp.webhookHandler()); // do not put a JSON body parser ahead of it
// Register `whatsapp` as a channel-router adaptor so replies go out by the Cloud API.- Inbound. The webhook handles Meta's GET subscription handshake and parses each POST. Each message becomes an
InboundRequestcarrying the parsed content channel-blind; the thread is the quoted message id, or the sender's number (the rolling-thread-per-contact convention). - Authentication is the router's job. Meta's
X-Hub-Signature-256is verified by aMetaSignatureAuthenticatorthe channel-router invokes — not inline in the webhook. On a valid signature it mints a principal whose id is the sender's number. - Outbound. The consumer-wired
renderturns the reply's parts into message text; the adaptor sends it by the Cloud API, quoting the inbound message.
