---
title: "Cómo crear un chatbot de IA con la API de OpenAI para responder en WhatsApp"
description: "Un webhook, una llamada a la API de OpenAI y una respuesta por la API de WhatsApp: el código completo de un chatbot que atiende en WhatsApp, Instagram y Messenger. Con memoria por contacto, control de costo y salida al humano."
url: "https://wame.api.br/blog/chatbot-ia-openai-whatsapp"
language: "pt-BR"
og:type: "article"
published_time: "2026-09-10"
modified_time: "2026-09-10"
author: "Raphael Serafim"
keywords: "chatbot ia whatsapp, openai api whatsapp, gpt en whatsapp, chatgpt whatsapp api, bot de ia whatsapp, integrar openai con whatsapp, asistente virtual whatsapp"
reading_time: "10 min de lectura"
---

# Cómo crear un chatbot de IA con la API de OpenAI para responder en WhatsApp

> Un webhook, una llamada a la API de OpenAI y una respuesta por la API de WhatsApp: el código completo de un chatbot que atiende en WhatsApp, Instagram y Messenger. Con memoria por contacto, control de costo y salida al humano.

**Un chatbot de IA en WhatsApp son tres piezas: recibir el mensaje, preguntarle al modelo, devolver la respuesta.** Ninguna es difícil — lo que suele costar es el medio de campo: el formato del webhook, la memoria de la conversación y saber cuándo la IA **no** debe responder.

Este artículo muestra el código completo, en Node.js, y resuelve las tres cosas.

## Lo que necesitas

1. Una instancia en la API — la no oficial conecta por código QR en segundos y sirve para probar.
2. Una clave de la [API de OpenAI](https://openai.com/es-419/index/openai-api).
3. Una URL pública para el webhook. En desarrollo, `ngrok` o similar.

## Pieza 1: recibir el mensaje

Apunta el webhook de tu instancia (formato `meta`) a tu URL. Todo evento llega en el sobre estándar de la Cloud API, y el campo `provider` dice el canal:

```json
{
  "object": "wame",
  "provider": "whatsapp",
  "entry": [{
    "id": "<instance-id>",
    "changes": [{
      "field": "messages",
      "value": {
        "messages": [{
          "from": "525512345678",
          "id": "wamid.XXXX",
          "type": "text",
          "text": { "body": "¿hacen envíos a Guadalajara?" }
        }]
      }
    }]
  }]
}
```

Esto importa más de lo que parece: como los tres canales llegan en el mismo sobre, el bot que escribas para WhatsApp ya atiende Instagram y Messenger. Es el [estándar único de webhook](/blog/api-instagram-messenger-misma-api-whatsapp) de la plataforma.

El extractor, con las guardas que evitan el 90% de los bugs:

```js
function extraer(body) {
  const msg = body?.entry?.[0]?.changes?.[0]?.value?.messages?.[0];

  // Los estados de entrega ("delivered", "read") también llegan acá.
  // Sin esta guarda, el bot se responde a sí mismo en bucle.
  if (!msg || msg.type !== 'text') return null;

  return {
    de: msg.from,
    texto: msg.text.body,
    canal: body.provider,
    messageId: msg.id,
  };
}
```

## Pieza 2: preguntarle al modelo

La API de OpenAI **no guarda estado**. Cada llamada es independiente, así que la memoria es tuya:

```js
import OpenAI from 'openai';

const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });

// En producción usa Redis o base de datos. En memoria se pierde al reiniciar.
const historial = new Map();

const SYSTEM = `Eres el agente de atención de Tienda Ejemplo, en WhatsApp.

Reglas:
- Responde en español neutro, en máximo 3 frases cortas.
- Nunca inventes plazos, precios ni disponibilidad.
- Si la pregunta exige un dato que no tienes, responde exactamente
  con el texto [HUMANO] y nada más.`;

async function responder(de, texto) {
  const anterior = historial.get(de) ?? [];

  // Últimos 10 mensajes: suficiente para el contexto y
  // bastante para que el costo no crezca sin límite.
  const mensajes = [
    { role: 'system', content: SYSTEM },
    ...anterior.slice(-10),
    { role: 'user', content: texto },
  ];

  const r = await openai.chat.completions.create({
    model: 'gpt-4o-mini',
    messages: mensajes,
    max_tokens: 300,
    temperature: 0.3,
  });

  const respuesta = r.choices[0].message.content.trim();

  historial.set(de, [
    ...anterior.slice(-10),
    { role: 'user', content: texto },
    { role: 'assistant', content: respuesta },
  ]);

  return respuesta;
}
```

Tres decisiones de ese código merecen explicación:

**`temperature: 0.3`** — la atención al cliente no quiere creatividad. Temperatura baja hace la respuesta más previsible y reduce la invención.

**`max_tokens: 300`** — WhatsApp no es lugar para párrafos largos. Además de mejorar la lectura, limita el costo por respuesta.

**`slice(-10)`** — el costo de OpenAI es por token, y el historial entero viaja en **cada** llamada. Sin recorte, una conversación larga se vuelve progresivamente más cara.

## Pieza 3: devolver por WhatsApp

```js
async function enviar(para, texto, canal) {
  await fetch(`https://server.wame.api.br/${process.env.WAME_KEY}/message/text`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ to: para, text: texto, channel: canal }),
  });
}
```

## Todo junto

```js
import express from 'express';

