diff --git a/robot_auxiliar.js b/robot_auxiliar.js deleted file mode 100644 index f2d9fbf..0000000 --- a/robot_auxiliar.js +++ /dev/null @@ -1,146 +0,0 @@ -import { chromium } from 'playwright'; -import pg from 'pg'; - -const { DATABASE_URL } = process.env; -if (!DATABASE_URL) { console.error("❌ Error: No hay DATABASE_URL."); process.exit(1); } - -const pool = new pg.Pool({ connectionString: DATABASE_URL, ssl: false }); -const HEADLESS = true; - -// Función auxiliar para reintentar la navegación -async function gotoWithRetry(page, url, retries = 3) { - for (let i = 0; i < retries; i++) { - try { - await page.goto(url, { waitUntil: 'domcontentloaded', timeout: 45000 }); - return; - } catch (e) { - if (i === retries - 1) throw e; - console.log(`⚠️ Fallo de red. Reintentando (${i + 1}/${retries})...`); - await page.waitForTimeout(3000); - } - } -} - -async function main() { - console.log("🤖 INICIANDO ROBOT AUXILIAR (Buscador de Detalles)"); - - while (true) { - const client = await pool.connect(); - try { - // Obtenemos las credenciales activas - const res = await client.query("SELECT * FROM provider_credentials WHERE status = 'active' AND provider = 'homeserve'"); - - for (const cred of res.rows) { - let password = Buffer.from(cred.password_hash, 'base64').toString('utf-8'); - console.log(`\n🔄 [AUXILIAR] Procesando HOMESERVE para owner_id: ${cred.owner_id}...`); - await runHomeserveAux(cred.owner_id, cred.username, password); - } - } catch (e) { - console.error("❌ Error ciclo Auxiliar:", e.message); - } finally { - client.release(); - } - - console.log("\n💤 [AUXILIAR] Durmiendo 10 minutos..."); - await new Promise(r => setTimeout(r, 10 * 60 * 1000)); - } -} - -// ========================================== -// 🧹 HOMESERVE AUXILIAR (Caza-Iconos y Detalles) -// ========================================== -async function runHomeserveAux(ownerId, user, pass) { - const browser = await chromium.launch({ - headless: HEADLESS, - args: ['--no-sandbox', '--disable-setuid-sandbox', '--disable-dev-shm-usage'] - }); - const page = await browser.newPage(); - - try { - console.log("🌍 [HomeServe AUX] Iniciando sesión..."); - await gotoWithRetry(page, 'https://www.clientes.homeserve.es/cgi-bin/fccgi.exe?w3exec=PROF_PASS'); - - if (await page.isVisible('input[name="CODIGO"]')) { - await page.fill('input[name="CODIGO"]', user); - await page.fill('input[type="password"]', pass); - await page.keyboard.press('Enter'); - await page.waitForTimeout(5000); - } - - // Vamos a la lista total de servicios - await gotoWithRetry(page, 'https://www.clientes.homeserve.es/cgi-bin/fccgi.exe?w3exec=lista_servicios_total'); - await page.waitForTimeout(3000); - - console.log("🔍 [HomeServe AUX] Escaneando iconos (Candados y Ojos)..."); - - // 🧠 LA MAGIA: Extraemos la referencia y verificamos si hay imágenes específicas junto a ella - const serviciosExtraidos = await page.evaluate(() => { - const results = []; - // Buscamos todas las filas de la tabla de expedientes - const rows = Array.from(document.querySelectorAll('table[bgcolor="#FCF4D6"] tr')); - - rows.forEach(tr => { - const firstTd = tr.querySelector('td'); - if (!firstTd) return; - - // Intentamos cazar el número de expediente (empieza por 15 y tiene 8 cifras) - const textMatch = firstTd.innerText.trim().match(/^15\d{6}$/); - const aMatch = firstTd.querySelector('a') ? firstTd.querySelector('a').innerText.trim().match(/^15\d{6}$/) : null; - - const ref = textMatch ? textMatch[0] : (aMatch ? aMatch[0] : null); - - if (ref) { - // Miramos si dentro de esa celda existe la imagen del candado o de los ojos - const hasLock = firstTd.querySelector('img[src*="candado.gif"]') !== null; - const hasEyes = firstTd.querySelector('img[src*="ojos.gif"]') !== null; - - results.push({ ref, hasLock, hasEyes }); - } - }); - return results; - }); - - console.log(`✅ [HomeServe AUX] Se han escaneado ${serviciosExtraidos.length} expedientes.`); - - // Guardamos los datos en la base de datos de forma segura - for (const data of serviciosExtraidos) { - await saveIconStatusToDB(ownerId, 'homeserve', data.ref, data.hasLock, data.hasEyes); - } - - console.log("🏁 [HomeServe AUX] Tarea completada."); - - } catch (e) { - console.error("❌ [HomeServe AUX] Error:", e.message); - } finally { - await browser.close(); - } -} - -// ========================================== -// 💾 GUARDADO SEGURO EN BD (Inyección en raw_data) -// ========================================== -async function saveIconStatusToDB(ownerId, provider, ref, hasLock, hasEyes) { - try { - // Actualizamos inyectando los valores booleanos dentro del JSON raw_data. - // Solo lo hacemos si el expediente existe. - await pool.query(` - UPDATE scraped_services - SET raw_data = jsonb_set( - jsonb_set(COALESCE(raw_data, '{}'::jsonb), '{has_lock}', $1::jsonb), - '{has_eyes}', $2::jsonb - ) - WHERE owner_id = $3 AND provider = $4 AND service_ref = $5 - `, [ - hasLock ? 'true' : 'false', - hasEyes ? 'true' : 'false', - ownerId, - provider, - ref - ]); - - } catch (e) { - console.error(`❌ Error inyectando iconos en ${ref}:`, e.message); - } -} - -main(); \ No newline at end of file