wapit

O Mailpit do WhatsApp.

Aponte o seu app para o wapit e cada mensagem que ele envia chega numa caixa de entrada com cara de conversa. Cada envio é conferido como a Meta confere, e você responde como o usuário.

$ brew install patriciomartinns/tap/wapit
Ler a documentação Ver no GitHub

No Windows, baixe o .zip da release mais recente. Também como imagem de container e com cargo install.

A caixa de entrada do wapit: uma cliente pergunta do pedido e o app responde com um template com botões, com a entrega do webhook embaixo da mensagem

Toque num botão. O seu app recebe o webhook.

Responda, anexe um arquivo, toque num botão ou marque uma mensagem como lida na caixa de entrada. O wapit envia o mesmo payload que a Meta enviaria, assinado com o seu app secret.

POST localhost:8000/webhook200 em 38 msRequisição que o seu app recebe
X-Hub-Signature-256: sha256=4f0c9e…b21a

{
  "object": "whatsapp_business_account",
  "entry": [{
    "id": "200000000000002",
    "changes": [{
      "field": "messages",
      "value": {
        "messaging_product": "whatsapp",
        "metadata": { "phone_number_id": "100000000000002", … },
        "contacts": [{ "wa_id": "15550001234",
          "profile": { "name": "Mary Smith" } }],
        "messages": [{
          "type": "interactive",
          "interactive": {
            "type": "button_reply",
            "button_reply": { "id": "hold",
              "title": "Yes, hold it" }
          }
        }]
      }
    }]
  }]
}

Falha onde a Meta falha, e diz por quê.

Um envio errado recebe o erro da Meta, então o tratamento de erro do seu app roda de verdade. A mensagem fica na caixa de entrada, marcada, com o motivo em palavras simples.

Ver todas as verificações na documentação
O seu app envia

POST /v26.0/100000000000002/messages

{
  "messaging_product": "whatsapp",
  "to": "15550001234",
  "type": "template",
  "template": {
    "name": "order_ready",
    "language": { "code": "en_US" },
    "components": [{
      "type": "body",
      "parameters": [
        { "type": "text", "text": "Mary" },
        { "type": "text", "text": "Main Street, 120" }
      ]
    }]
  }
}
A caixa de entrada mostra

Mary Smith+1 555 000 1234 no Example Shop

1 rejeitada

order_ready en_US, 2 variáveis

Rejeitado com o erro 13200014:06

O Example Shop mandou 2 variáveis no corpo, e o order_ready espera 3. O app recebeu o erro e nada foi entregue.

body: number of localizable_params (2) does not match the expected number of params (3)

O seu app recebe de volta

HTTP/1.1 400 Bad Request

{
  "error": {
    "message": "(#132000) Number of parameters
      does not match the expected number of params",
    "type": "OAuthException",
    "code": 132000,
    "fbtrace_id": "A3kQ8x…"
  }
}

Funciona sem configurar nada.

Um binário e um arquivo SQLite local. Rode e ele serve um app padrão. Nunca fala com a Meta, a não ser que você rode wapit sync.

terminal
$ wapit
Graph API mock on 127.0.0.1:8027
Inbox on http://127.0.0.1:8026

$ curl http://127.0.0.1:8027/v26.0/100000000000001/messages \
    -H 'Authorization: Bearer wapit-local-token' \
    -H 'Content-Type: application/json' \
    -d '{"messaging_product":"whatsapp","to":"15550000000",
         "type":"text","text":{"body":"Hello"}}'
{"messaging_product":"whatsapp","contacts":[...],"messages":[{"id":"wamid..."}]}