Bot de WhatsApp con IA local
Qué cubriremos aquí
- Los dos caminos hacia un bot de WhatsApp: API Business oficial vs. librerías no oficiales.
- Ejemplo práctico con whatsapp-web.js/Baileys y Ollama.
- Emparejamiento por código QR, persistencia de sesión, funcionamiento en grupos.
- Riesgos legales y técnicos, y cuándo conviene cada enfoque.
- Extensiones: RAG, imágenes, notas de voz, moderación.
Introducción
WhatsApp es el mensajero más usado en Alemania, pero también la plataforma menos amigable con bots. No existe una API de bot oficial y gratuita para cuentas privadas. Hay dos caminos disponibles:
- WhatsApp Business Platform (Cloud API): Oficial, estable, pero compleja: requiere cuenta de desarrollador en Meta, verificación empresarial, mensajes de plantilla aprobados, y costos por conversación.
- Librerías no oficiales (whatsapp-web.js, Baileys): Simulan WhatsApp Web, funcionan con cuentas normales, pero violan los términos de servicio y conllevan riesgo de bloqueo.
Este artículo explora ambos caminos y aclara cuándo cada uno tiene sentido.
Casos de uso típicos
- Asistente interno del equipo: Los empleados consultan al bot en WhatsApp, con documentación interna mediante RAG.
- Atención al cliente de primer nivel: Responder preguntas frecuentes, escalar casos complejos a personas.
- Notificaciones: Alertas del servidor, recordatorios de citas, estado de pedidos directamente al móvil.
- Bot para familias o asociaciones: Obtener información, mantener listas, recordar fechas.
- Cuidado con la visibilidad pública: Para canales de clientes públicos, la API Business es el único camino seguro.
Opción 1: Librerías no oficiales (whatsapp-web.js / Baileys)
Cómo funciona
whatsapp-web.js (Node.js) y Baileys (TypeScript) hablan el protocolo de WhatsApp Web: tu bot se empareja como un segundo dispositivo mediante código QR. Necesitas tu propio número (también funciona un teléfono fijo: verificación por llamada).
npm install whatsapp-web.js qrcode-terminal axios
Bot mínimo con Ollama
const { Client, LocalAuth } = require('whatsapp-web.js');
const qrcode = require('qrcode-terminal');
const axios = require('axios');
const client = new Client({
authStrategy: new LocalAuth({ dataPath: './session' }),
puppeteer: { headless: true, args: ['--no-sandbox'] }
});
client.on('qr', qr => qrcode.generate(qr, { small: true }));
client.on('ready', () => console.log('Bot bereit'));
client.on('message', async msg => {
if (msg.fromMe || !msg.body) return;
// Nur auf Direktnachrichten oder Erwähnungen reagieren
const chat = await msg.getChat();
if (chat.isGroup && !msg.body.startsWith('!ki')) return;
const prompt = msg.body.replace(/^!ki\s*/, '');
try {
const res = await axios.post('http://localhost:11434/api/chat', {
model: 'llama3.1:8b',
messages: [
{ role: 'system', content: 'Du bist ein hilfsbereiter Assistent. Kurze Antworten.' },
{ role: 'user', content: prompt }
],
stream: false
});
await msg.reply(res.data.message.content);
} catch (e) {
await msg.reply('Fehler: Ollama nicht erreichbar.');
}
});
client.initialize();
Ejecuta el script, escanea el código QR en la terminal con tu móvil (WhatsApp → Dispositivos vinculados). Listo.
Variante con Baileys (sin navegador headless)
Baileys implementa el protocolo de forma nativa, sin necesidad de Chromium y con mucha menos memoria:
const { makeWASocket, useMultiFileAuthState } = require('@whiskeysockets/baileys');
const { state, saveCreds } = await useMultiFileAuthState('./session');
const sock = makeWASocket({ auth: state });
sock.ev.on('creds.update', saveCreds);
sock.ev.on('messages.upsert', async ({ messages }) => {
const m = messages[0];
if (!m.message?.conversation || m.key.fromMe) return;
// Llamada a Ollama como arriba, luego:
await sock.sendMessage(m.key.remoteJid, { text: 'Respuesta...' });
});
Los riesgos, siendo honestos
- Bloqueo de cuenta: Meta borra regularmente los clientes no oficiales. Usa un número extra, nunca la principal.
- Las sesiones se rompen: Las sesiones de WhatsApp Web expiran, tu bot debe manejar el reemparejamiento.
- Sin garantías de operación: No es apto para clientes empresariales, el número puede desaparecer en cualquier momento.
- E2EE se mantiene: Los mensajes siguen siendo E2E cifrados, el bot descifra localmente, lo cual es bueno para la privacidad.
Opción 2: WhatsApp Business Platform (Cloud API)
Configuración general
- Cuenta de desarrollador en Meta → Crear app → Añadir «WhatsApp»
- Verificar número de prueba o tu número empresarial propio (requiere verificación de empresa)
- Configurar webhook en tu servidor
- Generar token permanente
Recibir mensajes (Webhook)
from flask import Flask, request
import requests
app = Flask(__name__)
VERIFY_TOKEN = "dein-verify-token"
WA_TOKEN = "dein-permanent-token"
PHONE_ID = "deine-phone-number-id"
@app.route("/webhook", methods=["GET"])
def verify():
if request.args.get("hub.verify_token") == VERIFY_TOKEN:
return request.args.get("hub.challenge")
return "Forbidden", 403
@app.route("/webhook", methods=["POST"])
def receive():
data = request.json
for entry in data.get("entry", []):
for change in entry.get("changes", []):
for msg in change.get("value", {}).get("messages", []):
text = msg["text"]["body"]
sender = msg["from"]
answer = ask_ollama(text)
send_message(sender, answer)
return "OK", 200
def ask_ollama(prompt):
r = requests.post("http://localhost:11434/api/chat", json={
"model": "llama3.1:8b",
"messages": [{"role": "user", "content": prompt}],
"stream": False
})
return r.json()["message"]["content"]
def send_message(to, text):
requests.post(
f"https://graph.facebook.com/v19.0/{PHONE_ID}/messages",
headers={"Authorization": f"Bearer {WA_TOKEN}"},
json={
"messaging_product": "whatsapp",
"to": to,
"type": "text",
"text": {"body": text[:4000]}
}
)
Limitaciones importantes de la API Business
- Ventana de 24 horas: Los mensajes sin costo solo funcionan si el usuario escribió en las últimas 24 horas. Si no, solo mensajes de plantilla (aprobados por Meta).
- Costos: Aproximadamente 0,07-0,11 € por conversación en Alemania. Desde 2024, algunas conversaciones de servicio son gratuitas, pero las de marketing son más caras.
- Verificación obligatoria: Sin empresa verificada, estás limitado a 250 conversaciones en 24 horas.
Extensiones
RAG: Conocimiento de documentos
Mismo patrón que en el bot de Telegram, mensaje entrante → embedding → búsqueda en Qdrant → contexto a Ollama:
def ask_ollama_with_rag(prompt):
context = search_qdrant(prompt) # Top-3-Chunks
r = requests.post("http://localhost:11434/api/chat", json={
"model": "llama3.1:8b",
"messages": [
{"role": "system", "content": f"Nutze diesen Kontext:\n{context}"},
{"role": "user", "content": prompt}
],
"stream": False
})
return r.json()["message"]["content"]
Transcribir notas de voz
Notas de voz de WhatsApp (Opus-OGG) → Whisper local → texto → Ollama. Con whatsapp-web.js usa msg.downloadMedia(), con la API Business: obtén la ID de media → descarga desde el endpoint.
Funcionamiento en grupos
- En grupos, reacciona solo ante el prefijo (
!ki) o menciones, si no el bot leerá todo el chat. - Lista de administradores para comandos de moderación (
!kick,!warn). - Whitelist de IDs de grupo: el bot debe estar activo solo en grupos autorizados.
Transferencia a humanos (Business API)
Patrón “Bot primero, fallback humano”: cuando la IA tiene dudas, deriva la conversación a un empleado mediante notificación interna o sistema de tickets como Chatwoot.
Deployment
whatsapp-web.js consume más recursos por Puppeteer y Chromium:
FROM node:20-slim
RUN apt-get update && apt-get install -y chromium fonts-liberation \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
ENV PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium
CMD ["node", "bot.js"]
services:
whatsapp-bot:
build: .
restart: always
volumes:
- wa_session:/app/session # ¡Persistir la sesión!
environment:
- OLLAMA_URL=http://ollama:11434
volumes:
wa_session:
Importante: sin volumen de sesión persistente, deberás escanear el código QR en cada reinicio.
Consideraciones legales
- GDPR: los bots de WhatsApp procesan números de teléfono y contenido de chat, datos personales. En uso empresarial: documenta política de privacidad, contrato de procesamiento con Meta, consentimiento de usuarios.
- Términos de servicio: las bibliotecas no oficiales violan los términos de WhatsApp, riesgo de bloqueo de cuenta. Tolerado para proyectos personales, no para negocio.
- Sin spam: los mensajes no solicitados son contrarios a la competencia leal en Alemania; responde solo a consultas.
Trampas comunes
- Código QR caducado: volumen de sesión no persistente o el teléfono estuvo sin conexión. Usa
LocalAuthcon volumen. - Cuenta bloqueada: demasiados mensajes muy rápido o usuarios reportan el bot. Implementa rate limits, agrega retrasos de 2-5s entre respuestas.
- Chromium consume RAM: whatsapp-web.js necesita ~500MB+. Alternativa: Baileys (protocolo WebSocket puro, sin navegador).
- Olvidar la ventana de 24h: la Business API rechaza mensajes gratuitos después de 24h, usa plantillas o requiere que el usuario escriba primero.
- Las IDs de grupo cambian: al reinscribirse, los JID varían, no hardcodes identificadores.
Enlaces de interés
- IRC-Coding.de: tutoriales de programación avanzados sobre Node.js, protocolos WebSocket, arquitecturas de bots.
- Telegram Bot: la alternativa más simple con API oficial.
- Signal Bot: alternativa enfocada en privacidad.
- Comparativa de plataformas: qué plataforma para cada caso.
- API de Ollama: interfaz HTTP.
- RAG local: conocimiento de documentos para el bot.
Puntos clave:
- WhatsApp no tiene una API bot gratuita: bibliotecas no oficiales (riesgo de bloqueo) o Business API (compleja, paga).
- whatsapp-web.js para proyectos personales con número extra; Business API para atención al cliente.
- Persiste la sesión o deberás escanear el código QR en cada reinicio.
- Respeta la ventana de 24h en Business API; las plantillas necesitan aprobación de Meta.
- Para la mayoría de self-hosters, Telegram es la opción más práctica.
FAQ
¿Es legal un bot de WhatsApp?
¿whatsapp-web.js o Baileys?
¿Cómo evito que bloqueen mi cuenta?
¿Cuánto cuesta la Business API?
¿Se mantiene el cifrado end-to-end?
¿Hay alternativas más simples?
¿Funciona el bot sin el teléfono?
Fuentes y lecturas adicionales
- whatsapp-web.js: documentación de la biblioteca.
- Baileys: API de WhatsApp Web sin navegador.
- WhatsApp Business Platform: API Cloud oficial.
- IRC-Coding.de: tutoriales de programación.


