Mailtrap Email Integration
MailtrapのEmail APIとSandboxを使用してアプリケーションにトランザクションメール送信を追加するためのパターン。認証、環境分離、および一般的な配信の落とし穴をカバーします。
アクティベーション条件
- 「メール送信」機能(サインアップ確認、パスワードリセット、通知、領収書)を実装する場合
- 開発/ステージング環境でメールが届かない理由をデバッグする場合
- プロジェクトで初めてメール送信インテグレーションを設定する場合
- Sandbox分離なしでメールAPIを直接呼び出すコードをレビューする場合
コアコンセプト
Sandboxと本番環境の分離。 MailtrapはSandbox APIを提供し、メールをキャプチャして配信しません。開発/ステージング環境で使用すると、テストメールが実際の受信トレイに届くことがありません。本番送信には、別途検証済みドメインのエンドポイントを使用します。開発環境を本番送信エンドポイントに決して向けてはいけません。
認証。 リクエストにはAuthorizationヘッダーにBearerトークンを使用します。トークンはプロジェクトごとにスコープ設定されており、Sandboxと本番環境では通常異なるトークンを使用します。
ドメイン検証。 本番送信には、DNSレコード(SPF、DKIM、DMARC)を介して送信ドメインを検証する必要があります。これを省略すると、メールが静かに配信に失敗したり、スパムフォルダに入ったりします。
コード例
// 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レコードを検証する |
| 送信失敗時のリトライ/エラーハンドリングがない | 通知が静かに失敗する(例:ユーザーがパスワードリセットメールを受け取れない) | レスポンスステータスを確認し、失敗をログに記録し、実行可能なエラーを表面化する |
ベストプラクティス
- Sandboxと本番環境のトークンは別々の環境変数に保持し、環境間でトークンを共有しない
- メールを伴う本番リリースの前に、送信ドメインのDNSレコードを検証する
- 送信失敗を十分なコンテキスト(受信者、テンプレート、タイムスタンプ、レスポンスコード)とともにログに記録する
- メール送信をエラーが発生しうるネットワーク呼び出しとして扱う:try/catchでラップし、成功を前提としない
関連スキル
api-and-interface-design, security-and-hardening, ci-cd-and-automation