124 lines
5.0 KiB
Python
124 lines
5.0 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""Tercer fix del path cascada del workflow Marca->Sucursal V2 (4UMRwxJdHFfOGHBp).
|
|
|
|
Tras arreglar el token y el locationId del 'Buscar Contacto Objetivo - SUCURSAL(mail)',
|
|
el endpoint responde correctamente con {contacts:[], total:0} cuando no encuentra
|
|
por email. Pero el IF siguiente `Si hay mas de un resultado` no maneja el caso
|
|
0 resultados:
|
|
|
|
condiciones actuales: contacts[1] exists AND total > 0 (AND)
|
|
true -> Retry telefono
|
|
false -> Obtener Contacto Cuenta objetivo - SUCURSAL (BUG: con id undefined)
|
|
|
|
Cuando total=0, ambas condiciones son false, va a [false] -> `Obtener Contacto`
|
|
con `$json.contacts[0].id` = undefined, lo que dispara 403 y termina en CREATE
|
|
fallido (si hay duplicate phone) o CREATE exitoso (si es contacto nuevo).
|
|
|
|
Fix: alinear con la logica del IF `Si hay mas de un resultado1` (el siguiente
|
|
en la cadena), que ya tiene la condicion correcta:
|
|
|
|
condiciones correctas: contacts[1] exists OR total equals 0 (OR)
|
|
true (2+ resultados o 0 resultados) -> Retry telefono
|
|
false (exactamente 1 resultado) -> Obtener Contacto
|
|
|
|
Cambio neto: 2 expressions (operator y combinator) en un solo IF. Total nodos
|
|
sin cambios.
|
|
"""
|
|
import argparse
|
|
import os
|
|
import sys
|
|
|
|
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
|
|
|
from scripts.n8n_workflow_lib import load_credentials, N8NClient
|
|
|
|
WID = "4UMRwxJdHFfOGHBp"
|
|
TARGET_NODE = "Si hay más de un resultado"
|
|
REFERENCE_NODE = "Si hay más de un resultado1" # ya tiene la logica correcta
|
|
|
|
|
|
def parse_args():
|
|
ap = argparse.ArgumentParser()
|
|
ap.add_argument("--apply", action="store_true",
|
|
help="Aplicar PUT real (default: dry-run a n8n/dryrun_*.json)")
|
|
return ap.parse_args()
|
|
|
|
|
|
def main():
|
|
args = parse_args()
|
|
api_key, base_url = load_credentials()
|
|
client = N8NClient(api_key, base_url)
|
|
|
|
print(f"[1/6] GET workflow {WID}")
|
|
wf = client.get_workflow(WID)
|
|
prev_version = wf.get("versionId")
|
|
print(f" versionId previo: {prev_version}")
|
|
print(f" total nodos : {len(wf.get('nodes') or [])}")
|
|
|
|
target = next((n for n in wf["nodes"] if n.get("name") == TARGET_NODE), None)
|
|
ref = next((n for n in wf["nodes"] if n.get("name") == REFERENCE_NODE), None)
|
|
if not target or not ref:
|
|
print(f"\nERROR: nodos requeridos no existen. Abortando.")
|
|
sys.exit(2)
|
|
|
|
target_conds = target["parameters"]["conditions"]
|
|
ref_conds = ref["parameters"]["conditions"]
|
|
|
|
print(f"\n[2/6] Diagnostico")
|
|
print(f" Target combinator: {target_conds.get('combinator')}")
|
|
print(f" Ref combinator: {ref_conds.get('combinator')}")
|
|
for i, (tc, rc) in enumerate(zip(target_conds["conditions"], ref_conds["conditions"])):
|
|
t_op = tc.get("operator", {}).get("operation")
|
|
r_op = rc.get("operator", {}).get("operation")
|
|
print(f" cond[{i}]: target.op={t_op} ref.op={r_op}")
|
|
|
|
# Aplicar misma estructura del ref al target (preservando los ids existentes)
|
|
if target_conds.get("combinator") == "or":
|
|
is_total_eq_zero = any(
|
|
c.get("operator", {}).get("operation") == "equals" and c.get("leftValue", "").endswith("total }}")
|
|
for c in target_conds["conditions"]
|
|
)
|
|
if is_total_eq_zero:
|
|
print(f"\n [SKIP] Target ya esta arreglado.")
|
|
return
|
|
|
|
print(f"\n[3/6] Backup fresco")
|
|
_, bpath = client.backup_workflow(WID, label="pre_fix_cascada_if_zero_results")
|
|
print(f" backup -> {bpath}")
|
|
|
|
print(f"\n[4/6] Aplicar cambio en memoria")
|
|
# Forzar combinator OR
|
|
target_conds["combinator"] = "or"
|
|
# Cambiar la segunda condicion (total > 0) a (total equals 0)
|
|
second = target_conds["conditions"][1]
|
|
second["operator"]["operation"] = "equals"
|
|
# rightValue ya era 0 (number), se queda igual
|
|
print(f" nuevo combinator: {target_conds['combinator']}")
|
|
print(f" nuevo cond[1].op: {second['operator']['operation']}")
|
|
|
|
print(f"\n[5/6] {'APPLY' if args.apply else 'DRY-RUN'} put_workflow")
|
|
result = client.put_workflow(WID, wf, dry_run=not args.apply)
|
|
if not args.apply:
|
|
print(f" dry-run dump -> {result}")
|
|
print("\nLISTO. Revisa el JSON. Si todo bien, corre con --apply.")
|
|
return
|
|
|
|
print(f"\n[6/6] Verificar y reactivar")
|
|
new_wf = client.verify_post(WID, prev_version_id=prev_version)
|
|
target_post = next((n for n in new_wf["nodes"] if n.get("name") == TARGET_NODE), None)
|
|
conds_post = target_post["parameters"]["conditions"]
|
|
print(f" versionId nuevo : {new_wf.get('versionId')}")
|
|
print(f" total nodos : {len(new_wf.get('nodes') or [])}")
|
|
print(f" combinator post : {conds_post.get('combinator')}")
|
|
print(f" cond[1].op post : {conds_post['conditions'][1]['operator']['operation']}")
|
|
if not new_wf.get("active"):
|
|
print(" workflow inactivo; reactivando...")
|
|
client.activate(WID)
|
|
new_wf = client.get_workflow(WID)
|
|
print(f" active final : {new_wf.get('active')}")
|
|
print("\nOK.")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|