Referência técnica
Formato exato do que chega no webhook, das respostas e dos métodos da API. Se é a sua primeira vez, comece pelo guia de início.
1. Resumo do fluxo
- Mande
/startpara um número do WhatsBot: o seu telefone ganha um canal nele. - Defina o webhook com
/webhook https://...(ou porsetWebhookcom o token de/token). - Tudo que você escrever para o número gera um
POSTno seu webhook. - Responda no corpo do webhook (
{"text": "..."}) ou chamesendMessagequando quiser.
2. O que chega no seu webhook
POST com Content-Type: application/json. Sem retentativa: se o seu servidor não responder 2xx em até 25 s, a mensagem é contada como falha e não é reenviada.
{
"event": "message",
"bot_id": 12,
"message": {
"id": "3EB0538DA65A59F6D8A251",
"timestamp": 1758100000,
"chat": { "id": "5511999999999@s.whatsapp.net", "type": "private", "name": null },
"from": { "id": "5511999999999@s.whatsapp.net", "phone": "5511999999999", "name": "Maria" },
"type": "text",
"text": "oi",
"media": null,
"location": null,
"contact": null,
"reply_to": null,
"raw_type": "conversation"
}
}
| Campo | Significado |
|---|---|
event | message para mensagem recebida; test quando você clica em "Testar webhook" (aí message é null). |
message.type | text · image · audio · video · document · sticker · location · contact · unsupported |
message.chat | type é private ou group. A resposta síncrona volta para chat.id. Grupos só chegam com /grupos on. |
message.from | Quem escreveu: sempre o dono do canal (é ele que o roteamento usa). Em grupo, chat é o grupo e from continua sendo o dono. |
message.media | Para imagem, áudio, vídeo, documento e sticker: { "url", "mime", "filename", "caption", "size", "duration" }. A URL é pública e temporária: baixe na hora se precisar guardar. Áudio vem em MP3. |
message.location | { "lat", "lng", "name", "address" } |
message.reply_to | id da mensagem citada, quando a pessoa respondeu a algo. |
Headers
X-Whatsbot-Bot-Id | id do bot |
X-Whatsbot-Event | message ou test |
X-Whatsbot-Secret | o segredo do seu bot, em texto puro. Compare com o que está no painel. |
X-Whatsbot-Signature | sha256=<HMAC-SHA256 do corpo bruto usando o segredo>, para quem prefere assinatura. |
Verificando a assinatura:
// PHP
$raw = file_get_contents('php://input');
$sig = 'sha256=' . hash_hmac('sha256', $raw, $SEGREDO);
if (!hash_equals($sig, $_SERVER['HTTP_X_WHATSBOT_SIGNATURE'] ?? '')) { http_response_code(401); exit; }
// Node (Express com express.raw({ type: 'application/json' }))
const sig = 'sha256=' + crypto.createHmac('sha256', SEGREDO).update(req.body).digest('hex');
if (sig !== req.get('X-Whatsbot-Signature')) return res.sendStatus(401);
3. Respondendo no corpo do webhook
Responda 200 com JSON e a resposta vai para o chat de origem. Corpo vazio, outro formato ou event: test: nada é enviado.
{ "text": "Olá! Como posso ajudar?", "typing_ms": 1200 }
{ "messages": [
{ "type": "text", "text": "Segue o catálogo:" },
{ "type": "image", "url": "https://exemplo.com/catalogo.jpg", "caption": "Coleção 2026" },
{ "type": "document", "url": "https://exemplo.com/tabela.pdf", "filename": "tabela.pdf" }
] }
typing_ms mostra "digitando…" por esse tempo antes de enviar (máx. 15000). reply_to cita a mensagem. Até 10 mensagens por resposta.
4. API do bot
Base: https://whatsbot.maike.my/bot<token>/<método>. Envie JSON por POST. Toda resposta é {"ok": true, "result": …} ou {"ok": false, "error_code": 4xx, "description": "…"}.
| Método | Parâmetros | Faz |
|---|---|---|
getMe | dados do bot, número, status e config do webhook (GET ou POST) | |
sendMessage | text, reply_to?, typing_ms?, to? | envia texto para o dono do canal |
sendMedia | type (image · video · audio · voice · document · sticker), url, caption?, filename?, to? | envia mídia por URL pública para o dono do canal |
setWebhook | url, secret?, receive_groups? | configura o webhook (mesmo efeito do painel) |
getWebhookInfo | url, contadores, último erro | |
deleteWebhook | desliga a entrega |
to é opcional e, se vier, precisa ser o próprio telefone do dono do canal (ou o chat.id dele). Qualquer outro destino devolve 403: o token nunca envia para terceiros.
curl -X POST https://whatsbot.maike.my/bot12:abc.../sendMessage \
-H 'Content-Type: application/json' \
-d '{"text": "Lembrete: reunião às 15h."}'
curl -X POST https://whatsbot.maike.my/bot12:abc.../sendMedia \
-H 'Content-Type: application/json' \
-d '{"type": "image", "url": "https://exemplo.com/foto.jpg", "caption": "Chegou!"}'
curl -X POST https://whatsbot.maike.my/bot12:abc.../setWebhook \
-H 'Content-Type: application/json' \
-d '{"url": "https://meu-servidor.com/whatsbot", "receive_groups": false}'
5. Regras e limites
- Não guardamos o conteúdo das conversas nem o telefone de quem escreveu. O painel mostra só metadados: hora, status HTTP do seu webhook, latência e erro, por 7 dias.
- Mensagens enviadas pelo próprio número (
fromMe) não chegam ao webhook, o que evita loop. - Sem retentativa de entrega. Se precisa de garantia, responda 200 rápido e processe depois do seu lado.
- Um número é compartilhado por várias pessoas; a entrega é separada pelo telefone de quem escreve.
- Canal pausado (
/pausar) não recebe nem envia.
6. Exemplo mínimo de webhook (PHP)
<?php
$in = json_decode(file_get_contents('php://input'), true);
if (($in['event'] ?? '') !== 'message') { http_response_code(200); exit; }
$texto = $in['message']['text'] ?? '';
header('Content-Type: application/json');
echo json_encode(['text' => "Você disse: $texto"]);