event-publishing

AWS SES 이벤트 게시

메일을 보내기만 하고 반응을 놓치고 있었나요? '잘 보냈는데 왜 열람률이 낮지?' 같은 고민이 들 때, SES 이벤트 게시(Event publishing)가 답이 돼요. Amazon SES는 보낸 메일의 결과(이벤트)를 Amazon SNS, Amazon Kinesis Data Firehose 같은 AWS 서비스로 자동으로 게시해 줘요. 이걸 활용하면 전송·전달·반송·열람·클릭까지 메일 하나하나의 생애를 입자 단위로 추적할 수 있죠. 이 글에서는 이벤트 게시가 어떻게 동작하는지, 그리고 어떻게 설정하는지 차근차근 살펴볼게요.

출처: 문서

본문

이벤트 게시를 이용하면 정의한 특성에 따라 메일 전송 이벤트를 CloudWatch, Data Firehose, Pinpoint, SNS, EventBridge로 게시할 수 있어요. 추적할 수 있는 이벤트는 전송(sends), 전달(deliveries), 열람(opens), 클릭(clicks), 반송(bounces), 불만 신고(complaints), 거부(rejections), 렌더링 실패(rendering failures), 전달 지연(delivery delays) 등 다양해요. 예를 들어 CloudWatch로 게시해서 캠페인 성과 대시보드를 만들 수도 있고, 특정 이벤트가 발생하면 SNS로 알림을 받을 수도 있어요.

Configuration set과 message tag로 동작하는 방식

이벤트 게시를 쓰려면 먼저 하나 이상의 configuration set을 설정해요. configuration set은 '어디로 이벤트를 게시할지, 어떤 이벤트를 게시할지'를 정의하는 규칙 모음이에요. 그 다음 메일을 보낼 때마다 configuration set 이름과 함께 메일을 분류하는 message tag(이름/값 쌍)를 지정해요. 예를 들어 책 광고를 보낸다면 genre라는 태그에 sci-fiwestern 값을 붙일 수 있어요.

메일 전송 인터페이스에 따라 message tag를 EmailTags 필드로 넘기거나, SES 전용 헤더 X-SES-MESSAGE-TAGS에 담아서 보내요.

내가 지정한 태그 외에도 SES는 메일에 auto-tag를 자동으로 붙여요. 추가 단계가 필요 없죠. 자동으로 붙는 태그는 이렇게 돼요.

Auto-tag 이름 설명
ses:caller-identity 메일을 보낸 SES 사용자의 IAM 자격
ses:configuration-set 메일과 연결된 configuration set 이름
ses:from-domain From 주소의 도메인
ses:outgoing-ip SES가 메일을 보낼 때 사용한 IP 주소
ses:source-ip 호출자가 메일을 보낼 때 사용한 IP 주소
ses:source-tls-version 호출자가 사용한 TLS 프로토콜 버전
ses:outgoing-tls-version SES가 사용한 TLS 프로토콜 버전

캠페인 단위의 세밀한 피드백

ses:feedback-id-<aorb> 태그는 선택 message tag로, 자동 태그와 비슷하지만 ses: 접두사 키를 붙여 직접 추가해야 해요. 최대 두 개(ses:feedback-id-a, ses:feedback-id-b)까지 쓸 수 있어요. 이 태그를 지정하면 SES가 표준 Feedback-ID 헤더에 자동으로 추가해서, 피드백 루프(FBL)로 불만·스팸 비율 같은 전달 통계를 생성하는 데 활용해요.

Feedback-ID 헤더는 SES가 불만 정보 수집에 쓰는 식별자 (SESInternalID)와 전송 플랫폼을 나타내는 정적 태그 (AmazonSES)로 구성돼요.

ses:feedback-id-<aorb>SendEmail 요청의 EmailTags 필드에 message tag로 지정해서 쓸 수 있어요. 예시는 이렇게 돼요.

{
  "FromEmailAddress": "[email protected]",
  "Destination": {
    "ToAddresses": [ "[email protected]" ]
  },
  "Content": {
    "Simple": {
      "Subject": { "Data": "Hello and welcome" },
      "Body": {
        "Text": { "Data": "Lorem ipsum dolor sit amet." },
        "Html": { "Data": "Lorem ipsum dolor sit amet." }
      }
    }
  },
  "EmailTags": [
    { "Name": "ses:feedback-id-a", "Value": "new-members-campaign" },
    { "Name": "ses:feedback-id-b", "Value": "football-campaign" }
  ],
  "ConfigurationSetName": "football-club"
}

raw 형식으로 보낼 때는 ses:feedback-id-<aorb>를 SES 전용 헤더 X-SES-MESSAGE-TAGS에 담아요.

이벤트 게시 용어 정리

