Documentación: Enviar Mensaje WhatsApp (Wassender API)¶
Descripción General¶
El Nodo Enviar Mensaje WhatsApp (Wassender) es un nodo de acción que envía mensajes por WhatsApp mediante la API Wassender. Soporta cuatro tipos de contenido: texto, multimedia (imagen, video, audio, documento), ubicación y botones/encuesta (poll). Opcionalmente puede esperar una respuesta del destinatario (texto o clic en botón).
Un solo tipo de mensaje a la vez
No se puede enviar todo al mismo tiempo. Solo se envía un tipo de mensaje por ejecución. La prioridad al decidir el tipo es: ubicación > multimedia > botones/poll > texto.
¿Cuándo usar este nodo?¶
Utiliza este nodo cuando necesites:
- Enviar mensajes de WhatsApp desde automatizaciones usando Wassender (no Twilio)
- Enviar texto, imágenes, videos, audio, documentos, ubicaciones o encuestas/botones
- Esperar respuesta del destinatario (texto o clic en botón) antes de continuar el flujo
- Enviar a uno o varios destinatarios en una sola acción
Obtención de credenciales (apiToken y accessToken)¶
El nodo requiere apiToken y accessToken de WasenderApi. Se obtienen por separado:
Api Token¶
- Crea una cuenta en WasenderApi: https://wasenderapi.com/register.
- Inicia sesión y entra en Configuración → Tokens: https://wasenderapi.com/settings/tokens.
- Genera un token en esa página. Ese valor es tu apiToken (úsalo en el campo
apiTokendel nodo).
Access Token¶
- Con la cuenta creada, accede a Crear sesión/instancia de WhatsApp: https://wasenderapi.com/whatsapp/create.
- Crea una nueva sesión (instancia) de WhatsApp.
- Vincula el dispositivo: en la app de WhatsApp en tu teléfono, ve a Ajustes → Dispositivos vinculados → Vincular un dispositivo y escanea el código QR que muestra WasenderApi.
- Cuando el dispositivo quede vinculado correctamente, en la misma página de la sesión se mostrarán las API Credentials, donde podrás ver y copiar el API Access Token. Ese valor es tu accessToken (úsalo en el campo
accessTokendel nodo).
Ejemplo de dónde aparece el accessToken una vez vinculado el dispositivo:

Tipos de mensaje¶
| Tipo | Condición en el input | Descripción |
|---|---|---|
| Ubicación | latitude y longitude definidos |
Envía una ubicación (opcional: nombre y dirección). |
| Multimedia | mediaUrl o mediaFile definido |
Envía imagen, video, audio o documento según mediaType; body como pie. |
| Botones / Poll | buttons no vacío |
Envía una encuesta: body = pregunta, textos de botones = opciones. |
| Texto | Resto (solo body) |
Envía solo texto. |
Solo uno de estos modos se aplica por envío; no combines ubicación + media + botones en la misma configuración.
Formularios por tipo de mensaje¶
Según el tipo de mensaje elegido, el nodo muestra un formulario distinto:
Texto

Multimedia

Ubicación

Botones / Poll
Formulario principal (pregunta o título de la encuesta):

Opciones de la encuesta o botones (pestaña "Buttons / Poll Options"):

Configuración del Nodo¶

