Integración de ChatGPT en Flujo de Mensajería con WhatsApp
Resumen
¿Cómo integrar OpenAI Service con el flujo de un chatbot?
Integrar un servicio de inteligencia artificial como OpenAI en un chatbot puede ser un proceso desafiante pero gratificante. La posibilidad de mejorar la comunicación automatizada y ofrecer respuestas precisas da un valor añadido enorme a cualquier proyecto. Aquí te mostramos un proceso paso a paso para lograr esta integración usando Assistant State y OpenAI.
¿Cómo inicializar el estado del asistente?
Para comenzar, debes asegurarte de que el servicio OpenAI ya esté conectado y haya un prompt del sistema esperando un mensaje del usuario. La clave inicial es establecer el estado del asistente dentro del constructor de la lógica existente. Este estado, Assistant State, será crucial para saber cuándo pasar al flujo de preguntas y respuestas, permitiendo que la inteligencia artificial responda de manera adecuada.
// Inicialización del estado del asistenteconstructor(){this.assistantState={};}// Definición del estado al recibir mensaje del usuarioelseif(this.assistantState){// Lógica de manejo de estado}
¿Cómo detectar el estado del asistente?
El siguiente paso es modificar el manejo de los mensajes entrantes para que el sistema pueda detectar cuando el estado del asistente está presente. Esto permitirá desviarse al flujo adecuado de procesamiento, utilizando una serie de condicionales para manejar las diferentes lógicas.
// Detectar el estado y redireccionar el flujoelseif(this.assistantState&& messageFrom){awaitthis.handleAssistantFlow(messageFrom, incomingMessage);}
¿Cómo manejar el flujo del asistente?
Para manejar el flujo del asistente, es necesario implementar la lógica que interactúe con el servicio de OpenAI. Esto involucra crear una función llamada handleAssistantFlow y manejar el estado de interacción con el usuario.
// Implementación del flujo del asistenteasynchandleAssistantFlow(user, message){const state =this.assistantState[user.id];let response;if(state.step==='question'){ response =await openAIService.message(user.message);}// Enviando respuesta al usuarioawait whatsappService.sendMessage(user, response);// Lógica para botones de interacciónconst menuMessage ="¿La respuesta fue de ayuda?";const buttons =[{type:'reply',reply:{id:'option1',title:'Sí, gracias.'}},{type:'reply',reply:{id:'option2',title:'Hacer otra pregunta'}},{type:'reply',reply:{id:'option3',title:'Emergencia'}}];await whatsappService.sendInteraction(user, menuMessage, buttons);}
¿Cómo enviar interacciones basadas en botones?
Una característica poderosa es enviar interacciones que no solo se limitan a texto, sino también incluyen opciones de botón. Esta funcionalidad no solo mejora la experiencia del usuario, sino que también permite respuestas rápidas a situaciones de emergencia o seguimiento de preguntas.
// Ejemplo de estructura de botonesconst menuMessage ="¿La respuesta fue de ayuda?";const buttons =[{type:'reply',reply:{id:'option1',title:'Sí, gracias.'}},{type:'reply',reply:{id:'option2',title:'Hacer otra pregunta'}},{type:'reply',reply:{id:'option3',title:'Emergencia'}}];// Envío del menú de botonesawait whatsappService.sendInteraction(user, menuMessage, buttons);
¿Cómo probar y ajustar el flujo?
Una vez que toda la lógica esté en su lugar, es importante validar y probar el flujo completando varias interacciones, evaluando tanto la precisión de las respuestas del GPT como la funcionalidad de los botones de interacción. Invita a los usuarios a probar preguntando: "Mi perro tiene dos días sin querer comer y está vomitando", para recibir respuestas y verificar si las opciones de interacción funcionan correctamente. Sin embargo, recuerda personalizar cualquier mensaje automatizado conforme a la sensibilidad de los usuarios.
Sugerencias y mejoras
Siempre es recomendable recoger retroalimentación y ajustar el flujo según los comentarios de los usuarios. También, considerar envolver toda la lógica en pruebas para garantizar la integridad del sistema. Compartir en comunidad mejora significativamente la experiencia, además de que puedes comentar con otros desarrolladores tus PROM para enriquecer las capacidades y eficacia de las respuestas de GPT en diversos escenarios.
si estas en el 2025 sin estas modificaciones no funcionará tu proyecto
en openAiService() el modelo es model: 'gpt-4o-mini', el gpt-4 ya no esta en uso
en la funcion handleMenuOption() en el case de consultar agrega this.assistandState[to] = { step: 'question' }; antes del response si no no va a funcionar tu implementacion
agrega 10 dolares de saldo porque si no no va a funcionar openAI
Al 1° de febrero de 2025, seguí los pasos que mencionaste, sin agregar los 10 dólares, y me funcionó la API de OpenAI.
La configuración funcionó perfecto, pero si me obliga a cargar al menos 5USD. Según leo en la documentación esto depende del país donde estés geográficamente hablando.
---- IMPORTANTE ----
La API de WhatsApp para los títulos de los botones de respuesta rápida puede tener un máximo de 20 caracteres en su título. Si pones uno mas totea. si pones 4 botones totea.
El profe llega al limite pero no lo dice, costo un chingo hallar el fallo
EJEMPLO
const buttons =[{type:"reply",reply:{id:"option_4",title:"Si"// Pasa: Este título tiene 2 caracteres, está dentro del límite de 20.}},{type:"reply",reply:{id:"option_5",title:"Tengo duda"// Pasa: Este título tiene 11 caracteres, está dentro del límite de 20.}},{type:"reply",reply:{id:"option_6",title:"Este título es demasiado largo"// No pasa: Tiene 29 caracteres, excede el límite de 20.}},];
Yo me base en la siguiente formula para tener un prompt efectivo [ROL] + [TAREA] + [INSTRUCCIONES] + [EJEMPLO/DATOS] y el resultado al cual llegue fue el siguiente:
"Eres un veterinario experto, tu tarea es responder todas las preguntas de los usuarios de la empresa Medpet, debes ser amable y coordial con los usuarios, en el momento que no tengas una respuesta clara deberas referirlo a un veterinario humano y que se dirija de forma fisica a un centro de atención, tus instrucciones son 1) Si el usuario te pregunta por algun medicamento deberas darle instrucciones especificas. 2) Asesorar a los usuarios con los posibles sintomas u enfermedades que tenga su mascota. 3) Si consideras que los sintomas de la mascota son graves debes indicarle que debe ir de forma inmediata a un centro asistencial Medpet 4) Solo puedes responder en ingles o español dependiendo del idioma en el cual te escriba el usuario, 5) Al inicio siempre pregunta por el nombre del usuario y a partir de alli llamalo por su nombre 6) Cuando el usuario te hable de su mascota, preguntale por su nombre y si te vas a referir a la mascota hazlo por su nombre, los datos de Medpet son los siguientes, es una cadena de centros asistenciales veterinario con muchos años de experiencia y con sedes en toda latinoamerica y dedicada a combinar tecnologia y veterinaria para el bienestar de las mascotas, su telefono de contacto es 477516242117521"
Mi repositorio es el siguiente donde me encuentro trabajando el proyecto:
El día que me encuentro acá es 3 de Marzo de 2025. Me encontre con 2 novedades y acá les dejo mi solución.
Debi cambiar CHATGPT_API_KEY por OPENAI_API_KEY en el archivo de env. No me lo reconoció de la manera anterior.
Es necesario tener saldo cargado en la consola de Open AI. En mi caso debí cargar 5 usd
Me funcionó
Yo lo adapte para usar con gemini ya que no pide algun pago para probarlo, cree otro archivo geminiAiService.js
import{GoogleGenAI}from"@google/genai";importconfigfrom"../config/env.js";const prompt ='Eres parte de un servicio de asistencia online y debes de comportarte como un veterinario de un comercio llamado "MedPet". Resuelve las preguntas lo más simple posible, con una explicación posible. Si es una emergencia o debe de llamarnos (MedPet). Debes de responde en texto simple como si fuera un mensaje de un bot conversacional, no saludes, no generas conversación, solo respondes con la pregunta del usuario.';const client =newGoogleGenAI({apiKey: config.GEMINI_API_KEY});constgeminiAiService=async(message)=>{try{const response =await client.models.generateContent({model:"gemini-2.5-flash",config:{systemInstruction: prompt,},contents: message,});return response.text;}catch(error){console.error(error);}};exportdefault geminiAiService;
Nose olviden de agregar la nueva apikey de chagpt en el archivo env.js
No se olviden agregar la funcion dentro del menu, tal cual como lo hicimos con las reservas
Debemos tener un plan de suspcricion en openAi, he intentado con modelos mas antiguos y aun asi me pide que me suscriba.
Yo tengo suscripción y sigue sin permitirme
Recordar que tener suscripcion en chatGpt no es lo mismo para usar la api eso se paga aparte
En lugar de utilizar ChatGPT de OpenAI, utilice Claude de Antrhopic pero con una librería llamada de los creadores de NextJS, que nos ayuda a poder abstraer los modelos de IA que utilicemos o inclusive mezclarlos, les dejo la muestra de mi código.
ai.service.js
import{ createAnthropic }from"@ai-sdk/anthropic";import{ generateText }from"ai";importconfigfrom"../config/env.js";const anthropicClient =createAnthropic({apiKey: config.AI_API_KEY,});constAIService=async(message)=>{try{const{ text }=awaitgenerateText({model:anthropicClient("claude-3-7-sonnet-20250219"),messages:[{role:"system",content:"Comportarte como un veterinario, deberás de resolver las preguntas lo más simple posible. Responde en texto plano, como si fuera una conversación por WhatsApp, no saludes, no generas conversaciones, solo respondes con la pregunta del usuario.",},{role:"user",content: message,},],});return text;}catch(error){console.log("AI ERROR", error);}};exportdefaultAIService;````message.handler.js````js
if(state.step==='question'){ response =awaitAIService(message);}
Recomiendo trabajar con la API de ChatGPT, pero si no quieren o no pueden pagar tokens, también pueden consultar cómo crear un servicio con la API de Gemini de Google.
Pueden probar ambas opciones. Solo deben agregar un nuevo archivo dentro del proyecto con la integración de la API de Gemini de Google.
Es una opción conveniente porque ofrece un millón de tokens gratis, no impone pagos mínimos y, además, su lógica es bastante similar para adaptarla con cada clase.
¿para usar la API de OpenAI es necesario configurar alguna tarjeta o pagar?
Si OpenAI es de pago, tipo prepago, te ofrecen $5 de crédito gratis (sin necesidad de cargar una tarjeta) para que puedas experimentar con la API. La verdad es que este crédito es más que suficiente para hacer bastantes pruebas con prompts cortos, que consumen pocos tokens. El cobro se realiza por tokens, y el precio de estos varía según el modelo de GPT que configures. GPT-4 es bastante más caro que GPT-3.5, que es muy bueno para este caso. Yo implementé un chatbot, y la verdad es que funciona muy bien, aunque requiere dedicarle tiempo a elaborar buenos prompts
Les dejo una actualización de la configuración de openAIServices.js para que sea más costo-eficiente:
Aquí tienes una versión optimizada de tu código para GPT-4o Mini, con el objetivo de minimizar los costos sin afectar la calidad de las respuestas. Se han agregado configuraciones adicionales para controlar el consumo de tokens y mejorar la eficiencia.
Se reduce el costo al limitar la cantidad de tokens generados (max_tokens).
Se optimiza la temperatura para un equilibrio entre creatividad y precisión.
Se añade frequency_penalty y presence_penalty para evitar respuestas demasiado largas o repetitivas.
Se asegura que las respuestas sean concisas y útiles.
importOpenAIfrom'openai';// Importar variables de entornoimportconfigfrom'../src/config/env.js';// Crear Cliente para que reciba la API Keyconst client =newOpenAI({apiKey: config.CHATGPT_API_KEY,});// Servicio de respuesta de ChatGPT optimizadoconstOpenAIService=async(message)=>{try{const response =await client.chat.completions.create({model:'gpt-4o-mini',// Modelo más costo-eficientemessages:[{role:'system',content:'Eres un veterinario experto de Medpet, una cadena de centros asistenciales veterinarios en Latinoamérica. Debes responder de forma concisa y clara, sin extenderte innecesariamente. Si un caso es grave, indica al usuario que acuda inmediatamente a un centro Medpet. Responde solo en el idioma en el que te escriban (inglés o español).'},{role:'user',content: message }],temperature:0.5,max_tokens:250,frequency_penalty:0.2,presence_penalty:0.1,});return response.choices[0].message.content;}catch(error){console.error('Error en OpenAIService:', error);return"Lo siento, ocurrió un error procesando tu solicitud.";}};exportdefaultOpenAIService;```importOpenAIfrom'openai';// Importar variables de entornoimportconfigfrom'../src/config/env.js';// Crear Cliente para que reciba la API Keyconst client =newOpenAI({  apiKey: config.CHATGPT\_API\_KEY,});// Servicio de respuesta de ChatGPT optimizadoconstOpenAIService=async(message)=>{ try{ const response =await client.chat.completions.create({  model:'gpt-4o-mini',// Modelo más costo-eficiente  messages: \[ {role:'system',content:'Eres un veterinario experto de Medpet, una cadena de centros asistenciales veterinarios en Latinoamérica. Debes responder de forma concisa y clara, sin extenderte innecesariamente. Si un caso es grave, indica al usuario que acuda inmediatamente a un centro Medpet. Responde solo en el idioma en el que te escriban (inglés o español).'}, {role:'user',content: message } ],  temperature:0.5,// Menos creatividad, respuestas más directas  max\_tokens:250,// Limita la longitud de la respuesta  frequency\_penalty:0.2,// Evita repeticiones innecesarias  presence\_penalty:0.1,// Evita respuestas redundantes }); return response.choices\[0].message.content; }catch(error){ console.error('Error en OpenAIService:', error); return"Lo siento, ocurrió un error procesando tu solicitud."; }};exportdefaultOpenAIService;
Adapten mejor con Groq, ahí pueden utilizar llama como IA
en mi app utilice gemini:
import fs from 'fs';
import path from 'path';
import { GoogleGenAI } from '@google/genai';
import { GEMINI_API_KEY } from '../config/envs.js';
Eres el asistente virtual inteligente del conjunto residencial Parques de Castilla 2.
Tu objetivo es responder de forma amable, clara y concisa las dudas de los residentes.
SIEMPRE debes basar tus respuestas estrictamente en el Manual de Convivencia que tienes indexado aquí:
\"\"\"
${MANUAL_CONVIVENCIA || "Horario de mudanzas: Lunes a Sábado de 8am a 5pm. Domingos y festivos prohibido."}
\"\"\"
Si el usuario te pregunta por algo que NO está en el manual o requiere atención humana,
indícale de forma muy educada que debe comunicarse directamente con la administración.
Usa un tono cordial, vecino y cercano. Máximo 3 o 4 líneas por respuesta.
`,
temperature: 0.3,
},
});
return response.text;
} catch (error) {
console.error('❌ Error real en el servicio de Gemini:', error.message);
return 'Lo siento, vecino. En este momento tengo un problema técnico para consultar el manual.';
}
};
A la fecha tanto openIA y deepSeek requieren créditos para poder utilizarla, yo utilice openrouter.ai que es gratuita
🦄✨No sé si tenga algo que ver
Pero anteriormente ya había usado los modelos de openAI y no tenía problema al usarlos. Pero actualmente a pesar de que tengo los $18 que se supone que te dan gratis cada mes, no me permite usar la api si no agrego un método de pago y una recarga de mínimo $5.
Si alguien sabe cómo funciona, le agradecería que me informe un poco :c
Para los que le interese cambiar de AI por problemas con openIA, les recomiendo usar OPENROUTER, tiene muchas IA gratis y es facil de implementar
Si quieren integrar algo gratuito pueden usar:
Obvio tienen que entrenarlo un poco porque es algo rebelde jajaj pero aún así es muy bueno