Actualizar server.js

This commit is contained in:
2026-03-07 22:17:35 +00:00
parent 49ffa5e315
commit 0ae7fce650

View File

@@ -434,24 +434,29 @@ async function registrarMovimiento(serviceId, userId, action, details) {
async function procesarConIA(ownerId, mensajeCliente, datosExpediente) {
try {
const userQ = await pool.query("SELECT wa_settings, full_name FROM users WHERE id=$1", [ownerId]);
const settings = userQ.rows[0]?.wa_settings || {};
const empresaNombre = userQ.rows[0]?.full_name || "nuestra empresa";
// 1. Extraemos TODO: nombre, settings y horarios reales de la ruta
const userQ = await pool.query("SELECT wa_settings, full_name, portal_settings FROM users WHERE id=$1", [ownerId]);
const userData = userQ.rows[0];
const settings = userData?.wa_settings || {};
const empresaNombre = userData?.full_name || "nuestra empresa";
// Si no hay horario configurado, usa un estándar lógico
const horarios = userData?.portal_settings || { m_start: "09:00", m_end: "14:00", a_start: "16:00", a_end: "19:00" };
if (!settings.wa_ai_enabled) return null;
// 🕒 1. Sincronización de Fecha Real
const ahora = new Date();
const fechaHoyTexto = ahora.toLocaleDateString('es-ES', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' });
const opciones = { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' };
const fechaHoyTexto = ahora.toLocaleDateString('es-ES', opciones);
// 🧠 2. Memoria de Conversación (Evitar saludos repetitivos)
// 🧠 MEMORIA: Evita parecer tonto
const chatCheck = await pool.query(`
SELECT id FROM service_communications
WHERE scraped_id = $1 AND created_at > NOW() - INTERVAL '60 minutes' LIMIT 1
WHERE scraped_id = $1
AND created_at > NOW() - INTERVAL '60 minutes' LIMIT 1
`, [datosExpediente.dbId]);
const yaSeHaPresentado = chatCheck.rowCount > 0;
// 📍 3. Inteligencia de Ruta (Buscar técnicos cerca)
// 📍 LOGÍSTICA: Buscar técnicos cerca
const poblacion = datosExpediente.poblacion || "";
let fechasSugeridas = "";
@@ -459,10 +464,8 @@ async function procesarConIA(ownerId, mensajeCliente, datosExpediente) {
const rutasCercanas = await pool.query(`
SELECT raw_data->>'scheduled_date' as fecha
FROM scraped_services
WHERE owner_id = $1
AND raw_data->>'Población' ILIKE $2
AND raw_data->>'scheduled_date' >= CURRENT_DATE::text
AND id != $3
WHERE owner_id = $1 AND raw_data->>'Población' ILIKE $2
AND raw_data->>'scheduled_date' > CURRENT_DATE::text AND id != $3
GROUP BY fecha ORDER BY fecha ASC LIMIT 2
`, [ownerId, poblacion, datosExpediente.dbId]);
@@ -475,29 +478,32 @@ async function procesarConIA(ownerId, mensajeCliente, datosExpediente) {
}
const promptSistema = `
Eres el Asistente IA de "${empresaNombre}".
Hoy es ${fechaHoyTexto}. Estamos en el año 2026.
Eres el Asistente Humano de "${empresaNombre}". Tienes que ser MUY natural, cercano y resolutivo. Nada de sonar robótico.
CONTEXTO Y HORARIOS:
- Hoy es: ${fechaHoyTexto}. Año 2026.
- HORARIO DE TRABAJO: Lunes a Viernes. Mañanas de ${horarios.m_start} a ${horarios.m_end}. Tardes de ${horarios.a_start} a ${horarios.a_end}.
- ⛔ LOS FINES DE SEMANA NO SE TRABAJA. Si el cliente pide un Sábado o Domingo, dile amablemente que descansamos el fin de semana y ofrécele un Viernes o Lunes dentro del horario.
DATOS EXPEDIENTE #${datosExpediente.ref}:
- Estado: ${datosExpediente.estado}
- Población: ${poblacion}
- Cita actual: ${datosExpediente.cita || 'Ninguna'}
LÓGICA DE SALUDO:
LÓGICA DE SALUDO (MUY IMPORTANTE):
${!yaSeHaPresentado
? `- Inicio de chat: Preséntate brevemente y menciona el expediente #${datosExpediente.ref}.`
: `- Conversación fluida: NO te presentes, NO digas hola, ve directo a la respuesta.`
? `- Es el inicio. Preséntate con empatía: "¡Hola! Soy el asistente de ${empresaNombre}. Te escribo sobre tu aviso #${datosExpediente.ref}..."`
: `- ⛔ YA HABÉIS HABLADO RECIENTEMENTE. PROHIBIDO decir "Hola" o volver a presentarte. Ve DIRECTO a la respuesta como harías en un chat real con un amigo.`
}
ESTRATEGIA DE RUTA (LOGÍSTICA):
ESTRATEGIA DE RUTA:
${fechasSugeridas
? `- Tenemos otros técnicos en ${poblacion} el ${fechasSugeridas}. SUGIERE estas fechas prioritariamente para optimizar la ruta.`
: `- No hay rutas previas en ${poblacion}. Pide al cliente su preferencia de mañana o tarde.`
? `- Casualmente tenemos técnicos yendo a ${poblacion} el ${fechasSugeridas}. Sugiere esas fechas amigablemente para aprovechar el viaje.`
: `- Pregúntale qué día de Lunes a Viernes le viene bien y si prefiere mañana o tarde.`
}
REGLA DE CITAS:
- Si el cliente propone algo, di que lo consultas y añade al final: [PROPUESTA:YYYY-MM-DD HH:mm]
- Máximo 2 frases. Sé muy natural, no parezcas un robot.
REGLA PARA GUARDAR LA CITA:
- Si el cliente confirma un día y hora válidos (L-V), dile que lo dejas anotado para que el técnico lo confirme y añade AL FINAL tu respuesta este código oculto: [PROPUESTA:YYYY-MM-DD HH:mm]
- Ejemplo: "Perfecto, te dejo anotado para el viernes a las 10:00. El técnico te confirmará en breve. [PROPUESTA:2026-03-13 10:00]"
`;
const completion = await openai.chat.completions.create({
@@ -506,7 +512,7 @@ async function procesarConIA(ownerId, mensajeCliente, datosExpediente) {
{ role: "system", content: promptSistema },
{ role: "user", content: mensajeCliente }
],
temperature: 0.4, // Más preciso, menos creativo
temperature: 0.4, // Controlado para no divagar
});
return completion.choices[0].message.content;