Mailtrap Email Integration
애플리케이션에 트랜잭션 이메일 전송을 추가하기 위한 패턴입니다. Mailtrap의 Email API와 Sandbox를 사용하며, 인증, 환경 분리, 그리고 일반적인 전송 실패 문제를 다룹니다.
활성화 시점
- "이메일 보내기" 기능 구현 (회원가입 확인, 비밀번호 재설정, 알림, 영수증)
- 개발/스테이징 환경에서 이메일이 도착하지 않는 문제 디버깅
- 프로젝트의 첫 이메일 전송 통합 설정
- 샌드박스 분리 없이 이메일 API를 직접 호출하는 코드 검토
핵심 개념
Sandbox와 Production 분리. Mailtrap은 Sandbox API를 제공하여 이메일을 캡처하고 실제로 전송하지 않습니다. 개발/스테이징 환경에서 사용하여 테스트 이메일이 실제 받은 편지함에 도달하지 않도록 합니다. 프로덕션 전송은 별도의 검증된 도메인 엔드포인트를 사용합니다. 개발 환경을 프로덕션 전송 엔드포인트에 연결하지 마세요.
인증. 요청은 Authorization 헤더에 Bearer 토큰을 사용합니다. 토큰은 프로젝트별로 범위가 지정되며, 샌드박스와 프로덕션은 일반적으로 다른 토큰을 사용합니다.
도메인 검증. 프로덕션 전송을 위해서는 DNS 레코드(SPF, DKIM, DMARC)를 통해 발송 도메인을 검증해야 Mailtrap이 실제 수신자에게 전달합니다. 이 단계를 생략하면 이메일이 자동으로 실패하거나 스팸 폴더로 분류됩니다.
코드 예제
// Mailtrap Email API를 통한 프로덕션 전송
async function sendEmail(to: string, subject: string, html: string) {
const response = await fetch("https://send.api.mailtrap.io/api/send", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.MAILTRAP_API_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
from: { email: "[email protected]", name: "Your App" },
to: [{ email: to }],
subject,
html,
}),
});
if (!response.ok) {
throw new Error(`Email send failed: ${response.status}`);
}
return response.json();
}
// 동일한 호출, 비-프로덕션 환경에서는 Sandbox로 라우팅
const MAILTRAP_ENDPOINT = process.env.NODE_ENV === "production"
? "https://send.api.mailtrap.io/api/send"
: `https://sandbox.api.mailtrap.io/api/send/${process.env.MAILTRAP_INBOX_ID}`;
안티 패턴
| 안티 패턴 | 문제점 | 대안 |
|---|---|---|
| 개발/테스트에서 프로덕션 전송 엔드포인트 사용 | 실제 테스트 이메일이 실제 받은 편지함에 도달하여 스팸 신고 위험 및 테스트 데이터 유출 가능 | 비-프로덕션 환경을 Sandbox 엔드포인트로 라우팅 |
| API 토큰을 소스 코드에 하드코딩 | 버전 관리에 커밋될 경우 자격 증명 유출 위험 | 환경 변수 / 시크릿 관리자에서 토큰 로드 |
| 도메인 검증 완료 전에 전송 | 이메일이 자동으로 실패하거나 스팸으로 분류됨 | 프로덕션 전송 활성화 전에 SPF/DKIM/DMARC 레코드 검증 |
| 전송 실패 시 재시도/오류 처리 없음 | 알림 전송 실패가 사용자에게 전달되지 않음 (예: 비밀번호 재설정 이메일을 받지 못함) | 응답 상태 확인, 실패 기록, 실행 가능한 오류 표시 |
모범 사례
- 샌드박스와 프로덕션 토큰을 별도의 환경 변수에 보관하고, 절대 하나의 토큰을 여러 환경에서 공유하지 마세요.
- 프로덕션 출시 전에 발송 도메인 DNS 레코드를 검증하세요.
- 전송 실패를 충분한 컨텍스트(수신자, 템플릿, 타임스탬프, 응답 코드)와 함께 기록하세요.
- 이메일 전송을 실패 가능한 네트워크 호출로 취급하고, try/catch로 감싸고 절대 성공을 가정하지 마세요.
관련 스킬
api-and-interface-design, security-and-hardening, ci-cd-and-automation