Python e WhatsApp: Automatize Mensagens com API
Aprenda a automatizar mensagens no WhatsApp com Python usando a API oficial da Meta. Envie textos, templates e receba webhooks com exemplos práticos.
Automatizar mensagens no WhatsApp é uma das demandas mais comuns em empresas brasileiras. Seja para notificações de pedido, confirmações de agendamento ou atendimento ao cliente, a WhatsApp Business API combinada com Python oferece uma solução robusta e escalável.
Neste artigo, vamos cobrir desde a configuração inicial na Meta até o envio de mensagens e recebimento de webhooks com código Python funcional.
WhatsApp Business API vs Bibliotecas Não-Oficiais
Antes de começar, é importante entender as opções disponíveis:
| Recurso | WhatsApp Cloud API (Meta) | pywhatkit | Twilio |
|---|---|---|---|
| Oficialidade | ✅ API oficial | ❌ Não-oficial | ✅ Intermediário oficial |
| Confiabilidade | Alta | Baixa (depende do WhatsApp Web) | Alta |
| Automação em produção | ✅ Sim | ❌ Não recomendado | ✅ Sim |
| Custo | 1.000 msgs/mês grátis | Grátis | Pago por mensagem |
| Suporte a templates | ✅ Sim | ❌ Não | ✅ Sim |
| Webhooks | ✅ Sim | ❌ Não | ✅ Sim |
A WhatsApp Cloud API da Meta é a escolha recomendada para qualquer projeto profissional. Bibliotecas como pywhatkit funcionam simulando interação com o WhatsApp Web e não são adequadas para produção.
Configuração Inicial na Meta
Para usar a API oficial, você precisa:
- Criar uma conta no Meta for Developers
- Criar um novo app do tipo Business
- Adicionar o produto WhatsApp ao app
- Na seção WhatsApp > API Setup, você terá:
- Um número de telefone de teste
- Um token de acesso temporário
- O Phone Number ID
Guarde essas informações — vamos usar nos exemplos a seguir.
Configurando o Ambiente Python
Crie um ambiente virtual e instale as dependências:
python -m venv venv
source venv/bin/activate # Linux/Mac
pip install requests flask python-dotenv
Crie um arquivo .env para suas credenciais:
WHATSAPP_TOKEN=seu_token_de_acesso
PHONE_NUMBER_ID=seu_phone_number_id
VERIFY_TOKEN=um_token_secreto_qualquer
Enviando Mensagens de Texto
O envio de mensagens usa a API REST da Meta. Veja como fazer com o módulo requests:
import os
import requests
from dotenv import load_dotenv
load_dotenv()
WHATSAPP_TOKEN = os.getenv("WHATSAPP_TOKEN")
PHONE_NUMBER_ID = os.getenv("PHONE_NUMBER_ID")
API_URL = f"https://graph.facebook.com/v19.0/{PHONE_NUMBER_ID}/messages"
def enviar_mensagem_texto(destinatario: str, texto: str) -> dict:
"""Envia uma mensagem de texto simples via WhatsApp."""
headers = {
"Authorization": f"Bearer {WHATSAPP_TOKEN}",
"Content-Type": "application/json",
}
payload = {
"messaging_product": "whatsapp",
"to": destinatario,
"type": "text",
"text": {"body": texto},
}
response = requests.post(API_URL, headers=headers, json=payload)
response.raise_for_status()
return response.json()
# Exemplo de uso
resultado = enviar_mensagem_texto(
destinatario="5511999999999",
texto="Olá! Seu pedido #1234 foi confirmado. 🎉"
)
print(resultado)
O número do destinatário deve incluir o código do país (55 para Brasil) sem o +. Para mais sobre consumo de APIs com Python, confira nosso artigo sobre consumo de APIs REST.
Enviando Templates de Mensagem
Templates são mensagens pré-aprovadas pela Meta — obrigatórios para iniciar conversas com usuários que não enviaram mensagem nas últimas 24 horas:
def enviar_template(destinatario: str, template_name: str, language: str = "pt_BR") -> dict:
"""Envia uma mensagem usando template aprovado."""
headers = {
"Authorization": f"Bearer {WHATSAPP_TOKEN}",
"Content-Type": "application/json",
}
payload = {
"messaging_product": "whatsapp",
"to": destinatario,
"type": "template",
"template": {
"name": template_name,
"language": {"code": language},
},
}
response = requests.post(API_URL, headers=headers, json=payload)
response.raise_for_status()
return response.json()
# Template padrão de teste da Meta
enviar_template("5511999999999", "hello_world")
Para templates com parâmetros dinâmicos (como nome do cliente ou número do pedido), adicione o campo components ao payload:
def enviar_template_com_parametros(
destinatario: str,
template_name: str,
parametros: list[str],
) -> dict:
"""Envia template com variáveis dinâmicas."""
headers = {
"Authorization": f"Bearer {WHATSAPP_TOKEN}",
"Content-Type": "application/json",
}
components = [
{
"type": "body",
"parameters": [
{"type": "text", "text": p} for p in parametros
],
}
]
payload = {
"messaging_product": "whatsapp",
"to": destinatario,
"type": "template",
"template": {
"name": template_name,
"language": {"code": "pt_BR"},
"components": components,
},
}
response = requests.post(API_URL, headers=headers, json=payload)
response.raise_for_status()
return response.json()
# Exemplo: template "confirmacao_pedido" com nome e número do pedido
enviar_template_com_parametros(
"5511999999999",
"confirmacao_pedido",
["Maria", "PED-2026-0331"]
)
Recebendo Webhooks com Flask
Para receber mensagens dos usuários, você precisa configurar um endpoint de webhook. A Meta envia notificações via HTTP POST:
from flask import Flask, request, jsonify
import os
from dotenv import load_dotenv
load_dotenv()
app = Flask(__name__)
VERIFY_TOKEN = os.getenv("VERIFY_TOKEN")
@app.route("/webhook", methods=["GET"])
def verificar_webhook():
"""Endpoint de verificação do webhook (challenge da Meta)."""
mode = request.args.get("hub.mode")
token = request.args.get("hub.verify_token")
challenge = request.args.get("hub.challenge")
if mode == "subscribe" and token == VERIFY_TOKEN:
return challenge, 200
return "Forbidden", 403
@app.route("/webhook", methods=["POST"])
def receber_mensagem():
"""Processa mensagens recebidas via webhook."""
data = request.get_json()
if data.get("object") == "whatsapp_business_account":
for entry in data.get("entry", []):
for change in entry.get("changes", []):
value = change.get("value", {})
messages = value.get("messages", [])
for msg in messages:
remetente = msg["from"]
tipo = msg["type"]
if tipo == "text":
texto = msg["text"]["body"]
print(f"Mensagem de {remetente}: {texto}")
# Responder automaticamente
enviar_mensagem_texto(
remetente,
f"Recebi sua mensagem: '{texto}'. Em breve um atendente responderá!"
)
return jsonify({"status": "ok"}), 200
if __name__ == "__main__":
app.run(port=5000, debug=True)
Se preferir usar FastAPI em vez de Flask, confira nosso guia completo de FastAPI — a lógica do webhook é muito semelhante, mas com tipagem nativa e async. Também temos um artigo sobre criação de bots de Telegram que usa uma arquitetura parecida.
Versão Assíncrona com HTTPX
Para aplicações de alto volume, usar uma biblioteca HTTP assíncrona como HTTPX melhora significativamente a performance:
import httpx
import asyncio
async def enviar_mensagens_em_lote(destinatarios: list[str], texto: str):
"""Envia mensagens para múltiplos destinatários de forma assíncrona."""
headers = {
"Authorization": f"Bearer {WHATSAPP_TOKEN}",
"Content-Type": "application/json",
}
async with httpx.AsyncClient() as client:
tarefas = []
for numero in destinatarios:
payload = {
"messaging_product": "whatsapp",
"to": numero,
"type": "text",
"text": {"body": texto},
}
tarefas.append(client.post(API_URL, headers=headers, json=payload))
respostas = await asyncio.gather(*tarefas)
for resp in respostas:
print(f"Status: {resp.status_code}")
# Executar
asyncio.run(enviar_mensagens_em_lote(
["5511999999999", "5521888888888"],
"Promoção especial para você! 🔥"
))
Para entender melhor programação assíncrona em Python, leia nosso guia sobre async/await.
Rate Limits e Boas Práticas
A API da Meta tem limites que você precisa respeitar:
- Tier padrão: 250 conversas iniciadas por negócio em 24h
- Mensagens por segundo: até 80 msg/s (varia por tier)
- Janela de 24h: após a última mensagem do usuário, você pode enviar mensagens de formato livre por 24h; depois, apenas templates
Boas práticas para evitar bloqueios:
import time
from functools import wraps
def rate_limiter(max_por_segundo: int = 10):
"""Decorator simples para limitar taxa de envio."""
intervalo = 1.0 / max_por_segundo
def decorator(func):
ultimo_envio = [0.0]
@wraps(func)
def wrapper(*args, **kwargs):
agora = time.time()
espera = intervalo - (agora - ultimo_envio[0])
if espera > 0:
time.sleep(espera)
ultimo_envio[0] = time.time()
return func(*args, **kwargs)
return wrapper
return decorator
@rate_limiter(max_por_segundo=10)
def enviar_com_limite(destinatario: str, texto: str):
"""Envia mensagem respeitando limite de taxa."""
return enviar_mensagem_texto(destinatario, texto)
Tratamento de Erros
Sempre trate erros da API adequadamente, incluindo retentativas para falhas temporárias:
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
def criar_sessao_com_retry() -> requests.Session:
"""Cria sessão HTTP com retentativa automática."""
session = requests.Session()
retry = Retry(
total=3,
backoff_factor=1,
status_forcelist=[429, 500, 502, 503, 504],
)
adapter = HTTPAdapter(max_retries=retry)
session.mount("https://", adapter)
return session
session = criar_sessao_com_retry()
def enviar_mensagem_robusta(destinatario: str, texto: str) -> dict | None:
"""Envia mensagem com tratamento de erros e retentativas."""
headers = {
"Authorization": f"Bearer {WHATSAPP_TOKEN}",
"Content-Type": "application/json",
}
payload = {
"messaging_product": "whatsapp",
"to": destinatario,
"type": "text",
"text": {"body": texto},
}
try:
response = session.post(API_URL, headers=headers, json=payload)
response.raise_for_status()
return response.json()
except requests.exceptions.HTTPError as e:
print(f"Erro HTTP: {e.response.status_code} - {e.response.text}")
except requests.exceptions.ConnectionError:
print("Erro de conexão com a API da Meta")
return None
Para mais sobre tratamento de erros em Python, veja nosso artigo sobre tratamento de exceções e trabalhando com JSON.
Considerações Éticas e Termos de Uso
A Meta impõe regras rígidas para uso da API:
- Nunca envie spam — mensagens não solicitadas podem banir seu número permanentemente
- Obtenha opt-in explícito dos usuários antes de enviar mensagens
- Respeite a LGPD — informe como os dados serão usados e permita opt-out
- Não use para mensagens de marketing sem consentimento prévio
- Templates precisam de aprovação — envie para revisão com antecedência
Alternativas: Twilio e pywhatkit
Se a API oficial da Meta não se encaixar no seu caso, considere:
- Twilio: intermediário oficial com SDK Python (
twilio), mais fácil de configurar mas com custo por mensagem. Ideal para empresas que já usam Twilio para SMS - pywhatkit: biblioteca que automatiza o WhatsApp Web. Funciona para projetos pessoais e testes, mas não é confiável para produção — depende do navegador aberto e pode quebrar com atualizações do WhatsApp
Conclusão
A integração Python + WhatsApp Business API é uma ferramenta poderosa para automação de comunicação no Brasil, onde o WhatsApp domina com mais de 120 milhões de usuários ativos. Com os exemplos deste artigo, você tem uma base sólida para construir desde notificações simples até sistemas de atendimento automatizado completos.
🐍 Se você trabalha com automação de APIs, confira também nossos artigos sobre WebSockets e deploy de aplicações Python. Para desenvolvedores que usam Go para microsserviços complementares, o golang.com.br tem conteúdo sobre APIs em Go.
Equipe python.dev.br
Contribuidor do Python Brasil — Aprenda Python em Português