SendGrid で送信したメールの Bounce Event を取得するサンプル
AWS Lambda(Python)で SendGrid を使ってメールを送信し、その Bounce Event(Bounced
およびDropped
)を取得するサンプルです。
サンプルの内容
「メール送信時に送信履歴用の DynamoDB テーブルに記録した情報」と「SendGrid の Event Webhook で取得した情報」を突合し、Bounce Event に関する情報を取得するサンプルです。
- SendGrid の Event Webhook によって Bounce Event 取得用 API Gateway を呼び出し
- 同 API Gateway 経由で Bounce Event 取得用 Lambda 関数を実行
- 同 Lambda 関数 で受信した
Bounced
およびDropped
のイベント情報と送信履歴用 DynamoDB テーブルのレコードを突合 - 突合した結果を Bounce Event 用 DynamoDB テーブルにレコード登録
という流れで Bounce Event を記録します。
こちらの GitHub リポジトリに実際のコードを置いてあります。
SendGrid 側の設定 (1)
1. Domain Authentication / Link Branding の設定
左側メニューから 「Settings」 - 「Sender Authentication」 を選択します。
Authenticate Your Domain をクリックします。
① レコードを登録する DNS host(どれにも当てはまらない場合は 「Other Host (Not Listed)」)を選択します。
② メール送信時に送信元ドメインを「sendgrid.net」ではなくカスタムドメインに書き換える場合は 「Yes」 を選択します。
その後 「Next」 をクリックします。
送信元ドメインを入力し、必要に応じて 「Advanced Settings」 の各項目を選択・入力します。
その後 「Next」 をクリックします。
① 表示された CNAME レコードを DNS に登録します。
(↓ は AWS の Route 53 の例)
登録したら SendGrid の画面に戻り、
② 「I've added these records.」 にチェックを入れて 「Verify」 をクリックします。
以上で Domain Authentication および Link Branding の作業(設定)は完了です。
2. API Keys の作成
メール送信用の API キーを作成します。
左側メニューから 「Settings」 - 「API Keys」 を選択します。
「Create API Key」 をクリックします。
キーの名前(任意の名前)を入力し、「Restricted Access」 を選択して 「Mail Send」 の詳細項目のほうの 「Mail Send」 のみ有効にします。
その後 「Create & View」 をクリックします。
表示された API キー(「SG.」で始まる文字列)をクリックするとクリップボードにコピーされます。
どこかに API キーを控え、「Done」 をクリックして完了です。
AWS 側の設定
1. Dynamo DB テーブルおよび KMS キーの作成
DynamoDB テーブルをいくつか作成していきます。
1-1. KMS キーの作成
最初に DynamoDB テーブル暗号化用 KMS キーを作成します。
「KMS」 - 「カスタマー管理型のキー」 画面で 「キーの作成」 をクリックします。
「次へ」 をクリックします。
エイリアス(キーの名前)を入力して 「次へ」 をクリックします。
キーの管理者を選択して 「次へ」 をクリックします。
「次へ」 をクリックします。
最後に 「完了」 をクリックして作成完了です。
1-2. メール送信用 DynamoDB テーブルの作成
「DynamoDB」(「ダッシュボード」 または 「テーブル」)画面で 「テーブルの作成」 をクリックします。
テーブル名 : 任意(testMailSender
など)、パーティションキー : id
(文字列)を入力し、「設定をカスタマイズ」 を選択します。
「キャパシティーモード」 は 「オンデマンド」 を、「暗号化キーの管理」 は 「アカウントからのキー」 で先ほど作成した KMS キーを選択します。
最後に 「テーブルの作成」 をクリックして作成完了を待ちます。
1-3. メール送信履歴用 DynamoDB テーブルの作成
引き続きメール送信履歴用テーブルを作成します。
- テーブル名 : 任意(
testMailSentLog
など) - パーティションキー :
messageId
(文字列)
ほかの項目はメール送信用テーブルと同じです。
1-4. Bounce Event 用 DynamoDB テーブルの作成
最後に Bounce Event 用テーブルを作成します。
- テーブル名 : 任意(
testMailBounce
など) - パーティションキー :
fullMessageId
(文字列)
ほかの項目はメール送信用テーブルと同じです。
2. Lambda 関数 / API Gateway / IAM Role および KMS キーの作成・設定
2-1. SendGrid Python SDK を Lambda レイヤーとして登録
Amazon Linux 2 の EC2(Cloud9)を用意し、 SendGrid Python SDK を(依存パッケージを含めて).zip
化します。
mkdir python
pip3 install sendgrid -t python
zip sendgrid-sdk.zip -r python
「Lambda」 - 「レイヤー」 画面で 「レイヤーの作成」 をクリックします。
- 名前 : 任意(
sendgrid
など) - 互換性のあるアーキテクチャ : x86_64・arm64 ともチェック
- ランタイム : Python 3.9
先ほど作った.zip
ファイルをアップロードし、 「作成」 をクリックします。
2-2. メール送信用 Lambda 関数の作成
「Lambda」 - 「関数」 画面で 「関数の作成」 をクリックします。
- 関数名 : 任意(
testMailSender
など) - ランタイム : Python 3.9
- アーキテクチャ : どちらでも可(ここでは arm64 を選択)
- 実行ロール : 基本的な Lambda アクセス権限で新しいロールを作成
「関数の作成」 をクリックします。
「コード」 - 「レイヤー」 - 「レイヤーの追加」 :
- レイヤーソース : 「カスタムレイヤー」 を選択
- カスタムレイヤー : 2-1. で作成したものを選択
- 画面は「バージョン 2」になっているが再作成等をしていない場合は「バージョン 1」
「追加」 をクリックします。
「コード」 - 「コードソース」 : lambda_function.py
「Deploy」 をクリックします。
「設定」 - 「一般設定」 - 「編集」 :
- タイムアウト : 3 分 0 秒
- 既存のロール : 「View the 【ロール名】」 のリンクをクリック
ポリシーの 「編集」 をクリックします。
DynamoDB に対する権限を追加します。
- アクション : ListStreams/リソース : *
- アクション : GetItem・Query・PutItem/リソース : メール送信履歴用 DynamoDB テーブルの ARN
- アクション : DescribeStream・GetRecords・GetShardIterator/リソース : メール送信用 DynamoDB テーブルの stream/*(ARN)を指定
「ポリシーの確認」 をクリックします。
「変更の保存」 をクリックします。
Lambda 関数の 「基本設定を編集」 画面に戻って 「保存」 をクリックします。
「設定」 - 「トリガー」 - 「トリガーを追加」 :
- トリガーの設定 : 「DynamoDB」 を選択
- DynamoDB テーブル : メール送信用テーブルを選択
- バッチサイズ : 100
「追加」 をクリックします。
2-3. Lambda 関数(メール送信)用 KMS キーの作成
1-1. と同様にキーを作成します。
- エイリアス : 任意の名前
- キーの使用者(ユーザー) : メール送信用 Lambda 関数の実行ロール
2-4. メール送信用 Lambda 関数の環境変数を設定
メール送信用 Lambda 関数の画面で 「設定」 - 「環境変数」 - 「編集」 をクリックします。
- キー :
-
SENDGRID_API_KEY
: SendGrid 側の設定 (1) の 2. で発行した API キー -
TABLE_SENT_LOG
: メール送信履歴用 DynamoDB テーブルの名前
-
- 転送時の暗号化 : 「転送時の暗号化に使用するヘルパーの有効化」 にチェック
- 保管時に暗号化する AWS KMS キー : 「カスタマーマスターキーの使用」 を選択
- カスタマーマスターキー : 2-3. で作成したキーを選択
キー「SENDGRID_API_KEY
」の右側にある 「暗号化」 で値の暗号化を行います。
先ほどと同じ AWS KMS キーを選択し、「暗号化」 をクリックします。
前の画面に戻ったら 「保存」 をクリックして完了です。
2-5. Bounce Event 取得用 Lambda 関数の作成
関数を作成します。
- 関数名 : 任意(
testBounceReceiver
など) - ランタイム : Python 3.9
- アーキテクチャ : どちらでも可(ここでは arm64 を選択)
- 実行ロール : 基本的な Lambda アクセス権限で新しいロールを作成
- コード :
lambda_function.py
- 一般設定 - タイムアウト : 30 秒
- アクセス権限 : 選択されているポリシーに DynamoDB に関する権限を追加
- アクション : GetItem/リソース : メール送信履歴用 DynamoDB テーブルの ARN
- アクション : PutItem/リソース : Bounce Event 用 DymanoDB テーブルの ARN
- 環境変数 :
-
TABLE_BOUNCE
: Bounce Event 用 DynamoDB テーブルの名前 -
TABLE_SENT_LOG
: メール送信履歴用 DynamoDB テーブルの名前
-
2-6. Bounce Event 取得用 API Gateway の作成
「API Gateway」 - 「API」 画面で 「API を作成」 をクリックします。
「REST API」 の 「構築」 をクリックします。
任意の API 名(例 : 「testEventHookReceiver」)を入力して 「API の作成」 をクリックします。
「リソース」 - 「アクション」 のメニューで 「リソースの作成」 を選択します。
任意のリソース名(悪用されにくいようランダムで長いもの)を入力して 「リソースの作成」 をクリックします。
同じリソースの 「アクション」 のメニューで 「メソッドの作成」 を選択します。
POST メソッドを選択します。
- 統合タイプ : Lambda 関数
- Lambda プロキシ統合の使用 : チェック
- Lambda 関数 : Bounce Event 取得用 Lambda 関数の名前
「保存」 をクリックします。
「OK」 をクリックします。
「メソッドレスポンス」 のリンクをクリックします。
「レスポンスの追加」 をクリックします。
ステータス 500 のレスポンスを追加(作成)します(チェックアイコン をクリック)。
「500 のレスポンス本文」 を登録します。
- コンテンツタイプ : application/json
- モデル : Empty
チェックアイコン をクリックして登録(保存)します。
同じリソースの 「アクション」 のメニューで 「API のデプロイ」 を選択します。
- デプロイされるステージ : [新しいステージ]
- ステージ名 : v1
「デプロイ」 をクリックして API をデプロイします。
2-7. Dynamo DB テーブル用 KMS キーにユーザー(IAM Role)を追加
「KMS」 - 「カスタマー管理型のキー」 画面で DynamoDB テーブル用 KMS キーのエイリアスのリンクをクリックします。
「キーユーザー」 の 「追加」 をクリックします。
- メール送信用 Lambda 関数
- Bounce Event 取得用 Lambda 関数
実行用の IAM Role を追加します。
SendGrid 側の設定 (2)
1. Event Webhook の設定
左側メニューから 「Settings」 - 「Mail Settings」 を選択します。
「Event Settings」 - 「Event Webhook」(リンクまたは右端の鉛筆アイコン)をクリックします。
- HTTP Post URL : Bounce Event 取得用 API Gateway の API エンドポイント URL
- Events to be POSTed to your URL :
- DELIVERABILITY DATA : Dropped・Bounced にチェック
- Event Webhook Status : ENABLED
「Save」 をクリックします。
以上ですべての設定が完了です。
テスト実行
テストメールを送信してみます。
1. 存在するメールアドレスに送信してみる
「DynamoDB」 - 「項目」 画面でメール送信用 DynamoDB テーブルを選択し、「項目を作成」 をクリックします。
画面の各属性・値を入力して 「項目を作成」 をクリックすると、メールが送信されます。
メール送信履歴用 DynamoDB テーブルで送信内容を確認します。
4 〜 5 分ほど待って、Bounce Event 用 DynamoDB テーブルにレコードが登録されないことを確認します。
2. 存在しないメールアドレスを追加して送信してみる
今度は、to
に 2 つ目のメールアドレス(存在しないアカウント)を追加して送信してみます。
メール送信履歴用 DynamoDB テーブルで送信内容を確認します。
3 〜 4 分ほど待って、SendGrid の画面(「Activity」 - 「Activity Feed」)でメールの送信処理状況を確認します。
その後、Bounce Event 用 DynamoDB テーブルにレコードが登録されたことを確認します。
Discussion