Campos obligatorios¶
| Campo | Tipo | Descripción |
|---|---|---|
apiToken |
string | Token de API Wassender (no vacío). |
accessToken |
string | Token de acceso para enviar mensajes (no vacío). |
sessionId |
string | ID de sesión WhatsApp. Debe estar conectada y validada. |
to |
string o []string | Destinatario(s). Un número/teléfono o lista; no puede estar vacío. |
Contenido del mensaje (elegir un solo tipo)¶
Texto: usar solo body. No definir mediaUrl/mediaFile, latitude/longitude ni buttons.
Multimedia: mediaUrl (URL o lista; si es array se usa la primera) o mediaFile (ruta/DriverHub); no ambos. Opcional: mediaType (default "image"), body (pie/caption). Tipos: image, video, audio, document.
Ubicación: latitude y longitude (ambos obligatorios). Opcional: locationName, locationAddress.
Botones (poll): buttons (lista de { "id", "text" }). body es la pregunta de la encuesta.
Campos opcionales¶
| Campo | Tipo | Default | Descripción |
|---|---|---|---|
body |
string | — | Texto del mensaje, pie de media o pregunta del poll. |
mediaUrl |
string o []string | — | URL(es) del medio. Si es array, se usa la primera. |
mediaFile |
string | — | Ruta/DriverHub del archivo. No usar junto con mediaUrl. |
mediaType |
string | "image" |
Tipo: image, video, audio, document. |
latitude |
number | — | Latitud (-90 a 90). Debe ir con longitude. |
longitude |
number | — | Longitud (-180 a 180). Debe ir con latitude. |
locationName |
string | — | Nombre del lugar. |
locationAddress |
string | — | Dirección del lugar. |
buttons |
[]{ "id", "text" } | — | Botones (en API se envían como opciones de poll). |
waitResponse |
bool | false |
Si es true, espera respuesta del primer destinatario exitoso. |
waitTime |
int (segundos) | 30 |
Tiempo máximo de espera cuando waitResponse es true. Debe ser > 0. |
waitForButton |
bool | false |
Si es true, espera clic en botón en lugar de mensaje de texto. |
Warning
mediaUrl y mediaFile no pueden usarse a la vez. latitude y longitude: si envías uno, el otro es obligatorio.
Output del nodo¶
El resultado se expone en el output del nodo:
| Campo | Tipo | Descripción |
|---|---|---|
total_recipients |
int | Número total de destinatarios. |
success_count |
int | Destinatarios a los que se envió correctamente. |
failure_count |
int | Destinatarios con envío fallido. |
results |
[]MessageResult | Resultado por destinatario. |
response |
ResponseData (opcional) | Respuesta recibida si waitResponse estaba activo. |
MessageResult (por destinatario)¶
| Campo | Tipo | Descripción |
|---|---|---|
to |
string | JID del destinatario. |
success |
bool | Si el envío fue exitoso. |
msgId |
string | ID del mensaje (si la API lo devuelve). |
timestamp |
int64 | Marca de tiempo del envío. |
error |
string | Mensaje de error si falló. |
ResponseData (cuando waitResponse: true)¶
| Campo | Tipo | Descripción |
|---|---|---|
received |
bool | Si se recibió respuesta. |
message_id |
string | ID del mensaje recibido. |
from |
string | JID del remitente. |
text |
string | Texto de la respuesta. |
timestamp |
int64 | Marca de tiempo. |
button_response |
ButtonResponse | Si se esperaba clic en botón. |
ButtonResponse¶
| Campo | Tipo | Descripción |
|---|---|---|
selected |
bool | Si se seleccionó un botón. |
button_id |
string | ID del botón. |
button_text |
string | Texto del botón. |
Estructura JSON¶
Ejemplo base (campos vacíos; en uso real debes definir credenciales, to y el contenido según el tipo de mensaje):
{
"apiToken": "",
"accessToken": "",
"sessionId": "",
"to": ["1223"],
"body": "",
"mediaUrl": [],
"mediaFile": "",
"mediaType": "image",
"locationName": "",
"locationAddress": "",
"buttons": [],
"waitResponse": false,
"waitTime": 30,
"waitForButton": false
}
Ejemplos de Uso¶
Ejemplo 1: Mensaje de texto¶
{
"apiToken": "{{secrets.wassender_api_token}}",
"accessToken": "{{secrets.wassender_access_token}}",
"sessionId": "{{trigger.session_id}}",
"to": "5215512345678",
"body": "Hola, este es un mensaje de prueba."
}
Ejemplo 2: Imagen con pie (multimedia)¶
{
"apiToken": "{{secrets.wassender_api_token}}",
"accessToken": "{{secrets.wassender_access_token}}",
"sessionId": "main-session",
"to": ["5215512345678", "5215598765432"],
"mediaUrl": "https://example.com/image.png",
"mediaType": "image",
"body": "Ver adjunto."
}
Ejemplo 3: Ubicación¶
{
"apiToken": "{{secrets.wassender_api_token}}",
"accessToken": "{{secrets.wassender_access_token}}",
"sessionId": "main-session",
"to": "5215512345678",
"latitude": 19.4326,
"longitude": -99.1332,
"locationName": "Oficina central",
"locationAddress": "Ciudad de México"
}
Ejemplo 4: Botones (poll) y espera de respuesta¶
{
"apiToken": "{{secrets.wassender_api_token}}",
"accessToken": "{{secrets.wassender_access_token}}",
"sessionId": "main-session",
"to": "5215512345678",
"body": "¿Confirmas la cita?",
"buttons": [
{ "id": "yes", "text": "Sí" },
{ "id": "no", "text": "No" }
],
"waitResponse": true,
"waitTime": 60,
"waitForButton": true
}
La respuesta del usuario estará en Output.response.button_response (por ejemplo button_id, button_text).
Espera de respuesta (waitResponse)¶
- Solo aplica si waitResponse es
true. - Se usa el primer mensaje enviado con éxito (primer destinatario que recibe) para esperar la respuesta.
- waitTime (segundos): tiempo máximo de espera; por defecto 30. Debe ser > 0.
- waitForButton: si es
true, se espera un clic en botón (respuesta de poll); si no, un mensaje de texto. - El resultado de la respuesta (si llega) se devuelve en
Output.response; si falla la espera, no se falla todo el nodo.
Validación¶
- apiToken, accessToken, sessionId y to son obligatorios y no vacíos.
- to: string no vacío o array de strings con al menos un elemento válido.
- mediaUrl y mediaFile no pueden usarse a la vez.
- latitude y longitude: si se envía uno, el otro es obligatorio; lat ∈ [-90, 90], lon ∈ [-180, 180].
- Si waitResponse es
true, waitTime debe ser > 0. - sessionId se valida contra el SessionManager (la sesión debe existir y estar conectada).
Si falla la validación, el nodo no envía mensajes.
Resolución de destinatarios (JID)¶
- Los valores de to (números/teléfonos) se convierten a JID de WhatsApp mediante una base de contactos asociada a la sesión.
- Ruta por defecto de la base:
public/uploads/wassender_contacts.json. - Si no se puede resolver un destinatario, el envío a ese destinatario falla y se refleja en
resultsconsuccess: falseyerror.
Solución de Problemas¶
Error: credenciales o sesión inválidos¶
Causa: apiToken, accessToken o sessionId vacíos o incorrectos; sesión no conectada.
Solución: verifica que la sesión Wassender esté conectada y que los tokens sean válidos. Usa secretos o variables para no exponer credenciales en el front.
Error: mediaUrl y mediaFile a la vez¶
Causa: se definieron ambos campos.
Solución: usa solo uno: mediaUrl (URL) o mediaFile (ruta/DriverHub).
Error: ubicación incompleta¶
Causa: se definió latitude sin longitude o viceversa.
Solución: incluye siempre ambos con valores en rango (lat -90..90, lon -180..180).
El destinatario no recibe el mensaje¶
Causa: el número no se pudo resolver a JID (no está en la base de contactos o formato incorrecto).
Solución: revisa results[].error para ese destinatario y la base de contactos de la sesión.
Mejores Prácticas¶
- apiToken y accessToken no deben exponerse en el front; usa secretos o variables de entorno.
- Envía un solo tipo de mensaje por nodo: no mezcles texto + media + ubicación + botones en la misma configuración.
- Los "botones" en la API Wassender se envían como poll; la estructura de botones del nodo se traduce a opciones de esa encuesta.
- Puedes usar templating en el input (p. ej.
{{trigger.field}},{{node_key.output_field}}). - Timeout de las peticiones HTTP a la API: 30 segundos.