Mailgun-connector
Verbind Mailgun met Brevo via Tajo om je transactionele en marketing-e-maildata te verenigen, leverings-events en engagement-metrics te synchroniseren en je e-mailinfrastructuur te consolideren in één klantbeeld.
Overzicht
| Eigenschap | Waarde |
|---|---|
| Platform | Mailgun (by Sinch) |
| Categorie | Email Marketing |
| Setupcomplexiteit | Eenvoudig |
| Officiële integratie | Nee |
| Gesynchroniseerde data | Events, Contacten, Deliverability, Campagnes |
| Auth-methode | API-sleutel (HTTP Basic Auth) |
Functies
- Leverings-event-sync - Track events voor delivered, bounced, opened en clicked
- Engagement-metrics - Synchroniseer open- en click-rates naar Brevo-contactattributen
- Bouncebeheer - Onderdruk gebouncete adressen automatisch in Brevo
- Klachtafhandeling - Synchroniseer spamklachten voor lijsthygiëne
- Domeinreputatie - Monitor de gezondheid en deliverability van je senderdomein
- Transactionele e-mail-tracking - Correleer transactionele sends met marketingdata
Vereisten
Voordat je begint, zorg dat je beschikt over:
- Een Mailgun-account met een geverifieerd senderdomein
- Een Mailgun API-sleutel uit het Mailgun Dashboard
- Een Brevo-account met API-toegang
- Een Tajo-account met connector-rechten
Authenticatie
API-sleutel-authenticatie
Mailgun gebruikt HTTP Basic Authentication met api als gebruikersnaam en je API-sleutel als wachtwoord:
# 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' ...Typen API-sleutels
Mailgun biedt domeinspecifieke sending keys en account-level API-sleutels. Gebruik domain sending keys voor berichtenoperaties en de account-API-sleutel voor beheeroperaties.
Configuratie
Basisopzet
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: 32Veldmapping
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_UNSUBSCRIBEDAPI-endpoints
| Endpoint | Methode | Beschrijving |
|---|---|---|
https://api.mailgun.net/v3/{domain}/messages | POST | E-mailberichten verzenden |
https://api.mailgun.net/v3/{domain}/events | GET | Event-logs opvragen |
https://api.mailgun.net/v3/{domain}/bounces | GET | Bounces opvragen |
https://api.mailgun.net/v3/{domain}/complaints | GET | Klachten opvragen |
https://api.mailgun.net/v3/{domain}/unsubscribes | GET | Uitschrijvingen opvragen |
https://api.mailgun.net/v3/{domain}/tags | GET | Tags opvragen |
https://api.mailgun.net/v3/{domain}/tags/{tag}/stats | GET | Tag-statistieken ophalen |
https://api.mailgun.net/v3/lists | GET | Mailinglijsten opvragen |
https://api.mailgun.net/v3/domains | GET | Domeinen opvragen |
https://api.mailgun.net/v4/address/validate | POST | E-mailadres valideren |
EU-regio
Gebruik voor Mailgun-accounts in de EU https://api.eu.mailgun.net in plaats van https://api.mailgun.net voor alle API-endpoints.
Codevoorbeelden
Connector initialiseren
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'});Bericht versturen via de Mailgun API
// 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.' }E-mail-events naar Brevo synchroniseren
// 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}Mailgun-webhooks afhandelen
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');});Bounces en klachten synchroniseren
// 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') });}Ratelimits
| Endpoint | Limiet | Opmerkingen |
|---|---|---|
| Messages API | Varieert per plan | 100/uur (free), onbeperkt (betaald) |
| Events API | Geen expliciete limiet | Gebruik paginatie met max 300 items |
| Validation API | Op basis van plan | Pay-per-validation |
| Webhooks | Realtime | Geen ratelimit op levering |
| Suppressions API | Geen expliciete limiet | Standaard rate-limiting van toepassing |
Verzendlimieten
Mailgun hanteert verzendlimieten op basis van je plan en domeinreputatie. Nieuwe domeinen starten met lagere limieten die toenemen naarmate je sender-reputatie verbetert. Monitor je domeinstatistieken in het Mailgun-dashboard.
Probleemoplossing
| Probleem | Oorzaak | Oplossing |
|---|---|---|
| 401 Unauthorized | Ongeldige API-sleutel | Verifieer de API-sleutel in het Mailgun-dashboard |
| Domein niet geverifieerd | Ontbrekende DNS-records | Voeg de vereiste TXT-, CNAME- en MX-records toe |
| Webhook niet ontvangen | URL niet bereikbaar | Zorg dat de webhook-URL publiekelijk bereikbaar is |
| Events ontbreken | Tijdsbereik te smal | Verruim begin/end-parameters |
| Lage deliverability | Domeinreputatie | Controleer domeinstats en authenticatie |
Debugmodus
connectors: mailgun: debug: true log_level: verbose log_webhooks: true log_events: trueBest practices
- Verifieer senderdomeinen - Rond DNS-verificatie af voor optimale deliverability
- Gebruik webhooks voor events - Realtime-webhook-levering in plaats van polling van de Events API
- Handel bounces proactief af - Onderdruk hard bounces direct in Brevo
- Tag je berichten - Gebruik tags om e-mailprestaties te categoriseren en analyseren
- Monitor domeinreputatie - Volg deliverabilitymetrics in het Mailgun-dashboard
- Gebruik e-mailvalidatie - Valideer adressen voordat je ze aan Brevo-lijsten toevoegt
Beveiliging
- HTTP Basic Auth - API-sleutel verzonden via Authorization-header
- Webhook-signatures - HMAC-SHA256-signatureverificatie
- Domeinverificatie - SPF, DKIM en DMARC DNS-authenticatie
- IP-whitelisting - Beschikbaar voor dedicated IP-plannen
- TLS-encryptie - Alle API-endpoints vereisen HTTPS
- Sleutelrotatie - Rouleer API-sleutels periodiek via het Mailgun-dashboard