Contenido del curso
Integración con la API de WhatsApp
Implementación de Servidor Express
Comunicación con la API de WhatsApp
Flujos de Interacción con la API de WhatsApp
Multimedia con WhatsApp API
Avances y Personalización
- 19

Integración de Google Sheets API para Guardar Datos del Bot
07:33 min - 20

Integración de Google Sheets con Node.js para Reservas Automáticas
18:34 min - 21

Conectar tu bot de WhatsApp con la API de OpenAI
08:50 min - 22

Integración de ChatGPT en Flujo de Mensajería con WhatsApp
10:40 min - 23

Enviar contacto de WhatsApp en emergencias
08:12 min - 24

Envío de ubicación con mapa en WhatsApp
09:54 min - 25

Refactor DRY en WhatsApp Service
11:03 min - 26

Despliegue de Bots de WhatsApp en Railway con Integración de GitHub
14:29 min - 27

Publicación y configuración de aplicaciones con API de WhatsApp
22:50 min - 28

Creación de Bots en WhatsApp: Domina la API y Optimiza Tu Negocio
02:52 min
Manejo de mensajes interactivos en WhatsApp
Resumen
Cuando tu bot de WhatsApp envía botones interactivos, el siguiente paso lógico es capturar la opción que elige el usuario y responder según corresponda. Aquí aprenderás a manejar mensajes de tipo interactive en Node.js, crear un switch para enrutar respuestas y resolver el error 400 que aparece cuando reutilizas lógica de eco sin ajustar el context message ID.
¿Por qué un mensaje interactivo no entra al flujo de texto?
El bot original solo escuchaba mensajes con message.type === 'text', así que cualquier respuesta proveniente de un botón quedaba sin procesar. La solución es agregar una rama nueva que detecte el tipo interactive [03:12] y extraiga el título o el ID del botón presionado.
Para capturar la elección del usuario se usa optional chaining y se normaliza el texto a minúsculas con toLowerCase(), lo que evita que un acento o una mayúscula rompan la comparación posterior.
javascript else if (message?.type === 'interactive') { const option = message?.interactive?.button_reply?.title.toLowerCase().trim(); await this.handleMenuOption(message.from, option); await whatsappService.markAsRead(message.id); }
¿Qué es optional chaining en JavaScript? Es el operador
?.que permite acceder a propiedades anidadas sin lanzar error si alguna esundefined. Útil cuando el objeto puede llegar incompleto desde la API.
¿Cómo enrutar cada opción del menú con un switch?
La función handleMenuOption recibe el número del usuario y la opción elegida, y usa un switch para definir qué responder en cada caso. Esta separación mantiene el código limpio y reutiliza el mismo sendMessage del servicio de WhatsApp.
Los tres casos definidos en la clase son:
- agendar: prepara el flujo para reservar una cita.
- consultar: invita al usuario a realizar su consulta.
- ubicacion: devuelve la ubicación del negocio.
javascript async handleMenuOption(to, option) { let response; switch (option) { case 'agendar': response = 'Agendar una cita'; break; case 'consultar': response = 'Realiza tu consulta'; break; case 'ubicacion': response = 'Esta es nuestra ubicación'; break; default: response = 'Lo siento, no entendí tu selección. Por favor, elige una de las opciones del menú.'; } await whatsappService.sendMessage(to, response); }
El bloque default es clave: cubre cualquier texto que no coincida con las opciones esperadas y guía al usuario de vuelta al menú [06:48].
¿Conviene validar por título o por ID del botón?
Validar por title es rápido pero frágil con tildes y mayúsculas. Validar por ID es más robusto porque el identificador no cambia aunque modifiques el texto visible. La clase deja como reto migrar la validación al ID y compartir la solución en comentarios.
¿Por qué falla el switch con la palabra ubicación? Porque el acento puede llegar codificado de forma distinta y romper la comparación. Lo más seguro es comparar contra el ID del botón o aplicar un regex que normalice acentos.
¿Por qué aparece el error 400 invalid request al responder?
Al probar el flujo con el botón agendar, la API devolvió un error 400 indicando que faltaba el parámetro context message_id [09:15]. El problema venía del bloque de eco que se había usado antes para responder citando el mensaje original.
Ese bloque enviaba un context con el ID del mensaje entrante, pero al cambiar al flujo interactivo ya no se cumplía la estructura esperada por la API de WhatsApp.
La solución fue comentar temporalmente esa lógica en el WhatsAppService para que el envío vuelva a ser un mensaje de texto plano:
- Si quieres replicar y citar el mensaje original, debes enviar el
context.message_id. - Si solo quieres responder, omite ese parámetro por completo.
Leer los logs es parte del trabajo: cada error cuenta una historia y suele apuntar al campo exacto que falta en el request.
¿Qué habilidades técnicas refuerza este flujo?
Más allá del bot, este ejercicio consolida prácticas de desarrollo backend que se aplican a cualquier integración con APIs de mensajería.
- Manejo de tipos de mensaje con condicionales
if/else ifpara diferenciar texto de interactivo [01:30]. - Optional chaining para navegar estructuras anidadas sin romper la app.
- Normalización de strings con
toLowerCase()ytrim()antes de comparar. - Patrón switch para enrutar lógica según la opción del usuario.
- Reutilización de servicios llamando a
whatsappService.sendMessagedesde distintos flujos. - Depuración con logs para interpretar errores HTTP como el 400 invalid request.
Con esto tu bot ya da la bienvenida, muestra un menú y reacciona a cada selección. El siguiente paso es enviar imágenes, audios y otros recursos para construir flujos completos de agendamiento, ubicación y captura de datos. ¿Cómo resolverías tú la validación con acentos o por ID? Cuéntalo en los comentarios.