""" Diagnostico: contactos de Chatwoot que NO tienen mensaje de campaña (no entran por el query de Postgre de la cartera). Muestra: telefono, fecha del contacto (contacts.created_at), fecha del primer y ultimo mensaje (si tiene), y si tiene algun mensaje. """ import os import psycopg2 from dotenv import load_dotenv import data_manager_v2 as dm # para reutilizar las campañas (frases de campaña) load_dotenv() PG_HOST = os.getenv("PG_HOST") PG_DB = os.getenv("PG_DATABASE") or os.getenv("PG_DB") PG_USER = os.getenv("PG_USER") PG_PASS = os.getenv("PG_PASSWORD") or os.getenv("PG_PASS") PG_PORT = os.getenv("PG_PORT", "5432") # Frases de campaña (mismas que usa la cartera / dashboard) FRASES = [c[0] for c in dm._campanias_supabase()] conn = psycopg2.connect(host=PG_HOST, dbname=PG_DB, user=PG_USER, password=PG_PASS, port=PG_PORT, connect_timeout=30) cur = conn.cursor() # Construir condicion: contacto que NO tiene NINGUN mensaje que haga match con alguna frase likes = " OR ".join(["m.content LIKE %s"] * len(FRASES)) params = [f"%{fr}%" for fr in FRASES] sql = f""" SELECT c.phone_number, c.created_at, COUNT(m.id) AS total_msjes, MIN(m.created_at) AS primer_msje, MAX(m.created_at) AS ultimo_msje, SUM(CASE WHEN ({likes}) THEN 1 ELSE 0 END) AS msjes_campania FROM contacts c LEFT JOIN conversations cv ON cv.contact_id = c.id LEFT JOIN messages m ON m.conversation_id = cv.id AND m.sender_type = 'Contact' GROUP BY c.phone_number, c.created_at HAVING SUM(CASE WHEN ({likes}) THEN 1 ELSE 0 END) = 0 -- SIN mensaje de campaña ORDER BY c.created_at DESC LIMIT 100 """ cur.execute(sql, params + params) rows = cur.fetchall() print(f"Contactos SIN mensaje de campaña (primeros 100):") print(f"{'phone_number':16} {'contacto_creado':22} {'#msjes':>7} {'primer_msje':22} {'ultimo_msje':22}") print("-" * 95) for ph, creado, tot, primer, ultimo, _camp in rows: print(f"{str(ph):16} {str(creado):22} {tot:>7} {str(primer):22} {str(ultimo):22}") print(f"\nTotal mostrados: {len(rows)} (limite 100)") conn.close()