diff --git a/robot.js b/robot.js index ca16050..bbc21b4 100644 --- a/robot.js +++ b/robot.js @@ -11,7 +11,6 @@ const HEADLESS = true; // 🧠 MOTOR DE CLASIFICACIÓN DE GREMIOS PRO // ========================================== const REGLAS_GREMIOS = [ - // 1. LOS MANITAS ESPECÍFICOS PRIMERO (Prioridad Alta) { 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"] @@ -24,7 +23,6 @@ const REGLAS_GREMIOS = [ nombres_db: ["MANITAS PERSIANAS", "MANITAS PERSIANISTA"], keywords: ["manitas persian", "cambiar cinta", "cuerda persiana", "recogedor", "atasco persiana", "lamas rotas", "persiana descolgada"] }, - // 2. GREMIOS OFICIALES (Prioridad Media) { nombres_db: ["ELECTRICISTA", "ELECTRICIDAD"], keywords: ["electric", "cortocircuito", "cuadro electrico", "salto de plomos", "apagon", "diferencial", "icp", "magnetotermico", "chispazo", "sin luz", "cableado", "derivacion"] @@ -45,7 +43,6 @@ const REGLAS_GREMIOS = [ nombres_db: ["CARPINTERO", "CARPINTERIA", "MADERA"], keywords: ["carpinter", "puerta de madera", "bisagra", "marco", "rodapie", "tarima", "armario", "cepillar puerta", "cajon", "encimera", "madera hinchada"] }, - // 3. EL COMODÍN (Prioridad Baja) { nombres_db: ["MANITAS GENERAL", "MANITAS", "BRICOLAJE"], keywords: ["manitas general", "colgar cuadro", "soporte tv", "estanteria", "montar mueble", "ikea", "cortina", "riel", "estor", "agujero", "taladro", "picaporte", "colgar espejo"] @@ -125,7 +122,17 @@ async function main() { // 🏥 MULTIASISTENCIA (CON INTELIGENCIA Y PAGINACIÓN REAL) // ========================================== async function runMultiasistencia(ownerId, user, pass, gremiosDB) { - const browser = await chromium.launch({ headless: HEADLESS, args: ['--no-sandbox'] }); + // ARGUMENTOS DE SEGURIDAD CONTRA CRASHEOS EN LINUX/DOCKER + const browser = await chromium.launch({ + headless: HEADLESS, + args: [ + '--no-sandbox', + '--disable-setuid-sandbox', + '--disable-dev-shm-usage', // Evita que se quede sin memoria compartida (causa del SIGSEGV) + '--disable-gpu' + ] + }); + const context = await browser.newContext(); const page = await context.newPage(); try { @@ -135,19 +142,22 @@ async function runMultiasistencia(ownerId, user, pass, gremiosDB) { await page.click('input[type="submit"]'); await page.waitForTimeout(4000); await page.goto('https://web.multiasistencia.com/w3multi/frepasos_new.php?refresh=1'); - await page.waitForTimeout(2000); + await page.waitForTimeout(3000); - // --- NUEVO: FORZAR RECARGA PARA VER TODOS LOS SERVICIOS --- - console.log("🔄 [Multi] Dando al botón de 'Recargar' para destapar todos los expedientes..."); - for (let i = 0; i < 2; i++) { - try { - if (await page.$('#recargar')) { - await page.click('#recargar'); - await page.waitForTimeout(4000); // Esperar a que recargue la página tras el submit + // --- NUEVO: FORZAR RECARGA DE FORMA SEGURA (SIN HACER CLIC FÍSICO) --- + console.log("🔄 [Multi] Forzando recarga segura mediante script interno..."); + try { + await page.evaluate(() => { + // Llamamos a la función nativa de la web para recargar sin reventar el motor gráfico + if (typeof refrescar === 'function') { + refrescar(); } - } catch (e) { - // ignorar si no está - } + }); + // Esperamos a que la red deje de cargar datos + await page.waitForLoadState('networkidle'); + await page.waitForTimeout(3000); + } catch (e) { + console.log("⚠️ [Multi] No se pudo ejecutar la recarga (puede que ya estuvieran cargados)."); } // ---------------------------------------------------------- @@ -167,7 +177,6 @@ async function runMultiasistencia(ownerId, user, pass, gremiosDB) { expedientesPagina.forEach(ref => todosExpedientes.add(ref)); // 2. Buscar el botón "Página siguiente" - // Ejecutamos exactamente la lógica que usa la web (document.filtros.submit()) const hasNextPage = await page.evaluate(() => { const links = Array.from(document.querySelectorAll('a.lnkheader')); const nextBtn = links.find(a => a.innerText.trim() === 'Página siguiente'); @@ -180,26 +189,24 @@ async function runMultiasistencia(ownerId, user, pass, gremiosDB) { }); if (hasNextPage) { - // Esperamos a que la red se calme tras el submit del formulario await page.waitForLoadState('networkidle'); - await page.waitForTimeout(2000); // Margen extra por si acaso + await page.waitForTimeout(2500); paginaActual++; - // Medida de seguridad antibucle if(paginaActual > 15) { console.log("⚠️ [Multi] Límite de 15 páginas alcanzado por seguridad."); break; } } else { console.log("🛑 [Multi] No hay más páginas."); - break; // Se acabó la paginación + break; } } const expedientes = Array.from(todosExpedientes); console.log(`✅ [Multi] Total expedientes detectados: ${expedientes.length}`); - // --- MEJORA: ARCHIVADO --- + // --- ARCHIVADO --- if (expedientes.length > 0) { await syncAndArchive(ownerId, 'multiasistencia', expedientes); } @@ -252,7 +259,6 @@ async function runMultiasistencia(ownerId, user, pass, gremiosDB) { } if (scrapData && scrapData['Nombre Cliente']) { - // 🪄 MAGIA: Clasificamos el gremio basándonos en la descripción leída de la web const idGremioDetectado = clasificarGremio(scrapData['Descripción'], gremiosDB); if (idGremioDetectado) { scrapData['guild_id'] = idGremioDetectado; @@ -271,7 +277,16 @@ async function runMultiasistencia(ownerId, user, pass, gremiosDB) { // 🧹 HOMESERVE (CON INTELIGENCIA) // ========================================== async function runHomeserve(ownerId, user, pass, gremiosDB) { - const browser = await chromium.launch({ headless: HEADLESS, args: ['--no-sandbox'] }); + // MISMOS ARGUMENTOS DE SEGURIDAD AQUÍ PARA EVITAR CRASHES + const browser = await chromium.launch({ + headless: HEADLESS, + args: [ + '--no-sandbox', + '--disable-setuid-sandbox', + '--disable-dev-shm-usage', + '--disable-gpu' + ] + }); const page = await browser.newPage(); try { console.log("🌍 [HomeServe] Entrando..."); @@ -297,7 +312,6 @@ async function runHomeserve(ownerId, user, pass, gremiosDB) { return [...new Set(found)]; }); - // --- MEJORA: ARCHIVADO --- if (refs.length > 0) { await syncAndArchive(ownerId, 'homeserve', refs); } @@ -339,7 +353,6 @@ async function runHomeserve(ownerId, user, pass, gremiosDB) { }); if (scrapData && scrapData['Nombre Cliente']) { - // 🪄 MAGIA: Clasificamos el gremio basándonos en la descripción leída de la web const idGremioDetectado = clasificarGremio(scrapData['Descripción'], gremiosDB); if (idGremioDetectado) { scrapData['guild_id'] = idGremioDetectado;