email-sending について
Node.js、Python、Javaでのメール送信例をまとめ、SMTPとトランザクションメールサービスを扱うスキルです。テンプレートの選択肢と、安定した配信に向けた運用チェック項目も紹介します。
主な機能
- 01NodemailerによるSMTP送信
- 02トランザクションメールサービスの例
- 03React EmailとMJMLのテンプレート
- 04PythonとJavaの実装例
- 05配信と再試行の実践方法
- 06本番向けメールチェックリスト
活用シーン
- 01アプリのトランザクションメールを送る
- 02歓迎メールやパスワード再設定メールを作る
- 03サービスのメール配信を設定する
- 04本番環境のメール送信を準備する
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ claude-dev-suite/ claude-dev-suite --skill email-sendingインストール後、Claude Code で/email-sendingを入力して読み込まれたか確認します。
詳細
メール送信
Node.js(Nodemailer)
import nodemailer from 'nodemailer';
const transporter = nodemailer.createTransport({
host: process.env.SMTP_HOST,
port: 587,
secure: false, // true for 465
auth: { user: process.env.SMTP_USER, pass: process.env.SMTP_PASS },
});
await transporter.sendMail({
from: '"My App" <[email protected]>',
to: '[email protected]',
subject: 'Welcome!',
html: '<h1>Welcome</h1><p>Thanks for signing up.</p>',
});
トランザクションメールサービス
Resend(シンプルさを重視する場合におすすめ)
import { Resend } from 'resend';
const resend = new Resend(process.env.RESEND_API_KEY);
await resend.emails.send({
from: 'My App <[email protected]>',
to: ['[email protected]'],
subject: 'Welcome!',
html: '<h1>Welcome</h1>',
});
SendGrid
import sgMail from '@sendgrid/mail';
sgMail.setApiKey(process.env.SENDGRID_API_KEY!);
await sgMail.send({
to: '[email protected]',
from: '[email protected]',
templateId: 'd-abc123', // Dynamic template
dynamicTemplateData: { name: 'John', link: resetUrl },
});
Amazon SES(AWS SDK v3 経由)
import { SESv2Client, SendEmailCommand } from '@aws-sdk/client-sesv2';
const ses = new SESv2Client({ region: 'us-east-1' });
await ses.send(new SendEmailCommand({
FromEmailAddress: '[email protected]',
Destination: { ToAddresses: ['[email protected]'] },
Content: {
Simple: {
Subject: { Data: 'Welcome!' },
Body: { Html: { Data: htmlContent } },
},
},
}));
メールテンプレート
React Email(React プロジェクトにおすすめ)
// emails/welcome.tsx
import { Html, Head, Body, Container, Text, Button } from '@react-email/components';
export function WelcomeEmail({ name, url }: { name: string; url: string }) {
return (
<Html>
<Head />
<Body style={{ fontFamily: 'sans-serif' }}>
<Container>
<Text>Welcome, {name}!</Text>
<Button href={url} style={{ background: '#000', color: '#fff', padding: '12px 20px' }}>
Get Started
</Button>
</Container>
</Body>
</Html>
);
}
// Render to HTML string
import { render } from '@react-email/render';
const html = await render(<WelcomeEmail name="John" url="https://app.com" />);
MJML(フレームワークに依存しない)
import mjml2html from 'mjml';
const { html } = mjml2html(`
<mjml>
<mj-body>
<mj-section>
<mj-column>
<mj-text>Welcome, {{name}}!</mj-text>
<mj-button href="{{url}}">Get Started</mj-button>
</mj-column>
</mj-section>
</mj-body>
</mjml>
`);
Python
from email.message import EmailMessage
import aiosmtplib
msg = EmailMessage()
msg["From"] = "[email protected]"
msg["To"] = "[email protected]"
msg["Subject"] = "Welcome!"
msg.set_content("Welcome!", subtype="html")
await aiosmtplib.send(msg, hostname=SMTP_HOST, port=587,
username=SMTP_USER, password=SMTP_PASS, start_tls=True)
Java(Spring Mail)
@Service
public class EmailService {
@Autowired private JavaMailSender mailSender;
@Autowired private TemplateEngine templateEngine; // Thymeleaf
public void sendWelcome(String to, String name) {
var ctx = new Context();
ctx.setVariable("name", name);
String html = templateEngine.process("welcome", ctx);
var message = mailSender.createMimeMessage();
var helper = new MimeMessageHelper(message, true);
helper.setTo(to);
helper.setFrom("[email protected]");
helper.setSubject("Welcome!");
helper.setText(html, true);
mailSender.send(message);
}
}
アンチパターン
| アンチパターン | 対策 |
|---|---|
| リクエストハンドラーでメールを送信する | バックグラウンドジョブキュー(BullMQ、Celery)を使用する |
| 一時的な障害時に再試行しない | 指数バックオフで再試行する(3 回) |
| 送信元アドレスをハードコードする | 環境変数を使用し、認証済みドメインと一致させる |
| プレーンテキストの代替版がない HTML | HTML 版とテキスト版の両方を必ず含める |
| 配信停止ヘッダーがない | List-Unsubscribe ヘッダーを追加する(Gmail/Yahoo で必須) |
| 未認証ドメインから送信する | SPF、DKIM、DMARC レコードを設定する |
本番環境チェックリスト
- SPF、DKIM、DMARC の DNS レコードを設定済み
- メールプロバイダーでドメインを認証済み
- マーケティングメールに
List-Unsubscribeヘッダーを設定済み - バウンスと苦情への対応(Webhook)
- バックグラウンドキュー経由でメールを送信(リクエスト内では送信しない)
- プロバイダーの制限を超えないようレート制限を設定済み
- すべての HTML メールにプレーンテキストの代替版を用意
- デプロイ前にテンプレートをプレビュー/テスト
コメント
Markdown 対応