Cloudflareの Email Workers を用いたシステムの起点

ここ数年バレンタインは抹茶ホワイトチョコマフィンをもらい続けています。
抹茶もホワイトチョコも大好き、甘いもの大好き、エンジニアの柿添です。

最近、出社したら会社が用意してくれたお菓子が自分のデスクの上に!
一瞬でなくなりました笑

Cloudflare Workers

Cloudflare の Workers をご存知ない方向けに、
「Workersとはなんぞや?」と言う話からです。

Cloudflare Workers は世界最大規模のエッジコンピューティングプラットフォームの1つです。
(私の大好きなエッジコンピューティング)

デプロイも簡単でCDNエッジでスクリプトを走らせることが可能です。
オリジンに到達するよりも、エッジキャッシュを拾いにいくよりも更に前段階で稼働します。

Workers の 無料範囲でできること

  • 1日あたり10万件のリクエスト(Workersスクリプト全体、UTC+0)
  • リクエストあたりのCPU時間:10ミリ秒以内
  • 最小遅延は最初のリクエスト後
  • 最大30本のWorkersスクリプト
  • 最大100件のネームスペース
  • 数百か所のデータセンターへ自動でグローバルデプロイメント
  • 自動スケール機能のあるメンテナンス不要のインフラストラクチャ
  • コールドスタートなしの高パフォーマンスのランタイム
  • JavaScriptと10言語以上をサポート
  • フルCLIデプロイメント機能
  • Mutual TLS for Workers

Workers KEY-VALUE ストレージの機能

  • 1日あたり10万件の読み込み操作
  • 1日あたり1,000件の書き込み操作、削除操作、列挙操作
  • 最大1GBのストレージ

Cloudflare Email Workers

Workers の メール版が beta で利用できるようになりました。

Email Workers を使用すると、Cloudflare Workers の機能を活用して、

  • メール処理
  • 複雑なルール展開
  • 必要なロジックをInjection

なんてことが可能になります。

メールの受信をトリガーに振る舞いを簡単に実装できます。

公式の例ではホワイトリストの電子メール ワーカーの例が記載されていました。

export default {
  async email(message, env, ctx) {
    const allowList = ["[email protected]", "[email protected]"];
    if (allowList.indexOf(message.from) == -1) {
      message.setReject("Address not allowed");
    } else {
      await message.forward("inbox@corp");
    }
  }
}

たったこれだけ、素敵ですね。

Cloudflare Email Workers を システムの起点に

最近会社で管理下に置かれているドメインに .green を追加していただきました。
こちらを使っていきます。

Email Routing を始める

ちょっと前まで beta版でしたが、現在は正式利用が可能となりました「Email Routing」を使っていきます。
私も個人のドメインでメールアドレスの割り振りにこちらを利用しています。

始めるをクリックして利用開始しましょう。

Cloudflare Email Workers 0001

まずは kakizoe で作っておきました。(作らないでスキップしても良いと思います。)

Cloudflare Email Workers 0002
Cloudflare Email Workers 0003

受信したメールを承認してカスタムメールアドレスの登録完了です。

Cloudflare Email Workers 0004

Email Workers を作成する

次に Email Workers のタブをクリックして移動します。

Cloudflare Email Workers 0005

「作成」をクリックして Workers を作っていきます。

Cloudflare Email Workers 0006

Cloudflare Email Workers 0007

ここでは先程の例の他に2つのスクリプト例がが公開されています。

Email Workers 例 ブラックリスト

block 記載の メールアドレスはブラックリストとし、受信トレイに配信しないようにします。

export default {
  async email(message, env, ctx) {
    const block = ["[email protected]", "[email protected]"]
    if (block.indexOf(message.headers.get("from")) == -1) {
      await message.forward("inbox@corp");
    } else {
      message.setReject("Address is blocked");
    }
  }
}

Email Workers 例 Slackに通知を送る

export default {
  async email(message, env, ctx) {
    switch (message.to) {
      case "[email protected]":
        await fetch("https://webhook.slack/notification", {
          body: `Got a marketing email from ${message.from}, subject: ${message.headers.get('subject')}`,
        });
        await message.forward("inbox@corp");
        break;

      default:
        message.setReject("Unknown address");
    }
  }
}

適当な名前をつけて Worker を作成していきます。

Email Workers で LINE通知させる

オンライン上で簡単にコードデプロイ可能です、左がエディタで右で簡単な検証ができます。

Cloudflare Email Workers 0008

エディタに以下のようにLINE通知するようなコードを書いてあげます。

export default {
  async email(message, env, ctx) {

    async function gatherResponse(response) {
      const { headers } = response;
      const contentType = headers.get('content-type') || '';
      if (contentType.includes('application/json')) {
        return JSON.stringify(await response.json());
      }
      return response.text();
    }

    // いつものようにLINE通知
    const body = new URLSearchParams({ message: message.from + "からメールがありました。"});
    const init = {method: 'POST', headers: {'content-type': 'application/json;charset=UTF-8','Authorization': 'Bearer XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'}};
    const url = "https://notify-api.line.me/api/notify/?" + body.toString();
    const response = await fetch(url, init);
    const results = await gatherResponse(response);
    console.log(results);

    // 宛先アドレス登録済のメールアドレスでないとエラーになる
    await message.forward("[email protected]");
  }
}

Cloudflare Email Workers 0009

最後にこの Email Workers のルートを作成してあげます。

作成した Email Workers をチェック

先程設定したルートの「カスタムアドレス」に対してメールを送ります。

Cloudflare Email Workers 0010

LINE Notify にて通知を受け取ることができたかと思います。

まとめ

通常ならCLI(wrangler)を使っていますが、
今回はコンパネ上でサクッと記述して試してみました。

メール受信をトリガーにpostfix・dovecotなんかを使ったやり方もあるかと思いますが、
Cloudflare Email Workers を起点にすれば簡単に実装でき、
世界中のCDNエッジ上で展開することが可能です。

メールを起点に動作するシステムの開発・Cloudflare Workers を用いたシステムなど、
ぜひ一度C-limberにご相談ください。

Related article

おすすめ関連記事