Añadir robot.js

This commit is contained in:
marsalva 2025-12-25 23:05:35 +00:00
parent 1bf95f1c40
commit da8e96f9be
1 changed files with 148 additions and 0 deletions

148
robot.js Normal file
View File

@ -0,0 +1,148 @@
// robot-homeserve/robot.js
const { chromium } = require('playwright');
const admin = require('firebase-admin');
// --- CONFIGURACIÓN FIREBASE (desde ENV de Render) ---
if (process.env.FIREBASE_PRIVATE_KEY) {
try {
admin.initializeApp({
credential: admin.credential.cert({
projectId: process.env.FIREBASE_PROJECT_ID,
clientEmail: process.env.FIREBASE_CLIENT_EMAIL,
privateKey: process.env.FIREBASE_PRIVATE_KEY.replace(/\\n/g, '\n'),
}),
});
console.log("✅ Firebase inicializado correctamente");
} catch (err) {
console.error("❌ Error inicializando Firebase:", err);
process.exit(1);
}
} else {
console.error("❌ Falta FIREBASE_PRIVATE_KEY en las variables de entorno");
process.exit(1);
}
const db = admin.firestore();
// --- VARIABLES DE ENTORNO ---
const HOMESERVE_USER = process.env.HOMESERVE_USER;
const HOMESERVE_PASS = process.env.HOMESERVE_PASS;
if (!HOMESERVE_USER || !HOMESERVE_PASS) {
console.error("❌ Faltan HOMESERVE_USER o HOMESERVE_PASS en ENV");
process.exit(1);
}
// --- FUNCIONES UTILES ---
async function delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
function safeText(str) {
return (str || '').toString().trim();
}
// --- LOGICA PRINCIPAL ---
async function main() {
const browser = await chromium.launch({
headless: true,
args: ['--no-sandbox', '--disable-setuid-sandbox'],
});
const context = await browser.newContext();
const page = await context.newPage();
try {
console.log("🌐 Entrando a HomeServe...");
await page.goto('https://gestor.homeserve.es/', { waitUntil: 'domcontentloaded', timeout: 120000 });
// Login
console.log("🔐 Login...");
await page.waitForSelector('input[type="text"]', { timeout: 60000 });
await page.fill('input[type="text"]', HOMESERVE_USER);
const selectorPass = 'input[type="password"]';
await page.waitForSelector(selectorPass, { timeout: 60000 });
await page.fill(selectorPass, HOMESERVE_PASS);
// Botón entrar (puede variar)
const btn = await page.$('button[type="submit"]');
if (btn) {
await btn.click();
} else {
// fallback: enter
await page.keyboard.press('Enter');
}
// Espera a panel
await page.waitForLoadState('networkidle', { timeout: 120000 });
console.log("✅ Logueado");
// Ir a lista de servicios / pendientes (URL/selector depende del portal)
// Aquí se mantiene la lógica robusta con esperas y tolerancia.
await delay(4000);
// Ejemplo: navegar a "Pendientes"
// (esto puede variar según HomeServe)
const pendientesLink = await page.$('text=Pendientes');
if (pendientesLink) {
await pendientesLink.click();
await page.waitForLoadState('networkidle', { timeout: 120000 });
await delay(2000);
}
// Extraer tabla/listado
console.log("📥 Extrayendo servicios...");
const servicios = await page.evaluate(() => {
// Intenta detectar filas en tabla
const rows =
Array.from(document.querySelectorAll('table tbody tr')) ||
Array.from(document.querySelectorAll('tbody tr'));
return rows.map(r => {
const cells = Array.from(r.querySelectorAll('td')).map(td => td.innerText.trim());
return { cells };
}).filter(x => x && x.cells && x.cells.length > 0);
});
console.log(`🧾 Encontrados ${servicios.length} servicios (filas)`);
// Guardar en Firestore
const batch = db.batch();
const col = db.collection('homeserve_pendientes');
let saved = 0;
for (const item of servicios) {
// Aquí puedes mapear celdas a campos reales según tu tabla.
// Ejemplo genérico:
const ref = col.doc();
batch.set(ref, {
raw: item,
createdAt: admin.firestore.FieldValue.serverTimestamp(),
source: 'homeserve',
});
saved++;
// Firestore batch max 500 ops
if (saved % 450 === 0) {
await batch.commit();
}
}
await batch.commit();
console.log(`✅ Guardados ${saved} registros en Firestore (homeserve_pendientes)`);
} catch (err) {
console.error("❌ Error en robot HomeServe:", err);
try {
await page.screenshot({ path: '/tmp/error-homeserve.png', fullPage: true });
console.log("📸 Screenshot guardada en /tmp/error-homeserve.png");
} catch (e) {}
process.exitCode = 1;
} finally {
await browser.close();
console.log("🧹 Browser cerrado");
}
}
main();