Meta channels
WhatsApp and Messenger over the Meta Cloud API, and how their webhooks are verified.
The Meta channel covers WhatsApp and Messenger through the Meta Cloud API. The adapter is live-pending: nothing mounts until the workspace credentials land, and every variable defaults to absent so a deployment without Meta simply has no Meta channel.
The four variables are META_APP_ID, META_APP_SECRET, META_VERIFY_TOKEN and META_WHATSAPP_TOKEN. The app secret and the verify token mount the two webhooks; unset either and no Meta channel exists. The WhatsApp token sends messages and downloads media, and without it WhatsApp outbound is off.
Webhook handshake
Meta verifies a webhook subscription with a GET that carries hub.mode=subscribe, hub.verify_token and hub.challenge. fikadesk answers it at GET /api/ingest/channels/{whatsapp|messenger}, echoing the challenge back verbatim when the token matches.
Webhook signature
Both products sign the raw body with the app secret under x-hub-signature-256: sha256=<hex>. Meta signs no timestamp, so verification stops at the HMAC and replay protection is the message-id dedup downstream rather than a clock check.
A request naming a channel this deployment does not run, a body that is not JSON, and a signature that does not verify all answer one 401 with no body, the same rule the email receivers follow.
The 24-hour session window
Meta lets a business answer a customer freely for 24 hours after the customer's last message. Outside that window only a template on WhatsApp or a tag on Messenger may be sent, and free-form sends refuse rather than guess which template the workspace wanted. The window is enforced before a byte leaves.
Inbound media arrives through two Graph calls: the media metadata for the download URL and declared type, then the download itself. The bytes are fetched at ingest and filed through the same attachment pipeline every other channel uses.
Note
The Graph API boundary talks to graph.facebook.com version v21.0 through a thin fetch with no vendor SDK, so the workspace's own credentials drive every call.