如何使用 Lambda 將 Amazon SES 電子郵件的 Amazon SNS 通知存放在 DynamoDB 中?

4 分的閱讀內容
0

我使用 Amazon Simple Notification Service (Amazon SNS) 接收有關透過 Amazon Simple Email Service (Amazon SES) 傳送的電子郵件通知。我想設定 AWS Lambda 函數,將這些通知存放在 Amazon DynamoDB 資料表中。

解決方法

**注意:**下列步驟的程式碼範例僅適用於 Node.js 16.x 版及更早版本的 Lambda 執行期。

(先決條件) 使用 Amazon SNS 主題設定 Amazon SES 電子郵件或網域,該主題已設定為接收 Amazon SES 的通知

如需詳細資訊,請參閱使用 Amazon SNS 接收 Amazon SES 通知

建立 DynamoDB 資料表

1.    在 DynamoDB 建立 有下列屬性的表格:
針對 表格名稱,輸入 SESNotifications
針對主要分區索引鍵,輸入 SESMessageId
針對主要排序索引鍵,輸入 SnsPublishTime

2.要允許 Lambda 查詢資料表並建立 Amazon SES 報告,設定下列次要索引

索引名稱分區索引鍵排序索引鍵
SESMessageType-IndexSESMessageType (字串)SnsPublishTime (字串)
SESMessageComplaintType-IndexSESComplaintFeedbackType (字串)SnsPublishTime (字串)

**注意:**您可以視需要新增更多次要索引。

如需在 DynamoDB 建立資料表的資訊,請參閱建立 DynamoDB 資料表

將權限新增至您的 Lambda 函數的 IAM 角色,以允許呼叫 DynamoDB 資料表

建立新的 AWS Identity and Access Management (IAM) 角色。設定角色以允許您的 Lambda 函數呼叫 DynamoDB:PutItem API

**注意:**針對不同的 Lambda 函數,最佳實務是建立和使用新的 IAM 角色。避免跨多個函數重複使用角色。

1.    在 IAM 主控台的導覽窗格,選擇角色

2.    選擇 建立角色

3.    針對選取受信任實體的類型,選擇 AWS 服務

4.    針對選擇使用案例,選擇 Lambda。然後,選擇下一步: 權限

5.    針對連接權限政策,選擇 AWSLambdaBasicExecutionRole 受管政策旁的核取方塊。然後,選擇下一步: 標籤

6.    (選用) 將 IAM 標籤新增至您使用案例的角色。如需詳細資訊,請參閱標記 IAM 資源

7.    選擇下一步: 檢閱

8.    針對角色名稱*,輸入 lambda_ses_execution

9.    選擇 建立角色

10.    返回 IAM 角色視圖,然後選擇您建立的角色。

11.    在權限索引標籤,選擇新增內嵌政策

12.    在視覺化編輯器索引標籤,選擇選擇服務

13.    選擇 DynamoDB

14.    在動作搜尋欄位,輸入 PutItem。在出現的下拉式清單,選擇 PutItem旁的核取方塊。

15.    針對 資源,選擇 特定

16.    選擇新增 ARN。然後,在出現的文字方塊中,輸入您的 DynamoDB 資料表的 Amazon Resource Name (ARN)

17.    選擇檢閱政策

18.    在名稱中,輸入政策的名稱。

19.    選擇建立政策

授予 DynamoDB 資料表存取權限的內嵌 IAM 政策範例

{
    "Version": "2012-10-17",
    "Statement": \[
         {
            "Sid": "Stmt1428510662000",
            "Effect": "Allow",
            "Action": \[
                "DynamoDB:PutItem"
            \],
            "Resource": \[
                "arn:aws:DynamoDB:us-east-1:12345678912:table/SESNotifications"
            \]
        }
    \]
}

建立 Lambda 函數以處理 Amazon SES 和 Amazon SNS 通知

使用下列範例函數程式碼,建立 名為** sesnotificationscode的 Lambda 函數**。您可以使用下列範例 Lambda 函數作為將資料寫入客戶關係管理 (CRM) 系統或其他目的地的範本。

**重要事項:**確定您將 lambda_ses_execution 角色指定給函數。

範例 Lambda 函數程式碼,會檢查 Amazon SNS 通知並將相關的 Amazon SES 通知放在 DynamoDB 資料表中

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,'')
      }
    });
  }
};

**注意:**使用 DynamoDB 資料表的名稱,取代 TableName 參數 SESNotifications

訂閱您的 Lambda 函數以取得一或多個 Amazon SNS 主題

使用 Amazon SNS 主控台

您必須手動將權限新增至函數資源政策,才能允許 SNS 叫用函數。要新增這些權限,執行下列 AWS CLI 命令:

**注意:**如果您執行 AWS CLI 命令時收到錯誤訊息,確認您使用的是最新版本的 AWS CLI

aws lambda add-permission --function-name my-function --action lambda:InvokeFunction --statement-id sns-my-topic \\  
\--principal sns.amazonaws.com --source-arn arn:aws:sns:us-east-1:123456789012:my-topic

**注意:使用函數、主題和完整 ARN的ID, 取代 my-functionsns-my-topic和 **arn:aws:sns:us-east-1:123456789012:my-topic。

新增必要權限後,完成下列步驟,為 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 主控台

1.    在 Lambda 主控台,開啟函數頁面

2.    選擇您建立的 Lambda 函數。

3.    在 函數概觀窗格,選擇 + 新增觸發器

  1. 觸發器組態 下拉式清單,選擇 SNS。然後出現組態面板。

5.    在 ** SNS 主題**下拉式清單,選擇您要訂閱該函數的 SNS 主題。

6.    選擇 新增

7.    (選用) 針對您要訂閱函數的每個額外通知主題,重複步驟 1–6。

測試設定: 傳送 Amazon SES 訊息以叫用您的 Lambda 函數

要傳送測試 Amazon SES 訊息,使用其中一個可用的郵箱模擬器地址

**注意:**您傳送測試訊息時,使用其中一個郵箱模擬器地址,避免對您的 SES 交付指標產生負面影響。

當您傳送測試訊息時,Amazon SES 會向 SNS 主題發佈通知。然後,Amazon SNS 將通知視為 SES 事件物件中 JSON 逸出的 SES 事件通知物件,傳遞到 Lambda。

要使用 Lambda 主控台以建立本機測試的範例事件,請參閱 Amazon SES 發佈到 Amazon SNS 的事件資料範例

**重要事項:**您無法使用這些事件資料範例,因為事件資料已寫入以在 Lambda 主控台傳送測試訊息。要在 Lambda 主控台使用範例進行測試,您必須將 eventType 訊息索引鍵變更為 notificationType。如果您不變更訊息索引鍵,則測試會失敗。

從 DynamoDB 下載報告以檢視 Amazon SES 通知

要以 .csv 檔案格式,查詢、排序及下載 DynamoDB 資料表的內容,完成下列步驟:

1.    開啟 DynamoDB 主控台,然後選擇 SESNotifications 資料表。

2.    選擇項目索引標籤。

3.    建立查詢掃描搜尋。如需詳細資訊,請參閱查詢和掃描資料的最佳實務

**注意:**您可以使用 DynamoDB 資料表匯出,預定時間,定期下載檔案到 Amazon Simple Storage Service (Amazon S3) 儲存貯體。如需詳細資訊,請參閱將 DynamoDB 資料匯出至 Amazon S3:運作方式

相關資訊

扇出到 Lambda 函數

透過 Amazon SNS 呼叫 AWS Lambda 函數

使用 Amazon SNS 接收 Amazon SES 通知

AWS 官方
AWS 官方已更新 1 年前