mcpField
C
cloudflare-email-routing

cloudflare-email-routing

github.com/secondskyクラウド・DevOps240226 回インストール5 週間前に更新
リポジトリ

cloudflare-email-routing について

Cloudflare Workers 開発者向けの Email Routing スキルです。メールの受信、解析、転送、送信方法を解説し、セットアップガイドやフィルターパターン、テンプレート、一般的なエラーへの対処を含みます。

主な機能

  1. 01Email Workers による受信処理
  2. 02本文と添付ファイルの解析
  3. 03メールの転送とフィルタリング
  4. 04Worker からのメール送信
  5. 05セットアップガイドと設定テンプレート
  6. 06一般的なエラーへの対処

活用シーン

  1. 01受信メールからサポートチケットを作成
  2. 02ユーザーへのメール通知送信
  3. 03ルールに基づくメールのフィルタリングと転送

インストール

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

$npx skills add https://github.com/secondsky/claude-skills --skill cloudflare-email-routing

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

同梱ファイル

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

references/
common-errors.md
dns-setup.md
local-development.md
setup-guide.md
templates/
receive-allowlist.ts
receive-basic.ts
receive-blocklist.ts
receive-reply.ts
send-basic.ts
send-notification.ts
wrangler-email.jsonc

詳細

Cloudflare Email Routing

ステータス:本番環境で利用可能 ✅ | 最終確認日:2025-11-18


Email Routing とは?

次の 2 つの機能があります。

  1. Email Workers - 受信メールの受け取りと処理(許可リスト、転送、解析)
  2. メール送信 - Workers から検証済みのアドレスにメールを送信

どちらも無料で、連携してメール機能を一通り利用できます。


クイックスタート(10 分)

パート 1:Email Routing を有効にする

ダッシュボードでの設定:

  1. ダッシュボード → ドメイン → Email → Email Routing
  2. Enable Email Routing → Add records and enable
  3. 送信先アドレスを作成します。
    • カスタム:[email protected]
    • 送信先:ご利用のメールアドレス
    • メールで認証します。
  4. ✅ 基本的な転送が有効になります。
パート 2:メールを受信する(Email Workers)

依存関係をインストールします:

bun add [email protected] [email protected]

メール Worker を作成します:

// src/email.ts
import { EmailMessage } from 'cloudflare:email';
import PostalMime from 'postal-mime';

export default {
  async email(message, env, ctx) {
    const parser = new PostalMime.default();
    const email = await parser.parse(await new Response(message.raw).arrayBuffer());

    console.log('From:', message.from);
    console.log('Subject:', email.subject);

    // Forward to destination
    await message.forward('[email protected]');
  }
};

wrangler.jsonc を設定します:

{
  "name": "email-worker",
  "main": "src/email.ts",
  "compatibility_date": "2025-10-11",  // must be >= 2024-09-23 for nodejs_compat
  "compatibility_flags": ["nodejs_compat"]  // Required! postal-mime needs Node.js compat
}

デプロイして接続します:

bunx wrangler deploy

ダッシュボード → Email Workers → Create address → Worker を選択

パート 3:メールを送信する

メール送信バインディングを追加します:

{
  "name": "my-worker",
  "main": "src/index.ts",
  "compatibility_date": "2025-10-11",
  "send_email": [
    {
      "name": "SES",
      "destination_address": "[email protected]"
    }
  ]
}

Worker から送信します:

import { EmailMessage } from 'cloudflare:email';
import { createMimeMessage } from 'mimetext';

const msg = createMimeMessage();
msg.setSender({ name: 'App', addr: '[email protected]' });
msg.setRecipient('[email protected]');
msg.setSubject('Hello!');
msg.addMessage({
  contentType: 'text/plain',
  data: 'Email body here'
});

const message = new EmailMessage(
  '[email protected]',
  '[email protected]',
  msg.asRaw()
);

await env.SES.send(message);

