Sarath 向您介绍
如何将 SES 的 SNS 通知存储
在 DynamoDB 中

lambda-sns-ses-dynamodb-sarath

我使用 Amazon Simple Notification Service (Amazon SNS) 接收有关通过 Amazon Simple Email Service (Amazon SES) 发送的电子邮件的退回邮件、投诉和传送的通知。我希望使用 AWS Lambda 将这些通知存储在 Amazon DynamoDB 数据库中。如何实现这一点?

配置通过 Amazon SNS 接收 Amazon SES 通知后,您可以使用 AWS Lambda 函数将这些通知写入 DynamoDB 数据库。然后,您可以将这些通知从 DynamoDB 数据库下载到 CSV 文件中。

注意:在此示例中创建的 Lambda 函数可用作将数据写入 CRM 或其他目标(基于您的邮件列表的托管位置)的模板。

完成以下各组步骤,以使用 Lambda 函数将 SES 的 SNS 通知内容存储到 DynamoDB 数据库中:

  1. 创建 DynamoDB 表。
  2. 为 Lambda IAM 角色添加权限以写入 DynamoDB 表。
  3. 创建一个 Lambda 函数以处理 SES 退回邮件通知。
  4. 为一个或多个主题订阅 Lambda 函数。
  5. 更新函数权限以允许 SNS 调用该函数。
  6. 通过发送 SES 邮件来调用 Lambda 函数以测试设置。
  7. 从 DynamoDB 下载报告来查看 SES 通知。

先决条件

  • 允许对 DynamoDB 数据库的读写访问权限。
  • 设置一个 SES 账户(电子邮件或域),保证该账户已经过验证并将一个 SNS 主题配置为接收 SES 通知。有关使用 SNS 接收 SES 通知的更多信息,请参阅通过 Amazon SNS 接收 Amazon SES 通知

1.创建 DynamoDB 表

在 DynamoDB 中创建一个名为 SESNotifications 的表,将其主分区键命名为 SESMessageId,主排序键命名为 SnsPublishTime

要查询表并生成 SES 报告,请按照下表中的说明设置通知类型和投诉类型二级索引。可以根据需要添加其他索引。

索引名称 分区键 排序键
SESMessageType-Index SESMessageType (String) SnsPublishTime (String)
SESMessageComplaintType-Index SESComplaintFeedbackType (String) SnsPublishTime (String)

有关在 DynamoDB 中创建表的信息,请参阅 Amazon DynamoDB 入门

2.为 Lambda IAM 角色添加权限以写入 DynamoDB 表

创建新的 AWS Identity and Access Management (IAM) 角色以供 Lambda 函数使用。该角色必须允许 Lambda 函数调用 DynamoDB:PutItem API。

注意:最佳实践是为不同的 Lambda 函数创建和使用新的 IAM 角色。避免在多个函数中重用角色。

  1. IAM 控制台的导航窗格中,选择角色,然后选择创建角色
  2. 选择 AWS 服务可信任的实体类型,选择 Lambda,再选择 Next: Permissions (下一步:权限)。
  3. 选择 AWSLambdaBasicExecutionRole 托管策略,再选择下一步
  4. lambda_ses_execution 角色指定一个名称,然后完成角色的创建。
  5. 返回“IAM 角色”视图,然后选择您创建的角色。
  6. 选择 Add an Inline Policy (添加内联策略)。
  7. 在可视化编辑器中,选择“Service DynamoDB”(服务 DynamoDB),并在“写入”类别下选择 PutItem 操作。在资源下,选择 Add ARN (添加 ARN),并提供先前创建的 DynamoDB 表 ARN。
  8. 选择审核,指定策略名称,然后选择创建策略

在以下示例中,添加到 lambda_ses_execution 角色的内联策略语句授予对步骤 1 中创建的 DynamoDB 数据库 us-east-1:12345678912:table/SESNotifications 的访问权限:

------------------------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-----------------------------

3.创建一个 Lambda 函数以处理 SES 退回邮件通知

