Actualizar robot.js
This commit is contained in:
110
robot.js
110
robot.js
@@ -7,33 +7,115 @@ if (!DATABASE_URL) { console.error("❌ Error: No hay DATABASE_URL."); process.e
|
||||
const pool = new pg.Pool({ connectionString: DATABASE_URL, ssl: false });
|
||||
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"]
|
||||
},
|
||||
{
|
||||
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"]
|
||||
},
|
||||
// 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"]
|
||||
},
|
||||
{
|
||||
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"]
|
||||
},
|
||||
// 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"]
|
||||
}
|
||||
];
|
||||
|
||||
function normalizarTexto(texto) {
|
||||
if (!texto) return "";
|
||||
return texto.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "");
|
||||
}
|
||||
|
||||
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)));
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
async function main() {
|
||||
console.log("🤖 ROBOT MODO: CIRUJANO + ASPIRADORA INTELIGENTE");
|
||||
console.log("🤖 ROBOT MODO: CIRUJANO + ASPIRADORA + CLASIFICADOR PRO");
|
||||
while (true) {
|
||||
const client = await pool.connect();
|
||||
try {
|
||||
// 1. CARGAMOS LOS GREMIOS ACTUALES DE LA BASE DE DATOS
|
||||
const gremiosRes = await client.query("SELECT id, name FROM guilds");
|
||||
const gremiosDB = gremiosRes.rows;
|
||||
|
||||
const res = await client.query("SELECT * FROM provider_credentials WHERE status = 'active'");
|
||||
for (const cred of res.rows) {
|
||||
let password = Buffer.from(cred.password_hash, 'base64').toString('utf-8');
|
||||
console.log(`\n🔄 Procesando ${cred.provider.toUpperCase()}...`);
|
||||
|
||||
// 2. PASAMOS LOS GREMIOS AL SCRAPER
|
||||
if (cred.provider === 'multiasistencia') {
|
||||
await runMultiasistencia(cred.owner_id, cred.username, password);
|
||||
await runMultiasistencia(cred.owner_id, cred.username, password, gremiosDB);
|
||||
} else if (cred.provider === 'homeserve') {
|
||||
await runHomeserve(cred.owner_id, cred.username, password);
|
||||
await runHomeserve(cred.owner_id, cred.username, password, gremiosDB);
|
||||
}
|
||||
|
||||
await client.query("UPDATE provider_credentials SET last_sync = NOW() WHERE id = $1", [cred.id]);
|
||||
}
|
||||
} catch (e) { console.error("❌ Error ciclo:", e.message); }
|
||||
finally { client.release(); }
|
||||
|
||||
console.log("\n💤 Durmiendo 15 minutos...");
|
||||
await new Promise(r => setTimeout(r, 15 * 60 * 1000));
|
||||
}
|
||||
}
|
||||
|
||||
// ==========================================
|
||||
// 🏥 MULTIASISTENCIA (FUNCIONANDO)
|
||||
// 🏥 MULTIASISTENCIA (CON INTELIGENCIA)
|
||||
// ==========================================
|
||||
async function runMultiasistencia(ownerId, user, pass) {
|
||||
async function runMultiasistencia(ownerId, user, pass, gremiosDB) {
|
||||
const browser = await chromium.launch({ headless: HEADLESS, args: ['--no-sandbox'] });
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
@@ -97,15 +179,22 @@ async function runMultiasistencia(ownerId, user, pass) {
|
||||
if (scrapData && scrapData['Nombre Cliente']) break;
|
||||
} catch (e) { continue; }
|
||||
}
|
||||
if (scrapData && scrapData['Nombre Cliente']) await saveServiceToDB(ownerId, 'multiasistencia', ref, scrapData);
|
||||
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;
|
||||
}
|
||||
await saveServiceToDB(ownerId, 'multiasistencia', ref, scrapData);
|
||||
}
|
||||
}
|
||||
} catch (e) { console.error("❌ Error Multi:", e.message); } finally { await browser.close(); }
|
||||
}
|
||||
|
||||
// ==========================================
|
||||
// 🧹 HOMESERVE (CORREGIDO)
|
||||
// 🧹 HOMESERVE (CON INTELIGENCIA)
|
||||
// ==========================================
|
||||
async function runHomeserve(ownerId, user, pass) {
|
||||
async function runHomeserve(ownerId, user, pass, gremiosDB) {
|
||||
const browser = await chromium.launch({ headless: HEADLESS, args: ['--no-sandbox'] });
|
||||
const page = await browser.newPage();
|
||||
try {
|
||||
@@ -174,6 +263,11 @@ async function runHomeserve(ownerId, user, pass) {
|
||||
});
|
||||
|
||||
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;
|
||||
}
|
||||
await saveServiceToDB(ownerId, 'homeserve', ref, scrapData);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user