mcpField
A
api-email-resend-react-email

api-email-resend-react-email

github.com/agents-inc開発2674 回インストール2 日前に更新
リポジトリ

api-email-resend-react-email について

Resend と React Email でトランザクションメールを実装する開発者向けのスキルです。型付きテンプレート、サーバー側送信、再試行、バッチ送信、Webhook 検証を扱います。

主な機能

  1. 01型付き React Email テンプレート
  2. 02送信前の非同期レンダリング
  3. 03サーバー側送信とエラー処理
  4. 04指数バックオフによる再試行
  5. 05バッチ送信と Webhook 検証

活用シーン

  1. 01認証メールやパスワードリセットメールの作成
  2. 02領収書や通知メールの送信
  3. 03複数宛先へのメール一括送信
  4. 04Resend Webhook イベントの検証

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/agents-inc/skills --skill api-email-resend-react-email

インストール後、Claude Code で/api-email-resend-react-emailを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

metadata.yaml
reference.md
examples/
advanced-features.md
async-batch.md
core.md
preferences.md
templates.md
webhooks.md

詳細

Resend と React Email を使ったメールのパターン

クイックガイド: Resend を React Email テンプレートと組み合わせて、トランザクションメールを送信します。送信前に必ず render() を await してください(Promise を返します)。サーバーサイドでのみ使用し、API キーをクライアントに公開しないでください。一時的な障害に備え、指数バックオフによる再試行を実装してください。トランザクションメール以外には、配信停止リンクを含めてください(CAN-SPAM)。2〜100 人の宛先には resend.batch.send() を使用してください(バッチ送信では添付ファイルとスケジュール送信はサポートされません)。React Email 5.0+ では renderAsync は非推奨です。代わりに render() を使用してください。Webhook の検証には、リクエストボディの生データと webhookSecret パラメーターが必要です。


<critical_requirements>

重要:このスキルを使用する前に

すべてのコードは CLAUDE.md のプロジェクト規約に従う必要があります(kebab-case、名前付きエクスポート、インポート順序、import type、名前付き定数)

(resend.emails.send() に HTML を渡す前に、必ず render() を await してください。render は Promise を返します)

(Resend API のエラーを必ず処理し、一時的な障害に備えた再試行ロジックを実装してください)

(すべてのメール送信には必ずサーバーサイドを使用してください。RESEND_API_KEY をクライアントに公開しないでください)

(マーケティング/通知メールには必ず配信停止リンクを含めてください。CAN-SPAM 準拠のために必要です)

(すべてのメールテンプレートに型付き props インターフェースを必ず使用してください。コンパイル時の検証が可能になります)

</critical_requirements>


自動検出: Resend、React Email、@react-email/components、resend.emails.send、メールテンプレート、トランザクションメール、確認メール、パスワードリセットメール、通知メール、メールのレンダリング、resend.batch.send、resend.webhooks.verify

使用する場面:

  • トランザクションメール(確認、パスワードリセット、領収書)の送信
  • Tailwind スタイルを使った React Email テンプレートの作成
  • メール配信を伴う通知システムの構築
  • Webhook によるメールのトラッキングの実装
  • 複数の宛先への一括送信

使用しない場面:

  • マーケティングキャンペーンの管理(専用のマーケティングツールを使用)
  • SMS またはプッシュ通知(別のサービスを使用)
  • メールリストの管理(Resend Audiences またはマーケティングツールを使用)

基本方針

現代のアプリケーションにおけるメールは、サーバーサイドでテンプレートを使う方式が基本です。React Email はメール開発にコンポーネントのパターンを取り入れ、Resend は信頼性の高い配信を担います。

基本原則:

  1. サーバーサイドのみ - API キーをクライアントに公開しないでください
  2. 型付きテンプレート - props インターフェースにより、コンパイル時にエラーを検出できます
  3. 信頼性の高い配信 - 一時的な障害に備えた再試行ロジックでエラーを処理します
  4. ノンブロッキング - 重要度の低いメールには、完了を待たずに送信する方式を使います