手順の全容については references/setup-guide.md を読み込んでください。


重要なルール

必ず行うこと ✅
  1. postal-mime 用に compatibility_flags: ["nodejs_compat"] を有効にする(compatibility_date >= 2024-09-23 が必要です)
  2. 送信前に送信先アドレスを検証する
  3. メールの内容を解析するには postal-mime を使用する
  4. メールを作成するには mimetext を使用する
  5. 許可リストでは message.from を確認する
  6. 転送には message.forward() を使用する(手動で転送しない)
  7. エラーを処理する(メールの配信に失敗する場合があります)
  8. 実際のメールでテストする(ダッシュボードだけでテストしない)
  9. MX レコードを追加する(ダッシュボードから自動で追加されます)
  10. デバッグ用にメールのアクティビティをログに記録する
絶対に行わないこと ❌
  1. nodejs_compat を省略しない(postal-mime には Node.js 互換フラグが必要です)
  2. 検証せずに送信しない(配信に失敗します)
  3. 公開コードにメールアドレスをハードコードしない
  4. 解析を省略しない(生のメールは扱いにくいため)
  5. スパムを無視しない(許可リスト/ブロックリストを実装します)
  6. Gmail の上限を超えない(Gmail への送信は 1 日あたり 500 通までです)
  7. エラー処理を省略しない(メールの送信に失敗する場合があります)
  8. DNS を手動で変更しない(ダッシュボードを使用します)
  9. ログにメールの内容を出力しない(個人情報が含まれます)
  10. 即時に配信されると想定しない(メールは非同期です)

よくあるパターン

許可リスト
const allowlist = ['[email protected]'];

if (!allowlist.includes(message.from)) {
  message.setReject('Not on allowlist');
  return;
}

await message.forward('[email protected]');
ブロックリスト
const blocklist = ['[email protected]'];

if (blocklist.includes(message.from)) {
  message.setReject('Blocked');
  return;
}

await message.forward('[email protected]');
メールに返信する
const msg = createMimeMessage();
msg.setSender({ addr: '[email protected]' });
msg.setRecipient(message.from);
msg.setSubject(`Re: ${email.subject}`);
msg.addMessage({
  contentType: 'text/plain',
  data: 'Thanks for your email!'
});

const reply = new EmailMessage(
  '[email protected]',
  message.from,
  msg.asRaw()
);

await env.SES.send(reply);
添付ファイルを解析する
const parser = new PostalMime.default();
const email = await parser.parse(await new Response(message.raw).arrayBuffer());

for (const attachment of email.attachments) {
  console.log('Filename:', attachment.filename);
  console.log('Type:', attachment.mimeType);
  console.log('Size:', attachment.content.byteLength);
}
カスタムのルーティングロジック
async email(message, env, ctx) {
  const parser = new PostalMime.default();
  const email = await parser.parse(await new Response(message.raw).arrayBuffer());

  // Route based on subject
  if (email.subject.includes('[Support]')) {
    await message.forward('[email protected]');
  } else if (email.subject.includes('[Sales]')) {
    await message.forward('[email protected]');
  } else {
    await message.forward('[email protected]');
  }
}

メールメッセージのプロパティ

受信メッセージ(ForwardableEmailMessage)
message.from        // Sender email
message.to          // Recipient email
message.headers     // Email headers
message.raw         // Raw email stream
message.rawSize     // Size in bytes

// Methods
message.forward(address)        // Forward to address
message.setReject(reason)       // Reject email
解析済みメール(PostalMime)
email.from          // { name, address }
email.to            // [{ name, address }]
email.subject       // Subject line
email.text          // Plain text body
email.html          // HTML body
email.attachments   // Array of attachments
email.headers       // All headers

