Skip to main content
osky
How to Design WhatsApp Bot Messages That Actually Convert: Email Marketing Principles Applied to Bots

Por qué el diseño de mensajes importa tanto en un bot de WhatsApp como en email marketing

Si alguna vez mandaste un mensaje desde tu bot y nadie respondió, no es que WhatsApp esté muerto ni que tu audiencia sea floja. Es que el mensaje apestaba en diseño. Y no lo digo con mala leche: lo digo porque en 2026 los usuarios de WhatsApp reciben entre 80 y 150 notificaciones diarias entre grupos, chats personales y bots de negocios. Si tu mensaje no engancha en los primeros dos segundos de lectura, ya valió.

La comunidad de SendPulse publicó recientemente un video con 15 dicas de diseño para email marketing que, aunque parezcan ajenas al mundo de los bots, son exactamente lo que necesitas adaptar a tu stack de WhatsApp. La razón es simple: el cerebro del usuario no distingue entre abrir un email y abrir un chat de bot. Ambos canales compiten por el mismo recurso escaso: la atención.

Este tutorial te lleva paso a paso por la integración de estos principios en un bot de WhatsApp real, usando la WhatsApp Cloud API de Meta y n8n como orquestador de flujos. El código está en Node.js porque es lo que corre en el 90% de los setups de producción que veo en México y Latinoamérica.


Requisitos

  • Cuenta de Meta for Developers con una app de WhatsApp Business API configurada
  • Token de acceso permanente (no el temporal de 24 horas, ese te va a arruinar en producción)
  • n8n v1.40+ instalado (self-hosted o cloud)
  • Node.js 20+ si vas a correr webhooks o lógica custom
  • Número de teléfono verificado en WhatsApp Business Platform
  • SendPulse cuenta activa (opcional, para A/B testing de copy)

Paso 1: Entiende la anatomía de un mensaje que convierte

Antes de tocar código, tienes que interiorizar la estructura. En email marketing, el principio número uno es el "above the fold": el usuario decide en milisegundos si sigue leyendo basándose en lo primero que ve. En WhatsApp, el equivalente es el texto que aparece en la notificación push antes de que el usuario abra el chat.

La notificación de WhatsApp muestra aproximadamente 65-70 caracteres del primer mensaje. Todo lo que escribas después de eso es invisible hasta que el usuario decida abrir. Eso significa que tu primera línea tiene que hacer el trabajo completo de un subject line de email.

Regla de oro: Si el usuario no abre por la primera línea, el resto no existe.


Paso 2: Configura tu webhook en n8n para recibir mensajes entrantes

// En tu nodo HTTP Request de n8n o en un webhook custom:
const express = require('express');
const app = express();
app.use(express.json());

app.post('/webhook/whatsapp', (req, res) => {
  const body = req.body;

  if (body.object === 'whatsapp_business_account') {
    const entry = body.entry?.[0];
    const changes = entry?.changes?.[0];
    const value = changes?.value;
    const messages = value?.messages;

    if (messages && messages.length > 0) {
      const msg = messages[0];
      const from = msg.from;
      const text = msg.text?.body || '';

      console.log(`Mensaje de ${from}: ${text}`);
      // Aquí disparas tu lógica de flujo en n8n
    }
  }

  res.sendStatus(200); // Meta necesita este 200 o te va a bombardear con reintentos
});

app.listen(3000, () => console.log('Webhook activo en puerto 3000'));

Advertencia de producción: Si no respondes con 200 en menos de 5 segundos, Meta reintenta el webhook hasta 3 veces. Si tu lógica tarda más (consulta a DB, llamada a API externa), responde el 200 inmediatamente y procesa de forma asíncrona con una cola.


Paso 3: Aplica los 5 principios de diseño más críticos del email marketing a tus mensajes de bot

3.1 Jerarquía visual con texto plano

En email usas H1, H2, negritas y colores. En WhatsApp tienes: *negrita*, _cursiva_, ~tachado~ y saltos de línea. Úsalos con intención quirúrgica.

async function sendStructuredMessage(to, phoneNumberId, accessToken) {
  const message = {
    messaging_product: 'whatsapp',
    to: to,
    type: 'text',
    text: {
      body: `*Osky DJ — Tu set de esta noche* 🎧\n\n` +
            `Tienes una reserva confirmada para:\n` +
            `_Viernes 10 de julio, 11 PM_\n` +
            `Venue: *Foro Indie CDMX*\n\n` +
            `¿Confirmas asistencia?`
    }
  };

  const response = await fetch(
    `https://graph.facebook.com/v20.0/${phoneNumberId}/messages`,
    {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${accessToken}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(message)
    }
  );

  return response.json();
}

3.2 Un solo call-to-action por mensaje

El error más común que veo en bots de WhatsApp en producción: meter tres preguntas en un mismo mensaje. El usuario no sabe qué responder y no responde nada. Igual que en email: un email, un CTA.

Usa los Interactive Messages con botones de respuesta rápida:

