From c77ad62b82cada6d89b844ba70838b4e76153f7d Mon Sep 17 00:00:00 2001 From: marsalva Date: Fri, 20 Feb 2026 14:27:21 +0000 Subject: [PATCH] Actualizar robot.js --- robot.js | 71 +++++++++++++++----------------------------------------- 1 file changed, 19 insertions(+), 52 deletions(-) diff --git a/robot.js b/robot.js index c56aa0d..2898d6a 100644 --- a/robot.js +++ b/robot.js @@ -8,70 +8,32 @@ const pool = new pg.Pool({ connectionString: DATABASE_URL, ssl: false }); const HEADLESS = true; // ========================================== -// 🧠 MOTOR DE CLASIFICACIƓN DE GREMIOS PRO +// 🧠 MOTOR DE CLASIFICACIƓN DE GREMIOS PRO (AHORA DINƁMICO) // ========================================== -const REGLAS_GREMIOS = [ - { - nombres_db: ["MANITAS ELECTRICISTA", "MANITAS ELECTRICO", "MANITAS ELECTRICIDAD"], - keywords: ["manitas electric", "cambiar bombilla", "colgar lampara", "instalar foco", "fluorescente", "casquillo", "lampara del dormitorio", "cambiar enchufe", "embellecedor"] - }, - { - nombres_db: ["MANITAS FONTANERIA", "MANITAS FONTANERO"], - keywords: ["manitas fontaner", "cambiar grifo", "sellar baƱera", "silicona", "latiguillo", "alcachofa", "tapon", "cambiar cisterna", "descargador"] - }, - { - nombres_db: ["MANITAS PERSIANAS", "MANITAS PERSIANISTA"], - keywords: ["manitas persian", "cambiar cinta", "cuerda persiana", "recogedor", "atasco persiana", "lamas rotas", "persiana descolgada"] - }, - { - nombres_db: ["ELECTRICISTA", "ELECTRICIDAD"], - keywords: ["electric", "cortocircuito", "cuadro electrico", "salto de plomos", "apagon", "diferencial", "icp", "magnetotermico", "chispazo", "sin luz", "cableado", "derivacion", "no hay luz", "SIN LUZ", "salta el termico", "CUADRO ELECTRICO", "cableado"] - }, - { - nombres_db: ["FONTANERO", "FONTANERIA"], - keywords: ["fontaner", "fuga de agua", "tuberia", "atasco", "desatasco", "bote sifonico", "llave de paso", "calentador", "termo", "radiador", "caldera", "gotera", "inundacion", "filtracion", "bajante", "humedad"] - }, - { - nombres_db: ["CRISTALERO", "CRISTALERIA"], - keywords: ["cristal", "vidrio", "ventana rota", "escaparate", "luna", "espejo", "climalit", "doble acristalamiento", "velux", "rotura"] - }, - { - nombres_db: ["PERSIANISTA", "PERSIANERO", "PERSIANAS"], - keywords: ["motor persiana", "eje persiana", "persianista", "persiana atascada", "rotura de persiana", "domotica persiana"] - }, - { - nombres_db: ["CARPINTERO", "CARPINTERIA", "MADERA"], - keywords: ["carpinter", "puerta de madera", "bisagra", "marco", "rodapie", "tarima", "armario", "cepillar puerta", "cajon", "encimera", "madera hinchada"] - }, - { - nombres_db: ["MANITAS GENERAL", "MANITAS", "BRICOLAJE"], - keywords: ["bombin", "colgar cuadro", "soporte tv", "estanteria", "montar mueble", "ikea", "cortina", "riel", "estor", "agujero", "taladro", "picaporte", "colgar espejo"] - } -]; function normalizarTexto(texto) { if (!texto) return ""; return texto.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, ""); } +// NUEVO: La función ahora lee las keywords directamente del JSON de la base de datos function clasificarGremio(descripcion, gremiosActivosDB) { if (!descripcion || gremiosActivosDB.length === 0) return null; const descNormalizada = normalizarTexto(descripcion); - for (const regla of REGLAS_GREMIOS) { - const coincide = regla.keywords.some(kw => descNormalizada.includes(normalizarTexto(kw))); + for (const gremio of gremiosActivosDB) { + // Obtenemos las palabras clave guardadas desde el panel de configuración + const keywords = Array.isArray(gremio.ia_keywords) ? gremio.ia_keywords : []; + + if (keywords.length === 0) continue; // Si no tiene reglas, pasamos al siguiente + + // Comprobamos si alguna palabra clave coincide con la descripción + const coincide = keywords.some(kw => descNormalizada.includes(normalizarTexto(kw))); if (coincide) { - const gremioEncontrado = gremiosActivosDB.find(gDB => { - const nombreDBNorm = normalizarTexto(gDB.name); - return regla.nombres_db.some(nRegla => nombreDBNorm.includes(normalizarTexto(nRegla))); - }); - - if (gremioEncontrado) { - console.log(` 🧠 Gremio detectado automĆ”ticamente: ${gremioEncontrado.name} (ID: ${gremioEncontrado.id})`); - return gremioEncontrado.id; - } + console.log(` 🧠 Gremio detectado automĆ”ticamente: ${gremio.name} (ID: ${gremio.id})`); + return gremio.id; } } return null; @@ -97,7 +59,8 @@ async function main() { while (true) { const client = await pool.connect(); try { - const gremiosRes = await client.query("SELECT id, name FROM guilds"); + // 1. CARGAMOS LOS GREMIOS ACTUALES (AHORA INCLUYE LAS PALABRAS CLAVE) + const gremiosRes = await client.query("SELECT id, name, ia_keywords FROM guilds"); const gremiosDB = gremiosRes.rows; await client.query(` @@ -105,6 +68,10 @@ async function main() { IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name='scraped_services' AND column_name='is_urgent') THEN ALTER TABLE scraped_services ADD COLUMN is_urgent BOOLEAN DEFAULT FALSE; END IF; + -- AƑADIDO: Aseguramos que exista la columna ia_keywords en los gremios + IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name='guilds' AND column_name='ia_keywords') THEN + ALTER TABLE guilds ADD COLUMN ia_keywords JSONB DEFAULT '[]'; + END IF; END $$; `); @@ -329,7 +296,7 @@ async function runHomeserve(ownerId, user, pass, gremiosDB) { const txt = cells[1].querySelector('textarea')?.value || ""; const cleanDesc = txt.split('\n').filter(line => { const l = line.toUpperCase(); - return !["CAMBIO DE ESTADO", "ESTADO ASIGNADO", "SMS NO ENVIADO", "Cobro banco", "Servicio asignado a", "importe para este asegurado", "CONTACTO CON PROF", "0000"].some(b => l.includes(b)); + return !["CAMBIO DE ESTADO", "ESTADO ASIGNADO", "SMS NO ENVIADO", "CONTACTO CON PROF", "0000"].some(b => l.includes(b)); }).slice(0, 3).join('\n').trim(); d['Descripción'] = cleanDesc; } else if (k.length > 1 && v.length > 0 && !k.includes("MENU")) {