name: comercialrs-meta-webhook-debug
description: Debug do webhook bidirecional WhatsApp do ComercialRS — parser de respostas, correlação com tasks, Send API confirmation, Supabase Realtime
ComercialRS Meta Webhook Bidirecional
Problema
Corretores recebem notificações de reunião via WhatsApp (Meta Business API) e respondem "iniciada", "concluida" ou "remarketing". O sistema deve parsear a resposta e atualizar tasks.status no Kanban em tempo real.
Arquitetura
`
WhatsApp → Meta Webhook POST → Nginx :443 → Python :8083 → Postgres
↓
Send API (confirmação)
`
- - Nginx (
comercialrs.rochasalesseguros.com.br): proxy/meta-webhook/→127.0.0.1:8083 - - Python server:
/var/www/comercialrs/data/meta_webhook_vps.py(porta 8083) - - DB: Postgres Docker
172.23.0.2:5432(não passa pelo Kong) - -
/var/www/comercialrs/data/meta_webhook_vps.log— stdout do processo (print statements) - -
/var/log/meta_webhook.log— logging Python (INFO/ERROR com timestamps) - -
task_alerts.py(cron 5min na VPS):send_30min_alerts()esend_overdue_alerts() - -
dispatch-automation(Edge Function no Supabase):overdue_alertscase - - App ID: 3014923135375381
- - Phone ID: 812251211981254 (NÃO 578716225306497 que era do App N8N.RS)
- - Verify Token: 1c526598c56179f772be896d233badab
- - Webhook URL: https://comercialrs.rochasalesseguros.com.br/meta-webhook/
Tabelas
`sql
message_log: id, meta_message_id UNIQUE, task_id, responsible_id, template_name, sent_at, phone, status
message_replies: id, message_log_id, meta_message_id, from_phone, response_text, parsed_status, task_id, processed_at
incoming_messages: id, message_id UNIQUE, from_number, timestamp, msg_type, body, source
tasks: last_meta_message_id TEXT (para correlação)
`
Colunas em auth.automations_config
meta_access_token, meta_phone_number_id (812251211981254), meta_webhook_verify_token, meta_business_account_id
Parser de resposta (case insensitive, com/sem ponto)
`
iniciada → in_progress
concluida/concluída → completed
remarketing → remarketing
`
Correlação
Meta envia context.message_id na resposta → é o mesmo meta_message_id gravado ao enviar. Lookup direto: message.context.id → message_log.meta_message_id → task_id
Confirmação ao corretor
Após update: POST para https://graph.facebook.com/v21.0/{phone_id}/messages com token do banco.
Investigação de problemas (técnica de debug)
Leitura de logs Python na VPS
Dois arquivos de log coexistem:
grep direto no segundo retorna "binary file matches". Use strings para decodificar:
`bash
strings /var/log/meta_webhook.log | grep -E '\[button\]|\[update\]|Iniciada'
strings /var/log/meta_webhook.log | grep -E 'task_id_aqui|task_id_b'
`
Verificar se botão realmente atualizou a task
1. Identificar clique no log: grep "button.*Iniciada" /var/log/meta_webhook.log
2. Confirmar no DB:
`python
Direct psycopg2 from VPS → Supabase Cloud
import psycopg2
conn = psycopg2.connect(
host='db.dauftiqcvgaydddoxqhh.supabase.co',
port=5432, dbname='postgres',
user='postgres', password='tSm?p8n57f+TX5n',
options='-csearch_path=public'
)
cur.execute("SELECT id, status, due_date::text, title FROM tasks WHERE id = %s", (task_id,))
`
3. Verificar alertas enviados após o clique:
`sql
SELECT alert_type, sent_at::text FROM task_alerts WHERE task_id = %s ORDER BY sent_at ASC;
`
Verificar duplicação de alertas (task_alerts vs button status)
Problema comum: vendedor clica "Iniciada", task vira in_progress, mas alertas continuam vindo.
Fontes de alerta a verificar:
Filtro correto: WHERE t.status = 'todo' — in_progress e completed devem ser excluídos.
Problemas known
1. dispatch-automation NÃO salva meta_message_id no message_log — replies não são correlacionadas. Bug crítico a corrigir no fluxo de envio.
2. Supabase Realtime WebSocket retorna HTTP 500 — Cloudflare/IronServer bloqueia. Kanban precisa de polling fallback (15s).
3. RLS em auth.tasks — SELECT policies ausentes (authenticated_select_tasks, anon_select_tasks) bloqueiam PostgREST e realtime.
4. task_alerts envia para in_progress — send_overdue_alerts() não filtrava status. Corrigido: WHERE t.status = 'todo' em ambas funções.
Fixes feitos
`sql
ALTER PUBLICATION supabase_realtime ADD TABLE tasks;
CREATE POLICY authenticated_select_tasks ON auth.tasks FOR SELECT USING (true);
CREATE POLICY anon_select_tasks ON auth.tasks FOR SELECT USING (true);
`