使用 Lambda 控制台创建名为 sesnotificationscode 的 Lambda 函数。

创建函数时,选择先前创建的 lambda_ses_execution 角色。

使用以下示例代码设置新函数。此示例代码检查三种类型的 SNS 通知(如Amazon SES 的 Amazon SNS 通知示例中所述),并将 SES 通知置于 DynamoDB 表内的某个条目中。

注意:使用您的表的名称替换以下示例代码中的 TableName 参数 SESNotifications 的值。

--------------------------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)
{
  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) { context.fail(err)}
  else {
           console.log(data);
           context.succeed();
      }
  });
}
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) { context.fail(err)}
  else {
          console.log(data);
          context.succeed();
      }
  });
}
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) { context.fail(err)}
  else {
          console.log(data);
          context.succeed();
>      }
  });
}
};
------------------------Lambda Code Ends----------------------------

4.为一个或多个主题订阅 Lambda 函数

假设您已创建至少一个 SNS 主题并将某个 SES 电子邮件域配置为使用该 SNS 主题接收反馈通知,请按照以下步骤操作:

  1. SNS 控制台导航窗格中,选择主题。确定要在 SES 中用于退回邮件的 SNS 主题,例如名为 ses_notifications_repo 的 SNS 主题。
  2. 选择 SNS 主题的 ARN 以打开“Topic Details”页面。
  3. 选择 Create Subscription
  4. 对于 Protocol,请选择 AWS Lambda
  5. 对于终端节点,请键入 Lambda 函数的 ARN,然后选择创建订阅。这会使用 Lambda 作为协议并使用 Lambda 函数 ARN 作为终端节点来创建订阅。

5.更新函数权限以允许 SNS 调用该函数

如果您在先前的步骤中未使用 SNS 控制台为主题创建 Lambda 描述,可以使用 Lambda 控制台手动创建触发器。

  1. 在函数的 Lambda 控制台中,添加来自 Designer 上的触发器列表的 SNS 触发器。此时 Designer 下方会显示一个配置面板。
  2. 从配置面板的下拉列表中选择主题。

重复此过程,以添加要订阅此 Lambda 函数的不同通知主题。

6.通过发送 SES 邮件来调用 Lambda 函数以测试设置

现在 Lambda 函数已订阅 SNS 主题,下一步是在 Lambda 控制台中发布 SES 邮件并观察 Lambda 函数的调用。您可以使用 SES 控制台来发送测试邮件。

要发送测试邮件,您可以使用某个可用的邮箱模拟器地址,避免对 SES 送达率指标产生负面影响。有关更多信息,请参阅在 Amazon SES 中测试电子邮件发送

发送 SES 邮件后,SES 会向 SNS 主题发布通知。SNS 会将此通知作为 SNS 事件对象中的 JSON 转义 SES 事件通知对象,传送给 Lambda。

要使用 Lambda 控制台创建示例事件以用于本地测试,请参阅 Amazon SES 通过电子邮件接收示例事件

关于 SES 退回邮件、投诉和传送通知示例,请参阅 Amazon SES 的 Amazon SNS 通知示例

7.从 DynamoDB 下载报告来查看 SES 通知

您可以使用 DynamoDB 控制台,对表的内容进行查询、排序以及下载为 CSV 文件。

  1. DynamoDB 控制台中,选择 SESNotifications 表。
  2. 转到项目选项卡。
  3. 创建一个查询扫描搜索。

有关更多信息,请参阅什么是 Amazon DynamoDB?您还可以使用 AWS Data Pipeline 来安排定期将文件下载到 Amazon Simple Storage Service (Amazon S3) 存储桶,以实现合规性和记录保留。有关更多信息,请参阅将 DynamoDB 表导出到 S3第 2 部分:从 DynamoDB 导出数据


此页面对您有帮助吗? |

返回 AWS Support 知识中心

需要帮助?请访问 AWS 支持中心

发布时间:2018 年 6 月 13 日

更新时间:2018 年 7 月 9 日