SDK de JavaScript y TypeScript de WAME: WhatsApp tipado, en los tres canales
El SDK oficial de WAME en Node.js y TypeScript: envío tipado con autocompletado, los tres canales de Meta en la misma llamada y el webhook en el sobre estándar. Instalación, primer envío y el handler que sirve para los tres.
Si tu sistema es Node, el SDK de WAME tipa la integración completa — los tres canales de Meta, el envío, la instancia y el webhook. Esta guía va del npm install al handler recibiendo mensajes.
Instalación
npm install @raphaelvserafim/client-api-whatsapp
import { Wame, TypeMessage } from '@raphaelvserafim/client-api-whatsapp';
const wa = new Wame({
server: 'https://us.api-wa.me',
key: process.env.WAME_KEY!,
});
Los tipos vienen en el paquete. No hay @types aparte que instalar.
Primer envío
const to = '525512345678'; // internacional, solo dígitos
await wa.message.send({
type: TypeMessage.TEXT,
body: { to, text: 'Tu pedido #1042 salió para entrega 🚚' },
});
TypeMessage es un enum, y es lo que hace el trabajo pesado en el editor: el autocompletado lista los tipos disponibles y el cuerpo esperado cambia según el tipo elegido.
// el compilador lo rechaza: un mensaje de texto no tiene `url`
await wa.message.send({
type: TypeMessage.TEXT,
body: { to, url: 'https://ejemplo.com/foto.jpg' },
});
Ese error, en un proyecto sin tipos, sería una respuesta 400 en producción a las tres de la mañana.
Archivos
await wa.message.send({
type: TypeMessage.IMAGE,
body: { to, url: 'https://ejemplo.com/factura.jpg', caption: 'Tu factura' },
});
await wa.message.send({
type: TypeMessage.AUDIO,
body: { to, url: 'https://ejemplo.com/audio.mp3' },
});
Los tres canales
await wa.message.send({
type: TypeMessage.TEXT,
body: { to, text: 'Hola', provider: 'instagram' },
});
Un campo. Sin provider va a WhatsApp; con instagram o messenger va al otro canal — misma instancia, misma key, mismo webhook.
Instancia y webhook
// Conectar (API no oficial)
const qr = await wa.instance.connect();
const code = await wa.instance.pairingCode('525512345678');
// Estado
const info = await wa.instance.info();
// Operación
await wa.instance.logout();
await wa.instance.restart();
await wa.instance.resync();
Configurar a dónde van los eventos:
await wa.instance.updateWebhook({
allowWebhook: true,
allowNumber: 'all',
webhookMessage: 'https://tusistema.com/webhook/wame',
webhookFormat: 'meta', // sobre de la Cloud API — el mismo para los 3
});
const stats = await wa.instance.webhookStatistics();
webhookStatistics() vale conocerlo: cuando el webhook "deja de funcionar", muestra si las entregas están saliendo y fallando o si ni siquiera se están intentando — y eso decide de qué lado buscar. Es el paso siguiente a la prueba con webhook.site.
El handler para los tres canales
import express from 'express';
type EventoWame = {
provider: 'whatsapp' | 'instagram' | 'messenger';
entry: Array<{
changes: Array<{
value: {
messages?: Array<{
from: string;
id: string;
type: string;
text?: { body: string };
}>;
statuses?: Array<{ id: string; status: string }>;
};
}>;
}>;
};
const app = express();
app.use(express.json());
app.post('/webhook/wame', (req, res) => {
res.sendStatus(200); // primero esto, siempre
procesar(req.body as EventoWame).catch(console.error);
});
async function procesar(evento: EventoWame) {
const value = evento.entry?.[0]?.changes?.[0]?.value;
// `statuses` es entrega o lectura, no un mensaje nuevo.
const msg = value?.messages?.[0];
if (!msg || msg.type !== 'text') return;
await registrar({
canal: evento.provider,
de: msg.from,
texto: msg.text!.body,
messageId: msg.id,
});
}
Un handler. Tres canales. El único campo que varía es provider.
En Next.js y serverless
Solo del lado del servidor:
// app/api/webhook/wame/route.ts
export async function POST(req: Request) {
const evento = await req.json();
after(() => procesar(evento)); // responde ya, procesa después
return Response.json({ ok: true });
}
Nunca llames al SDK desde el cliente. La key de la instancia iría al bundle y cualquier visitante podría enviar mensajes por tu número.
En serverless hay una segunda trampa: si respondes y la función termina, el procesamiento en segundo plano muere con ella. Usa el mecanismo de la plataforma para trabajo posterior a la respuesta (after en Next, waitUntil en runtimes edge) o empuja a una cola.
Manejo de errores
try {
await wa.message.send({ type: TypeMessage.TEXT, body: { to, text } });
} catch (e) {
// Número sin WhatsApp, instancia desconectada, límite alcanzado.
// El error trae el código; trata cada caso, no te lo comas en un catch mudo.
console.error('falló el envío a', to, e);
await encolarParaReintento({ to, text });
}
Vale comprobar antes de enviar, cuando la lista viene de un alta de cliente:
const existe = await wa.contact.checkNumber(to);
if (!existe) return marcarInvalido(to);
Eso separa una lista que entrega de una lista que quema reputación — el tema de opt-in, limpieza y opt-out.
Conclusión
La ganancia del SDK tipado no es escribir menos: es el compilador rechazando el payload equivocado antes del deploy. Con tres canales en el mismo contrato, eso vale por tres.
Si trabajas en PHP, el SDK de PHP cubre lo mismo. La referencia completa está en docs/sdk/ts.
¿Listo para automatizar tu WhatsApp?
Crea tu cuenta gratis y empieza a enviar mensajes por la API en minutos.
Empezar gratisPreguntas frecuentes
¿Cómo instalo el SDK de JavaScript de WAME?+
Con npm install @raphaelvserafim/client-api-whatsapp. El paquete ya incluye las definiciones de tipos, así que funciona en JavaScript puro y en TypeScript sin instalar @types por separado.
¿El SDK funciona con TypeScript?+
Sí, y es donde más rinde. Los tipos de mensaje son un enum y el cuerpo de cada tipo está tipado, así que el editor muestra los campos válidos y el compilador marca error si mandas una url en un mensaje de texto.
¿Se puede usar en Next.js o en serverless?+
Sí, siempre que la llamada ocurra en el servidor: route handler, server action o función serverless. Nunca en el cliente, porque la key de la instancia quedaría expuesta en el bundle y cualquiera podría enviar mensajes en nombre de tu número.
¿Cómo envío a Instagram y Messenger?+
Con el mismo método send, agregando el campo provider en el cuerpo del mensaje. WhatsApp es el valor por defecto; indicar instagram o messenger dirige la misma llamada al otro canal, porque la instancia cubre los tres.
¿El SDK cubre la creación de instancias?+
Sí. El objeto instance expone conexión por código QR y por pairing code, información, logout, restart, resync y configuración de webhook — suficiente para aprovisionar y operar cuentas sin que nadie abra un panel.
Sigue leyendo
API de Instagram y Messenger en la misma API de WhatsApp: una instancia, un estándar
Tres canales oficiales de Meta casi siempre significan tres integraciones. Con una sola instancia, el mismo envío y el mismo sobre de webhook, solo cambia un campo: provider. Cómo funciona y qué te ahorra.
API no oficial de WhatsApp: qué es, si es segura y cómo usarla (2026)
Entiende qué es una API no oficial de WhatsApp, cómo funciona la conexión por código QR, si es segura y legal, cuál es el riesgo real de bloqueo y cuándo conviene usarla en lugar de la API oficial.
API oficial vs no oficial de WhatsApp: ¿cuál elegir? (comparativa 2026)
Comparativa completa entre la API oficial de WhatsApp (Cloud API de Meta) y la API no oficial: costo, aprobación, límites de envío, plantillas, soporte y riesgo de bloqueo. Descubre cuál tiene sentido para tu caso.