メールを送信する場面:

  • ユーザー認証に関するイベント(確認、パスワードリセット、2FA)
  • トランザクションの確認(購入、登録、招待)
  • 重要な通知(セキュリティ警告、アカウントの変更)
  • チームでのコラボレーション(招待、メンション、更新)

メールを送信しない場面:

  • 細かな操作のたびに送信する(メール疲れにつながります)
  • 同意を得ずにマーケティングメールを送信する(スパムとなり、違法です)
  • リアルタイムのアラートを送信する(プッシュ通知を使用してください)
  • アプリ内の操作を通知する(代わりにアプリ内通知を表示してください)

基本パターン

パターン 1:メールテンプレートの構成

型付き props を定義し、React Email コンポーネントを使用して、開発サーバー向けに PreviewProps を追加します。

interface WelcomeEmailProps {
  userName: string;
  loginUrl: string;
  features?: string[];
}

export function WelcomeEmail({ userName, loginUrl, features = [] }: WelcomeEmailProps) {
  return (
    <BaseLayout preview={`Welcome, ${userName}!`}>
      <Heading>Welcome!</Heading>
      <Text>Hi {userName},</Text>
      <Button href={loginUrl}>Get Started</Button>
    </BaseLayout>
  );
}

WelcomeEmail.PreviewProps = { userName: "John", loginUrl: "..." } satisfies WelcomeEmailProps;

レイアウトとスタイルを含む完全なテンプレートについては、examples/core.md のパターン 1 を参照してください。


パターン 2:エラー処理を伴う送信

必ず render() を await し、{ data, error } のレスポンスを確認して、型付きの結果を返します。

const html = await render(options.react); // CRITICAL: must await

const { data, error } = await resend.emails.send({
  from: `${DEFAULT_FROM_NAME} <${DEFAULT_FROM_ADDRESS}>`,
  to: options.to,
  subject: options.subject,
  html,
});

if (error) {
  return { success: false, error: error.message };
}
return { success: true, id: data?.id };

完全な送信ラッパーと指数バックオフによる再試行については、examples/core.md のパターン 2〜3 を参照してください。


パターン 3:非同期の送信(完了を待たない方式)

重要度の低いメール(ウェルカムメール、通知)では、レスポンスを待たせないようにします。

// Non-blocking - catches errors internally
sendEmailAsync(options);
return Response.json({ success: true }); // Returns immediately

正常なシャットダウンに備えて、処理中の Promise を追跡してください。examples/async-batch.md のパターン 1〜2 を参照してください。


### パターン 4:バッチ API

2~100 人の受信者には resend.batch.send() を使用します。すべてのテンプレートを並列でレンダリングします。

const rendered = await Promise.all(
  emails.map(async (e) => ({
    from,
    to: e.to,
    subject: e.subject,
    html: await render(e.react),
  })),
);
const { data, error } = await resend.batch.send(rendered);

バッチの制限: attachments と scheduledAt は使用できません。タグと冪等性キーはサポートされています。examples/async-batch.md のパターン 3~4を参照してください。


パターン 5:Webhook の検証

生のリクエスト本文を使って resend.webhooks.verify() を使用します。JSON を解析すると署名の検証に失敗します。

const payload = await request.text(); // Raw body, NOT .json()

const event = resend.webhooks.verify({
  payload,
  headers: {
    id: request.headers.get("svix-id") ?? "",
    timestamp: request.headers.get("svix-timestamp") ?? "",
    signature: request.headers.get("svix-signature") ?? "",
  },
  webhookSecret: process.env.RESEND_WEBHOOK_SECRET!,
});

イベント処理と Svix の代替手段を含む完全なハンドラーについては、examples/webhooks.md を参照してください。


パターン 6:送信予約、冪等性キー、タグ
// Scheduled (up to 30 days, NOT supported in batch)
await resend.emails.send({ ...payload, scheduledAt: futureDate.toISOString() });

// Idempotency (256 char limit, expires 24h) — second argument to send()
await resend.emails.send(payload, {
  idempotencyKey: `order-confirmation-${orderId}`,
});

// Tags (ASCII alphanumeric, underscores, dashes only)
await resend.emails.send({
  ...payload,
  tags: [{ name: "campaign", value: "launch" }],
});

