Mailgun 커넥터
Tajo를 통해 Mailgun을 Brevo에 연결하여 트랜잭션 및 마케팅 이메일 데이터를 통합하고, 배달 이벤트와 참여 지표를 동기화하며, 이메일 인프라를 단일 고객 뷰로 통합하십시오.
개요
| 속성 | 값 |
|---|---|
| 플랫폼 | Mailgun (by Sinch) |
| 카테고리 | 이메일 마케팅 |
| 설정 복잡도 | 쉬움 |
| 공식 통합 | 아니오 |
| 동기화 데이터 | 이벤트, 연락처, 배달률, 캠페인 |
| 인증 방법 | API Key (HTTP Basic Auth) |
기능
- 배달 이벤트 동기화 - 배달, 반송, 오픈, 클릭 이벤트 추적
- 참여 지표 - 오픈 및 클릭률을 Brevo 연락처 속성에 동기화
- 반송 관리 - Brevo에서 반송된 주소 자동 차단
- 불만 처리 - 목록 정리를 위한 스팸 불만 동기화
- 도메인 평판 - 발송 도메인 상태 및 배달률 모니터링
- 트랜잭션 이메일 추적 - 트랜잭션 발송을 마케팅 데이터와 연관시키기
사전 요구 사항
시작하기 전에 다음이 준비되어 있는지 확인하십시오.
- 확인된 발송 도메인이 있는 Mailgun 계정
- Mailgun 대시보드의 Mailgun API 키
- API 접근이 가능한 Brevo 계정
- 커넥터 권한이 있는 Tajo 계정
인증
API 키 인증
Mailgun은 사용자 이름으로 api를 사용하고 비밀번호로 API 키를 사용하는 HTTP Basic 인증을 사용합니다.
# https://app.mailgun.com/settings/api_security 에서 API 키 가져오기export 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 형식const headers = { 'Authorization': `Basic ${Buffer.from( `api:${process.env.MAILGUN_API_KEY}` ).toString('base64')}`};
// 또는 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" # 또는 EU 지역의 경우 "eu"
sync: events: true contacts: true bounces: true complaints: true schedule: "*/15 * * * *" # 15분마다
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를 통해 메시지 전송
// Mailgun의 Messages API를 사용하여 이메일 전송const 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로 동기화
// Mailgun 이벤트를 쿼리하고 참여 데이터 동기화const 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; }}
// 추가 이벤트를 위한 페이지네이션 따라가기if (paging.next) { // paging.next URL을 사용하여 다음 페이지 가져오기}Mailgun 웹훅 처리
const crypto = require('crypto');
app.post('/webhooks/mailgun', async (req, res) => { // 웹훅 서명 확인 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 });
// 반송 억제 처리 if (event === 'failed' && eventData.severity === 'permanent') { await tajo.contacts.update(email, { attributes: { MG_BOUNCE_TYPE: 'hard_bounce' }, emailBlacklisted: true }); }
res.status(200).send('OK');});반송 및 불만 동기화
// 목록 정리를 위한 반송된 주소 동기화const 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 | 요금제 기반 | 검증당 유료 |
| Webhooks | 실시간 | 배달에 속도 제한 없음 |
| 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 Auth - Authorization 헤더를 통해 API 키 전송
- 웹훅 서명 - HMAC-SHA256 서명 확인
- 도메인 확인 - SPF, DKIM, DMARC DNS 인증
- IP 허용 목록 - 전용 IP 요금제에서 사용 가능
- TLS 암호화 - 모든 API 엔드포인트에 HTTPS 필요
- 키 교체 - Mailgun 대시보드를 통해 주기적으로 API 키 교체