Ejercicio: Atención humana y traspaso
Objetivo
Construir las cuatro decisiones de un traspaso a una persona: saber si el negocio está abierto, avisar solo cuando corresponde, redactar el aviso al dueño y decidir cuándo el bot debe retomar la conversación.
Cómo se trabaja
La parte A es práctica real en tu terminal con el código de referencia. La parte B son funciones de JavaScript puro que se comprueban en esta página. Todas las horas son milisegundos (Date.UTC(...)) y Lima está en UTC-5 durante todo el año. Recuerda que en Date.UTC los meses empiezan en 0 (octubre es 9) y que el domingo es el día 0.
💡 Reto extra
Escribe proximaApertura(ahora, horario, desfaseHoras = -5): devuelve un texto como "hoy a las 8:00" o "mañana a las 9:00" con la próxima hora de apertura. Es lo que haría falta para que el mensaje de fuera de horario diga cuándo te van a responder, en lugar de repetir toda la tabla.
Pasos
Marca cada paso a medida que lo completes. Tu avance se guarda en este navegador.
💡 Pista 1: Hora local
const local = new Date(ahora + desfaseHoras * 3600000); te da una fecha «corrida». Con local.getUTCDay() obtienes el día (0 a 6) y con local.getUTCHours() + local.getUTCMinutes() / 60 la hora decimal.
💡 Pista 2: Franja ausente
const franja = horario[local.getUTCDay()]; es undefined si ese día no está en la tabla. En ese caso devuelve false antes de comparar horas.
💡 Pista 3: Sumar cantidades
sesion.carrito.reduce((n, l) => n + l.cantidad, 0) suma las cantidades de todas las líneas. Para el texto usa una plantilla: `Tiene ${n} producto(s) en el carrito.`.
🔎 Comprueba tu trabajo
Pega tu código y pulsa Comprobar. La revisión ocurre en tu navegador; nada se envía a ningún sitio. Cada punto en rojo incluye una pista. Pega solo el JavaScript, sin las etiquetas <script>.
✅ Ver una solución posible
Intenta resolverlo antes de mirar. Tu versión puede ser distinta y también correcta.
function estaAbierto(ahora, horario, desfaseHoras = -5) {
const local = new Date(ahora + desfaseHoras * 3600000);
const franja = horario[local.getUTCDay()];
if (!franja) return false;
const hora = local.getUTCHours() + local.getUTCMinutes() / 60;
return hora >= franja[0] && hora < franja[1];
}
function debeAvisar(antes, despues) {
return despues === "ESPERANDO_HUMANO" && antes !== "ESPERANDO_HUMANO";
}
function avisoDueno(sesion, nombre) {
const n = sesion.carrito.reduce((suma, l) => suma + l.cantidad, 0);
const quien = nombre ? `${nombre} (${sesion.telefono})` : sesion.telefono;
const carrito = n > 0 ? `Tiene ${n} producto(s) en el carrito.` : "No tiene nada en el carrito.";
return `Cliente pide atencion: ${quien}. ${carrito}`;
}
function humanoVencido(desde, ahora, maxMs = 3 * 3600 * 1000) {
return desde != null && ahora - desde >= maxMs;
}