Cara, esse é o tipo de tutorial que eu queria ter encontrado pronto há 2 anos. Hoje (1 de maio de 2026) com o CLI oficial da Meta lançado em 29/04, montar um workflow desse virou trivial. Tipo "1 hora de trabalho" trivial.
O que você vai construir aqui: um sistema que toda manhã às 8h dispara mensagem no seu WhatsApp com performance da sua conta Meta Ads do dia anterior. Spend, leads, CPL, alertas se algo deu errado, próxima ação sugerida. Tudo automático, sem você precisar abrir o Ads Manager.
Esse é um dos workflows que rodamos nas 27 contas de cliente da Café Online. Funciona, é robusto, custa quase nada. Vou abrir o código completo.
Pra quem é esse workflow
Você se encaixa em pelo menos um desses perfis:
- Dono de pequeno negócio que faz próprio tráfego e quer receber resumo sem abrir o Ads Manager toda manhã
- Freela júnior que gerencia 3-5 contas e quer mostrar profissionalismo automatizando o reporting
- Gestor de tráfego intermediário que quer parar de gastar 30 min/dia gerando relatório manualmente
- Equipe de marketing in-house que precisa que CMO/CEO receba número diário sem ficar pedindo
Se você gerencia 20+ contas, esse workflow ainda funciona mas você vai querer adaptar pra agregação multi-conta — e aí o artigo sobre gerenciar 100+ contas com Claude Code é melhor referência.
O que você vai receber no WhatsApp todo dia
Essa é a mensagem real que sai de um dos clientes nossos:
📊 RELATÓRIO MIRA AGENCY — 30/04/2026
Spend ontem: R$ 287,40
Spend média (7 dias): R$ 264,90 (+8% acima)
Impressões: 14.503
Clicks: 142
CTR: 0,98% (média 7d: 0,89%)
CPC: R$ 2,02
Conversões:
- Leads pixel: 4
- Conversas WhatsApp: 11
- Total leads: 15
- CPL real: R$ 19,16
Top campanha:
"Casamento Goiânia 2026" — 9 leads, CPL R$ 13,40
⚠️ ALERTAS:
- Campanha "Bodas Anápolis" sem leads há 2 dias
- Frequência da "Engajamento Goiânia" subiu pra 3,8 (criativo cansado?)
Próxima ação sugerida:
1. Pausar campanha "Bodas Anápolis" e diagnosticar
2. Subir 2 criativos novos pra "Engajamento Goiânia"
3. Considerar aumentar budget da "Casamento Goiânia 2026" (ROI 3x)
Tudo isso chega às 8h da manhã, todo dia útil, sem você fazer nada. E o melhor: não é resumo genérico. Cada campo é dado real puxado da Meta API.
Stack do workflow (4 componentes)
| Componente | Função | Custo |
|---|---|---|
CLI meta-ads | Puxa dados da Meta API | Grátis |
| Python 3.12+ | Roda o script | Grátis |
| Z-API | Envia mensagem WhatsApp | R$ 99/mês |
| Cron (no VPS) ou GitHub Actions (gratuito) | Roda script todo dia 8h | R$ 30/mês ou grátis |
Total: R$ 30 a R$ 130/mês dependendo se você usa VPS ou GitHub Actions. Se já tem Z-API pra outro propósito (tipo agente IA WhatsApp), custo marginal é R$ 0-30.
Passo 1: Setup do CLI meta-ads + token
Se ainda não tem CLI instalado e token gerado, segue o tutorial completo de Claude Code + Meta Ads. Vou só listar os comandos essenciais aqui:
# Instalar CLI
uv tool install meta-ads --python 3.12
# Configurar token (gerado no developers.facebook.com)
export ACCESS_TOKEN=EAA...seu_token_aqui
# Listar contas pra pegar o ID
meta -o json ads adaccount list
# Anota o ID da conta (começa com act_) — vai usar no script
Anota o act_XXXXXXXXX da sua conta. Vai precisar no passo 3.
Passo 2: Setup do Z-API
Z-API é o serviço que vai enviar mensagem WhatsApp pelo seu número. Se ainda não tem:
- Cria conta em z-api.io
- Cria uma instância (escolhe plano — o mais barato R$ 99/mês serve)
- Conecta a instância escaneando QR Code com seu WhatsApp Business (ou pessoal — funciona dos 2)
- Anota: Instance ID, Token, Client-Token (3 valores diferentes)
O número que você vai escanear pra conectar o Z-API é o número que VAI ENVIAR a mensagem. O número pra onde você quer receber é separado (vai no script).
Outras opções: Twilio (mais caro, melhor pra escala internacional), Gupshup (ok mas API confusa). Recomendo Z-API pra mercado brasileiro pela simplicidade.
Quer que a gente implemente isso pra você?
Em 1 dia útil deixamos o relatório diário rodando no seu WhatsApp. Setup completo + 30 dias de suporte. Conversa rápida.
Solicitar ImplementaçãoPasso 3: Script Python completo (copia e cola)
Salva isso como relatorio_diario.py. Tem ~70 linhas, comentado, pronto pra rodar:
# relatorio_diario.py
import os
import json
import subprocess
import requests
from datetime import datetime
# CONFIGURAÇÃO — TROCAR ESSAS 5 VARIÁVEIS
ACCESS_TOKEN = os.getenv("ACCESS_TOKEN") # Token Marketing API
ACCOUNT_ID = "act_XXXXXXXXXXXXXX" # ID da conta
ZAPI_INSTANCE = "SUA_INSTANCE_ID"
ZAPI_TOKEN = "SEU_TOKEN"
ZAPI_CLIENT_TOKEN = "SEU_CLIENT_TOKEN"
NUMERO_WHATSAPP = "5562999999999" # Pra onde enviar
def puxar_insights():
"""Roda CLI meta-ads e retorna dados parseados"""
cmd = [
"meta", "-o", "json", "ads", "insights", "get",
"--account-id", ACCOUNT_ID,
"--date-preset", "yesterday",
"--fields", "spend,impressions,clicks,ctr,cpc,reach,actions"
]
result = subprocess.run(cmd, capture_output=True, text=True)
return json.loads(result.stdout)
def puxar_media_7d():
"""Média dos últimos 7 dias pra comparar"""
cmd = [
"meta", "-o", "json", "ads", "insights", "get",
"--account-id", ACCOUNT_ID,
"--date-preset", "last_7d",
"--fields", "spend"
]
result = subprocess.run(cmd, capture_output=True, text=True)
data = json.loads(result.stdout)
return float(data[0]["spend"]) / 7 if data else 0
def montar_mensagem(insights, media_7d):
"""Formata mensagem WhatsApp"""
d = insights[0] if insights else {}
spend = float(d.get("spend", 0))
var = ((spend - media_7d) / media_7d * 100) if media_7d else 0
# Conversões (ajustar action_type conforme caso)
leads_pixel = 0
conversas = 0
for action in d.get("actions", []):
if action["action_type"] == "lead":
leads_pixel = int(action["value"])
elif "messaging_conversation" in action["action_type"]:
conversas = int(action["value"])
total_leads = leads_pixel + conversas
cpl = spend / total_leads if total_leads else 0
msg = f"""📊 RELATÓRIO META ADS — {datetime.now().strftime('%d/%m/%Y')}
Spend ontem: R$ {spend:.2f}
Spend média 7d: R$ {media_7d:.2f} ({var:+.0f}%)
Impressões: {int(d.get('impressions', 0)):,}
Clicks: {int(d.get('clicks', 0))}
CTR: {float(d.get('ctr', 0)):.2f}%
CPC: R$ {float(d.get('cpc', 0)):.2f}
Conversões:
- Leads pixel: {leads_pixel}
- Conversas WhatsApp: {conversas}
- Total: {total_leads}
- CPL: R$ {cpl:.2f}
Próximas ações: revisar performance hoje pela manhã."""
return msg.replace(',', '.') # Formato BR
def enviar_whatsapp(mensagem):
"""Envia via Z-API"""
url = f"https://api.z-api.io/instances/{ZAPI_INSTANCE}/token/{ZAPI_TOKEN}/send-text"
headers = {
"Client-Token": ZAPI_CLIENT_TOKEN,
"Content-Type": "application/json; charset=utf-8"
}
payload = {"phone": NUMERO_WHATSAPP, "message": mensagem}
r = requests.post(url, headers=headers, json=payload, timeout=30)
print(f"Status envio: {r.status_code}")
return r.status_code == 200
if __name__ == "__main__":
insights = puxar_insights()
media = puxar_media_7d()
msg = montar_mensagem(insights, media)
print(msg)
enviar_whatsapp(msg)
Só trocar as 5 variáveis no topo. Rodar pra testar:
python3 relatorio_diario.py
Se chegou no WhatsApp, deu certo. Se não, vê o troubleshooting mais embaixo.
Passo 4: Configurar cron pra rodar todo dia 8h
Numa VPS (ou no seu próprio computador, se ele fica ligado):
crontab -e
Adiciona essa linha:
0 8 * * 1-5 cd /caminho/do/script && /usr/bin/python3 relatorio_diario.py >> /var/log/relatorio.log 2>&1
Significado: às 8h da manhã, segunda a sexta (1-5), entra no diretório do script, roda Python, redireciona output pra arquivo de log.
Se quer todo dia inclusive fim de semana: troca 1-5 por *.
Se prefere usar GitHub Actions (gratuito), cria .github/workflows/relatorio.yml:
name: Relatório Diário Meta Ads
on:
schedule:
- cron: '0 11 * * 1-5' # 8h Brasília = 11h UTC
workflow_dispatch:
jobs:
run:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with: { python-version: '3.12' }
- run: pip install meta-ads requests
- run: python relatorio_diario.py
env:
ACCESS_TOKEN: ${{ secrets.META_ACCESS_TOKEN }}
GitHub Actions é grátis pra repos públicos e tem 2000 minutos/mês free pra privados — mais que suficiente.
Leia também: Automação Python: guia completo 2025 — se quiser aprofundar em automações Python como essa.
Bônus: kill criteria automatizado no mesmo script
Quer ir além do "só ler"? Adiciona kill criteria. O script aplica regras e dispara alerta urgente se algo crítico aconteceu.
Adiciona essa função no script:
def aplicar_kill_criteria(insights, media_7d):
"""Retorna lista de alertas baseados em regras"""
d = insights[0] if insights else {}
spend = float(d.get("spend", 0))
ctr = float(d.get("ctr", 0))
leads_pixel = 0
for action in d.get("actions", []):
if action["action_type"] == "lead":
leads_pixel = int(action["value"])
cpl = spend / leads_pixel if leads_pixel else float('inf')
alertas = []
# Regra 1: CPL acima de 2x meta
META_CPL = 30 # ajusta pra sua meta real
if cpl > META_CPL * 2:
alertas.append(f"🚨 URGENTE: CPL R$ {cpl:.2f} (2x acima da meta R$ {META_CPL})")
# Regra 2: 0 leads em dia normal
if leads_pixel == 0 and spend > 50:
alertas.append(f"⚠️ ALERTA: 0 leads ontem com spend de R$ {spend:.2f}")
# Regra 3: CTR muito baixo
if ctr < 0.5:
alertas.append(f"⚠️ CTR caiu pra {ctr:.2f}% (abaixo de 0,5%)")
# Regra 4: Spend explodiu
if spend > media_7d * 1.5:
alertas.append(f"⚠️ Spend ontem 50% acima da média (overdelivery?)")
return alertas
E na função montar_mensagem, adiciona os alertas:
alertas = aplicar_kill_criteria(insights, media_7d)
if alertas:
msg += "
⚠️ ALERTAS:
" + "
".join(alertas)
Pronto. Agora o relatório vem com alertas se algo crítico aconteceu. Se quiser ir ainda mais longe, adiciona uma função que pausa a campanha automaticamente (mas recomendo ter humano no loop antes de fazer isso).
Setup completo + customização pro seu negócio.
Implemento esse workflow do zero ou customizo o que você já tem. Inclui kill criteria, multi-conta, dashboard e suporte por 30 dias. Conversa pra ver se cabe.
Falar com FelipeTroubleshooting comum
Erro: "command not found: meta"
O CLI não tá no PATH. Adiciona export PATH="$HOME/.local/bin:$PATH" no ~/.zshrc ou ~/.bashrc e reinicia terminal.
Erro: "Invalid OAuth access token"
Token errado ou sem permissão. Confere: começa com EAA? Tem permissões ads_read e ads_management? System User com role admin no BM?
Mensagem não chega no WhatsApp
Confere: instância Z-API conectada (vê no painel)? Número no formato 5562999999999 sem espaço/hífen? Token e Client-Token corretos? Status de retorno é 200?
Cron roda mas não envia
Cron não tem as variáveis de ambiente. Adiciona export ACCESS_TOKEN=... no início do comando do cron, ou usa python-dotenv carregando de um .env. Se quer aprender mais sobre essa parte, vê o guia de automação com IA que cobre integrações similares.
Insights vem zerado
Conta talvez não teve spend ontem (ad pausado?). Testa com --date-preset last_7d pra ver se vem dado. Se vier, é só ajustar a lógica pra dia anterior.
Conclusão: 1 hora pra economizar 5h por semana
Cara, esse workflow leva no máximo 1 hora pra montar do zero. E economiza facilmente 5 horas por semana de quem hoje gera relatório manualmente. ROI: 5x na primeira semana.
O que era impossível há 6 meses (precisa OAuth, browser, server-side complicado) virou trivial com o CLI oficial da Meta. A janela de oportunidade tá aberta — quem implementar agora ganha vantagem grande sobre quem demorar.
Se travar em qualquer parte, me chama no WhatsApp. Já implementei isso em 27 contas, conheço cada erro possível. E se quiser ir além, vê também a stack completa de tráfego pago + agente IA WhatsApp — que combina esse workflow com um bot que atende os leads que chegam.
Perguntas Frequentes (FAQ)
Preciso saber programar pra montar esse workflow? +
Quanto custa pra rodar? +
Posso receber em mais de um número WhatsApp? +
Funciona pra receber também resumo semanal e mensal? +
E se a Z-API cair? Perco o relatório? +
Fundador da Agência Café Online. Especialista em agentes de IA, automação empresarial e marketing digital. Ver perfil completo