Initial commit - dashboard leads
This commit is contained in:
95
backend/check_choque_campania.py
Normal file
95
backend/check_choque_campania.py
Normal file
@@ -0,0 +1,95 @@
|
||||
# check_choque_campania.py
|
||||
# Revisa si una campaña NUEVA chocaría (duplicaría leads) contra las existentes.
|
||||
# Regla de choque (igual que el JOIN LIKE del dashboard):
|
||||
# - una frase es sub-cadena de la otra (contención de texto), Y
|
||||
# - los rangos de fecha se solapan.
|
||||
# Un mensaje que caiga en ambas frases + ambas fechas => 2 filas => lead duplicado.
|
||||
#
|
||||
# Edita NUEVA abajo y ejecuta: python check_choque_campania.py
|
||||
import os, requests
|
||||
from datetime import date
|
||||
from dotenv import load_dotenv
|
||||
load_dotenv()
|
||||
|
||||
# ── CAMPAÑA NUEVA A PROBAR (edita aquí) ──
|
||||
NUEVA = {
|
||||
"frase": "🎟️ Me interesa el programa de Aire Acondicionado",
|
||||
"inicio": "2026-08-10",
|
||||
"fin": "2026-10-10",
|
||||
}
|
||||
# ─────────────────────────────────────────
|
||||
|
||||
URL = os.getenv("CARTERA_URL") or os.getenv("SUPABASE_PAUTA_URL", "")
|
||||
KEY = os.getenv("CARTERA_KEY") or os.getenv("SUPABASE_PAUTA_KEY", "")
|
||||
TABLA = os.getenv("SUPABASE_TABLA_CAMPANIAS", "campanias")
|
||||
HEAD = {"apikey": KEY, "Authorization": f"Bearer {KEY}"}
|
||||
assert URL and KEY, "Falta CARTERA_URL / CARTERA_KEY en .env"
|
||||
|
||||
|
||||
def traer_todo():
|
||||
filas, paso, desde = [], 1000, 0
|
||||
while True:
|
||||
hdr = dict(HEAD); hdr["Range-Unit"] = "items"; hdr["Range"] = f"{desde}-{desde+paso-1}"
|
||||
r = requests.get(f"{URL}/rest/v1/{TABLA}", params={"select": "*", "order": "id"},
|
||||
headers=hdr, timeout=60)
|
||||
r.raise_for_status()
|
||||
data = r.json()
|
||||
if not data:
|
||||
break
|
||||
filas.extend(data); desde += len(data)
|
||||
if len(data) < paso:
|
||||
break
|
||||
return filas
|
||||
|
||||
|
||||
def _d(s):
|
||||
try:
|
||||
return date.fromisoformat(str(s)[:10])
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
|
||||
def _solapan(i1, f1, i2, f2):
|
||||
if not (i1 and f1 and i2 and f2):
|
||||
return False
|
||||
return i1 <= f2 and i2 <= f1 # rangos [i1,f1] y [i2,f2] se cruzan
|
||||
|
||||
|
||||
def _norm(t):
|
||||
return " ".join(str(t or "").lower().split())
|
||||
|
||||
|
||||
filas = traer_todo()
|
||||
ni, nf = _norm(NUEVA["frase"]), None
|
||||
n_ini, n_fin = _d(NUEVA["inicio"]), _d(NUEVA["fin"])
|
||||
|
||||
print("\n" + "="*90)
|
||||
print(f"CAMPAÑA NUEVA: \"{NUEVA['frase']}\"")
|
||||
print(f"FECHAS: {NUEVA['inicio']} → {NUEVA['fin']}")
|
||||
print("="*90)
|
||||
|
||||
choques = []
|
||||
for f in filas:
|
||||
fr = _norm(f.get("frase_busqueda"))
|
||||
if not fr:
|
||||
continue
|
||||
ei, ef = _d(f.get("fecha_inicio")), _d(f.get("fecha_fin"))
|
||||
contiene = (fr in ni) or (ni in fr) # una es sub-cadena de la otra
|
||||
fechas = _solapan(n_ini, n_fin, ei, ef)
|
||||
if contiene and fechas:
|
||||
choques.append((f, fr))
|
||||
|
||||
if not choques:
|
||||
print("\n✅ SIN CHOQUES. Ninguna campaña existente comparte texto contenido")
|
||||
print(" y fechas solapadas. Tu campaña NO duplicaría leads.\n")
|
||||
else:
|
||||
print(f"\n⚠️ {len(choques)} CHOQUE(S) DETECTADO(S) — estas campañas duplicarían leads:\n")
|
||||
for f, fr in choques:
|
||||
rel = "existente ⊂ nueva" if fr in ni else "nueva ⊂ existente"
|
||||
print(f" id {f.get('id')} cod {f.get('codigo')} [{rel}]")
|
||||
print(f" frase: \"{f.get('frase_busqueda')}\"")
|
||||
print(f" fechas: {str(f.get('fecha_inicio'))[:10]} → {str(f.get('fecha_fin'))[:10]}")
|
||||
print()
|
||||
print(" Un mensaje que contenga ambas frases dentro de estas fechas se")
|
||||
print(" contaría 2 veces (2 códigos de pauta para el mismo lead).\n")
|
||||
print("="*90)
|
||||
Reference in New Issue
Block a user