Objetivos de aprendizaje
Después de leer este artículo podrás:
- Elegir entre Baileys, whatsapp-web.js y la Cloud API oficial
- Crear un bot con Baileys que responde a un comando y guarda la sesión
- Enviar tu primer mensaje por la Cloud API y evitar los errores más comunes
Crear un bot de WhatsApp es más una decisión que un tutorial. WhatsApp no tiene un portal abierto para cualquier número, como sí lo tiene Discord. Hay dos caminos: librerías de la comunidad que se hacen pasar por un dispositivo vinculado a tu número, y la Cloud API oficial de Meta, pensada para empresas.
Esa elección define lo que viene después: qué número usas, si hay riesgo de bloqueo, cuánto cuesta y si necesitas un dominio con HTTPS. Esta guía compara las opciones, monta un bot funcional con Baileys y muestra el primer envío por la Cloud API.
¿Qué opciones hay para crear un bot de WhatsApp?#
| Baileys | whatsapp-web.js | Cloud API | |
|---|---|---|---|
| Oficial | No | No | Sí |
| Cómo conecta | WebSocket directo | Chromium con Puppeteer | Webhook HTTPS + Graph API |
| Número | Cualquiera, incluso personal | Cualquiera, incluso personal | Comercial, en cuenta de Meta |
| Riesgo de bloqueo | Sí | Sí | Sin el riesgo de usar un cliente no oficial |
| Necesita dominio | No | No | Sí, con HTTPS válido |
| Memoria | Baja | Alta (ejecuta un navegador) | Solo tu servidor web |
Los mantenedores de Baileys advierten que el proyecto no tiene vínculo con WhatsApp y no apoya usos que violen los Términos de Servicio. Por eso, las notificaciones masivas o el número de una empresa que no puede quedarse sin servicio requieren la Cloud API. Para la comparación completa, mira Baileys, whatsapp-web.js o la API oficial.
Regla práctica: para un bot personal, un proyecto de estudio o un grupo de amigos, usa una librería con una SIM aparte. Para atención al cliente, ventas o cualquier cosa que genere ingresos, usa la Cloud API.
¿Qué necesitas antes de empezar?#
- La versión LTS activa de Node.js, que cumple el mínimo del campo
enginesde Baileys 7. - Un número de WhatsApp dedicado al bot, de preferencia una SIM que no sea la principal.
- WhatsApp instalado en el teléfono de ese número.
- Para la Cloud API: una cuenta de desarrollador de Meta, una app con el producto WhatsApp y, para recibir mensajes, una URL pública con HTTPS.
¿Cómo crear un bot de WhatsApp con Baileys?#
Crea el proyecto. Baileys 7 es un módulo ES, por eso el type=module:
npm init -y
npm pkg set type=module
npm install baileysEl código de abajo usa la API de Baileys 7. Revisa en npm a qué versión apunta la etiqueta latest antes de instalar; la serie 6.x sigue publicada como legacy y tiene una API distinta, así que los tutoriales antiguos pueden no funcionar.
Define WA_PHONE con el número del bot, solo dígitos y con el código de país (por ejemplo 5215512345678). Crea index.js:
import makeWASocket, {
DisconnectReason,
useMultiFileAuthState,
} from "baileys";
const AUTH_DIR = process.env.AUTH_DIR ?? "auth_info";
const PHONE = process.env.WA_PHONE;
async function start() {
const { state, saveCreds } = await useMultiFileAuthState(AUTH_DIR);
const sock = makeWASocket({ auth: state });
let pairingRequested = false;
sock.ev.on("creds.update", saveCreds);
sock.ev.on("connection.update", async ({ connection, lastDisconnect, qr }) => {
// Primera ejecución: sin sesión guardada, pide un código de emparejamiento.
// El evento qr se repite; el código se pide una vez por conexión.
if (qr && !pairingRequested && !sock.authState.creds.registered) {
if (!PHONE) return console.error("Define WA_PHONE para emparejar.");
pairingRequested = true;
console.log("Código de emparejamiento:", await sock.requestPairingCode(PHONE));
}
if (connection === "open") console.log("Conectado a WhatsApp.");
if (connection === "close") {
const code = lastDisconnect?.error?.output?.statusCode;
if (code === DisconnectReason.loggedOut) {
console.error("Sesión cerrada desde el teléfono. Borra la carpeta y empareja de nuevo.");
process.exit(1);
}
start(); // caída de red o reinicio pedido por WhatsApp: reconecta
}
});
sock.ev.on("messages.upsert", async ({ messages, type }) => {
if (type !== "notify") return;
for (const msg of messages) {
if (msg.key.fromMe || !msg.message) continue;
const text =
msg.message.conversation ?? msg.message.extendedTextMessage?.text;
if (text?.trim().toLowerCase() === "!ping") {
await sock.sendMessage(msg.key.remoteJid, { text: "pong" });
}
}
});
}
start();Ejecútalo con WA_PHONE=5215512345678 node index.js. En el teléfono del bot, abre Dispositivos vinculados, elige vincular con número de teléfono y escribe el código que apareció en el log. Si prefieres un código QR, llega en el campo qr del evento connection.update: la opción printQRInTerminal de las versiones antiguas quedó obsoleta y ya no imprime el QR.
¿Cómo comprobar que funcionó?#
El log muestra "Conectado a WhatsApp." Envía !ping al bot desde otro número y espera pong. Detén el proceso y vuelve a ejecutarlo: debe conectarse solo, sin pedir código, porque la sesión está en la carpeta auth_info.
Trata esa carpeta como una contraseña. No la subas a Git ni la borres en un deploy, o el bot se convierte en un dispositivo nuevo y tiene que emparejarse otra vez. Para el siguiente paso, mira cómo mantener el bot en línea 24/7.
¿Y whatsapp-web.js?#
whatsapp-web.js controla un WhatsApp Web real dentro de Chromium mediante Puppeteer. La API es simple (client.on("message", ...) y msg.reply(...)) y entras escaneando un QR. El costo es la memoria: un navegador completo corre junto al bot. En servidores y contenedores, sobre todo si corre como root, Chromium suele necesitar flags como --no-sandbox. Si el bot es pequeño y quieres poca RAM, Baileys suele ser más ligero.
¿Cómo enviar el primer mensaje por la Cloud API?#
La Cloud API no tiene emparejamiento. En el panel de desarrolladores de Meta, crea una app con el producto WhatsApp y, en API Setup, selecciona el número de prueba y copia su ID. El token temporal que se genera ahí caduca rápido. Para producción, crea un usuario del sistema en la configuración de la empresa y genera un token permanente con los permisos business_management, whatsapp_business_messaging y whatsapp_business_management.
El envío es una llamada HTTP. La versión de la Graph API va en la URL, aquí en la variable GRAPH_VERSION (con el formato vXX.0); usa la más reciente que aparece en el changelog de versiones de la Graph API:
curl -X POST "https://graph.facebook.com/$GRAPH_VERSION/$PHONE_NUMBER_ID/messages" \
-H "Authorization: Bearer $WA_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"messaging_product": "whatsapp",
"recipient_type": "individual",
"to": "5215512345678",
"type": "text",
"text": { "body": "¡Hola desde mi bot!" }
}'Dos reglas marcan el uso. La primera es la ventana de atención: cuando un usuario te escribe, se abre una ventana de 24 horas que se renueva con cada mensaje suyo. Dentro de ella respondes con texto libre; fuera, solo con plantillas (templates) preaprobadas. La segunda es el precio: desde el 1 de julio de 2025, Meta cobra por mensaje de plantilla entregado. Mira la página de precios de Meta y cuánto cuesta la API oficial.
Para recibir mensajes, Meta llama a tu webhook. Verifica el endpoint con un GET que trae hub.mode, hub.verify_token y hub.challenge: si el token coincide, responde 200 con el valor de hub.challenge. Los POST llegan firmados en X-Hub-Signature-256 (HMAC-SHA256 del cuerpo sin procesar con el secreto de la app). El certificado debe ser válido: los autofirmados no funcionan. El servidor completo está en cómo alojar un bot de WhatsApp 24/7.
¿Cuáles son los errores más comunes?#
- Pedir el código otra vez en cada reinicio: la carpeta de autenticación se borró o no es persistente. Mira bot de WhatsApp que se desconecta.
- Dos instancias con la misma sesión: una desconecta a la otra. Ejecuta solo una.
- Seguir un tutorial antiguo de Baileys:
printQRInTerminaly los imports viejos cambiaron en la versión 7. Fija la versión ennpm install. - Texto rechazado en la Cloud API: la ventana de 24 horas se cerró. Usa una plantilla aprobada.
- Webhook que Meta no valida: URL sin HTTPS válido, o
hub.verify_tokendistinto del configurado. - Número bloqueado: las librerías no oficiales, sobre todo con envíos masivos, ponen el número en riesgo. Usa una SIM aparte.
Cómo hacerlo en Square Cloud#
En Square Cloud, el hosting es self-service: tú haces el deploy y controlas memoria, variables y reinicios. Baileys, WPPConnect, whatsapp-web.js y la Cloud API oficial tienen soporte, así que la elección entre ellas sigue siendo tuya.
Para el bot de esta guía, sube el proyecto como ZIP en el panel, o usa la CLI, GitHub o la extensión de VS Code, y define WA_PHONE y las demás variables en la configuración de la aplicación. La carpeta de autenticación queda en el disco de la aplicación, así que la sesión sigue conectada después de un reinicio. Los contenedores están siempre encendidos, con reinicio automático (activado por defecto en el deploy desde el panel) cuando el proceso termina con error. Si eliges la Cloud API, la aplicación web recibe un subdominio squareweb.app con HTTPS que puede servir de URL del webhook.
Todos los planes son de pago, en reales. El Hobby cuesta R$12,49 al mes, con 1 GB de RAM compartido entre tus aplicaciones; el mínimo es 256 MB por aplicación en segundo plano, como un bot, y 512 MB por aplicación web. Mira la página de hosting de bots de WhatsApp.
Hosting de bots
Tu bot en línea 24/7, con reinicio automático
Preguntas frecuentes
¿Tengo que pagar para crear un bot de WhatsApp?
Las librerías no oficiales son de código abierto y no cobran licencia. En la Cloud API oficial, Meta cobra por mensaje de plantilla entregado, y el texto libre dentro de la ventana de 24 horas no se cobra. En ambos casos necesitas un servidor para mantener el proceso en marcha.
¿Puedo usar mi número personal para el bot?
Con Baileys o whatsapp-web.js sí, pero el número puede ser bloqueado, así que usa una SIM aparte. La Cloud API no vincula tu número personal: registras un número en una cuenta comercial de Meta.
¿Necesito saber programar para hacer un bot de WhatsApp?
Para un bot con lógica propia, sí: con lo básico de JavaScript alcanza para los ejemplos más simples. Si no quieres programar, puedes usar una herramienta de automatización sobre la Cloud API, pero con menos flexibilidad.
¿Qué lenguaje es mejor para un bot de WhatsApp?
Node.js es el más común, porque Baileys y whatsapp-web.js son librerías de JavaScript. La Cloud API es HTTP puro, así que sirve cualquier lenguaje que haga peticiones y reciba webhooks.
Más en Bots
Ver los 33 artículos- ¿Cuánto cuesta hospedar un bot de Discord?El costo de hospedar un bot de Discord depende de la RAM, el tiempo en línea, la base de datos y los servicios externos. Aprende a estimar el tuyo.
- Correr un bot en el celular (Termux) o en tu PC vs hospedarloUn bot en tu PC o celular (Termux) se cae cuando el equipo se apaga, se suspende o pierde la red. Compara las tres opciones y cuándo sirve cada una.
- Cómo mantener tu bot de Discord en línea 24/7Para mantener un bot de Discord en línea 24/7, ejecuta el proceso en una máquina siempre encendida con reinicio automático. Compara PC, VPS con pm2 o systemd.
- Por qué tu bot de Discord se apaga o aparece offlineUn bot de Discord aparece offline cuando el proceso se cae, el token es inválido, falta una intent o se acaba la memoria. Diagnostica y corrige cada causa.