Saltar al contenido
Chatbots de WhatsApp desde cero
Temario

Ejercicio: El servidor del bot

  • ⏱ 55 minutos
  • 📶 Nivel: intermedio

Objetivo

Levantar el Worker del minimarket en tu computadora, comprobar cada ruta con curl, y escribir cinco funciones puras que reproducen las decisiones del servidor: enrutar, elegir el estado HTTP, nombrar claves de KV con su vida útil y no procesar dos veces el mismo mensaje.

Cómo se trabaja

La parte A es práctica real: necesitas la carpeta codigo/ del curso con npm install hecho. No usas cuenta de Cloudflare ni de Meta. La parte B son funciones de JavaScript puro que se comprueban en esta página; son versiones simplificadas de lo que hace worker.js, y escribirlas te obliga a entender cada decisión.

💡 Reto extra

Añade a mensajesNuevos un tope: si la lista trae más de 20 mensajes, procesa solo los 20 primeros. Piensa por qué un servidor público querría ese límite y qué debería hacer con los demás.

▶ Prueba tu código aquí (opcional)
Consola

Pasos

Marca cada paso a medida que lo completes. Tu avance se guarda en este navegador.

💡 Pista 1: Enrutar con orden

Evalúa las condiciones en este orden: primero «GET con hub.mode», luego GET / y /salud, luego POST a / o /webhook, luego GET /webhook sin hub.mode, y al final "no-encontrado". Usa params && "hub.mode" in params para no fallar si params es undefined.

💡 Pista 2: Por qué primero la firma

En recibirWebhook la firma se comprueba antes de intentar leer el JSON. Eso fija el orden de tu función: if (!firmaValida) return 401; va primero.

💡 Pista 3: Claves y vida útil

Un objeto { sesion: 2 * 86400, pedido: 30 * 86400, visto: 86400 } sirve para las dos funciones. Valida con tipo in objeto (o con Object.keys) antes de armar la clave.

💡 Pista 4: Idempotencia con Set

Recorre los eventos: si e.tipo !== "mensaje", sigue; si vistos.has(e.id), sigue; si no, vistos.add(e.id) y agrégalo al resultado. Como el add ocurre dentro del bucle, un duplicado dentro de la misma lista también se descarta.

🔎 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.

    funciones.js
    function enrutar(metodo, ruta, params) {
      var tieneHub = !!params && Object.prototype.hasOwnProperty.call(params, "hub.mode");
      if (metodo === "GET" && tieneHub) return "verificar";
      if (metodo === "GET" && ruta === "/") return "inicio";
      if (metodo === "GET" && ruta === "/salud") return "salud";
      if (metodo === "POST" && (ruta === "/" || ruta === "/webhook")) return "recibir";
      if (metodo === "GET" && ruta === "/webhook") return "verificar";
      return "no-encontrado";
    }
    
    function estadoDelPost(firmaValida, jsonValido) {
      if (!firmaValida) return 401;
      if (!jsonValido) return 400;
      return 200;
    }
    
    var DIA = 24 * 60 * 60;
    var TTL = { sesion: 2 * DIA, pedido: 30 * DIA, visto: DIA };
    
    function claveKV(tipo, id) {
      if (!Object.prototype.hasOwnProperty.call(TTL, tipo)) throw new Error("Tipo de clave desconocido: " + tipo);
      return tipo + ":" + id;
    }
    
    function ttlSegundos(tipo) {
      return TTL[tipo];
    }
    
    function mensajesNuevos(eventos, vistos) {
      var nuevos = [];
      eventos.forEach(function (e) {
        if (e.tipo !== "mensaje") return;
        if (vistos.has(e.id)) return;
        vistos.add(e.id);
        nuevos.push(e);
      });
      return nuevos;
    }