const app = express();
app.use(express.json());

app.post('/webhook/wame', async (req, res) => {
  // Responde 200 DE INMEDIATO. OpenAI tarda segundos, y un webhook
  // que demora se reenvía — el cliente recibiría la misma respuesta
  // dos o tres veces.
  res.sendStatus(200);

  const msg = extraer(req.body);
  if (!msg) return;

  try {
    const respuesta = await responder(msg.de, msg.texto);

    if (respuesta.includes('[HUMANO]')) {
      await enviar(msg.de, 'Un momento, te comunico con alguien del equipo.', msg.canal);
      await avisarAgente(msg);   // tu cola, tu CRM
      return;
    }

    await enviar(msg.de, respuesta, msg.canal);
  } catch (e) {
    console.error('falló la respuesta a', msg.de, e);
    await enviar(msg.de, 'Tuve un problema. Ya te paso con una persona.', msg.canal);
    await avisarAgente(msg);
  }
});

app.listen(3000);
```

Listo — unas 60 líneas para un bot de IA que atiende en los tres canales.

## El detalle que separa demo de producción

**Responder 200 antes de procesar.** Es la línea más importante del archivo. La llamada a OpenAI tarda de 1 a 5 segundos; si tu handler la espera antes de contestar al webhook, la entrega se considera fallida y se reenvía. El resultado es el cliente recibiendo la misma respuesta tres veces — y tú pagándola tres veces.

**Tener una salida al humano.** El `[HUMANO]` del system prompt existe para eso. Un bot que responde "no sé" es malo; uno que inventa el plazo de entrega es peor, porque se convierte en reclamo. Cómo funciona el otro lado —cola, asignación y el bot saliendo de escena— está en [varios agentes en el mismo número](/blog/varios-agentes-mismo-numero-whatsapp).

**Tratar el error como camino normal.** OpenAI va a fallar en algún momento: timeout, límite, indisponibilidad. El `catch` no deja al cliente en el vacío.

**No responderse a sí mismo.** La guarda en `extraer` se encarga: los estados de entrega y lectura también llegan al webhook.

## ¿Y si el webhook no llega?

Pasa, y casi siempre es una de las mismas causas. Antes de tocar el código, apunta el webhook a una URL de [webhook.site](https://webhook.site) y envía un mensaje: si el evento aparece ahí, el problema es tu servidor; si no aparece, es la configuración de la instancia. Esa prueba de 30 segundos separa los dos mundos. La guía completa está en [el webhook no llega: las 7 causas](/blog/webhook-whatsapp-no-llega-como-probar).

## Conclusión

El chatbot en sí es la parte fácil. Lo que decide si se queda en producción es el entorno: responder el webhook al instante, recortar el historial, tener salida al humano y tratar el error como camino esperado.

Empieza con una instancia no oficial y un número de prueba. Cuando el comportamiento esté bien, pasa a la [API oficial](/blog/whatsapp-business-api-oficial-que-es) — el webhook y el SDK son los mismos, así que el código del bot no cambia.

## Perguntas frequentes

### ¿Cómo conecto la API de OpenAI con WhatsApp?

Son tres piezas: un webhook que recibe el mensaje de WhatsApp, una llamada a la API de OpenAI con el historial de la conversación, y un POST a /{key}/message/text devolviendo la respuesta. El webhook recibe todos los canales en el mismo formato, así que el mismo código atiende WhatsApp, Instagram y Messenger.

### ¿Necesito n8n para hacer un bot de IA en WhatsApp?

No. n8n es cómodo si quieres armar el flujo visualmente o ya usas la herramienta. En código son unas 60 líneas, y ganas control total sobre la memoria, el costo y las reglas de cuándo no responder.

### ¿Cuánto cuesta tener un chatbot de IA en WhatsApp?

Dos costos separados: el de OpenAI, cobrado por token consumido, y el del mensaje. En la API no oficial el mensaje tiene precio fijo por instancia; en la oficial, Meta cobra por conversación. El costo de la IA es el que más varía y depende del tamaño del historial que envías en cada llamada.

### ¿Cómo hago que el bot recuerde la conversación?

La API de OpenAI no guarda estado: cada llamada es independiente. Guardas los últimos mensajes por contacto en un almacenamiento tuyo (Redis, base de datos o memoria) y los envías como historial en cada petición. Con los últimos diez suele alcanzar, y mantiene el costo previsible.

### ¿Qué hago cuando la IA no sabe responder?

Instruye al modelo en el system prompt para que devuelva un marcador acordado cuando no tenga certeza, y maneja ese marcador en tu código derivando a una persona. Un bot que inventa el plazo de entrega sale más caro que uno que pasa la pelota.
