Lambda를 사용하여 Amazon SES 이메일에 대한 Amazon SNS 알림을 DynamoDB에 저장하려면 어떻게 해야 합니까?

최종 업데이트 날짜: 2021년 11월 11일

Amazon Simple Notification Service(Amazon SNS)를 사용하여 Amazon Simple Email Service(Amazon SES)를 통해 전송되는 이메일에 대한 알림을 수신합니다. AWS Lambda 함수를 설정하여 이러한 알림을 Amazon DynamoDB 테이블에 저장하려면 어떻게 해야 하나요?

해결 방법

참고: 다음 예제 Lambda 함수는 고객 관계 관리(CRM) 시스템이나 다른 대상에 데이터를 쓰기 위한 템플릿으로 사용할 수 있습니다.

(사전 요구 사항) Amazon SES에서 알림을 수신하도록 구성된 Amazon SNS 주제로 Amazon SES 이메일 또는 도메인을 설정합니다

자세한 내용은 Amazon SNS를 사용하여 Amazon SES 알림 수신을 참조하세요.

DynamoDB 테이블 생성

1.    다음 속성을 가진 DynamoDB에 테이블을 생성합니다.
Table-nameSESNotifications를 입력합니다.
기본 파티션 키SESMessageId를 입력합니다.
기본 정렬 키SnsPublishTime을 입력합니다.

2.    Lambda가 테이블을 쿼리하고 Amazon SES 보고서를 생성하도록 허용하려면 다음 보조 인덱스를 설정합니다.

인덱스 이름 파티션 키 정렬 키
SESMessageType-Index SESMessageType(문자열) SnsPublishTime(문자열)
SESMessageComplaintType-Index SESComplaintFeedbackType(문자열) SnsPublishTime(문자열)

참고: 필요에 따라 보조 인덱스를 더 추가할 수 있습니다.

DynamoDB에 테이블을 생성하는 방법에 대한 자세한 내용은 Amazon DynamoDB 시작하기를 참조하세요.

Lambda 함수의 IAM 역할에 DynamoDB 테이블을 호출할 수 있는 권한 추가

새 AWS Identity and Access Management(IAM) 역할을 생성합니다. 다음을 수행하여 Lambda 함수가 DynamoDB:PutItem API를 호출할 수 있도록 역할을 구성합니다.

참고: 다양한 Lambda 함수에 대해 새로운 IAM 역할을 생성하여 사용하는 것이 모범 사례입니다. 여러 함수에서 역할을 재사용하지 마세요.

1.    IAM 콘솔의 왼쪽 탐색 창에서 역할을 선택합니다.

2.    [역할 생성(Create Role)]을 선택합니다.

3.    [Select type of trusted entity]에서 [AWS service]를 선택합니다.

4.    사용 사례 선택에서 Lambda를 선택합니다. 그런 다음 다음: 권한을 선택합니다.

5.    연결 권한 정책에 대해 AWSLambdaBasicExecutionRole 관리형 정책 옆에 있는 확인란을 선택합니다. 그런 다음, [다음: 태그(Next: Tags)]를 선택합니다.

6.    (선택 사항) 사용 사례에 대한 역할에 IAM 태그를 추가합니다. 자세한 내용은 IAM 리소스 태깅을 참조하십시오.

7.    [다음: 검토]를 선택합니다.

8.    역할 이름lambda_ses_execution을 입력합니다.

9.    [역할 생성(Create Role)]을 선택합니다.

10.    IAM 역할 보기로 돌아가서 생성한 역할을 선택합니다.

11.    [권한(Permissions)] 탭에서 [인라인 정책 추가(Add inline policy)]를 선택합니다.

12.    Visual editor 탭에서 [서비스 선택(Choose a service)]을 선택합니다.

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

하나 이상의 Amazon SNS 주제에 대해 Lambda 함수 구독

Amazon SNS 콘솔을 사용하여 Amazon 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.    [추가]를 선택합니다.

7.    (선택 사항) 함수에 구독하려는 각각의 추가 알림 주제에 대해 1~6단계를 반복합니다.

Lambda 함수를 호출하는 Amazon SES 메시지를 전송하여 설정 테스트

테스트 Amazon SES 메시지를 보내려면 사용 가능한 메일박스 시뮬레이터 주소 중 하나를 사용하십시오.

참고: 테스트 메시지를 보낼 때 메일박스 시뮬레이터 주소 중 하나를 사용하면 SES 전달률 지표에 부정적인 영향을 미치지 않습니다.

테스트 메시지를 보내면 Amazon SES에서 SNS 주제에 알림을 게시합니다. 그런 다음 Amazon SNS는 이 알림을 SNS 이벤트 객체에서 JSON 이스케이프 SES 이벤트 알림 객체로 Lambda에 전송합니다.

Lambda 콘솔을 사용하여 로컬 테스트를 위한 샘플 이벤트를 생성하려면 Amazon SES에서 Amazon SNS에 게시하는 이벤트 데이터 예제를 참조하십시오.

중요: Amazon SES에서 Amazon SNS에 게시하는 이벤트 데이터 예제는 Lambda 콘솔에서 테스트 메시지를 전송하기 위해 작성되었기 때문에 사용할 수 없습니다. Lambda 콘솔에서 테스트할 예제를 사용하려면 eventType 메시지 키를 notificationType으로 변경해야 합니다. 메시지 키를 변경하지 않으면 테스트에 실패합니다.

DynamoDB에서 보고서를 다운로드하여 Amazon SES 알림 보기

DynamoDB 테이블의 내용을 CSV 파일로 쿼리, 정렬, 다운로드하려면 다음을 수행합니다.

1.    DynamoDB 콘솔에서 SESNotifications 테이블을 선택합니다.

2.    [항목(Items)] 탭을 선택합니다.

3.    쿼리 또는 스캔 검색을 생성합니다. 자세한 내용은 데이터 쿼리 및 스캔의 모범 사례를 참조하세요.

참고: DynamoDB 테이블 내보내기를 사용하여 Amazon Simple Storage Service(Amazon S3) 버킷에 파일을 정기적으로 다운로드하도록 예약할 수 있습니다. 자세한 내용은 Amazon S3로 DynamoDB 테이블 데이터 내보내기를 참조하세요.