検証を含む完全な実装については、examples/advanced-features.md を参照してください。


パターン 7:配信停止と設定

トランザクションメール以外のメールには、配信停止リンクを必ず含める必要があります(CAN-SPAM)。セキュリティのため、署名付きトークンを使用してください。

// In every notification/marketing template:
<Link href={unsubscribeUrl}>Unsubscribe from these notifications</Link>

// Generate signed unsubscribe URLs
const token = jwt.sign({ userId, category }, UNSUBSCRIBE_SECRET, { expiresIn: "30d" });
const url = `${APP_URL}/api/email/unsubscribe?token=${token}`;

設定スキーマ、送信前の確認、配信停止エンドポイントについては、examples/preferences.md を参照してください。


詳細なリソース:


<red_flags>

要注意事項

優先度の高い問題:

  • render() を await していない - メール本文として "[object Promise]" が送信されます
  • API キーがクライアントに公開されている - セキュリティ上の脆弱性です
  • エラー処理がない - 失敗が検知されません
  • トランザクションメール以外のメールに配信停止リンクがない - CAN-SPAM 違反です
  • ユーザー設定を確認せずに送信している - スパムになります

優先度が中程度の問題:

  • 一時的な障害(レート制限、5xx エラー)に対する再試行ロジックがない
  • 重要度の低いメールの同期送信によってリクエストハンドラーがブロックされる
  • 環境変数の代わりに送信元アドレスがハードコードされている
  • Webhook の署名検証チェックがない
  • メール送信の結果をログに記録していない

よくある間違い:

  • メールテンプレートで Grid や Flexbox を使用する(メールクライアントではサポートされていません)
  • メールで影やグラデーションが表示されることを想定する
  • rem 単位を使用する(メールクライアントによって扱いが異なります)
  • 開発サーバー用の PreviewProps を忘れる

注意点とエッジケース:

  • Resend SDK は react プロパティを直接受け付けます(内部でレンダリングします)が、事前に await render() を使ってレンダリングし、html に渡すと出力を制御でき、Resend SDK の外部でも動作します
  • React Email 5.0 以降では render() は非同期です(renderAsync は非推奨です)
  • バッチ API は最大 100 通までで、attachments と scheduledAt はサポートされていません
  • Webhook には生のリクエスト本文が必要です - JSON を解析すると署名の検証に失敗します
  • Webhook の検証では secret ではなく webhookSecret パラメーターを使用します
  • Webhook のヘッダーオブジェクトでは短いキーを使用します:id、timestamp、signature
  • 冪等性キーはメールペイロードのヘッダーではなく、resend.emails.send() の第 2 引数として渡します
  • 冪等性キーの有効期限は 24 時間で、最大 256 文字です
  • タグに使用できるのは ASCII の英数字、アンダースコア、ダッシュのみで、キー/値ごとに最大 256 文字です
  • メールで Tailwind を使用するには @react-email/tailwind ラッパーが必要です(React Email 5.0 以降では Tailwind 4 をサポートしています)
  • 画像には絶対 URL を使用する必要があります(相対パスは使用できません)

</red_flags>


<critical_reminders>

重大な注意事項

すべてのコードは、CLAUDE.md のプロジェクト規約に従う必要があります(kebab-case、名前付きエクスポート、インポートの順序、import type、名前付き定数)

(HTML を resend.emails.send() に渡す前に、必ず render() を await してください。render は Promise を返します)

(Resend API のエラーを必ず処理し、一時的な障害に対するリトライロジックを実装してください)

(すべてのメールは必ずサーバー側で送信してください。RESEND_API_KEY をクライアントに公開してはいけません)

(マーケティングメール/通知メールには必ず配信停止リンクを含めてください。CAN-SPAM 準拠に必要です)

(すべてのメールテンプレートで、型付きの props インターフェースを必ず使用してください。これによりコンパイル時の検証が可能になります)

これらのルールに従わないと、メール配信の失敗、セキュリティ上の脆弱性、または法令遵守上の問題が発生します。

</critical_reminders>


参照元

コメント