Actualizar server.js
This commit is contained in:
122
server.js
122
server.js
@@ -1812,38 +1812,104 @@ app.post("/providers/credentials", authMiddleware, async (req, res) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// ==========================================
|
// ==========================================
|
||||||
// 📤 OBTENER SERVICIOS PARA EL BUZÓN (ESTO ES LO QUE SE BORRÓ SIN QUERER)
|
// 📥 RECEPCIÓN DE SERVICIOS (EMBUDO INTELIGENTE DEFINITIVO)
|
||||||
// ==========================================
|
// ==========================================
|
||||||
app.get("/providers/scraped", authMiddleware, async (req, res) => {
|
app.post("/providers/scraped", authMiddleware, async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const q = await pool.query(`
|
const { provider, services } = req.body;
|
||||||
SELECT
|
|
||||||
s.*,
|
|
||||||
ap.token as active_token,
|
|
||||||
EXTRACT(EPOCH FROM (ap.expires_at - CURRENT_TIMESTAMP)) as seconds_left,
|
|
||||||
u.full_name as current_worker_name,
|
|
||||||
(SELECT json_agg(json_build_object('name', u2.full_name, 'phone', u2.phone))
|
|
||||||
FROM assignment_pings ap2
|
|
||||||
JOIN users u2 ON ap2.user_id = u2.id
|
|
||||||
WHERE ap2.scraped_id = s.id AND ap2.status IN ('expired', 'rejected')) as attempted_workers_data
|
|
||||||
FROM scraped_services s
|
|
||||||
LEFT JOIN assignment_pings ap ON s.id = ap.scraped_id AND ap.status = 'pending'
|
|
||||||
LEFT JOIN users u ON ap.user_id = u.id
|
|
||||||
WHERE s.owner_id = $1
|
|
||||||
ORDER BY s.created_at DESC
|
|
||||||
`, [req.user.accountId]);
|
|
||||||
|
|
||||||
const services = q.rows.map(row => {
|
if (!provider || !Array.isArray(services)) {
|
||||||
if (row.seconds_left && row.seconds_left > 0) {
|
return res.status(400).json({ ok: false, error: "Formato de datos inválido" });
|
||||||
row.token_expires_at = new Date(Date.now() + (row.seconds_left * 1000));
|
}
|
||||||
} else if (row.seconds_left <= 0) {
|
|
||||||
row.token_expires_at = new Date(Date.now() - 1000);
|
let count = 0;
|
||||||
|
|
||||||
|
const credsQ = await pool.query(
|
||||||
|
"SELECT auto_dispatch FROM provider_credentials WHERE owner_id = $1 AND provider = $2",
|
||||||
|
[req.user.accountId, provider]
|
||||||
|
);
|
||||||
|
const autoDispatchEnabled = credsQ.rowCount > 0 && credsQ.rows[0].auto_dispatch === true;
|
||||||
|
|
||||||
|
for (const svc of services) {
|
||||||
|
|
||||||
|
// 1. EXTRAER REFERENCIA A PRUEBA DE BOMBAS (Incluye "SERVICIO" de HomeServe)
|
||||||
|
const ref = svc['service_ref']
|
||||||
|
|| svc['SERVICIO']
|
||||||
|
|| svc['Referencia']
|
||||||
|
|| svc['Nº Siniestro']
|
||||||
|
|| svc['Expediente']
|
||||||
|
|| svc['expediente']
|
||||||
|
|| (svc.raw_data && (svc.raw_data['SERVICIO'] || svc.raw_data['Referencia'] || svc.raw_data['Nº Siniestro'] || svc.raw_data['Expediente'] || svc.raw_data['expediente']));
|
||||||
|
|
||||||
|
if (!ref) {
|
||||||
|
console.log("⚠️ Se omitió un servicio por no encontrar el número de referencia.");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. DETECTOR DE URGENCIAS (APLASTAMIENTO TOTAL - CERO FALSOS POSITIVOS)
|
||||||
|
let esUrgente = false;
|
||||||
|
|
||||||
|
// Juntamos todos los valores del objeto en un solo string
|
||||||
|
const textoPlano = JSON.stringify(svc).toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "");
|
||||||
|
|
||||||
|
// Caso HomeServe: frases mágicas exactas (cero falsos positivos)
|
||||||
|
if (
|
||||||
|
textoPlano.includes('atencion presencial urgencias') ||
|
||||||
|
textoPlano.includes('atencion de la urgencia')
|
||||||
|
) {
|
||||||
|
esUrgente = true;
|
||||||
|
} else {
|
||||||
|
// Caso Multiasistencia u otros: si la columna se llama Urgencia/Urgent y el valor es "si" o "true"
|
||||||
|
for (const key in svc) {
|
||||||
|
const col = String(key).toLowerCase();
|
||||||
|
const val = String(svc[key]).toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "");
|
||||||
|
if ((col.includes('urgent') || col === 'urgencia') && (val === 'si' || val === 'true' || val === 'si')) {
|
||||||
|
esUrgente = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const guildId = svc.guild_id || svc['guild_id'] || (svc.raw_data && svc.raw_data.guild_id);
|
||||||
|
|
||||||
|
// 3. GUARDAMOS EN LA BD (CON MEMORIA ETERNA: OR EXCLUDED.is_urgent)
|
||||||
|
const insertRes = await pool.query(`
|
||||||
|
INSERT INTO scraped_services (owner_id, provider, service_ref, raw_data, is_urgent)
|
||||||
|
VALUES ($1, $2, $3, $4, $5)
|
||||||
|
ON CONFLICT (owner_id, provider, service_ref)
|
||||||
|
DO UPDATE SET
|
||||||
|
raw_data = scraped_services.raw_data || EXCLUDED.raw_data,
|
||||||
|
is_urgent = scraped_services.is_urgent OR EXCLUDED.is_urgent
|
||||||
|
RETURNING id, automation_status
|
||||||
|
`, [req.user.accountId, provider, ref, JSON.stringify(svc), esUrgente]);
|
||||||
|
|
||||||
|
const newSvcId = insertRes.rows[0].id;
|
||||||
|
const autoStatus = insertRes.rows[0].automation_status;
|
||||||
|
|
||||||
|
// 4. AUTO-DESPACHO
|
||||||
|
if (esUrgente && guildId && autoDispatchEnabled && (autoStatus === 'manual' || autoStatus === 'pending')) {
|
||||||
|
console.log(`⚡ [AUTO-DISPATCH] Lanzando urgencia ${ref} de ${provider} a la bolsa...`);
|
||||||
|
|
||||||
|
const cpMatch = textoPlano.match(/\b\d{5}\b/);
|
||||||
|
const cpFinal = cpMatch ? cpMatch[0] : "00000";
|
||||||
|
|
||||||
|
const port = process.env.PORT || 3000;
|
||||||
|
fetch(`http://127.0.0.1:${port}/providers/automate/${newSvcId}`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json', 'Authorization': req.headers.authorization },
|
||||||
|
body: JSON.stringify({ guild_id: guildId, cp: cpFinal, useDelay: false })
|
||||||
|
}).catch(e => console.error("Error en auto-despacho:", e.message));
|
||||||
|
}
|
||||||
|
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
res.json({ ok: true, inserted: count });
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error("❌ Error recibiendo servicios:", error);
|
||||||
|
res.status(500).json({ ok: false, error: error.message });
|
||||||
}
|
}
|
||||||
delete row.seconds_left;
|
|
||||||
return row;
|
|
||||||
});
|
|
||||||
res.json({ ok: true, services });
|
|
||||||
} catch (e) { res.status(500).json({ ok: false }); }
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// ==========================================
|
// ==========================================
|
||||||
|
|||||||
Reference in New Issue
Block a user