今までは大量にメールを配信するシステムをつくるのは簡単なことではなかた。
ですが、AWSが提供している複数のサービスを組み合わせることで大量のメールを配信する機能も簡単に作れるようになりましたね。いろいろなユーズケースによって、様々設計方法があるかと思いますが今回はAWS Lambda + SQS + DynamoDB + S3の組み合わせでつくるメール配信機能を設計してみました。
作成したい機能
テンプレートで作成したメールマガジンデータファイルをS3にアップして、おなじく対象のユーザリストをcsv形式のファイルをアップすると、配信希望の時間になったら大量のユーザに対してメールを配信する。配信したメールの配信履歴を6月間保存してそれ以前の配信履歴を削除する。
設計図
パタン1:事前準備しないで送信
パタン2:事前に送信対象を準備してより早く送信する
設計パタンの紹介
今回は簡単なServerless実装を考えた結果、上のような図になりました。また2パタンを準備していますが、パタン1はそれほど件数が多くなくて、データ準備から配信まで一つのSchedule Eventにて実装しているパタンです。
パタン2は配信データ件数が大量の場合、より早く多くのユーザへメールを配信するために、配信時間になる前に配信するデータを準備して置きます。配信時間になったらそのデータを送信するような設計になります。そのため、実行処理が2つのEventにて処理する想定です。
パタン1:
- Webのフロントエントで配信するメール文面ファイルと対象のメールアドレスを含むユーザリストファイルをS3へアップロードします。今回はVue.jsにてFrontendを準備する予定です。Vue.js +AWS Amplify をつかってFrontendからS3へ直接ファイルをアップします。
- ファイルがアップロードできたらそれらのファイル名、配信日、S3のファイルPathなどのMetadataをDynamoDBのmagazine Tableに記録しています。この登録の処理はAWS AppSyncを利用して実施します。
- 配信時間になったらCloudWatch EventによってScheduleされたEventが発行され、PrepareSendListFunctionが実行されます。
- PrepareSendListFunctionでMagazine Tableから該当のレコードをQueryします。
- Query結果で配信対象が存在したらそのレコードにあるs3のPathからメールの文面情報と、ユーザリストを取得します。
- MagazineTableのステタスを処理済みに更新します。
- ユーザごとの配信情報を作成してmagazineDat TableにInsertします。
- magazineDat Tableに登録されたらProcessMailFunctionをTriggerするようにDynamaoDbStreamを設定します。
- ProcessMailFunctionでメールをSESへ登録行います。
- SESがユーザへメール送信します。
- SESが受け取ったメール情報を各ユーザへ送ります。
パタン2:
- Webのフロントエントで配信するメール文面ファイルと対象のメールアドレスを含むユーザリストファイルをS3へアップロードします。今回はVue.jsにてFrontendを準備する予定です。Vue.js + AWS Amplify をつかってFrontendからS3へ直接ファイルをアップします。
- ファイルがアップロードできたらそれらのファイル名、配信日、S3のファイルPathなどのMetadataをDynamoDBのmagazine Tableに記録しています。この登録の処理はAWS AppSyncを利用して実施します。
- 配信時間になる前(30分前を想定します)CloudWatch Event(ScheduleEventToQueue)によってScheduleされたEventがTriggerされ、PrepareSendListFunctionが実行されます。
- PrepareSendListFunctionでMagazine Tableから該当のレコードがあるかをQueryします。
- Query結果で配信対象が存在したらそのレコードにあるs3のPathからメールの文面情報と、ユーザリストを取得します。
- ユーザごとの配信情報を作成してmagazineDat TableにInsertします。
- MagazineTableのステタスを処理済みに更新します。
- 配信時間になったらCloudWatch Event(ScheduleEventToSend)によってScheduleされたEventがTriggerされ、CheckSendListFunctionが実行されます。
- CheckSendListFunctionでMagazineDat Tableから配信必要なレコードがあるかをQueryします。
- 該当のレーコドがあったらSQS(TriggerMail)に登録します。
- SQSにqueueが登録されたらProcessMailFunctionをTriggerするようSQS Queueの設定します。
- ProcessMailFunctionでメールをSESへ登録行います。
- SESへメール登録成功したらMagazineDat TableのメールステータスをSentにupdateします。
- SESが受け取ったメール情報を各ユーザへ送ります。
おわりに
コードの実装はこれからになりますが、設計図を考えてみたら実装が難しくないですね。また実装はしてないですが、今度実装したらその内容を投稿します。