8. Mailing
Introducción
El sistema de mailing gestiona campañas de email, contactos, plantillas y componentes específicos para envíos. Es uno de los módulos más completos del panel: cubre desde la captura de suscriptores hasta el envío masivo y el reporte de resultados.
El módulo se compone de cuatro pantallas principales accesibles desde el menú lateral (entrada Mailing): campañas, contactos, plantillas y componentes. Una quinta pantalla, el log de envío de cada campaña, permite revisar aperturas, clics y rebotes una vez la campaña ha sido lanzada.
Acceso rápido
- Campañas:
/mailing/campaigns - Contactos:
/mailing/contacts - Plantillas:
/mailing/templates - Componentes de mailing:
/mailing/components - Reporte / log de una campaña:
/mailing/reports/{id}
Todas las rutas son accesibles desde el menú lateral, en la entrada Mailing.
Pantalla principal (listado de campañas)
/mailing/campaigns). Muestra cada campaña con su estado, destinatarios, fecha de envío y acciones disponibles.La pantalla principal de campañas muestra, en formato tabla:
- Nombre de la campaña: título interno que identifica la campaña.
- Estado:
borrador,programada,enviando,enviada,pausada,cancelada. - Destinatarios: número total de emails a los que se enviará (o se ha enviado) la campaña.
- Fecha de envío: fecha y hora de lanzamiento (real o prevista, según el estado).
- Acciones: editar, duplicar, previsualizar, lanzar, pausar, ver reporte, eliminar.
En la parte superior de la tabla hay un botón destacado Crear campaña que abre el formulario de alta (ver 8.1) y, a la derecha, un campo de búsqueda y filtros por estado y fecha.
Tareas habituales
8.1 Crear una campaña
Para lanzar una nueva campaña de email:
- Entra en
/mailing/campaigns. - Pulsa el botón Crear campaña (esquina superior derecha).
- Rellena los campos del formulario:
- Nombre interno (no lo ven los destinatarios).
- Remitente: nombre y email desde el que se envía (por defecto toma los valores de
/variables, clavesMAIL_FROM_NAMEyMAIL_FROM_EMAIL). - Asunto del email.
- Preheader (texto预览 que aparece junto al asunto en muchos clientes de correo).
- Plantilla: elige una de las plantillas disponibles (ver 8.3).
- Destinatarios: elige una lista o segmento de contactos (ver 8.2) o importa un CSV ad-hoc.
- Programación: envía ahora o programa la fecha y hora exactas.
- Previsualiza el email (botón Previsualizar) y comprueba cómo se ve en cliente de escritorio y móvil.
- Guarda la campaña. Quedará en estado
borrador(oprogramadasi indicaste fecha futura). - Cuando estés listo, pulsa Lanzar (o se lanzará automáticamente en la fecha programada).
8.2 Gestionar contactos
/mailing/contacts). Permite buscar, importar, exportar, segmentar y dar de baja contactos.La pantalla de contactos es la base de datos de suscriptores del mailing. Funciones principales:
- Listado: tabla con email, nombre, estado (suscrito / dado de baja / rebotado), listas a las que pertenece, fecha de alta y última interacción.
- Importar: botón Importar CSV. El archivo debe tener, como mínimo, columna
email; opcionales:name,lastname,phone, columnas de listas (tipolist:<nombre>) y campos personalizados. - Exportar: botón Exportar, genera un CSV con los contactos filtrados.
- Segmentar: crea segmentos guardados a partir de filtros (por ejemplo, "suscritos a la lista X que llevan más de 30 días sin abrir emails"). Los segmentos se pueden usar como destinatarios de una campaña (ver 8.1).
- Dar de baja manualmente: desde la ficha del contacto, botón Marcar como baja. El contacto dejará de recibir futuras campañas y constará como
unsubscribed. - Eliminar: acción destructiva, solo disponible para administradores. Elimina el contacto y todo su histórico.
8.3 Crear y usar plantillas
/mailing/templates). Editor HTML con vista previa en tiempo real y soporte para variables y condicionales.Las plantillas definen la estructura visual y el contenido reutilizable de los emails. Se editan en HTML con marcadores que se rellenan en el momento del envío:
- Variables de contacto:
{{name}},{{lastname}},{{email}}, etc. Se sustituyen por el valor del destinatario. - Variables globales:
{{site_name}},{{site_url}},{{unsubscribe_url}}, etc. Toman el valor definido en/variables. - Condicionales: bloques
{{#if campo}}...{{/if}}para mostrar contenido según el valor de un campo del contacto. - Listas de repetición:
{{#each items}}...{{/each}}para renderizar arrays (por ejemplo, líneas de un pedido).
Para crear una nueva plantilla:
- Entra en
/mailing/templates. - Pulsa Nueva plantilla.
- Asigna un nombre interno, un asunto por defecto y pega o edita el HTML.
- Usa la pestaña Vista previa para ver el resultado con datos de prueba.
- Guarda. La plantilla ya está disponible al crear una campaña (ver 8.1).
8.4 Componentes de mailing
/mailing/components). Bloques reutilizables (cabecera, pie, botón CTA, etc.) que se insertan en las plantillas.Los componentes de mailing son bloques HTML reutilizables (cabecera con logo, pie con datos de contacto, botón CTA, divisor, etc.) que se insertan dentro de las plantillas. Esto evita repetir HTML y permite cambiar el logo o el pie en un solo sitio para que afecte a todos los emails.
El manejo es similar al de los componentes de página (ver sección 4): tienen un nombre, un slug, un template HTML con campos editables y un flag is_global que indica si se comparten entre todas las plantillas.
8.5 Ver el log de envío de una campaña
/mailing/reports/{id}). Estadísticas agregadas (entregados, aperturas, clics, rebotes) y log por destinatario.Una vez lanzada una campaña, esta pantalla muestra:
- Resumen: total enviados, entregados, abiertos, clics, rebotes, bajas, quejas de spam.
- Tasas: tasa de apertura, tasa de clic (CTR), tasa de rebote, tasa de baja.
- Gráfica de envíos en el tiempo: distribución de envíos/lecturas por hora desde el lanzamiento.
- Log por destinatario: tabla con, para cada contacto, el estado del envío (
queued,sent,delivered,opened,clicked,bounced,unsubscribed), fecha/hora de cada evento y, si está disponible, la URL desde la que se abrió el email.
Los datos de apertura y clic se obtienen de los webhooks que los proveedores de email envían (ver webhooks). Puede haber un retraso de varios minutos respecto al envío real.
Referencia técnica (webmasters)
Configuración SMTP en el .env
El envío de emails se realiza a través de un servidor SMTP externo (por ejemplo, Mailgun, Amazon SES, SendGrid, el SMTP de tu hosting). Las claves habituales en el .env son:
MAIL_HOST=smtp.example.com
MAIL_PORT=587
MAIL_USER=apikey
MAIL_PASS=xxxxxxxxxxxxxxxxxxxx
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=noreply@example.com
MAIL_FROM_NAME="${SITE_NAME}"
- MAIL_HOST / MAIL_PORT: host y puerto del servidor SMTP.
587con TLS es lo más habitual. Para SSL legacy,465. - MAIL_USER / MAIL_PASS: credenciales. En algunos proveedores (Mailgun, SendGrid) el usuario es literal
apikeyy la contraseña es la API key. - MAIL_ENCRYPTION:
tls(recomendado) ossl. - MAIL_FROM_ADDRESS / MAIL_FROM_NAME: dirección y nombre del remitente por defecto. Es importante que el dominio del
FROMtenga configurados SPF, DKIM y DMARC en DNS, si no muchos proveedores marcarán el correo como spam.
Colas de envío
Para no bloquear la web durante el envío masivo, las campañas se procesan con una cola (queue). El flujo es:
- Al lanzar una campaña, se crea una fila por destinatario en una tabla de cola (estado
queued). - Un worker en background (cron, daemon, o disparado por la propia web) toma N mensajes de la cola, los envía por SMTP, y actualiza el estado a
sentofailed. - Si el envío falla por un error transitorio (timeout, rate limit), el mensaje vuelve a la cola con un backoff y se reintenta hasta un máximo. Si el error es permanente (email inválido), se marca como
bouncedy se desuscribe al contacto.
El ritmo de envío lo controla un parámetro de throttle (por ejemplo, MAIL_THROTTLE_PER_MINUTE=200) para no superar el rate limit del proveedor SMTP.
Webhooks del proveedor de email
Para que el log de la campaña registre aperturas, clics, rebotes y bajas, el panel expone un endpoint público al que el proveedor de email envía eventos HTTP POST:
POST /api/mailing/webhook/{provider}
Content-Type: application/json
Signature: <firma del proveedor>
{ "event": "delivered", "recipient": "user@example.com", "timestamp": "..." }
El endpoint verifica la firma del proveedor, identifica al destinatario, actualiza el estado del envío en la base de datos y registra el evento. Cada proveedor tiene su propio formato de payload y de firma, por lo que el endpoint suele tener una rama por proveedor (/api/mailing/webhook/mailgun, /api/mailing/webhook/sendgrid, etc.).
Rutas internas relevantes
GET /mailing/campaigns— listado de campañas.GET/POST /mailing/campaigns/create— alta de campaña.GET/POST /mailing/campaigns/{id}/edit— edición (solo en estadoborrador).POST /mailing/campaigns/{id}/launch— lanzar manualmente.POST /mailing/campaigns/{id}/pause— pausar un envío en curso.GET /mailing/reports/{id}— reporte de una campaña.GET/POST /mailing/contacts— listado y alta/edición de contactos.POST /mailing/contacts/import— importación CSV.GET /mailing/contacts/export.csv— exportación CSV.GET/POST /mailing/templates— listado y edición de plantillas.GET/POST /mailing/components— listado y edición de componentes de mailing.POST /api/mailing/subscribe— alta pública de suscriptor (usado por formularios de newsletter).POST /api/mailing/unsubscribe— baja pública (enlace del pie de los emails).POST /api/mailing/webhook/{provider}— endpoint para webhooks del proveedor SMTP.
Errores frecuentes
- Los emails no se envían (no salen): revisa la configuración SMTP en el
.env(host, puerto, usuario, contraseña, encriptación). Un error típico es usartlsen el puerto465(que requieressl) o viceversa. Comprueba también que el worker de la cola está activo. - Los emails van a la carpeta de spam del destinatario: el dominio remitente no tiene SPF/DKIM/DMARC bien configurados, o el contenido del email dispara filtros (palabras tipo "gratis", "oferta", muchos enlaces, imágenes sin texto alternativo).
- Aparecen contactos duplicados: dos importaciones del mismo CSV, o dos formularios de alta que se cruzan. El sistema intenta deduplicar por email, pero si los contactos tienen campos personalizados distintos, no los fusiona. Usa la búsqueda por email antes de importar para detectar duplicados.
- La campaña se queda en estado
borradory no se envía: olvidaste pulsar Lanzar (o no se programó, o el programado no se disparó por un fallo del cron). Lánzala manualmente desde el listado o revisa los logs del cron. - El log de la campaña muestra muchos rebotes: la lista contiene direcciones inválidas o abandonadas. Limpia la lista eliminando los rebotes duros; algunos proveedores penalizan tasas de rebote altas y pueden suspender la cuenta.
- Las aperturas no se registran: el webhook del proveedor no está configurado, o lo está contra una URL incorrecta. Verifica en el panel del proveedor (Mailgun, SendGrid, etc.) que el endpoint configurado apunta a
/api/mailing/webhook/{provider}y que la firma se valida correctamente. - El envío va muy lento: el throttle (
MAIL_THROTTLE_PER_MINUTE) es muy bajo para el volumen de la campaña. Sube el límite con cuidado de no superar el rate limit del proveedor. - Los acentos y emojis salen rotos en el email: la plantilla no declara
<meta charset="utf-8">o el proveedor SMTP está forzando otra codificación. Asegúrate de que la plantilla lleva la meta charset y que elMAIL_CHARSET(si existe) está enutf-8.