Lambda を使用して、Amazon SES E メールの Amazon SNS 通知を DynamoDB に保存するにはどうすればよいですか?
最終更新日: 2022 年 11 月 10 日
Amazon Simple Email Service (Amazon SES) で送信されてくる E メールに関する通知を受け取るために、Amazon Simple Notification Service (Amazon SNS) を使っています。このような通知を Amazon DynamoDB テーブルに保存するように AWS Lambda 関数をセットアップするにはどうすればよいですか?
解決方法
注: 次の Lambda 関数の例は、顧客関係管理 (CRM) システムやその他の送信先にデータを書き込むためのテンプレートとして使用できます。
(前提条件) Amazon SES からの通知を受信するように Amazon SNS トピックが設定された Amazon SES E メールまたはドメインをセットアップする
詳細については、「Amazon SNS を使用して Amazon SES 通知を受信する」を参照してください。
DynamoDB テーブルを作成する
1. DynamoDB で、次の属性を持つテーブルを作成します。
[テーブル名] には、「SESNotifications」と入力します。
[プライマリパーティションキー] には、「SESMessageId」と入力します。
プライマリ [ソートキー] には、「SnsPublishTime」と入力します。
2. Lambda がテーブルをクエリして Amazon SES レポートを作成できるようにするには、次のセカンダリインデックスを設定します。
インデックス名 | パーティションキー | ソートキー |
---|---|---|
SESMessageType-Index | SESMessageType (文字列) | SnsPublishTime (文字列) |
SESMessageComplaintType-Index | SESComplaintFeedbackType (文字列) | SnsPublishTime (文字列) |
注: 必要に応じて、セカンダリインデックスを追加できます。
Amazon DynamoDB におけるテーブル作成の詳細に関しては、「DynamoDB の使用開始」を参照してください。
DynamoDB テーブルの呼び出しを許可する Lambda 関数の IAM ロールにアクセス許可を追加します。
新しい AWS Identity and Access Management (IAM) ロールを作成します。次の手順を実行して、Lambda 関数が DynamoDB:PutItem API を呼び出しできるようにロールを設定します。
注: 異なる Lambda 関数には、新しい IAM ロールを作成して使用するのがベストプラクティスです。複数の関数にわたって、ロールを使いまわすのは避けるようにします。
1. IAM コンソールの左ナビゲーションペインで、[Roles] (ロール) を選択します。
2. [ロールの作成] を選択します。
3. [Select type of trusted entity] (信頼されたエンティティのタイプの選択) で、[AWS サービス] を選択します。
4. [ユースケースを選択] で、[Lambda] を選択します。[次の手順: アクセス許可] を選択します。
5. [アクセス許可ポリシーのアタッチ] で、[AWSLambdaBasicExecutionRole] 管理ポリシーの横にあるチェックボックスをオンにします。[次へ: タグ] を選択します。
6. (オプション) ユースケースのロールに IAM タグを追加します。詳細については、「IAM リソースのタグ付け」を参照してください。
7. [Next: Review] を選択します。
8. [ロール名*] に「lambda_ses_execution.」と入力します。
9. [ロールの作成] を選択します
10. IAM ロールの画面に戻って、ユーザーが作成したロールを選択します。
11. [アクセス許可] タブで、[インラインポリシーの追加] を選択します。
12. [ビジュアルエディタ] タブで、[サービスの選択] をクリックし、
13. [DynamoDB] を選択します。
14. [アクション] 検索フィールドに「PutItem」と入力します。表示されるドロップダウンリストで、[PutItem] の横にあるチェックボックスを選択します。
15. [リソース] で [特定] を選択します。
16. [ARN の追加] を選択します。次に、表示されるテキストボックスに、DynamoDB テーブルの Amazon リソースネーム (ARN) を入力します。
17. [ポリシーの確認] をクリックします。
18. [名前] で、ポリシーの名前を入力します。
19. [ポリシーの作成] を選択します。
DynamoDB テーブルへのアクセスを許可するインライン IAM ポリシーの例
------------------------IAM Policy Begins---------------------------
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1428510662000",
"Effect": "Allow",
"Action": [
"DynamoDB:PutItem"
],
"Resource": [
"arn:aws:DynamoDB:us-east-1:12345678912:table/SESNotifications"
]
}
]
}
------------------------IAM Policy Ends-----------------------------
Amazon SES および Amazon SNS 通知を処理する Lambda 関数を作成する
次のサンプル関数コードを使用して、sesnotificationscode という名前の Lambda 関数を作成します。
重要: 作成した関数 lambda_ses_execution ロールを関数に割り当ててください。
Amazon SNS 通知をチェックし、関連する Amazon SES 通知を DynamoDB テーブルに配置する Lambda 関数コードの例
重要: TableName パラメータ SESNotifications を DynamoDB テーブルの名前に置き換えます。
--------------------------Lambda Code Begins------------------------
console.log("Loading event");
var aws = require("aws-sdk");
var ddb = new aws.DynamoDB({ params: { TableName: "SESNotifications" } });
exports.handler = function (event, context, callback) {
console.log("Received event:", JSON.stringify(event, null, 2));
var SnsPublishTime = event.Records[0].Sns.Timestamp;
var SnsTopicArn = event.Records[0].Sns.TopicArn;
var SESMessage = event.Records[0].Sns.Message;
SESMessage = JSON.parse(SESMessage);
var SESMessageType = SESMessage.notificationType;
var SESMessageId = SESMessage.mail.messageId;
var SESDestinationAddress = SESMessage.mail.destination.toString();
var LambdaReceiveTime = new Date().toString();
if (SESMessageType == "Bounce") {
var SESreportingMTA = SESMessage.bounce.reportingMTA;
var SESbounceSummary = JSON.stringify(SESMessage.bounce.bouncedRecipients);
var itemParams = {
Item: {
SESMessageId: { S: SESMessageId },
SnsPublishTime: { S: SnsPublishTime },
SESreportingMTA: { S: SESreportingMTA },
SESDestinationAddress: { S: SESDestinationAddress },
SESbounceSummary: { S: SESbounceSummary },
SESMessageType: { S: SESMessageType },
},
};
ddb.putItem(itemParams, function (err, data) {
if (err) {
callback(err)
} else {
console.log(data);
callback(null,'')
}
});
} else if (SESMessageType == "Delivery") {
var SESsmtpResponse1 = SESMessage.delivery.smtpResponse;
var SESreportingMTA1 = SESMessage.delivery.reportingMTA;
var itemParamsdel = {
Item: {
SESMessageId: { S: SESMessageId },
SnsPublishTime: { S: SnsPublishTime },
SESsmtpResponse: { S: SESsmtpResponse1 },
SESreportingMTA: { S: SESreportingMTA1 },
SESDestinationAddress: { S: SESDestinationAddress },
SESMessageType: { S: SESMessageType },
},
};
ddb.putItem(itemParamsdel, function (err, data) {
if (err) {
callback(err)
} else {
console.log(data);
callback(null,'')
}
});
} else if (SESMessageType == "Complaint") {
var SESComplaintFeedbackType = SESMessage.complaint.complaintFeedbackType;
var SESFeedbackId = SESMessage.complaint.feedbackId;
var itemParamscomp = {
Item: {
SESMessageId: { S: SESMessageId },
SnsPublishTime: { S: SnsPublishTime },
SESComplaintFeedbackType: { S: SESComplaintFeedbackType },
SESFeedbackId: { S: SESFeedbackId },
SESDestinationAddress: { S: SESDestinationAddress },
SESMessageType: { S: SESMessageType },
},
};
ddb.putItem(itemParamscomp, function (err, data) {
if (err) {
callback(err)
} else {
console.log(data);
callback(null,'')
}
});
}
};
------------------------Lambda Code Ends----------------------------
Lambda 関数を 1 つ、または複数の Amazon SNS トピックにサブスクライブします。
Amazon SNS コンソールを使用して Amazon SNS トピックに関数をサブスクライブするには
SNS が関数を呼び出せるようにするには、機能リソースポリシーにアクセス権限を手動で追加する必要があります。これらのアクセス権限は、次の AWS CLI コマンドで追加できます。
aws lambda add-permission --function-name my-function --action lambda:InvokeFunction --statement-id sns-my-topic \<br>--principal sns.amazonaws.com --source-arn arn:aws:sns:us-east-1:123456789012:my-topic
注意:my-function、sns-my-topic、および arn:aws:sns:us-east-1:123456789012:my-topic の値を、必ず関数の ID、トピック、および完全な ARN に置き換えてください。
必要な権限を追加したら、以下の手順に従って関数を SNS トピックにサブスクライブします。
1. Amazon SNS コンソールの左のナビゲーションペインで、[トピック] を選択します。
2. バウンス通知のために Amazon SES で使用される SNS トピックを特定します。例: ses_notifications_repo という名前の SNS トピック。
3. SNS トピックの ARN を選択します。[トピックの詳細] ページが開きます。
4. [サブスクリプションの作成] を選択します。
5. [プロトコル] で、[AWS Lambda] を選択します。
6. [エンドポイント] に、Lambda 関数の ARN を入力します。
7. [サブスクリプションの作成] を選択します。
8. (オプション) 関数にサブスクライブする追加の通知トピックごとに、手順 1 ~ 7 を繰り返します。
Lambda コンソールを使用して Amazon SNS トピックに関数をサブスクライブするには
1. Lambda コンソールで関数ページを開きます 。
2. 前に作成した Lambda 関数を選択します。
3. [関数の概要] ペインで、[+トリガーの追加] ボタンを選択します。
4. [トリガーの設定] ドロップダウンリストで、[SNS] を選択します。設定パネルが表示されます。
5. [SNS トピック] ドロップダウンリストで、関数をサブスクライブする SNS トピックを選択します。
6. [Add] を選択します。
7. (オプション) 関数にサブスクライブする追加の通知トピックごとに、手順 1 ~ 6 を繰り返します。
Lambda 関数に Amazon SES メッセージを送信して起動することで設定をテストする
テスト用に Amazon SES メッセージを送信するには、メールボックスシミュレーターで利用可能なアドレスのいずれかを使用します。
注: テストメッセージの送信時にメールボックスシミュレーターのアドレスの 1 つを使用して、SES の配信性能メトリクスに対する悪影響を防ぐことができます。
テストメッセージを送信すると、Amazon SES は SNS トピックに通知を発行します。次に、Amazon SNS はこの通知を Lambda に対し、SNS イベントオブジェクトにおける JSON エスケープした SES イベント通知オブジェクトとして配信します。
Lambda コンソールを使用してローカルテスト用のサンプルイベントを作成するには、「Amazon SES が Amazon SNS に発行するサンプルイベントデータ」を参照してください。
重要: Amazon SES が Amazon SNS に発行するサンプルイベントデータは、Lambda コンソールでテストメッセージの送信用に作成されているため使用できません。サンプルを Lambda コンソールでテストに使用するには、eventType メッセージキーを notificationType に変更する必要があります。メッセージキーを変更しないと、テストは失敗します。
DynamoDB からレポートをダウンロードして、Amazon SES 通知を表示する
DynamoDB テーブルの内容をクエリ、ソート、および CSV ファイルとしてダウンロードするには、次の手順を実行します。
1. DynamoDB コンソールで、[SESNotifications] テーブルを選択します。
2. [項目] タブを選択します。
3. [クエリ] または [スキャン] 検索を作成します。詳細については、「データのクエリとスキャンに関するベストプラクティス」を参照してください。
注: DynamoDB テーブルのエクスポートを使用して、Amazon Simple Storage Service (Amazon S3) バケットへのファイルのダウンロードを定期的にスケジュールできます。詳細については、「DynamoDB data export to Amazon S3: how it works」(Amazon S3 への DynamoDB データのエクスポート: 仕組み) を参照してください。