CloudflareのEmail Workersで正規表現許可リストを使って複数宛先に受信メールを転送する

CloudflareのEmail Routing機能を使うと、受信アドレスごとに転送先を振り分けることができるんですが、Email Workersという機能を使えばスクリプトでもっと細やかな制御ができるようです。

たとえばどこかのサービス登録に使うアドレスは、そのサービスのドメインからのメールしか受信しないようにするとか。

Email Workersには、許可されたアドレスからのメールだけを転送するAllowlist sendersというテンプレートがあるんですが、そのままだと正規表現が使えないのでメールアドレスをフルで決め打ちする必要があるし、転送先が1つしか書けません。なので、これを改造してみることにしました。

とはいえスクリプトの文法がよくわからないので、いろいろなAIに頼んでみました。

それでEmail Workersでちゃんと動くコードが返ってきたのが、Claudeだけ。中国語の文法のわからないことを聞いてもかしこい答えを返すなあとふだんから感心していたんですが、コード生成でも優秀です。そもそもほかのAIは、Email Workersのコードを何の言語で書けばいいのかわかってなかったです。

で、そのClaudeの生成したものに若干手を加えてできたのが以下。

// Cloudflare Email Workers Forwarding Script with Regex Filtering

export default {
  async email(message, env, ctx) {
    // Regular expression patterns for allowed From addresses
    const allowedFromPatterns = [
      /^.*@aaa\.com$/i,
      /^.*@.*\.aaa\.com$/i,
      /^.*@bbb\.com$/i,
      /^.*@.*\.bbb\.com$/i
    ];

    // Forwarding destination email addresses
    const forwardToAddresses = [
      "[email protected]",
      "[email protected]"
    ];

    // Check the From address
    const from = message.from;

    if (allowedFromPatterns.some(pattern => pattern.test(from))) {
      // Forward the message to each destination address
      for (const forwardTo of forwardToAddresses) {
        // Forward the original message without modification
        await message.forward(forwardTo);
        console.log(`Forwarded email from ${from} to ${forwardTo}`);
      }
    } else {
      // Reject the email if it doesn't match the allowed patterns
      message.setReject("Address not allowed");
      console.log(`Set to reject email from ${from}. Reason: Address not allowed`);
    }
  }
}

aaa.combbb.comのメールアドレス(サブドメイン含む)がFromにあったら、 [email protected] [email protected] に転送して、それ以外のメールは拒否するというコードです。
( [email protected] [email protected] は、事前にCloudflareのダッシュボード上でEmail > Email Routing > Destination addressesに登録しておく必要があります。)

この正規表現からすると、Fromの末尾が厳密にaaa.combbb.comになっていないと転送されないように見えるんですが、メールヘッダ上“AAA” <aaa.com>のような形式のFromのメールでもちゃんと転送対象になります。さすがにそのあたりちゃんとわかってくれてます。

Email Workersの注意点

Email Workersはいろいろできておもしろそうなんですが、ちょっと注意点が。

Cloudflareのダッシュボード上、Email Workersで転送されたメールは、Email RoutingActivity LogResultDroppedになってしまうんです。Forwardedでなく。

転送されずにRejectされたメールはDelivery Failedとなるので区別はつくんやけど。

ちなみに複数の転送先のうち転送できたところとできなかったところが混ざっていた場合もDelivery Failedでした。

追記 2024-11-24

Email Workersで転送されたメールのActivity LogでのResultが最近DroppedからForwardedに変わっていました。

ただ、たとえば1通の受信メールを4アドレスに転送した場合、Email Routing summaryでは

Total received: 5
Forwarded: 4
Dropped: 1
Other: 0

のようにカウントされています。

コメント

読み込み中...