Mailgun コネクター
Mailgun を Tajo 経由で Brevo に接続して、トランザクショナルメールとマーケティングメールのデータを統合し、配信イベントとエンゲージメントメトリクスを同期し、メールインフラを単一の顧客ビューに集約します。
概要
| 項目 | 値 |
|---|---|
| プラットフォーム | Mailgun (by Sinch) |
| カテゴリー | メールマーケティング |
| セットアップ難易度 | 容易 |
| 公式統合 | なし |
| 同期データ | イベント、コンタクト、配信性、キャンペーン |
| 認証方式 | API キー (HTTP Basic 認証) |
機能
- 配信イベント同期 - 配信、バウンス、開封、クリックイベントを追跡
- エンゲージメントメトリクス - 開封率とクリック率を Brevo コンタクト属性に同期
- バウンス管理 - バウンスしたアドレスを Brevo で自動的に抑制
- 苦情処理 - リスト衛生のためスパム苦情を同期
- ドメインレピュテーション - 送信ドメインの健全性と配信性を監視
- トランザクショナルメール追跡 - トランザクショナル送信とマーケティングデータを相関
前提条件
開始する前に、以下をご用意ください。
- 認証済み送信ドメインを持つ Mailgun アカウント
- Mailgun Dashboard からの Mailgun API キー
- API アクセス付きの Brevo アカウント
- コネクター権限を持つ Tajo アカウント
認証
API キー認証
Mailgun は HTTP Basic 認証を使用し、ユーザー名に api、パスワードに API キーを設定します。
# 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' ...API キーの種類
Mailgun はドメイン固有の送信キーとアカウントレベルの API キーを提供します。メッセージ操作にはドメイン送信キー、管理操作にはアカウント API キーを使用してください。
設定
基本セットアップ
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: 32フィールドマッピング
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 エンドポイント
| エンドポイント | メソッド | 説明 |
|---|---|---|
https://api.mailgun.net/v3/{domain}/messages | POST | メールメッセージを送信 |
https://api.mailgun.net/v3/{domain}/events | GET | イベントログをクエリ |
https://api.mailgun.net/v3/{domain}/bounces | GET | バウンス一覧 |
https://api.mailgun.net/v3/{domain}/complaints | GET | 苦情一覧 |
https://api.mailgun.net/v3/{domain}/unsubscribes | GET | 配信停止一覧 |
https://api.mailgun.net/v3/{domain}/tags | GET | タグ一覧 |
https://api.mailgun.net/v3/{domain}/tags/{tag}/stats | GET | タグ統計を取得 |
https://api.mailgun.net/v3/lists | GET | メーリングリスト一覧 |
https://api.mailgun.net/v3/domains | GET | ドメイン一覧 |
https://api.mailgun.net/v4/address/validate | POST | メールアドレスを検証 |
EU リージョン
EU 拠点の Mailgun アカウントでは、すべての API エンドポイントで https://api.mailgun.net の代わりに https://api.eu.mailgun.net を使用してください。
コード例
コネクターの初期化
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'});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.' }メールイベントを 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}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');});バウンスと苦情の同期
// 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') });}レート制限
| エンドポイント | 制限 | 備考 |
|---|---|---|
| Messages API | プランによる | 100/時 (無料)、無制限 (有料) |
| Events API | 明示的制限なし | ページネーションは最大 300 件 |
| Validation API | プランに基づく | 検証ごとの従量制 |
| ウェブフック | リアルタイム | 配信にレート制限なし |
| Suppressions API | 明示的制限なし | 標準のレート制限が適用 |
送信制限
Mailgun はプランとドメインレピュテーションに基づいて送信制限を適用します。新しいドメインは低い制限から始まり、送信者レピュテーションの向上に伴って増加します。Mailgun ダッシュボードでドメイン統計を監視してください。
トラブルシューティング
| 問題 | 原因 | 解決策 |
|---|---|---|
| 401 Unauthorized | 無効な API キー | Mailgun ダッシュボードで API キーを確認 |
| ドメイン未認証 | DNS レコード欠落 | 必要な TXT、CNAME、MX レコードを追加 |
| ウェブフックが受信されない | URL にアクセスできない | ウェブフック URL が公開アクセス可能か確認 |
| イベントが欠落 | 時間範囲が狭すぎる | begin/end パラメータを拡大 |
| 配信率が低い | ドメインレピュテーション | ドメイン統計と認証を確認 |
デバッグモード
connectors: mailgun: debug: true log_level: verbose log_webhooks: true log_events: trueベストプラクティス
- 送信ドメインを認証 - 最適な配信性のため DNS 認証を完了
- イベントにはウェブフックを使用 - Events API をポーリングするのではなくリアルタイムのウェブフック配信
- バウンスを積極的に処理 - ハードバウンスは Brevo で即座に抑制
- メッセージにタグ付け - タグを使ってメールパフォーマンスを分類・分析
- ドメインレピュテーションを監視 - Mailgun ダッシュボードで配信性メトリクスを追跡
- メール検証を活用 - Brevo リストに追加する前にアドレスを検証
セキュリティ
- HTTP Basic 認証 - API キーを Authorization ヘッダーで送信
- ウェブフック署名 - HMAC-SHA256 署名検証
- ドメイン認証 - SPF、DKIM、DMARC の DNS 認証
- IP ホワイトリスト - 専用 IP プランで利用可能
- TLS 暗号化 - すべての API エンドポイントで HTTPS 必須
- キーローテーション - Mailgun ダッシュボードで API キーを定期的にローテーション