이벤트 게시에서 자주 쓰는 용어를 미리 정리할게요.

  • Email sending event – SES에 제출한 메일의 결과에 대한 정보. 이벤트 종류는 다음과 같아요.
    • Send – 전송 요청이 성공해 SES가 수신자 메일 서버로 전달을 시도할 예정인 상태. (계정 수준이나 전역 억제가 적용 중이어도 Send로 집계되지만 전달은 억제돼요.)
    • RenderingFailure – 템플릿 렌더링 문제로 메일이 전송되지 않은 경우. 템플릿 데이터 누락이나 파라미터 불일치가 원인. SendTemplatedEmail이나 SendBulkTemplatedEmail API로 보낼 때만 발생해요.
    • Reject – SES가 메일은 수락했지만 바이러스를 포함해 수신자 메일 서버로 전달하지 않기로 한 상태.
    • Delivery – SES가 수신자 메일 서버로 메일 전달에 성공한 상태.
    • Bounce – 하드 반송(hard bounce)으로 수신자 메일 서버가 메일을 영구 거부한 상태. (소프트 반송은 SES가 더 이상 재전송을 시도하지 않을 때만 포함돼요. 대체로 전달 실패를 뜻하지만, 부재 중 자동 회신처럼 수신자가 받았는데도 소프트 반송이 뜨는 경우도 있어요.)
    • Complaint – 메일은 성공적으로 전달됐지만 수신자가 스팸으로 표시한 상태.
    • DeliveryDelay – 일시적 문제로 수신자 메일 서버에 전달하지 못한 상태. 수신자 메일함이 가득 찬 경우나 수신 서버의 일시적 장애 같은 경우 발생해요.
    • Subscription – 메일은 성공적으로 전달됐지만 수신자가 헤더의 List-Unsubscribe 또는 바닥글의 Unsubscribe 링크를 눌러 구독 설정을 변경한 상태.
    • Open – 수신자가 메일을 받아 이메일 클라이언트에서 열어본 상태.
    • Click – 수신자가 메일 안의 링크를 하나 이상 클릭한 상태.
  • Configuration set – SES가 이벤트를 게시할 대상과 게시할 이벤트 종류를 정의하는 규칙 모음. 이벤트 게시를 쓸 메일에는 이 configuration set을 지정해요.
  • Event destination – SES 이벤트를 게시하는 AWS 서비스. 설정한 event destination은 하나의 configuration set에만 속해요.
  • Message tag – 이벤트 게시 목적으로 메일을 분류하는 이름/값 쌍. API 호출 파라미터나 SES 전용 헤더로 지정해요.
  • Auto-tag – 이벤트 게시 보고서에 자동으로 포함되는 메시지 태그. configuration set 이름, From 주소 도메인, 호출자 IP, SES 발신 IP, 호출자 IAM 자격에 대한 태그가 있어요.

Event destination 설정

event destination은 SES 이벤트를 게시할 목적지예요. 설정한 event destination은 하나의 configuration set에만 속해요. 목적지로 다음 AWS 서비스 중 하나를 고를 수 있어요.

  • Amazon CloudWatch
  • Amazon Data Firehose
  • Amazon EventBridge
  • Amazon Pinpoint
  • Amazon Simple Notification Service (Amazon SNS)

어느 서비스를 고를지는 원하는 상세 수준과 수신 방식에 따라 달라져요.

  • 각 이벤트 유형의 누적 합계만 있으면 충분할 때(예: 합계가 너무 높아지면 알람을 울리도록) CloudWatch를 써요.
  • OpenSearch Service나 Redshift 같은 다른 서비스로 보내 분석할 상세 이벤트 레코드가 필요하면 Firehose를 써요.
  • 특정 이벤트가 발생하면 알림을 받고 싶을 때는 SNS를 써요.

설정 순서

이벤트 게시를 설정하는 큰 흐름은 세 단계예요.

  1. SES 콘솔이나 API로 configuration set을 만든다.
  2. configuration set에 event destination(CloudWatch, Firehose, Pinpoint, SNS)을 하나 이상 추가하고, 목적지별 파라미터를 설정한다.
  3. 메일을 보낼 때, 이벤트 destination을 담고 있는 configuration set을 지정한다.

SNS로 설정할 때는 콘솔에서 Destination type으로 Amazon SNS를 고른 뒤 SNS topic을 선택하거나 새로 만들면 돼요. topic 유형은 Standard만 선택해요 — SES는 FIFO 유형 topic을 지원하지 않아요. 생성 후에는 SES가 topic에 알림을 게시할 권한을 줘야 하는데, SNS 콘솔에서 topic의 Access policy JSON에 아래처럼 ses.amazonaws.com 서비스 주체에게 sns:Publish를 허용하는 정책을 추가해요.

{
  "Version":"2012-10-17",
  "Id": "notification-policy",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": { "Service": "ses.amazonaws.com" },
      "Action": "sns:Publish",
      "Resource": "arn:aws:sns:{{us-east-1}}:{{111122223333}}:{{topic_name}}",
      "Condition": {
        "StringEquals": {
          "AWS:SourceAccount": "{{111122223333}}",
          "AWS:SourceArn": "arn:aws:ses:{{topic_region}}:{{111122223333}}:configuration-set/{{configuration-set-name}}"
        }
      }
    }
  ]
}

위 정책 예시에서 {{topic_region}}(topic을 만든 리전), {{111122223333}}(AWS 계정 ID), {{topic_name}}(topic 이름), {{configuration-set-name}}(SNS event destination과 연결된 configuration set 이름)을 실제 값으로 바꾸면 돼요.

더 알아보기 (Learn more)