Actualizar robot.js

This commit is contained in:
2026-02-20 14:27:21 +00:00
parent c8fa40b988
commit c77ad62b82

View File

@@ -8,70 +8,32 @@ const pool = new pg.Pool({ connectionString: DATABASE_URL, ssl: false });
const HEADLESS = true; 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) { function normalizarTexto(texto) {
if (!texto) return ""; if (!texto) return "";
return texto.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, ""); 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) { function clasificarGremio(descripcion, gremiosActivosDB) {
if (!descripcion || gremiosActivosDB.length === 0) return null; if (!descripcion || gremiosActivosDB.length === 0) return null;
const descNormalizada = normalizarTexto(descripcion); const descNormalizada = normalizarTexto(descripcion);
for (const regla of REGLAS_GREMIOS) { for (const gremio of gremiosActivosDB) {
const coincide = regla.keywords.some(kw => descNormalizada.includes(normalizarTexto(kw))); // 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) { if (coincide) {
const gremioEncontrado = gremiosActivosDB.find(gDB => { console.log(` 🧠 Gremio detectado automáticamente: ${gremio.name} (ID: ${gremio.id})`);
const nombreDBNorm = normalizarTexto(gDB.name); return gremio.id;
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;
}
} }
} }
return null; return null;
@@ -97,7 +59,8 @@ async function main() {
while (true) { while (true) {
const client = await pool.connect(); const client = await pool.connect();
try { 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; const gremiosDB = gremiosRes.rows;
await client.query(` 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 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; ALTER TABLE scraped_services ADD COLUMN is_urgent BOOLEAN DEFAULT FALSE;
END IF; 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 $$; END $$;
`); `);
@@ -329,7 +296,7 @@ async function runHomeserve(ownerId, user, pass, gremiosDB) {
const txt = cells[1].querySelector('textarea')?.value || ""; const txt = cells[1].querySelector('textarea')?.value || "";
const cleanDesc = txt.split('\n').filter(line => { const cleanDesc = txt.split('\n').filter(line => {
const l = line.toUpperCase(); 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(); }).slice(0, 3).join('\n').trim();
d['Descripción'] = cleanDesc; d['Descripción'] = cleanDesc;
} else if (k.length > 1 && v.length > 0 && !k.includes("MENU")) { } else if (k.length > 1 && v.length > 0 && !k.includes("MENU")) {