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.

7 min de leitura Equipe python.dev.br

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:

RecursoWhatsApp Cloud API (Meta)pywhatkitTwilio
Oficialidade✅ API oficial❌ Não-oficial✅ Intermediário oficial
ConfiabilidadeAltaBaixa (depende do WhatsApp Web)Alta
Automação em produção✅ Sim❌ Não recomendado✅ Sim
Custo1.000 msgs/mês grátisGrátisPago 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:

  1. Criar uma conta no Meta for Developers
  2. Criar um novo app do tipo Business
  3. Adicionar o produto WhatsApp ao app
  4. 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.

E

Equipe python.dev.br

Contribuidor do Python Brasil — Aprenda Python em Português