防止できる主なエラー 5 件

  1. 「Email Trigger を利用できません」:compatibility_flags: ["nodejs_compat"] を有効にします(compatibility_date >= 2024-09-23 が必要です)
  2. 送信先が検証されていない:すべての送信先を検証します
  3. Gmail のレート制限:Gmail への送信は 1 日あたり最大 500 通です
  4. SPF permerror:ダッシュボードを使用して DNS を設定します
  5. Worker の呼び出しに失敗:解析エラーがないかログを確認します

ユースケース

ユースケース 1:サポートチケットシステム
async email(message, env, ctx) {
  const parser = new PostalMime.default();
  const email = await parser.parse(await new Response(message.raw).arrayBuffer());

  // Create ticket in database
  await env.DB.prepare(
    'INSERT INTO tickets (email, subject, body, created_at) VALUES (?, ?, ?, ?)'
  ).bind(message.from, email.subject, email.text, Date.now()).run();

  // Send confirmation
  const msg = createMimeMessage();
  msg.setSender({ addr: '[email protected]' });
  msg.setRecipient(message.from);
  msg.setSubject('Ticket Created');
  msg.addMessage({
    contentType: 'text/plain',
    data: 'Your support ticket has been created.'
  });

  const confirmation = new EmailMessage(
    '[email protected]',
    message.from,
    msg.asRaw()
  );

  await env.SES.send(confirmation);
}
ユースケース 2:メール通知
export default {
  async fetch(request, env, ctx) {
    // User signup
    const { email, name } = await request.json();

    const msg = createMimeMessage();
    msg.setSender({ name: 'App', addr: '[email protected]' });
    msg.setRecipient(email);
    msg.setSubject('Welcome!');
    msg.addMessage({
      contentType: 'text/html',
      data: `<h1>Welcome, ${name}!</h1>`
    });

    const message = new EmailMessage(
      '[email protected]',
      email,
      msg.asRaw()
    );

    await env.SES.send(message);

    return new Response('Welcome email sent!');
  }
};
ユースケース 3:フィルタリング付きメール転送
async email(message, env, ctx) {
  const parser = new PostalMime.default();
  const email = await parser.parse(await new Response(message.raw).arrayBuffer());

  // Filter spam keywords
  const spamKeywords = ['viagra', 'lottery', 'prince'];
  const isSpam = spamKeywords.some(keyword =>
    email.subject.toLowerCase().includes(keyword) ||
    email.text.toLowerCase().includes(keyword)
  );

  if (isSpam) {
    message.setReject('Spam detected');
    return;
  }

  await message.forward('[email protected]');
}

リファレンスを読み込むタイミング

次の場合は references/setup-guide.md を読み込みます:
  • Email Routing を初めて設定するとき
  • MX レコードを設定するとき
  • メール Worker を設定するとき
  • メール送信バインディングを設定するとき
  • 手順の全容が必要なとき

同梱リソースの使用

リファレンス(references/):

  • setup-guide.md - セットアップの全手順(ルーティングの有効化、メールワーカー、メールの送信)
  • common-errors.md - 解決策と予防策を含む、文書化された8つのエラーすべて
  • dns-setup.md - MXレコード、SPF、DKIMの設定ガイド
  • local-development.md - ローカルテストと開発のパターン

テンプレート(templates/):

  • receive-basic.ts - 基本的なメール受信ワーカー
  • receive-allowlist.ts - メールの許可リストの実装
  • receive-blocklist.ts - メールのブロックリストの実装
  • receive-reply.ts - 自動返信メールワーカー
  • send-basic.ts - 基本的なメール送信の例
  • send-notification.ts - 通知メールのパターン
  • wrangler-email.jsonc - メールルーティング用のWrangler設定

公式ドキュメント


質問や問題がありますか?

  1. セットアップの全手順については、references/setup-guide.mdを確認してください
  2. wrangler.jsoncでcompatibility_flags: ["nodejs_compat"]を確認してください
  3. 宛先アドレスが検証済みであることを確認してください
  4. エラーがないかログを確認してください

コメント