Actualizar server.js
This commit is contained in:
56
server.js
56
server.js
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user