Resultados de búsqueda
Primeros pasos
Todo lo que necesitas para crear tu cuenta, conectar WhatsApp y lanzar tu primer flujo en minutos.
Crear una cuenta
Haz clic en Ingresar desde la página principal y selecciona Continuar con Google. Solo necesitas una cuenta de Gmail. Al registrarte recibes 100 créditos gratis para explorar el marketplace.
También puedes ingresar con correo y contraseña si no tienes Google. La versión Demo te permite explorar el editor sin cuenta, pero los flujos son temporales y no se guardan.
Lanzar tu primer flujo
¿Funciona en móvil?
El panel de gestión, marketplace y configuración están optimizados para móvil. El editor visual es más cómodo en pantalla grande, pero puedes activar y desactivar flujos desde el celular sin problemas.
Editor de flujos
El editor visual te permite construir automatizaciones completas sin escribir código, conectando nodos de lógica, acción y condición.
Tipos de nodos
- Disparadores — inician el flujo: Mensaje recibido, Webhook, Horario (Cron).
- Acciones — hacen algo: Enviar mensaje, Enviar media, Llamar API, Esperar.
- Lógica — controlan el camino: Condición Si/No, Bucle, División.
- IA / LLM — conecta tu clave de OpenAI, Anthropic o Groq para respuestas inteligentes.
Conectar nodos
Cada nodo tiene puertos de salida (punto derecho) y entrada (punto izquierdo). Haz clic y arrastra desde la salida de un nodo hasta la entrada del siguiente. Haz clic sobre una conexión para eliminarla.
Variables
Las variables guardan datos entre nodos. Escríbelas como {{nombre_variable}} en cualquier campo de texto.
- Variables de sesión — duran mientras dura la conversación. Ej:
{{nombre}}. - Variables globales — persisten entre conversaciones. Ej:
{{contador_ventas}}.
Usa el nodo Guardar variable para crear o actualizar variables desde un flujo.
Desplegar (activar) un flujo
En el editor haz clic en Desplegar, o activa el interruptor en la lista de flujos. Una vez desplegado, el flujo procesa mensajes y disparadores en tiempo real. Puedes desactivarlo sin perder su configuración.
Disparador Horario (Cron)
Usa expresiones cron estándar o las opciones visuales. Ejemplo: 0 9 * * 1-5 ejecuta el flujo a las 9 am de lunes a viernes.
Disparador Webhook
Genera una URL única que puedes llamar desde cualquier sistema externo (tienda, CRM, formulario) para iniciar el flujo con los datos que envíes en el cuerpo de la petición.
Conecta tu número personal o de negocio mediante el protocolo multi-dispositivo de WhatsApp. No necesitas la API oficial de Meta.
Conectar un número
Importante: no uses el mismo número simultáneamente en WhatsApp Web o en otro dispositivo vinculado. Eso desconecta la sesión de NodoWA.
Si la sesión se desconecta
Las sesiones pueden desconectarse si WhatsApp detecta actividad inusual o hay un problema de red. Para reconectar:
- Haz clic en Reconectar junto a la sesión.
- Escanea el nuevo código QR desde tu celular.
NodoWA intenta reconectar las sesiones automáticamente al reiniciarse el servidor.
Múltiples números
Puedes crear varias sesiones con nombres distintos. En tus flujos y scripts eliges qué sesión usar para enviar o recibir mensajes. Útil para manejar varias líneas de negocio desde la misma cuenta.
Tipos de medios que puedes enviar
El nodo Enviar media soporta: imágenes, videos, audio, documentos, stickers y mensajes de voz. Proporciona la URL pública del archivo o una variable que contenga esa URL.
Sobre Baileys
NodoWA usa la librería Baileys, que conecta WhatsApp mediante el mismo protocolo multi-dispositivo que WhatsApp Web. No requiere aprobación de Meta ni pago de API oficial. Úsalo de forma responsable: WhatsApp puede limitar cuentas con actividad automatizada masiva.
¿Qué es un script?
Un script es una mini-aplicación JavaScript que corre directamente en el servidor de NodoWA. Te da control total del código para construir lógica que los nodos estándar no pueden manejar.
¿Para qué sirve?
- Consultar APIs externas (clima, precios, ERPs, bases de datos)
- Procesar y transformar datos (parsear archivos, calcular totales)
- Enviar mensajes de WhatsApp condicionalmente desde código
- Crear una mini web app o API pública con tu propia URL
- Integrar con webhooks que necesiten lógica personalizada
Las tres zonas del editor
① Panel izquierdo — Configuración: nombre, descripción, permisos y opción de publicar.
② Área central — Código: pestaña JS para tus funciones, pestaña HTML para la interfaz web pública.
③ Panel de pruebas: se abre con el botón ▶ Probar y te permite ejecutar cualquier función con argumentos JSON.
Tu primer script
async function hola(args) {
const nombre = args.nombre || "Mundo";
return { mensaje: `¡Hola, ${nombre}! Desde NodoWA.` };
}
Si pruebas la función anterior con {"nombre":"Juan"}, obtendrás {"mensaje":"¡Hola, Juan! Desde NodoWA."}
Sintaxis de funciones
Todas las funciones ejecutables deben declararse como async function. Reciben un único argumento args (el JSON que pasas al probar o llamar la función) y retornan el resultado con return.
Reglas básicas
- Usa siempre
async function nombre(args)— aunque no usesawaitadentro. argses el objeto JSON que llega. Accede a sus propiedades conargs.clave.- Lo que retornes con
returnaparece en el panel de pruebas y en la respuesta de_run. - Puedes lanzar errores con
throw new Error("mensaje")— el sistema los captura y los muestra. console.log()escribe en los logs del servidor (no visibles en el panel de pruebas).- Puedes declarar funciones auxiliares normales fuera de las async (sin necesidad de que sean async).
Ejemplo: validación y cálculo
async function calcularDescuento(args) {
const precio = Number(args.precio);
const pct = Number(args.descuento) || 10;
if (isNaN(precio) || precio <= 0) {
throw new Error("El precio debe ser un número positivo");
}
const descuento = precio * (pct / 100);
const final = precio - descuento;
return {
precioOriginal: precio,
descuento: descuento.toFixed(2),
precioFinal: final.toFixed(2),
porcentaje: pct
};
}
Ejemplo: llamada a API externa
fetch está disponible de forma nativa (Node.js 18+). Puedes hacer peticiones HTTP a cualquier servicio externo.
async function obtenerClima(args) {
const ciudad = args.ciudad || "Buenos Aires";
const url = `https://wttr.in/${encodeURIComponent(ciudad)}?format=j1`;
const res = await fetch(url);
if (!res.ok) throw new Error(`Error HTTP ${res.status}`);
const data = await res.json();
const temp = data.current_condition[0].temp_C;
const desc = data.current_condition[0].weatherDesc[0].value;
return { ciudad, temperatura: `${temp}°C`, descripcion: desc };
}
Múltiples funciones en el mismo script
// Función auxiliar (no necesita ser async si no usa await)
function formatearPrecio(num) {
return new Intl.NumberFormat('es-AR', {
style: 'currency', currency: 'ARS'
}).format(num);
}
// Función principal — llamable desde el panel de pruebas
async function verPrecio(args) {
const valor = Number(args.valor) || 1000;
return { formateado: formatearPrecio(valor) };
}
Manejo de errores con try/catch
async function consultarAPI(args) {
try {
const res = await fetch(args.url);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return await res.json();
} catch (err) {
return { error: true, mensaje: err.message };
}
}
Panel de pruebas
El panel de pruebas te permite ejecutar cualquier función de tu script con los argumentos que quieras, directamente desde el editor, sin necesidad de publicar.
{"ciudad": "Bogotá"}El script se guarda automáticamente justo antes de ejecutarse. Siempre pruebas la versión más reciente aunque no hayas presionado Guardar.
Publicar y URL pública
Al publicar un script obtienes una URL propia donde se sirve tu HTML y desde donde cualquier sistema externo puede llamar tus funciones.
https://nodowa.lat/apps/<usuario>/<script>/Endpoints de la URL pública
| Método | Ruta | Descripción |
|---|---|---|
GET | /apps/usuario/script/ | Sirve el HTML de tu pestaña HTML |
POST | /apps/usuario/script/_run | Ejecuta una función del script |
Llamar una función desde el HTML publicado
El servidor inyecta automáticamente window.NODOWA_RUN_URL con la URL correcta del endpoint _run. Úsala siempre en lugar de URLs relativas para evitar errores de resolución.
<button onclick="ejecutar()">Obtener clima</button>
<p id="resultado"></p>
<script>
async function ejecutar() {
// window.NODOWA_RUN_URL es inyectado automáticamente por el servidor
const res = await fetch(window.NODOWA_RUN_URL, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
fn: 'obtenerClima',
args: { ciudad: 'Bogotá' }
})
});
const data = await res.json();
document.getElementById('resultado').textContent =
data.temperatura + ' — ' + data.descripcion;
}
</script>
No uses './_run' como URL relativa. Usa siempre window.NODOWA_RUN_URL para garantizar que la URL se resuelve correctamente sin importar cómo el navegador cargó la página.
Cuerpo de la petición POST a _run
| Campo | Tipo | Descripción |
|---|---|---|
fn | string | Nombre exacto de la función a ejecutar |
args | object | Objeto JSON que recibe la función como argumento args |
Mini web app: formularios e integración
Combina la pestaña HTML (interfaz) con la pestaña JS (lógica de servidor) para crear apps completas accesibles desde cualquier navegador.
Ejemplo completo: cotizador con IVA
Pestaña JS:
// Permiso necesario: whatsapp:send (solo si quieres enviar por WA)
async function cotizar(args) {
const precio = Number(args.precio) || 0;
const iva = precio * 0.21;
const total = precio + iva;
if (args.enviarWA && args.sesion && args.numero) {
await nodo.whatsapp.send(args.sesion, {
to: args.numero + "@s.whatsapp.net",
type: "text",
text: `💰 Cotización\nSubtotal: $${precio.toFixed(2)}\nIVA 21%: $${iva.toFixed(2)}\nTotal: $${total.toFixed(2)}`
});
}
return { subtotal: precio, iva, total };
}
Pestaña HTML:
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<title>Cotizador</title>
<style>
body { font-family: sans-serif; max-width: 400px; margin: 40px auto; padding: 0 20px; }
input, button { width: 100%; padding: 10px; margin: 8px 0;
border-radius: 8px; border: 1px solid #ddd; font-size: 1rem; }
button { background: #7c3aed; color: white; border: none; cursor: pointer; }
#resultado { background: #f0fdf4; border: 1px solid #bbf7d0;
border-radius: 8px; padding: 16px; margin-top: 16px; display: none; }
</style>
</head>
<body>
<h2>Cotizador con IVA</h2>
<input id="precio" type="number" placeholder="Precio sin IVA">
<button onclick="calcular()">Calcular</button>
<div id="resultado"></div>
<script>
async function calcular() {
const precio = document.getElementById('precio').value;
const res = await fetch(window.NODOWA_RUN_URL, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ fn: 'cotizar', args: { precio } })
});
const d = await res.json();
const el = document.getElementById('resultado');
el.style.display = 'block';
el.innerHTML = `<b>Subtotal:</b> $${d.subtotal.toFixed(2)}<br>
<b>IVA 21%:</b> $${d.iva.toFixed(2)}<br>
<b>Total:</b> $${d.total.toFixed(2)}`;
}
</script>
</body>
</html>
Leer parámetros de la URL (Query Parameters)
Puedes pasar datos directamente en la URL pública para que tu HTML los procese al cargar. Por ejemplo:
https://nodowa.lat/apps/usuario/script/?cliente=Juan&telefono=5491112345678
<script>
// Leer los parámetros de la URL al cargar la página
const params = new URLSearchParams(window.location.search);
const cliente = params.get('cliente'); // "Juan"
const tel = params.get('telefono'); // "5491112345678"
// Rellenar campos automáticamente
if (cliente) document.getElementById('nombre').value = cliente;
// O pasarlos directamente a una función del script
async function cargar() {
const res = await fetch(window.NODOWA_RUN_URL, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
fn: 'buscarCliente',
args: { nombre: cliente, telefono: tel }
})
});
const data = await res.json();
// Usar data...
}
cargar();
</script>
Esto es útil para crear formularios pre-rellenados desde un flujo de WhatsApp: el flujo genera la URL con los datos del usuario y la envía por mensaje, el usuario la abre y ve su información cargada.
Errores frecuentes
Referencia rápida de los errores más comunes y cómo resolverlos.
Function "X" not found
El nombre que escribiste en el panel de pruebas no coincide con ninguna función declarada. Revisa mayúsculas y que uses async function nombre(args).
SyntaxError: Unexpected token
Tu código tiene un error de sintaxis. Revisa llaves {}, paréntesis y que todas las cadenas estén cerradas.
Invalid JSON in args
El campo Argumentos no es JSON válido. Usa comillas dobles en las claves: {"clave": "valor"}, no comillas simples.
Permission denied: whatsapp:send
El script usa nodo.whatsapp.send sin tener el permiso activado. Ve al panel izquierdo → Permisos → activa whatsapp:send y guarda.
nodo is not defined
Estás usando el objeto nodo sin tener ningún permiso activado. Activa al menos un permiso en el panel izquierdo.
fetch failed / ENOTFOUND
La URL a la que intentas acceder no existe o está caída. Verifica la URL en el navegador antes de usarla en el script.
Unexpected token '<' — is not valid JSON
Tu HTML publicado está usando './_run' como URL relativa en lugar de window.NODOWA_RUN_URL, y el servidor está devolviendo HTML en vez de JSON. Cambia siempre al uso de window.NODOWA_RUN_URL.
Objeto nodo — referencia completa
El objeto global nodo expone los métodos de la plataforma dentro de tus scripts. Cada grupo de métodos requiere que actives el permiso correspondiente en el panel izquierdo del editor.
nodo.whatsapp.send(sesionId, mensaje)
Envía un mensaje de WhatsApp a través de una de tus sesiones conectadas. Requiere permiso whatsapp:send.
| Parámetro | Tipo | Descripción |
|---|---|---|
sesionId | string | ID de tu sesión WhatsApp (nombre que le diste al crearla) |
mensaje.to | string | Destinatario. Formato: "5491112345678@s.whatsapp.net" |
mensaje.type | string | Tipo de mensaje. Ver tabla de tipos abajo. |
mensaje.text | string | Texto del mensaje (solo para type: "text") |
mensaje.url | string | URL pública del archivo (para tipos media) |
mensaje.caption | string | Texto acompañante para imágenes/videos/documentos (opcional) |
mensaje.fileName | string | Nombre del archivo para documentos (opcional) |
Tipos de mensaje (type)
| type | Descripción | Campos requeridos |
|---|---|---|
"text" | Mensaje de texto plano | text |
"image" | Imagen JPEG/PNG/WEBP | url |
"video" | Video MP4 | url |
"audio" | Audio MP3/OGG (nota de voz) | url |
"document" | Documento PDF, DOCX, etc. | url, fileName |
"sticker" | Sticker WEBP estático o animado | url |
Ejemplos:
// Texto
await nodo.whatsapp.send("mi-sesion", {
to: "5491112345678@s.whatsapp.net",
type: "text",
text: "Hola, tu pedido está listo 🎉"
});
// Imagen con caption
await nodo.whatsapp.send("mi-sesion", {
to: "5491112345678@s.whatsapp.net",
type: "image",
url: "https://ejemplo.com/comprobante.jpg",
caption: "Aquí está tu comprobante de pago"
});
// Documento PDF
await nodo.whatsapp.send("mi-sesion", {
to: "5491112345678@s.whatsapp.net",
type: "document",
url: "https://ejemplo.com/factura.pdf",
fileName: "factura-001.pdf",
caption: "Tu factura del mes"
});
nodo.flows.getVar(flowId, key)
Lee el valor de una variable global de un flujo. Requiere permiso flows:read. Devuelve el valor almacenado o undefined si no existe.
| Parámetro | Tipo | Descripción |
|---|---|---|
flowId | string | ID del flujo (visible en la URL del editor) |
key | string | Nombre de la variable |
const valor = await nodo.flows.getVar("abc123", "ultimo_pedido");
return { variable: "ultimo_pedido", valor };
nodo.flows.setVar(flowId, key, value)
Escribe o actualiza una variable global de un flujo. Requiere permiso flows:write. El valor puede ser cualquier tipo serializable (string, number, object, array).
| Parámetro | Tipo | Descripción |
|---|---|---|
flowId | string | ID del flujo |
key | string | Nombre de la variable |
value | any | Valor a guardar (string, number, object, array…) |
await nodo.flows.setVar("abc123", "ultimo_pedido", {
id: args.pedidoId,
monto: args.monto,
fecha: new Date().toISOString()
});
return { guardado: true };
Permisos
Los scripts corren en un entorno aislado por seguridad. Para acceder a funciones privilegiadas activa el permiso correspondiente en el panel izquierdo del editor (sección Permisos).
whatsapp:send
Enviar mensajes de texto, imágenes, audio, video, stickers y documentos a través de tus sesiones conectadas.
whatsapp:read
Leer el estado de tus sesiones de WhatsApp: conectada, desconectada, número vinculado.
flows:read
Leer variables globales almacenadas en tus flujos y obtener la lista de flujos de tu cuenta.
flows:write
Escribir y modificar variables globales en tus flujos.
Activa solo los permisos que tu script realmente necesita. Si compartes el script, alguien con acceso a la URL pública podría llamar sus funciones — mínimo privilegio es la mejor práctica.
Entorno de ejecución
Especificaciones técnicas del entorno donde corre tu código. Conocerlas te ayuda a saber qué puedes hacer y qué límites respetar.
path, crypto, url, querystring, buffer, stream, util, events, zlib.node_modules. Usa fetch para llamar APIs REST externas en su lugar.nodo.flows.setVar.return, pero los objetos muy grandes pueden ralentizar la serialización.args de la función o nodo.flows.getVar.No almacenes credenciales (contraseñas, tokens, API keys) en el código del script. El código de scripts publicados puede ser visible. Guarda secretos en variables de flujo vía nodo.flows.setVar o pásalos en los args desde tu sistema.
Marketplace
La tienda donde puedes comprar flujos listos creados por la comunidad y vender los tuyos. La moneda son los créditos.
Comprar un flujo
Vender un flujo
Cuenta y créditos
Los créditos son la moneda interna de NodoWA. Se usan para comprar flujos en el marketplace.
Cómo obtener créditos
- Registro: recibes 100 créditos gratis al crear tu cuenta.
- Vendiendo: cuando alguien compra uno de tus flujos, los créditos se acreditan a tu saldo.
- Transferencia: otro usuario puede transferirte créditos usando tu correo. Ve a tu perfil para hacer una transferencia (es inmediata e irreversible).
- Comprando: el botón de recarga te lleva a Hotmart para adquirir paquetes de créditos.
Ver tu saldo
Tu saldo aparece en la parte superior del panel de inicio (Mi cuenta) y en el icono de moneda de la barra de navegación.
Eliminar tu cuenta
Ve a Mi cuenta → Configuración → Eliminar cuenta. Esta acción es irreversible: se borran todos tus flujos, sesiones de WhatsApp, créditos y datos personales. Exporta cualquier flujo que quieras conservar antes de proceder.
Privacidad de mensajes
NodoWA procesa los mensajes en tiempo real para ejecutar tus flujos, pero no almacena el historial de conversaciones. Solo se guardan las variables que tú definas explícitamente en tus flujos.
¿No encontraste lo que buscabas?
La comunidad y el equipo de NodoWA están disponibles para ayudarte.