async function sendCTAMessage(to, phoneNumberId, accessToken) {
  const message = {
    messaging_product: 'whatsapp',
    to: to,
    type: 'interactive',
    interactive: {
      type: 'button',
      body: {
        text: '*¿Confirmas tu lugar en el set de esta noche?*\n\nSolo quedan 3 espacios en lista de invitados.'
      },
      action: {
        buttons: [
          {
            type: 'reply',
            reply: { id: 'confirm_yes', title: 'Sí, voy' }
          },
          {
            type: 'reply',
            reply: { id: 'confirm_no', title: 'No puedo ir' }
          }
        ]
      }
    }
  };

  const response = await fetch(
    `https://graph.facebook.com/v20.0/${phoneNumberId}/messages`,
    {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${accessToken}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(message)
    }
  );

  return response.json();
}

Advertencia: Los botones de WhatsApp tienen límite de 20 caracteres por botón. Sé brutal con el copy. Nada de "Sí, me gustaría confirmar mi asistencia al evento".

3.3 El principio de escasez y urgencia (sin mentir)

En email marketing, la urgencia falsa destruye la confianza a largo plazo. En WhatsApp es peor porque el canal es más personal. Si dices "últimos 3 lugares" y el usuario sabe que siempre dices lo mismo, te bloquea.

Usa urgencia real: fechas concretas, conteos reales de inventario desde tu base de datos.

// Ejemplo: obtener conteo real antes de mandar el mensaje
async function getAvailableSpots(eventId, db) {
  const result = await db.query(
    'SELECT capacity - reserved AS available FROM events WHERE id = $1',
    [eventId]
  );
  return result.rows[0]?.available || 0;
}

async function sendUrgencyMessage(to, phoneNumberId, accessToken, eventId, db) {
  const spots = await getAvailableSpots(eventId, db);

  if (spots <= 0) {
    // No mandes el mensaje si no hay lugares: no hagas quedar mal a Osky
    return null;
  }

  const urgencyText = spots <= 5
    ? `*Solo quedan ${spots} lugares disponibles.*`
    : `Hay ${spots} lugares disponibles.`;

  // Aquí llamas a sendCTAMessage con el texto dinámico
}

3.4 Timing: cuándo mandar el mensaje

En email, el mejor horario para abrir es martes-jueves entre 9 y 11 AM. En WhatsApp para un bot de DJ/eventos nocturnos, el timing es diferente: jueves entre 6-8 PM y viernes entre 2-5 PM tienen las tasas de respuesta más altas según datos de bots de entretenimiento en México.

En n8n, puedes usar el nodo Schedule Trigger o un nodo IF con lógica de horario:

// Lógica de horario en nodo Function de n8n
const now = new Date();
const hour = now.getHours(); // En la zona horaria configurada en n8n
const day = now.getDay(); // 0=domingo, 4=jueves, 5=viernes

const isGoodTime = (day === 4 && hour >= 18 && hour <= 20) ||
                   (day === 5 && hour >= 14 && hour <= 17);

return [{ json: { shouldSend: isGoodTime, currentHour: hour, currentDay: day } }];

Paso 4: A/B testing de copy con SendPulse y WhatsApp

SendPulse tiene API para envío de mensajes de WhatsApp y permite hacer variantes de mensajes. Puedes dividir tu lista de contactos en dos grupos y medir cuál copy tiene mejor tasa de respuesta.

# Endpoint de SendPulse para WhatsApp
POST https://api.sendpulse.com/whatsapp/contacts/sendByPhones

# Headers necesarios:
Authorization: Bearer {tu_token_sendpulse}
Content-Type: application/json

# Body:
{
  "bot_id": "tu_bot_id",
  "phones": ["+5215512345678"],
  "message": {
    "type": "text",
    "text": { "body": "Tu mensaje variante A" }
  }
}

Advertencia crítica de producción: WhatsApp tiene políticas estrictas contra el spam. Si tu tasa de "reportar como spam" supera el 0.5%, Meta puede suspender tu número. Nunca mandes mensajes no solicitados. Siempre opt-in explícito.


Paso 5: Monitoreo y métricas que sí importan

No te obsesiones con "mensajes enviados". Las métricas que debes rastrear:

  1. Tasa de lectura (WhatsApp reporta delivered vs read via webhooks de status)
  2. Tasa de respuesta (usuarios que respondieron / mensajes leídos)
  3. Tasa de conversión (usuarios que completaron el flujo / usuarios que respondieron)
  4. Tasa de opt-out (usuarios que mandaron STOP o te bloquearon)
// Webhook para capturar status de mensajes
app.post('/webhook/whatsapp', (req, res) => {
  const statuses = req.body.entry?.[0]?.changes?.[0]?.value?.statuses;

  if (statuses) {
    statuses.forEach(status => {
      // status.status puede ser: sent, delivered, read, failed
      console.log(`Mensaje ${status.id}: ${status.status} para ${status.recipient_id}`);
      // Guarda esto en tu DB para calcular métricas reales
    });
  }

  res.sendStatus(200);
});

Conclusión

El diseño de mensajes en WhatsApp Bot no es una ocurrencia de último momento: es la diferencia entre un bot que genera negocio y uno que la gente bloquea. Los principios de email marketing son transferibles, pero requieren adaptación al canal. Jerarquía con texto plano, un solo CTA, urgencia real, timing correcto y métricas honestas. Eso es lo que convierte.

Implementa estos pasos en tu bot de osky.dj y mide durante dos semanas. Los números te van a decir el resto.