MyBotBoxMyBotBox

WhatsApp

Trigger workflows from WhatsApp Business messages via Meta Cloud API webhooks.

The WhatsApp trigger receives messages from the Meta WhatsApp Business platform. Inbound messages from any phone arrive as a whatsapp_business_account webhook entry; the trigger flattens the first message and exposes the full envelope on <whatsapp1.raw>.

How to configure

  1. In Meta for Developers open your app → WhatsApp → Configuration → Webhook → Edit. Paste the Webhook URL as the Callback URL and pick a Verify Token (any random string you choose) — paste the same value into the trigger's verify-token field. Meta does a one-time GET handshake with hub.mode=subscribe&hub.verify_token=<token>&hub.challenge=<n>; the trigger replies with the hub.challenge if the token matches.
  2. Subscribe to the messages field under Webhook fields (and message_status if you want delivery receipts). Then under App settings → Basic copy the App Secret and paste it as the trigger's signing secret. Meta signs requests with HMAC-SHA256 over the raw body and sends X-Hub-Signature-256: sha256=<hex>. The trigger default-denies unsigned or invalid-signed requests with 401.
  3. WhatsApp delivers a whatsapp_business_account entry containing changes[].value.messages[]. The trigger flattens the first inbound message: <whatsapp1.from> (E.164 sender phone), <whatsapp1.text> (body), <whatsapp1.messageId> (wamid.*), <whatsapp1.phoneNumberId> (your business number that received it). The full envelope is on <whatsapp1.raw>.
  4. Verify by sending a WhatsApp message to your business number from any phone. Expect a fire within ~2 seconds. Meta retries non-2xx for up to 7 days with exponential backoff — the trigger ACKs 200 immediately and processes asynchronously. Test numbers added in the Meta dashboard work without a paid messaging tier.

Signature format

HeaderValue
X-Hub-Signature-256sha256=<hex> HMAC-SHA256 over the raw request body using the App Secret

The wamid.* from entry[0].changes[0].value.messages[0].id is the dedup key. Status updates (message_status) deliver under a different field and use the status id for deduplication.

Sample payload

{
  "object": "whatsapp_business_account",
  "entry": [
    {
      "id": "102290129340398",
      "changes": [
        {
          "field": "messages",
          "value": {
            "messaging_product": "whatsapp",
            "metadata": {
              "display_phone_number": "15551234567",
              "phone_number_id": "106540352242922"
            },
            "contacts": [
              {
                "profile": { "name": "Alex Chen" },
                "wa_id": "15555550100"
              }
            ],
            "messages": [
              {
                "from": "15555550100",
                "id": "wamid.HBgLMTU1NTU1NTAxMDAVAgARGBI5RkMzQjZCNkVDQTk0RDk5MEUA",
                "timestamp": "1745700000",
                "text": { "body": "Hi, I need to reschedule my appointment." },
                "type": "text"
              }
            ]
          }
        }
      ]
    }
  ]
}

Verify with the bundled scripts

bun apps/sat/tests/staging/triggers/whatsapp/verify.ts \
  https://mybotbox.com/api/webhooks/trigger/<path> \
  --secret=<meta-app-secret>
python3 apps/sat/tests/staging/triggers/whatsapp/verify.py \
  https://mybotbox.com/api/webhooks/trigger/<path> \
  --secret=<meta-app-secret>

Source: apps/sat/tests/staging/triggers/whatsapp/.

Troubleshooting

  • Webhook verification fails on save in Meta dashboard — the verify token in the trigger does not match what you typed in the dashboard. Both fields are case-sensitive; retype rather than copy-paste if special characters could be invisible whitespace.
  • 401 after verification succeeded — App Secret mismatch. App Secret lives under App settings → Basic and is distinct from the temporary access token shown in WhatsApp → API setup. Don't confuse them.
  • Workflow doesn't fire on real WhatsApp messages — either the receiving number is not subscribed to the messages field, or your test phone is not in the Meta dashboard's allowlist (required while in dev mode). Add the phone under WhatsApp → API setup → Add phone number.
  • Duplicates — Meta retries non-2xx for 7 days. The trigger ACKs 200 immediately and dedupes on wamid via webhook_event_dedup.