[이메일 시스템 #2] AWS SES 기반 트랜잭션 이메일부터 통계 추적

osohyun0224·2025년 5월 30일

이메일 시스템

목록 보기
2/2
post-thumbnail

안녕하세요! 프론트엔드 개발자 Garden, 오소현입니다.

지난 [이메일 시스템 #1] 기본 이메일 시스템의 원리와 이해 글에서는 전체적으로 이메일 시스템을 이해하기 위해 전통적 이메일 인프라 구조에 대한 내용을 담았다면, 이번 글에서는 AWS SES를 기반으로 구축된 대량 이메일 발송 시스템에 대해 상세히 기록해보았습니다.

전체적으로 비용 효율성과 확장성을 모두 만족시켜야 했고, SES와 GraphQL, MongoDB, Workflow 기반의 자체 이메일 시스템이 구현되었습니다. 해당 시스템은 단순 발송을 넘어서 템플릿 생성, 대상자 필터링, 배치 발송, 이벤트 추적, 이력 저장 및 재시도 로직까지 모두 포함된 통합 이메일 인프라로 나아가고 있어요 !!


✉️ 왜 이메일 시스템을 직접 구축했을까요?

저희는 마케팅, 프로덕트 팀 등 다양한 부서에서 다음과 같은 이메일 발송 요구사항을 받았습니다.

  • 신규 회원가입, 비밀번호 초기화, 인증메일 등 트랜잭션 이메일
  • 유튜버/광고주 대상의 정기 리포트
  • 유저 타입, 언어 설정, 인증 상태 등에 따라 정교하게 타겟팅된 발송

MailChimp, SendGrid, Stibee와 같은 SaaS 서비스도 검토했지만,

커스터마이징이 어렵고,트래픽이 많아질수록 단가가 급증하며,내부 시스템(워크플로우, GraphQL, MongoDB)과의 연동이 복잡해지는 문제가 발생하고 있었기 때문에 결국 직접 구축을 선택했습니다.


⚙️ 시스템 구성요소

대량 발송, 커스터마이징, 비용 절감, 그리고 추적 가능성 확보를 목표로 현재 아래와 같은 스택을 선택했습니다.

  • AWS SES (Simple Email Service) – 이메일 전송
  • GraphQL (Apollo Federation) – 이메일 발송 API 서버
  • MongoDB – 사용자 정보 및 이메일 발송 이력 저장
  • Node.js (Express 기반) – 워크플로우 및 모듈화 처리
  • ArgoCD + Kubernetes CronJob – 대상자 추출 및 발송 스케줄 관리
  • AWS SNS + CloudWatch – 이메일 전송 이벤트 수집 및 모니터링

📦 시스템 아키텍처 개요

이메일 발송은 단순히 SES API를 호출하는 것이 아니라, 다음의 복잡한 플로우를 거쳐 최종적으로 사용자에게 도달합니다.

대상자 필터링 
    ↓ 대상자 필터링 
워크플로우 트리거 
    ↓
배치 발송 컨트롤러 
    ↓
GraphQL API
    ↓
AWS SES 발송
    ↓
이벤트 발생 (Open, Click, Bounce)
    ↓
AWS SNS → public_listener → MongoDB

이런 구조를 통해 저희는 아래와 같은 기능들을 완성시킬 수 있었습니다.

  • 발송 대상자 동적 필터링
  • 언어 분기 자동화
  • 발송 실패 시 3회 재시도 로직
  • 이메일 오픈 및 클릭 추적
  • 수신거부 처리 및 이력 기록

📡 이메일 발송 API 서버

템플릿 관리

  • 템플릿 생성 및 수정할 수 있습니다.
  • 언어 기준 자동 분기 ({템플릿명}_kr, {템플릿명}_en)됩니다.

마케팅 팀이 HTML을 제작하고 코드화하여 등록합니다.

이메일 발송

  • 단일 및 최대 50명 대상 일괄 발송됩니다.
  • 이벤트 기반 자동 발송되는 시스템 입니다.

수신거부자는 자동 제외되며, 모든 발송은 MongoDB에 기록됩니다.

발송 이력 관리

  • 발송 이벤트(열람, 클릭 등) 자동 업데이트됩니다.
  • 사용자별, 메시지별 발송 이력 조회를 할 수 있습니다.

🔄 워크플로우: 사용자 필터링부터 발송까지

워크플로우는 전체 이메일 발송 과정을 관리합니다.

사용자 필터링 단계

  • 사용자 DB에서 필터링 조건에 따라 대상자를 추출하고 리스트업 하고 있습니다.

배치 발송 단계

  • 대상자를 1,000명 단위로 분리 후 50명 단위로 배치 발송됩니다.
  • 이메일 중복 제거 및 언어별 분리 발송, 발송 실패시 재 발송 시도 로직도 구현되어있습니다.
  • 트래픽 관리 위해 일정 간격으로 발송 지연되도록 하였습니다.

🔐 AWS SES 구성 포인트

  • Region us-east-1 (N. Virginia)
  • 일일 발송 제한량: 최대 200,000건
  • Configuration Set: 이벤트 추적을 위한 SNS/CloudWatch 연동
  • Template: UI에서 템플릿 확인 가능, 내부에선 코드로 직접 등록

설정 예시: 대상자 언어 기준 자동 분기 발송


🧠 이벤트 트래킹 시스템

이메일 발송 후 다음과 같은 이벤트가 발생합니다.

  • 📬 Send (성공 발송)
  • 👁 Open (수신자가 메일을 열람)
  • 👉 Click (링크 클릭)
  • ❌ Bounce (전송 실패)

이 이벤트는 AWS SES → SNS → Webhook(/listenerSNS) → emailHistory로 업데이트됩니다.

이메일 추적 상태 Open 이슈

1) AWS SES는 1x1 픽셀 크기의 투명한 GIF 이미지를 이메일에 삽입하여 열람을 추적합니다. 이 이미지가 다운로드되면 "Open" 이벤트로 간주합니다.
2) 일부 이메일 클라이언트는 보안 및 프라이버시 설정으로 인해 이메일을 열지 않아도 자동으로 이미지를 다운로드할 수 있습니다.
3) 현재 이메일 시스템에서는 비정상적으로 빠른 시간(12초) 내에 발생한 "Open" 이벤트는 필터링하고 있습니다.
4) 그럼에도 불구하게 비정상적인 "Open" 이벤트는 발생할 수 밖에 없는 상황이기에 이에 대한 처리를 고민하고 있습니다.


