Gmail で受信したメールを Amazon SES 経由で Slack に通知する
2019-05-31Amazon SES (Amazon Simple Email Service) は 企業や開発者のための、フレキシブルで可用性が高く、手頃な価格の E メール送受信プラットフォーム です。AWS で提供されているメール送受信サービスということで、他の AWS のサービスとの連携が容易です。
今回は、 Amazon SES (以降、 SES) と AWS Lambda を使って、Gmail で受信したメールを Amazon SES 経由で Slack に通知する仕組みを実装してみました。
概要
やりたいこと
- Gmail で特定の差出人から受信したメールを Slack に通知したい。
今回の前提条件
- バージニア北部リージョン (us-east-1) を利用する。
- Route 53 で管理しているドメインがある。
- Slack のプランはフリープランである。
- Slack の以下の情報を取得済みである。
- Incoming WebHooks の Webhook URL
- Legacy tokens で生成された API Token
当初は Slack Apps にある Email を使おうと思っていましたが、この App はスタンダードプラン以上のプランでのみ利用可能ということが判明し、今回の仕組みを実装することになりました。
やること
- Route 53 で MX レコードを追加
- SES で Rule Sets を作成
- SES で受信したメール内容を Slack に通知する Lambda 関数を作成
- SES の Actions に Lambda を追加
- Gmail で転送フィルタを作成
構成としては下図のような形です。

では、順番にやっていきます。
投稿日は古いですが、基本的に流れは下記の記事の通りです。 [[新機能]Amazon SES でメール受信が出来るようになりました! | DevelopersIO](https://dev.classmethod.jp/cloud/receiving-email-with-amazon-ses/)1. Route 53 で MX レコードを追加
SES で利用するメールアドレスのドメインに対して、 MX レコードを追加します。今回は Route 53 で管理しているドメインのサブドメインに対して登録します。

値に指定するのは、利用するリージョンによって異なります。今回はバージニア北部リージョンを利用するので、 10 inbound-smtp.us-east-1.amazonaws.com
を指定します。他のリージョンでの値については公式ドキュメントを参照してください。
2. SES で Rule Sets を作成
マネジメントコンソールを開いて、リージョンを バージニア北部 に変更し、 SES のコンソールを開きます。
左のメニューの Email Receiving の Rule Sets から Create Rule ボタンを押して Rule Set を作成します。
Recipient
を追加する画面になるので、先ほど MX レコードを登録したドメインを入力して Add Recipient
ボタンを押します。

追加された行の Verify domain
を押すとモーダルが表示されます。

Use Route 53
を押すと Warning が出ますが、赤枠で囲った Email Receiving Record
にチェックを入れ、 Create Record Sets
を押します。

続いて Actions の設定です。ここでは、 SES でメールを受信したあとにどんな Action をするかを設定します。あとで変更しますが、一旦は S3 への保存のみを設定します。

次の画面では Rule の詳細設定をしますが、特に触らずにそのまま次へ進みます。

最後に設定を確認して Create Rule
を押します。

これらの手順が終わった後に、 SES のコンソールの左にある Domains で、追加したドメインが有効になっているかを確認します。

Verification Status が verified になっていれば OK です。
3. SES で受信したメール内容を Slack に通知する Lambda 関数を作成
ソースは GitHub に置いてるのでここには貼りませんが、やっていることは次のようなことです。
- S3 に保存されたメッセージを取得
- body 部分を適切にデコード (base64 or quoted-printable)
- Slack へ通知
わざわざ S3 からメッセージデータを取得しているのは、 SES から Lambda に渡される Event の中にメールの本文データが含まれていないためです。 message id は含まれているので、それをもとに S3 からオブジェクトを取得します。
また、Slack への通知に際して、メール本文をタイムラインにポストすると圧迫感が凄いので、次のような形でポストしてます。
- 差出人、日時、件名、宛先 のみをタイムラインにポスト
- そのポストのスレッドに本文をポスト
結果的にはこんな感じになります。

4. SES の Actions に Lambda を追加
SES の Actions 設定で、S3 への保存の次の Action として、作成した Lambda (ここでは SEStoSlack という名前の関数) を指定します。

5. Gmail で転送フィルタを作成
あとは Gmail の設定画面で、 SES 宛に転送するようなフィルタを作れば完了です。
Gmail で転送用アドレスを追加する際には確認コードが必要になりますが、そのメール自体も S3 に保存されるので、確認コードはそのファイルから取得する形になります。
手順 4 で Lambda の設定が完了していれば、確認コードを含んだこのメールも Slack に通知されるので、そこで確認することができます。
まとめ
以上、Gmail で受信したメールを Amazon SES 経由で Slack に通知する仕組みを作ってみた話でした。
もちろん Amazon SES も料金は発生しますが、メールの受信に関しては 最初の 1,000 件までは 0 USD。それ以降は 1,000 件ごとに 0.10 USD となっています。 Slack のスタンダードプランは 1 ユーザあたり 850 円 (年払い) なので、仮に 1 ユーザだったとしてもその金額に達するにはメールを 約 78,272 (= 850 / 110 / 0.10 * 1000 + 1000) 通受信する必要があります ($1 = 110円 で計算)
もしメールの転送がしたいためだけにスタンダードプランにすることがあれば (なさそうですが) Amazon SES + Lambda でのメール通知もありかもしれません。
comments powered by Disqus