Conector de Mailgun
Conecta Mailgun con Brevo a través de Tajo para unificar tus datos de email transaccional y de marketing, sincronizar eventos de entrega y métricas de engagement, y consolidar tu infraestructura de email en una única vista de cliente.
Resumen
| Propiedad | Valor |
|---|---|
| Plataforma | Mailgun (by Sinch) |
| Categoría | Email marketing |
| Complejidad de configuración | Fácil |
| Integración oficial | No |
| Datos sincronizados | Eventos, Contactos, Entregabilidad, Campañas |
| Método de autenticación | Clave API (HTTP Basic Auth) |
Funcionalidades
- Sincronización de eventos de entrega - Registra eventos de entregado, rebotado, abierto y clicado
- Métricas de engagement - Sincroniza tasas de apertura y clic como atributos de contacto de Brevo
- Gestión de rebotes - Suprime automáticamente las direcciones rebotadas en Brevo
- Gestión de quejas - Sincroniza las quejas por spam para mantener la higiene de la lista
- Reputación del dominio - Monitoriza el estado del dominio de envío y la entregabilidad
- Seguimiento de email transaccional - Correlaciona los envíos transaccionales con los datos de marketing
Requisitos previos
Antes de empezar, asegúrate de tener:
- Una cuenta de Mailgun con un dominio de envío verificado
- Una clave API de Mailgun desde el panel de Mailgun
- Una cuenta de Brevo con acceso a la API
- Una cuenta de Tajo con permisos de conector
Autenticación
Autenticación con clave API
Mailgun usa HTTP Basic Authentication con api como nombre de usuario y tu clave API como contraseña:
# Get your API key from https://app.mailgun.com/settings/api_securityexport MAILGUN_API_KEY=key-your-api-keyexport MAILGUN_DOMAIN=your-domain.comexport TAJO_API_KEY=your_tajo_api_keyexport BREVO_API_KEY=your_brevo_api_key// HTTP Basic Auth formatconst headers = { 'Authorization': `Basic ${Buffer.from( `api:${process.env.MAILGUN_API_KEY}` ).toString('base64')}`};
// Or using curl// curl -s --user 'api:YOUR_API_KEY' ...Tipos de clave API
Mailgun ofrece sending keys específicas por dominio y claves API a nivel de cuenta. Usa las sending keys de dominio para las operaciones de mensajes y la clave API de cuenta para operaciones de gestión.
Configuración
Configuración básica
connectors: mailgun: enabled: true api_key: "${MAILGUN_API_KEY}" domain: "${MAILGUN_DOMAIN}" region: "us" # or "eu" for EU region
sync: events: true contacts: true bounces: true complaints: true schedule: "*/15 * * * *" # Every 15 minutes
webhook: signing_key: "${MAILGUN_WEBHOOK_SIGNING_KEY}"
lists: engaged: 30 bounced: 31 complained: 32Asignación de campos
field_mapping: email: email first_name: FIRSTNAME last_name: LASTNAME open_rate: MG_OPEN_RATE click_rate: MG_CLICK_RATE last_delivered: MG_LAST_DELIVERED bounce_type: MG_BOUNCE_TYPE engagement_score: MG_ENGAGEMENT unsubscribed: MG_UNSUBSCRIBEDEndpoints de la API
| Endpoint | Método | Descripción |
|---|---|---|
https://api.mailgun.net/v3/{domain}/messages | POST | Enviar mensajes de email |
https://api.mailgun.net/v3/{domain}/events | GET | Consultar los logs de eventos |
https://api.mailgun.net/v3/{domain}/bounces | GET | Listar rebotes |
https://api.mailgun.net/v3/{domain}/complaints | GET | Listar quejas |
https://api.mailgun.net/v3/{domain}/unsubscribes | GET | Listar bajas |
https://api.mailgun.net/v3/{domain}/tags | GET | Listar etiquetas |
https://api.mailgun.net/v3/{domain}/tags/{tag}/stats | GET | Obtener estadísticas de etiqueta |
https://api.mailgun.net/v3/lists | GET | Listar mailing lists |
https://api.mailgun.net/v3/domains | GET | Listar dominios |
https://api.mailgun.net/v4/address/validate | POST | Validar una dirección de email |
Región UE
Para cuentas de Mailgun basadas en la UE, usa https://api.eu.mailgun.net en vez de https://api.mailgun.net en todos los endpoints de la API.
Ejemplos de código
Inicializar el conector
import { TajoClient } from '@tajo/sdk';
const tajo = new TajoClient({ apiKey: process.env.TAJO_API_KEY, brevoApiKey: process.env.BREVO_API_KEY});
await tajo.connectors.connect('mailgun', { apiKey: process.env.MAILGUN_API_KEY, domain: process.env.MAILGUN_DOMAIN, region: 'us'});Enviar un mensaje vía la API de Mailgun
// Send an email using Mailgun's Messages APIconst formData = new URLSearchParams();formData.append('from', `Your App <noreply@${domain}>`);formData.append('subject', 'Welcome to our platform');formData.append('html', '<h1>Welcome!</h1><p>Thanks for signing up.</p>');formData.append('o:tag', 'welcome-email');formData.append('o:tracking', 'yes');
const response = await fetch( `https://api.mailgun.net/v3/${domain}/messages`, { method: 'POST', headers: { 'Authorization': `Basic ${Buffer.from(`api:${apiKey}`).toString('base64')}` }, body: formData });
const result = await response.json();// { id: '<[email protected]>', message: 'Queued. Thank you.' }Sincronizar eventos de email con Brevo
// Query Mailgun events and sync engagement dataconst eventsResponse = await fetch( `https://api.mailgun.net/v3/${domain}/events?` + new URLSearchParams({ begin: lastSyncDate, ascending: 'yes', limit: 300, event: 'delivered OR opened OR clicked' }), { headers: { 'Authorization': `Basic ${Buffer.from(`api:${apiKey}`).toString('base64')}` } });
const { items, paging } = await eventsResponse.json();
for (const event of items) { const email = event.recipient;
switch (event.event) { case 'delivered': await tajo.contacts.update(email, { attributes: { MG_LAST_DELIVERED: event.timestamp } }); break; case 'opened': await tajo.events.track({ email, event: 'email_opened', properties: { subject: event.message.headers.subject } }); break; case 'clicked': await tajo.events.track({ email, event: 'email_clicked', properties: { url: event.url } }); break; }}
// Follow pagination for more eventsif (paging.next) { // Fetch next page using paging.next URL}Gestionar webhooks de Mailgun
const crypto = require('crypto');
app.post('/webhooks/mailgun', async (req, res) => { // Verify webhook signature const { timestamp, token, signature } = req.body.signature; const encodedToken = crypto .createHmac('sha256', process.env.MAILGUN_WEBHOOK_SIGNING_KEY) .update(timestamp.concat(token)) .digest('hex');
if (encodedToken !== signature) { return res.status(401).send('Unauthorized'); }
const eventData = req.body['event-data']; const event = eventData.event; const email = eventData.recipient;
await tajo.connectors.handleWebhook('mailgun', { topic: event, payload: eventData });
// Handle bounce suppression if (event === 'failed' && eventData.severity === 'permanent') { await tajo.contacts.update(email, { attributes: { MG_BOUNCE_TYPE: 'hard_bounce' }, emailBlacklisted: true }); }
res.status(200).send('OK');});Sincronizar rebotes y quejas
// Sync bounced addresses for list hygieneconst bouncesResponse = await fetch( `https://api.mailgun.net/v3/${domain}/bounces?limit=100`, { headers: { 'Authorization': `Basic ${Buffer.from(`api:${apiKey}`).toString('base64')}` } });
const { items: bounces } = await bouncesResponse.json();
for (const bounce of bounces) { await tajo.contacts.update(bounce.address, { attributes: { MG_BOUNCE_TYPE: bounce.error.includes('550') ? 'hard_bounce' : 'soft_bounce', MG_BOUNCE_DATE: bounce.created_at }, emailBlacklisted: bounce.error.includes('550') });}Límites de velocidad
| Endpoint | Límite | Notas |
|---|---|---|
| Messages API | Varía según el plan | 100/h (free), ilimitado (de pago) |
| Events API | Sin límite explícito | Usa paginación con máx. 300 elementos |
| Validation API | Según el plan | Pago por validación |
| Webhooks | Tiempo real | Sin límite de velocidad en la entrega |
| Suppressions API | Sin límite explícito | Se aplican límites de velocidad estándar |
Límites de envío
Mailgun aplica límites de envío según tu plan y la reputación del dominio. Los dominios nuevos parten de límites más bajos que aumentan a medida que mejora la reputación del remitente. Monitoriza las estadísticas de tu dominio en el panel de Mailgun.
Resolución de problemas
| Problema | Causa | Solución |
|---|---|---|
| 401 Unauthorized | Clave API no válida | Verifica la clave API en el panel de Mailgun |
| Dominio no verificado | Faltan registros DNS | Añade los registros TXT, CNAME y MX necesarios |
| Webhook no recibido | URL no accesible | Asegúrate de que la URL del webhook sea accesible públicamente |
| Faltan eventos | Rango de tiempo demasiado estrecho | Amplía los parámetros begin/end |
| Baja entregabilidad | Reputación del dominio | Revisa las estadísticas del dominio y la autenticación |
Modo depuración
connectors: mailgun: debug: true log_level: verbose log_webhooks: true log_events: trueBuenas prácticas
- Verifica los dominios de envío - Completa la verificación DNS para una entregabilidad óptima
- Usa webhooks para los eventos - La entrega en tiempo real de webhooks frente al polling de la Events API
- Gestiona los rebotes de forma proactiva - Suprime los hard bounces inmediatamente en Brevo
- Etiqueta tus mensajes - Usa etiquetas para categorizar y analizar el rendimiento del email
- Monitoriza la reputación del dominio - Haz seguimiento de las métricas de entregabilidad en el panel de Mailgun
- Usa la validación de email - Valida las direcciones antes de añadirlas a las listas de Brevo
Seguridad
- HTTP Basic Auth - Clave API transmitida en la cabecera Authorization
- Firmas de webhook - Verificación de firma HMAC-SHA256
- Verificación de dominio - Autenticación DNS con SPF, DKIM y DMARC
- Lista blanca de IPs - Disponible en planes con IP dedicada
- Cifrado TLS - Todos los endpoints de la API requieren HTTPS
- Rotación de claves - Rota las claves API periódicamente desde el panel de Mailgun