🧾 마치며

AWS SES는 단순히 이메일을 보내는 기능을 넘어서, 이벤트 추적, 통계 분석, 수신거부 처리, 대량 발송 제어까지 통합적으로 관리할 수 있는 시스템을 구축할 수 있게 합니다.

저희는 이 시스템을 통해 마케팅/운영/프로덕트 모두가 이메일 발송을 신뢰하고 관리할 수 있는 기반을 만들었습니다.

이 글이 대량 이메일 시스템을 직접 구축하고자 하는 개발자분들에게 현실적이고 실질적인 도움이 되기를 바랍니다!

profile
Junior Frontend Developer

7개의 댓글

comment-user-thumbnail
2025년 5월 30일

원하는게 없기 때문에, 직접 구축한다..? 오
진짜 대단한 것 같아요. 개발 하시면서도 엄청 뿌듯했을 것 같습니다!
좋은 인사이트 감사합니다!

답글 달기
comment-user-thumbnail
2025년 5월 31일

프론트엔드 업무를 진행하면서 경험해보기 어려운것을 직접 구현해보면서 많은 시행착오가 있으셨군요
고생많으셨습니다! 덕분에 제가 했던 작업을 다시한번 살펴보면서 개선할부분을 찾아볼 수 있을것같아요!

답글 달기
comment-user-thumbnail
2025년 5월 31일

매번 좋은 경험을 쌓고 계시군요! 정말 대단하신거 같아요:) 뭘 하든 일단 돌아가게 하자 정도로 끝내지 않고 깊게 파고드는 부분에서 정말 많은 자극을 받고 있습니다:) 좋은 글 잘 읽었습니다!

답글 달기
comment-user-thumbnail
2025년 5월 31일

어떤 툴을 가지고 어떤 플로우로 개발했는지를 작성해주셔서 흥미롭게 읽었어요! 나중에 기회가 되신다면 공개가 가능한 범위에서 코드 공유해주셔도 재밌을 것 같아요~!

답글 달기
comment-user-thumbnail
2025년 5월 31일

혹시 이메일을 보내기 위해 이메일 템플릿을 구현하는 것에 있어서 고민한 부분이 있으실까요?
저희도 사내에서 이메일 템플릿을 구현해야하는데, 이때 에디터가 스티비에 비해서 적은 기능(속성?)들을 가지고 있어 불편하다는 얘기를 접했거든요..! 서버측면 말고 프론트엔드 부분에서의 시행착오는 없으셨는지도 궁금하네요 ㅎㅎ

답글 달기
comment-user-thumbnail
2025년 5월 31일

직접 구축하시느라 여러가지로 고민하셔야할 지점이 많으셨을텐데 너무 멋있으십니다bb

답글 달기
comment-user-thumbnail
2025년 6월 1일

소현님 정말 대단하시네요!
글을 보고 얘기도 나누며 느끼는 거지만 소현님은 주도적으로 문제를 해결해나가시는 것 같아요!
저도 소현님처럼 주도적으로 문제를 해결해나가는 개발자가 되도록 노력하겠습니다.
자극 많이 받고 갑니다!
잘 읽었어요! 좋은 글 감사합니다!!

답글 달기