Como Integrar WhatsApp Business API: Guia Tecnico Completo
Tutorial passo a passo para integrar WhatsApp Business API no seu sistema. Requisitos, configuracao, webhooks e exemplos de codigo.
Integrar o WhatsApp Business API parece complicado, mas seguindo os passos certos voce consegue em algumas horas. Este guia cobre tudo: desde a aprovacao da Meta ate o primeiro envio de mensagem.
Requisitos Antes de Comecar
Conta Business Verificada
Voce precisa de:
- Conta no Facebook Business Manager
- Empresa verificada (CNPJ ou equivalente)
- Numero de telefone dedicado (nao pode estar em outro WhatsApp)
- Politica de privacidade publicada no seu site
Infraestrutura Minima
| Componente | Requisito |
|---|---|
| Servidor | HTTPS obrigatorio |
| Webhook | Endpoint publico acessivel |
| SSL | Certificado valido (Let’s Encrypt funciona) |
| IP | Fixo recomendado |
Provedores de Solucao (BSP)
Voce pode usar a API diretamente (Cloud API) ou via provedores:
API Direta (Cloud API):
- Gratis ate 1000 conversas/mes
- Sem custo de setup
- Mais controle tecnico
Via BSP (Twilio, Vonage, etc):
- Setup mais rapido
- Suporte incluso
- Custo por mensagem maior
Para este guia, usaremos a Cloud API direta.
Passo 1: Configurar Meta Business
1.1 Criar App no Meta Developers
- Acesse developers.facebook.com
- Crie novo app tipo “Business”
- Adicione o produto “WhatsApp”
- Anote o App ID e App Secret
1.2 Configurar Numero
Na secao WhatsApp > Getting Started:
- Adicione numero de telefone
- Verifique via SMS ou ligacao
- Gere token de acesso temporario (para testes)
Token permanente: Para producao, crie um System User no Business Manager e gere token permanente.
1.3 Configurar Webhook
Voce precisa de um endpoint que:
- Aceite GET (verificacao)
- Aceite POST (mensagens recebidas)
- Retorne 200 OK em ate 20 segundos
Passo 2: Criar Endpoint de Webhook
Exemplo em Node.js (Express)
const express = require('express');
const app = express();
app.use(express.json());
const VERIFY_TOKEN = 'seu_token_secreto';
// Verificacao do webhook (GET)
app.get('/webhook', (req, res) => {
const mode = req.query['hub.mode'];
const token = req.query['hub.verify_token'];
const challenge = req.query['hub.challenge'];
if (mode === 'subscribe' && token === VERIFY_TOKEN) {
console.log('Webhook verificado');
res.status(200).send(challenge);
} else {
res.sendStatus(403);
}
});
// Receber mensagens (POST)
app.post('/webhook', (req, res) => {
const body = req.body;
if (body.object === 'whatsapp_business_account') {
body.entry?.forEach(entry => {
entry.changes?.forEach(change => {
if (change.field === 'messages') {
const message = change.value.messages?.[0];
if (message) {
processMessage(message, change.value.metadata);
}
}
});
});
res.sendStatus(200);
} else {
res.sendStatus(404);
}
});
function processMessage(message, metadata) {
const from = message.from;
const type = message.type;
const phoneNumberId = metadata.phone_number_id;
console.log(`Mensagem de ${from}: ${JSON.stringify(message)}`);
// Aqui voce processa a mensagem
if (type === 'text') {
const text = message.text.body;
// Responder automaticamente
sendMessage(phoneNumberId, from, `Recebi: ${text}`);
}
}
app.listen(3000, () => console.log('Servidor rodando'));
Exemplo em PHP (Laravel)
// routes/api.php
Route::get('/webhook', [WebhookController::class, 'verify']);
Route::post('/webhook', [WebhookController::class, 'handle']);
// WebhookController.php
class WebhookController extends Controller
{
private $verifyToken = 'seu_token_secreto';
public function verify(Request $request)
{
$mode = $request->query('hub_mode');
$token = $request->query('hub_verify_token');
$challenge = $request->query('hub_challenge');
if ($mode === 'subscribe' && $token === $this->verifyToken) {
return response($challenge, 200);
}
return response('Forbidden', 403);
}
public function handle(Request $request)
{
$body = $request->all();
if ($body['object'] === 'whatsapp_business_account') {
foreach ($body['entry'] as $entry) {
foreach ($entry['changes'] as $change) {
if ($change['field'] === 'messages') {
$this->processMessages($change['value']);
}
}
}
return response('OK', 200);
}
return response('Not Found', 404);
}
private function processMessages($value)
{
$messages = $value['messages'] ?? [];
$metadata = $value['metadata'];
foreach ($messages as $message) {
Log::info('Mensagem recebida', $message);
// Processar mensagem
}
}
}
Exemplo em Python (FastAPI)
from fastapi import FastAPI, Request, Response
import httpx
app = FastAPI()
VERIFY_TOKEN = "seu_token_secreto"
@app.get("/webhook")
async def verify_webhook(request: Request):
mode = request.query_params.get("hub.mode")
token = request.query_params.get("hub.verify_token")
challenge = request.query_params.get("hub.challenge")
if mode == "subscribe" and token == VERIFY_TOKEN:
return Response(content=challenge, status_code=200)
return Response(status_code=403)
@app.post("/webhook")
async def handle_webhook(request: Request):
body = await request.json()
if body.get("object") == "whatsapp_business_account":
for entry in body.get("entry", []):
for change in entry.get("changes", []):
if change.get("field") == "messages":
await process_messages(change.get("value", {}))
return Response(status_code=200)
return Response(status_code=404)
async def process_messages(value: dict):
messages = value.get("messages", [])
metadata = value.get("metadata", {})
for message in messages:
print(f"Mensagem: {message}")
# Processar aqui
Passo 3: Enviar Mensagens
Funcao de Envio (Node.js)
const axios = require('axios');
const WHATSAPP_TOKEN = 'seu_token_permanente';
const API_VERSION = 'v18.0';
async function sendMessage(phoneNumberId, to, text) {
const url = `https://graph.facebook.com/${API_VERSION}/${phoneNumberId}/messages`;
try {
const response = await axios.post(url, {
messaging_product: 'whatsapp',
to: to,
type: 'text',
text: { body: text }
}, {
headers: {
'Authorization': `Bearer ${WHATSAPP_TOKEN}`,
'Content-Type': 'application/json'
}
});
console.log('Mensagem enviada:', response.data);
return response.data;
} catch (error) {
console.error('Erro ao enviar:', error.response?.data);
throw error;
}
}
// Enviar mensagem com botoes
async function sendButtonMessage(phoneNumberId, to, bodyText, buttons) {
const url = `https://graph.facebook.com/${API_VERSION}/${phoneNumberId}/messages`;
const response = await axios.post(url, {
messaging_product: 'whatsapp',
to: to,
type: 'interactive',
interactive: {
type: 'button',
body: { text: bodyText },
action: {
buttons: buttons.map((btn, i) => ({
type: 'reply',
reply: {
id: `btn_${i}`,
title: btn
}
}))
}
}
}, {
headers: {
'Authorization': `Bearer ${WHATSAPP_TOKEN}`,
'Content-Type': 'application/json'
}
});
return response.data;
}
// Uso
sendButtonMessage(phoneNumberId, '5511999999999',
'Como posso ajudar?',
['Preco', 'Horario', 'Endereco']
);
Enviar Midia
// Enviar imagem
async function sendImage(phoneNumberId, to, imageUrl, caption) {
const url = `https://graph.facebook.com/${API_VERSION}/${phoneNumberId}/messages`;
return axios.post(url, {
messaging_product: 'whatsapp',
to: to,
type: 'image',
image: {
link: imageUrl,
caption: caption
}
}, {
headers: {
'Authorization': `Bearer ${WHATSAPP_TOKEN}`,
'Content-Type': 'application/json'
}
});
}
// Enviar documento
async function sendDocument(phoneNumberId, to, docUrl, filename) {
const url = `https://graph.facebook.com/${API_VERSION}/${phoneNumberId}/messages`;
return axios.post(url, {
messaging_product: 'whatsapp',
to: to,
type: 'document',
document: {
link: docUrl,
filename: filename
}
}, {
headers: {
'Authorization': `Bearer ${WHATSAPP_TOKEN}`,
'Content-Type': 'application/json'
}
});
}
Passo 4: Templates de Mensagem
Para iniciar conversas (mensagens fora da janela de 24h), voce precisa de templates aprovados.
Criar Template
- Va em WhatsApp Manager > Message Templates
- Crie novo template
- Escolha categoria (Marketing, Utility, Authentication)
- Defina idioma e conteudo
- Aguarde aprovacao (algumas horas a 2 dias)
Exemplo de Template
Nome: pedido_confirmado Categoria: Utility Conteudo:
Ola {{1}}!
Seu pedido #{{2}} foi confirmado.
Previsao de entrega: {{3}}
Acompanhe pelo link: {{4}}
Enviar Template
async function sendTemplate(phoneNumberId, to, templateName, params) {
const url = `https://graph.facebook.com/${API_VERSION}/${phoneNumberId}/messages`;
return axios.post(url, {
messaging_product: 'whatsapp',
to: to,
type: 'template',
template: {
name: templateName,
language: { code: 'pt_BR' },
components: [{
type: 'body',
parameters: params.map(p => ({
type: 'text',
text: p
}))
}]
}
}, {
headers: {
'Authorization': `Bearer ${WHATSAPP_TOKEN}`,
'Content-Type': 'application/json'
}
});
}
// Uso
sendTemplate(phoneNumberId, '5511999999999', 'pedido_confirmado', [
'Joao',
'12345',
'15/12/2025',
'https://seusite.com/pedido/12345'
]);
Passo 5: Tratamento de Erros
Erros Comuns
| Codigo | Significado | Solucao |
|---|---|---|
| 131030 | Numero nao existe no WhatsApp | Validar numero antes |
| 131047 | Mais de 24h sem resposta do usuario | Use template |
| 131051 | Mensagem nao entregue | Numero bloqueou ou desinstalou |
| 131026 | Limite de taxa excedido | Implemente rate limiting |
| 132015 | Template nao existe | Verifique nome e idioma |
Rate Limiting
Limites da API:
- 80 mensagens/segundo (Business)
- 1000 conversas/mes (gratis)
- 250 requisicoes/hora (por numero)
const Bottleneck = require('bottleneck');
const limiter = new Bottleneck({
maxConcurrent: 10,
minTime: 50 // 20 req/segundo
});
async function sendMessageRateLimited(phoneNumberId, to, text) {
return limiter.schedule(() => sendMessage(phoneNumberId, to, text));
}
Passo 6: Estrutura de Projeto Recomendada
whatsapp-bot/
├── src/
│ ├── config/
│ │ └── whatsapp.js # Credenciais
│ ├── handlers/
│ │ ├── text.js # Mensagens de texto
│ │ ├── button.js # Cliques em botoes
│ │ └── media.js # Imagens, docs
│ ├── services/
│ │ ├── whatsapp.js # API wrapper
│ │ └── database.js # Persistencia
│ ├── utils/
│ │ └── validator.js # Validacoes
│ └── index.js # Entry point
├── .env
└── package.json
Arquivo de Configuracao
// config/whatsapp.js
module.exports = {
token: process.env.WHATSAPP_TOKEN,
verifyToken: process.env.VERIFY_TOKEN,
phoneNumberId: process.env.PHONE_NUMBER_ID,
apiVersion: 'v18.0',
baseUrl: 'https://graph.facebook.com'
};
Checklist de Producao
Antes de ir pra producao:
- Token permanente (nao temporario)
- HTTPS configurado
- Webhook respondendo em menos de 20s
- Rate limiting implementado
- Logs de erros configurados
- Templates aprovados
- Numero verificado
- Politica de privacidade publicada
- Backup de mensagens (se necessario)
- Monitoramento de uptime
Proximos Passos
Com a integracao basica funcionando, voce pode:
- Adicionar persistencia (salvar conversas)
- Implementar fluxos de conversa (estado)
- Integrar com seu sistema (CRM, ERP)
- Adicionar processamento de linguagem natural
A documentacao oficial da Meta tem exemplos adicionais: developers.facebook.com/docs/whatsapp
Sakaguchi IA - Inteligencia Artificial para Empresas Brasileiras