Documentación Técnica del Chatbot de WhatsApp
Este documento detalla la arquitectura, los componentes clave, los flujos de conversación y las integraciones del chatbot de WhatsApp. Está diseñado para desarrolladores y personal técnico que necesiten comprender, mantener o extender la funcionalidad del bot.
1. Introducción
El chatbot de WhatsApp es una herramienta automatizada diseñada para asistir a los usuarios con diversas funcionalidades, incluyendo la descarga de instructivos, la generación de tickets de soporte y la gestión de alta de nuevos usuarios. Construido sobre el framework @builderbot/bot , se integra con el backend de la página web de SIGES para gestionar datos de usuarios, computadoras, instructivos y tickets (Freshdesk).
2. Arquitectura General
El chatbot sigue una arquitectura basada en flujos de conversación, donde cada flujo representa un camino lógico que el usuario puede seguir.
- Framework: @bot-whatsapp/bot
- Proveedor (Provider): BaileysProvider (para conexión con WhatsApp)
- Adaptador de Base de Datos (Database Adapter): MockAdapter (utilizado para simulación/pruebas; en un entorno de producción).
- Flujos (Flows): Módulos JavaScript que definen las interacciones del bot.
- APIs (Backend Integrations): Módulos JavaScript que encapsulan la lógica de comunicación con el servidor backend.
3. Estructura de Archivos y Carpetas
├── app.js
├── .env (esencial para configuración)
├── flows/
│ ├── altaBotUser/
│ │ ├── flujoAltaBotUser.js
│ │ ├── flujoAltaBotUserUnaEstacion.js
│ │ └── flujoConfirmacionAlta.js
│ ├── instructivos/
│ │ ├── flujoInstructivosArchivos.js
│ │ └── flujoInstructivosCategorias.js
│ ├── SOS/
│ │ ├── flujoSOS.js
│ │ └── flujoSOSUnaEstacion.js
│ ├── soporte/
│ │ ├── flujoSoporte.js
│ │ └── flujoSoporteUnaEstacion.js
│ │ ├── tiposProblemas/
│ │ │ ├── flujoAplicaciones.js
│ │ │ ├── flujoDespachosCio.js
│ │ │ ├── flujoImpresoraComun.js
│ │ │ ├── flujoImpresoraFiscal.js
│ │ │ ├── flujoLibroIva.js
│ │ │ ├── flujoServidor.js
│ │ │ └── flujoSiges.js
│ ├── flujoInactividad.js
│ └── flujoPrincipal.js
└── api/
├── apiInstructivos.js
├── apiMensajes.js
├── apiOpciones.js
├── apiSoporte.js
├── apiTickets.js
└── apiUsuarios.js
4. Flujos de Conversación (Flows)
Los flujos son esenciales para la lógica del chatbot, definiendo en ellos las secuencias de preguntas, respuestas y acciones que se realizan.
Existen tres flujos que tienen copias con el mismo nombre, pero agregando “Unaestacion” al final del mismo, se hizo de esta manera para manejar los casos en donde los usuarios del bot solo tengan una estación asociada. Los flujos afectados son: flujoAltaBotUser, flujoSOS y flujoSoporte. La lógica de los flujos como flujoSOSUnaEstacion es idéntica a la del flujoSOS pero quitando el apartado de selección de estaciones.
4.1. app.js
Este es el archivo principal que inicializa el bot.
- Configuración: Carga variables de entorno (dotenv), configura MockAdapter para la base de datos, BaileysProvider para WhatsApp y createFlow para manejar todos los flujos.
- Registro de Flujos: Todos los flujos del directorio flows/ son importados y registrados en el bot.
4.2. flujoPrincipal.js
Es el punto de entrada principal del chatbot, activado por la palabra clave "sigesbot".
- Inicio: Saluda al usuario y valida su número de teléfono contra el backend (validateUser de apiUsuarios.js). Si el usuario no está registrado, termina el flujo.
- Menú Inicial: Muestra un menú de opciones dinámico (opMenuInicial de apiOpciones.js) basado en los permisos del usuario (si puede generar tickets SOS o dar de alta nuevos usuarios agregará estas opciones al menú mostrado).
- Manejo de Opciones: Dirige al usuario a los flujos correspondientes (flujoSOS, flujoInstructivosCategorias, flujoSoporte, flujoAltaBotUser) según su selección.
- Inactividad: Incluye un mecanismo de detección de inactividad (idle: 300000 para 5 minutos) que redirige al flujoInactividad.js.
- Comando 'salir': Permite al usuario finalizar la conversación y regresar al inicio.
4.3. flujoInactividad.js
Este flujo se activa cuando el usuario permanece inactivo por un tiempo determinado en cualquier punto del bot.
- Mensaje de Inactividad: Informa al usuario sobre la inactividad.
- Fin del Flujo: Termina la conversación y le indica al usuario cómo reiniciar el bot.
4.4. Flujos de Instructivos
Gestionan la descarga de documentos.
- flujoInstructivosCategorias.js:
- Obtiene las categorías de instructivos dependiendo los permisos del usuario desde el backend y las muestra (obtenerCategorias de apiInstructivos.js).
- Permite al usuario seleccionar una categoría.
- Al seleccionar una categoría, obtiene los archivos asociados (obtenerArchivosDeCategoria) y los guarda en el estado para el siguiente flujo.
- Redirige a flujoInstructivosArchivos.js.
- flujoInstructivosArchivos.js:
- Muestra la lista de archivos disponibles en la categoría seleccionada.
- Permite al usuario seleccionar un archivo para descargar.
- Envía el archivo al usuario a través de WhatsApp (enviarArchivo de apiInstructivos.js).
- Ofrece opciones para volver a las categorías o al menú principal.
4.5. Flujos de Alta de Usuario
Gestionan el proceso de dar de alta nuevos números de teléfono para usar el chatbot.
- flujoAltaBotUser.js:
- Captura de Datos:Guía al usuario a través de una serie de preguntas para recopilar información del nuevo usuario:
- Nombre
- Número de teléfono (con validación de formato y adición de prefijo internacional)
- Cliente/Estación asociado (obtenido dinámicamente usando getUsers de apiTickets.js y apiUsuarios.js). Si solo hay un cliente, se asocia automáticamente.
- Permisos (dar de alta usuarios, ver instructivos admin/contables, enviar tickets SOS).
- Si es encargado de área (manager), solicita el área y el correo electrónico.
- Resumen: Al finalizar la captura, construye y muestra un resumen de los datos ingresados (buildNewUserInfoSummary de apiUsuarios.js).
- Redirección: Dirige a flujoConfirmacionAlta.js para la confirmación.
- Captura de Datos:Guía al usuario a través de una serie de preguntas para recopilar información del nuevo usuario:
- flujoConfirmacionAlta.js:
- Opciones de Confirmación: Presenta al usuario opciones para confirmar, cancelar o reiniciar el proceso de alta.
- Alta: Si se confirma, llama a altaBotuser de apiUsuarios.js para registrar el nuevo usuario en el backend.
- Limpieza de Estado: Limpia el estado newBotuser después de un alta exitosa o cancelación.
4.6. Flujos de Soporte
Gestionan la creación de tickets de soporte.
- flujoSoporte.js:
- Selección de Cliente: Identifica el cliente/estación asociado al usuario que reporta el incidente (getUsers de apiTickets.js). Si hay un solo cliente, lo asocia automáticamente. Si hay múltiples, pide al usuario que seleccione.
- Selección de Área: Solicita al usuario que elija el área donde se encuentra el puesto de trabajo (Playa/Boxes, Tienda, Administración).
- Selección de Puesto/PC: Obtiene una lista de PCs para el cliente y área seleccionados (computers de apiUsuarios.js, computerOptions de apiOpciones.js) y permite al usuario seleccionar una. Si no se conoce el PC, se puede indicar "0".
- Selección de Problema General: Presenta un menú de problemas generales (opMenuProblemas de apiOpciones.js) que varía según el área seleccionada (ej. "Libro IVA" y "Servidor" solo para Administración).
- Redirección: Dirige a flujos específicos de tipo de problema (ej. flujoAplicaciones.js, flujoImpresoraFiscal.js, etc.).
4.7. Flujos Específicos de Problemas (dentro de flows/soporte/tiposProblemas/)
Estos flujos son sub-flujos del flujoSoporte.js y se encargan de recopilar detalles específicos para cada tipo de problema antes de generar el ticket. Todos comparten una estructura similar:
- flujoAplicaciones.js: Problemas con aplicaciones (propias, Mercado Pago, etc.).
- flujoDespachosCio.js: Problemas relacionados con Despachos CIO.
- flujoImpresoraComun.js: Problemas con impresoras comunes/de oficina.
- flujoImpresoraFiscal.js: Problemas con impresoras fiscales/comanderas.
- flujoLibroIva.js: Problemas con el Libro IVA (compra/venta), incluye validación de formato de período.
- flujoServidor.js: Problemas con el servidor.
- flujoSiges.js: Problemas con el Sistema SIGES (Facturación, Cierre de turno, Informes, Otro).
Estructura Común de estos Flujos:
- Selección de Sub-tipo de Problema (si aplica): Pregunta más detalles sobre el problema específico dentro de la categoría general.
- Descripción del Problema: Solicita una descripción detallada por escrito o mediante un audio. Utiliza addAudio de apiTickets.js para manejar archivos de audio.
- Adjuntar Imagen (Opcional): Permite al usuario adjuntar una imagen relevante al ticket. Utiliza addImage de apiTickets.js para manejar archivos de imagen.
- Nivel de Urgencia: Solicita al usuario que clasifique la urgencia del ticket (Bajo, Medio, Alto).
- Confirmación de Envío:Ofrece la opción de enviar o cancelar el ticket.
- Si se envía, llama a sendProblemTicket de apiTickets.js para generar el ticket en Freshdesk.
- Si el usuario está en modo "testing" (configurado en el backend para el selectedUser), se muestra un resumen del ticket sin enviarlo realmente (buildTicketSummaryMessage).
- Limpia los adjuntos de correo (clearMailAttachments) y el período (period) del estado al finalizar o cancelar.
4.8. flujoSOS.js
Este flujo está diseñado para situaciones de alta urgencia ("SOS").
- Confirmación de Urgencia: Pregunta al usuario si más de la mitad de los puntos de venta no pueden facturar.
- Selección de Cliente: Similar al flujo de soporte, identifica o permite seleccionar el cliente afectado.
- Descripción y Adjuntos: Solicita una descripción del incidente (texto o audio) y permite adjuntar una imagen, de manera similar a los flujos de soporte.
- Generación de Ticket SOS: Llama a sendSosTicket de apiTickets.js para crear un ticket de alta prioridad en Freshdesk.
- Modo Testing: Si el usuario está en modo "testing", muestra un resumen del ticket SOS sin enviarlo.
5. Módulos de API (api/ folder)
Estos módulos contienen la lógica para interactuar con servicios externos y manejar datos.
5.1. apiMensajes.js
Contiene funciones utilitarias para enviar mensajes a través del proveedor de WhatsApp.
- respuesta(from, provider, text): Envía un mensaje de texto simple al usuario.
- respuestaConDelay(from, provider, text): Envía un mensaje de texto con un pequeño retraso (600ms), útil para asegurar que los mensajes lleguen en orden.
5.2. apiInstructivos.js
Maneja la integración con Google Drive (o un servicio similar) para los instructivos.
- obtenerCategorias(): Realiza una solicitud GET al backend para obtener una lista de carpetas (categorías) de instructivos.
- obtenerArchivosDeCategoria(folderId): Realiza una solicitud GET al backend para obtener los archivos dentro de una carpeta específica.
- enviarArchivo(from, url, filename, provider): Envía un documento (archivo) a través de WhatsApp utilizando la URL proporcionada.
5.3. apiOpciones.js
Genera las opciones de menú dinámicamente.
- opMenuInicial(state): Construye el menú principal del bot basándose en los permisos del usuario (canSOS, createUser) almacenados en el state.
- computerOptions(state): Genera una lista formateada de puestos de trabajo/PCs para que el usuario seleccione, obteniendo los datos del state.
- opMenuProblemas(state): Devuelve un array de problemas de soporte, que varía si el área seleccionada es "Administración" (incluye "Libro IVA" y "Servidor").
5.4. apiTickets.js
Es un módulo crucial para la gestión de tickets y la interacción con Freshdesk a través del backend.
- isValidPeriodFormat(periodString) y isValidDate(dateString): Funciones de utilidad para validar el formato de fecha y período, utilizadas en flujoLibroIva.js.
- computerInfo(state, option): Actualiza el estado con la información del PC seleccionado (alias, TeamViewer ID, etc.) basándose en la opción elegida por el usuario.
- addAudio(state, from, ctx): Descarga un mensaje de audio de WhatsApp, lo convierte a un buffer, utiliza la función auxiliar convertToMp3Buffer para pasarlo a formato.mp3 y lo añade a un array de mailAttachments en el estado.
- addImage(state, from, ctx): Similar a addAudio, pero para imágenes.
- clearMailAttachments(state): Limpia el array de adjuntos de correo del estado (aquí se guardan los audios y fotos enviados por los clientes).
- sendProblemTicket(state, from):
- Recopila todos los datos relevantes del ticket del estado (selectedUser, area, generalProblem, typeProblem, etc).
- Construye el subject y la description del ticket de forma dinámica.
- Utiliza FormData para enviar los datos del ticket y los adjuntos (audio/imagen) al endpoint /freshdesk/tickets del backend.
- Requiere process.env.BACKEND_STATIC_API_KEY para autenticación con el backend.
- Limpia los adjuntos y el período del estado después de enviar.
- sendSosTicket(state, from):
- Similar a sendProblemTicket, pero específico para tickets SOS.
- Establece la prioridad en '4' (Urgencia) y el subject con un prefijo *TICKET SOS*.
- También maneja adjuntos y se comunica con el mismo endpoint de Freshdesk.
- getUsers(state, from):
- Obtiene la lista de clientes asociados al usuario actual del estado (state.get('users')).
- Almacena estas opciones en altaBotuserClientsOptions en el estado para su uso en los flujos de alta/soporte.
- Devuelve una cadena formateada con las opciones de clientes para mostrar al usuario.
- buildTicketSummaryMessage(state, from):
- Construye un mensaje de resumen detallado de un ticket utilizando todos los datos recopilados en el estado.
- Es utilizado en el modo "testing" para mostrar al usuario los datos que se enviarían en el ticket.
- Limpia los adjuntos y el período del estado después de construir el resumen.
5.5. apiUsuarios.js
Maneja la validación de usuarios y la gestión de datos de usuarios y computadoras.
- validateUser(state, from):
- Realiza una solicitud GET al backend (/botusers?phone=${from}) para verificar si un número de teléfono está registrado.
- Si el usuario existe, actualiza el estado con sus credenciales (creds: createUser, canSOS, adminPdf, id) y los clientes asociados (users).
- Devuelve true si el usuario existe, false en caso contrario.
- validateUserID(state, fullId):
- Realiza una solicitud GET al backend (/clients?id=${fullId}) para obtener información detallada de un cliente por su ID.
- Actualiza el estado con la información del cliente (info, vip, vipmail, testing).
- Devuelve el objeto de usuario si se encuentra, false en caso contrario.
- computers(state):
- Obtiene la lista de computadoras (PCs) asociadas a un cliente y área específicos desde el backend (/pcs?clientId=${userId}&area=${zone}).
- Ordena las computadoras por alias y las guarda en el estado (computers).
- altaBotuser(state):
- Realiza una solicitud POST al backend (/botusers) para dar de alta un nuevo usuario del bot, utilizando los datos recopilados en el estado (newBotuser).
- buildNewUserInfoSummary(state):
- Construye un resumen formateado de los datos del nuevo usuario que se va a dar de alta, utilizando la información de newBotuser en el estado.
6. Manejo del Estado (State Management)
El framework Bot-WhatsApp utiliza un objeto state (proporcionado en las funciones addAnswer y addAction) para mantener el contexto de la conversación para cada usuario.
- state.update(key, value): Se utiliza para almacenar o actualizar datos relevantes para el usuario actual.
- state.get(key): Se utiliza para recuperar datos previamente almacenados.
Ejemplos de datos almacenados en el estado:
- creds: Permisos del usuario actual.
- users: Clientes asociados al usuario actual.
- selectedUser: Información del cliente/estación seleccionado para un ticket.
- area: Área seleccionada para un ticket de soporte ('P', 'S', 'A').
- generalProblem: Categoría general del problema (ej. "Sistema SIGES").
- typeProblem: Tipo específico de problema (ej. "Facturación").
- pf: Puesto de trabajo/PC seleccionado.
- tv: ID de TeamViewer.
- description: Descripción del problema.
- priority: Nivel de urgencia del ticket.
- period: Período para problemas de Libro IVA.
- mailAttachments: Array de objetos (buffers) de audio/imagen para adjuntar al correo del ticket.
- newBotuser: Objeto temporal que almacena los datos de un nuevo usuario durante el proceso de alta.
- instructivosCategorias: Lista de categorías de instructivos.
- instructivosArchivos: Lista de archivos dentro de una categoría de instructivos.
7. Variables de Entorno
El bot depende de variables de entorno para su correcto funcionamiento. Estas deben estar definidas en un archivo .env en la raíz del proyecto.
- SERVER_URL: La URL base del servidor backend que expone las APIs para usuarios, clientes, PCs, instructivos y Freshdesk.
- Ejemplo: SERVER_URL=http://localhost:3000.
- BACKEND_STATIC_API_KEY: Una clave API estática utilizada para autenticar las solicitudes del bot al backend, especialmente para la creación de tickets en Freshdesk.
8. Despliegue
- Instalar dependencias (npm install).
- Configurar .env.
- Iniciar bot (node app.js).
- Iniciar backend (npm run start).