🐐

SendGrid で送信したメールの Bounce Event を取得するサンプル

2023/01/11に公開

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 リポジトリに実際のコードを置いてあります。

https://github.com/hmatsu47/sendgrid-test

SendGrid 側の設定 (1)

左側メニューから 「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

https://github.com/hmatsu47/sendgrid-test/blob/5c6c03beb108dcc675646f3a4a459cfe3f379acc/lambda/testMailSender/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

https://github.com/hmatsu47/sendgrid-test/blob/5c6c03beb108dcc675646f3a4a459cfe3f379acc/lambda/testBounceReceiver/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 テーブルにレコードが登録されたことを確認します。

GitHubで編集を提案

Discussion