
Cómo Conectar WhatsApp con Ollama (IA Local)
Ejecuta tu chatbot de WhatsApp completamente en tu propia máquina — sin API keys, sin costos de nube, sin datos saliendo de tu red. Ollama facilita ejecutar modelos open source como Llama, Gemma y Mistral localmente.
Requisitos Previos
- Una sesión vinculada de whatsmeow-node (Cómo Vincular)
- Ollama instalado y corriendo
- Un modelo descargado:
ollama pull llama3.2 - El SDK de Ollama:
npm install ollama
Paso 1: Descargar un Modelo
# Install Ollama from https://ollama.com, then:
ollama pull llama3.2
Otras buenas opciones para chat:
gemma3— modelo abierto de Google, rápido y capazmistral— potente para su tamañollama3.2:1b— el Llama más pequeño, respuestas más rápidas
Paso 2: Configurar Ambos Clientes
import { createClient } from "@whatsmeow-node/whatsmeow-node";
import { Ollama } from "ollama";
const client = createClient({ store: "session.db" });
const ollama = new Ollama({ host: "http://localhost:11434" });
const MODEL = "llama3.2";
const SYSTEM_PROMPT = "You are a helpful WhatsApp assistant. Keep responses concise — under 500 characters when possible, since this is a chat interface.";
Paso 3: Manejar Mensajes Entrantes
client.on("message", async ({ info, message }) => {
if (info.isFromMe) return;
const text =
(message.conversation as string) ??
(message.extendedTextMessage as { text?: string } | undefined)?.text;
if (!text) return;
await client.sendChatPresence(info.chat, "composing");
const reply = await askOllama(info.sender, text);
await client.sendMessage(info.chat, { conversation: reply });
});
Paso 4: Enviar a Ollama
async function askOllama(userJid: string, userMessage: string): Promise<string> {
const response = await ollama.chat({
model: MODEL,
messages: [
{ role: "system", content: SYSTEM_PROMPT },
{ role: "user", content: userMessage },
],
});
return response.message.content;
}
Paso 5: Agregar Historial de Conversación
import type { Message } from "ollama";
const conversations = new Map<string, Message[]>();
const MAX_HISTORY = 20;
async function askOllama(userJid: string, userMessage: string): Promise<string> {
const history = conversations.get(userJid) ?? [];
history.push({ role: "user", content: userMessage });
if (history.length > MAX_HISTORY) {
history.splice(0, history.length - MAX_HISTORY);
}
const response = await ollama.chat({
model: MODEL,
messages: [{ role: "system", content: SYSTEM_PROMPT }, ...history],
});
const reply = response.message.content;
history.push({ role: "assistant", content: reply });
conversations.set(userJid, history);
return reply;
}
Ejemplo Completo
import { createClient } from "@whatsmeow-node/whatsmeow-node";
import { Ollama } from "ollama";
import type { Message } from "ollama";
const client = createClient({ store: "session.db" });
const ollama = new Ollama({ host: "http://localhost:11434" });
const MODEL = "llama3.2";
const SYSTEM_PROMPT =
"You are a helpful WhatsApp assistant. Keep responses concise — under 500 characters when possible, since this is a chat interface.";
const conversations = new Map<string, Message[]>();
const MAX_HISTORY = 20;
async function askOllama(userJid: string, userMessage: string): Promise<string> {
const history = conversations.get(userJid) ?? [];
history.push({ role: "user", content: userMessage });
if (history.length > MAX_HISTORY) {
history.splice(0, history.length - MAX_HISTORY);
}
const response = await ollama.chat({
model: MODEL,
messages: [{ role: "system", content: SYSTEM_PROMPT }, ...history],
});
const reply = response.message.content;
history.push({ role: "assistant", content: reply });
conversations.set(userJid, history);
return reply;
}
client.on("message", async ({ info, message }) => {
if (info.isFromMe) return;
const text =
(message.conversation as string) ??
(message.extendedTextMessage as { text?: string } | undefined)?.text;
if (!text) return;
console.log(`${info.pushName}: ${text}`);
await client.sendChatPresence(info.chat, "composing");
try {
const reply = await askOllama(info.sender, text);
await client.sendMessage(info.chat, { conversation: reply });
console.log(`→ ${reply.slice(0, 80)}...`);
} catch (err) {
console.error("Ollama error:", err);
await client.sendMessage(info.chat, {
conversation: "Sorry, I'm having trouble right now. Make sure Ollama is running.",
});
}
});
client.on("logged_out", ({ reason }) => {
console.error(`Logged out: ${reason}`);
client.close();
process.exit(1);
});
async function main() {
const { jid } = await client.init();
if (!jid) {
console.error("Not paired! See: How to Pair WhatsApp");
process.exit(1);
}
await client.connect();
await client.sendPresence("available");
console.log(`Ollama bot is online! (model: ${MODEL})`);
process.on("SIGINT", async () => {
await client.sendPresence("unavailable");
await client.disconnect();
client.close();
process.exit(0);
});
}
main().catch(console.error);
Errores Comunes
Asegúrate de que el servidor de Ollama esté corriendo (ollama serve) antes de iniciar el bot. Si no está corriendo, todas las peticiones van a fallar.
Los modelos locales corren en tu CPU/GPU. Modelos más pequeños como llama3.2:1b responden en 1-3 segundos en hardware moderno. Modelos más grandes pueden tardar 10+ segundos — el indicador de escritura mantiene informado al usuario mientras espera.
Siempre verifica info.isFromMe primero. Sin esto, el bot responde a sus propios mensajes para siempre.
Ejecuta ollama pull llama3.2 antes de iniciar el bot. Si el modelo no está descargado, las peticiones van a fallar.







