자동 메일 발송 시스템 구축: 실패 방지와 검증까지

하려던 것 📝

  • 매주 화요일 인기 상품 메일을 자동으로 만들어주는 에이전트 구축 사례

  • veasly의 매주 화요일 "인기 상품 홍보 메일"을 자동으로 만들어주는 에이전트를 구축하고자 함.

  • 사람의 감이 아니라 실제로 팔린 데이터(Sales Truth)만 근거로 베스트셀러를 뽑고, AI가 메일 초안을 생성하면 사람이 검토·승인한 뒤 발송하는 파이프라인을 만들고자 함.

  • 과거에 같은 실수(중복 발송 등)를 반복하지 않도록 실패를 학습하는 Failure Memory와, 발송 전 다중 안전장치(승인 게이트, 10개 조건 검사)를 갖추고자 함.

  • 원본 보존, 개인정보·대외비 익명화, 승인 게이트, 중복 발송 방지, 수신동의 관리, 미리보기 기능을 구현하고자 함.

활용한 툴 ⚒️

  • Claude Code Opus 4.8 : 전 과정의 코드 작성·수정·테스트·디버깅에 활용함. 단일 세션으로 v0.1부터 v1.0까지 완성함.

  • Python 3.9 (표준 라이브러리만) : 작업 환경에 Node가 없어, 추가 설치 없이 어디서나 도는 의존성 0 구조로 구현함.

  • veasly admin '홍보 메일 쓰기' : 실제 고객 발송을 담당하는 도구. 우리 에이전트가 만든 메일을 여기에 붙여넣어 발송하는 구조로 연동함.

  • smtplib / SMTP : 직접 발송 경로 검증에 활용함. 로컬 테스트 서버로 실제 전송 트랜잭션을 확인함.

    Markdown 문서 : 14개 모듈로 시스템 전체 스펙을 먼저 설계하는 데 활용함.

진행 세부 내용 🔍

  • 1️⃣ 시스템 개요 및 파이프라인을 정의함

  • 매주 화요일 메일 자동화를 "수집된 실패 학습 → 매출 진실 → 베스트셀러 선정 → 캠페인 생성 → 검증 → 화요일 발송 → 성과 학습"의 파이프라인으로 정의함.

  • 14개 모듈(Command Center, Failure Memory, Sales Truth, Ranking, Campaign Factory, QA Gate, Tuesday Send Engine 등)로 시스템 전체 골격을 설계함.

  • 실패 학습 결과가 캠페인 생성과 발송 전 검증 양쪽에 되먹임되도록 구조를 잡음.

  • 2️⃣ 과거 실패를 구조화하고 Failure Memory를 설계함

  • "중복 발송 가능성", "인기 상품 기준 미정" 같은 과거 실패를 규칙으로 정제하여 적재함.

  • AI가 '인기'를 실판매가 아닌 단순 노출이나 트래픽으로 오해할 위험을 별도 규칙으로 박아둠.

  • 실패 규칙을 캠페인 생성 단계에서 사전 회피하고, 발송 직전 검증 단계에서 다시 확인하도록 연결함.

  • 3️⃣ v0.1 미리보기 전용 MVP를 구현함

  • 주문 데이터를 업로드하거나 샘플 데이터를 로딩해 최근 7일 판매 1위 상품을 선정하도록 구현함.

  • 취소·환불 주문과 품절 상품을 자동으로 제외하고, 왜 그 상품이 뽑혔는지 선정 이유를 함께 표시하도록 함.

  • 이메일 제목·프리헤더·본문 초안과 미리보기를 생성하되, 실제 발송 기능은 만들지 않음.

  • 샘플 데이터에 일부러 품절·취소·환불 케이스를 넣어, 1위였던 상품이 품절로 제외되고 재고 있는 상품이 선정되는 과정을 눈으로 확인함.

  • 4️⃣ v0.1 동작을 테스트하고 발견된 문제를 수정함

  • 판매 1위 선정, 취소·환불·품절 제외, 동률 시 매출 우선, 미리보기 생성 등 10개 항목을 검증하는 테스트를 작성함.

  • 테스트 작성 중 이미지가 없을 때의 대체 처리, 상품 링크가 없을 때 '발송 불가' 표시가 빠진 것을 발견하여 수정함.

  • 검증 결과를 테스트 리포트 문서로 정리함.

  • 5️⃣ v0.2 내부 테스트 발송 기능을 추가함

  • 실제 고객 발송은 막아두고, 미리 등록한 내부 테스트 주소로만 보낼 수 있도록 구현함.

  • 허용 목록에 없는 주소로는 발송이 차단되도록 하고, 발송 전 체크리스트와 발송 기록 저장 기능을 마련함.

  • 이메일 API 키 같은 비밀값은 별도 설정 파일에서만 읽고 공유 파일에는 올라가지 않도록 분리함.

  • 6️⃣ v0.3 승인 게이트를 추가함

  • 캠페인 상태를 "초안 → 내부 테스트 완료 → 승인 완료"로 관리하는 상태 흐름을 구현함.

  • 승인 전에는 실제 발송이 불가능하도록 막고, 누가 언제 승인했는지와 승인 취소 이력을 기록함.

  • 같은 캠페인이 중복 생성·발송되지 않도록 고유 키를 만들어 차단함.

  • 7️⃣ v1.0 매주 화요일 자동 발송 기능을 구현함

  • 승인 완료, 내부 테스트 완료, 수신동의 고객만 포함, 수신거부 제외, 재고 있음, 상품·이미지 정상, 광고 표기, 수신거부 링크, 중복 미발송 등 10개 조건을 모두 통과할 때만 발송하도록 구현함.

  • 조건이 하나라도 실패하면 발송하지 않고 '차단' 상태로 바꾼 뒤 실패 사유를 로그에 남기도록 함.

  • 재고를 0으로 둔 시뮬레이션에서 발송이 차단되고 사유가 기록되는 것을 확인함.

  • 8️⃣ 실제 SMTP 전송을 검증하고 발송 구조를 진단함

  • 운영용 메일 서버 자격증명이 없어, 로컬에 임시 SMTP 서버를 띄워 실제 전송 트랜잭션이 정상 동작하는지 검증함.

  • 이후 실제 발송을 시도하던 중 veasly.com 연결이 타임아웃되어, DNS를 조회해 veasly.com이 메일 서버가 아니라는 점을 확인함.

  • 실제 발송은 veasly admin의 '홍보 메일 쓰기' 기능이 담당한다는 사실을 파악하고 연동 방향을 바꿈.

  • 9️⃣ veasly 붙여넣기용 자료와 미리보기·원클릭 데모를 만듦

  • 승인된 캠페인을 veasly 편집기에 붙여넣을 수 있는 형태(제목·본문·사용법)로 내보내고, 광고 표기와 수신거부 안내를 자동으로 포함하도록 함.

  • 실제 받은편지함에서 어떻게 보이는지 메일 미리보기를 만들어 연동 전에 결과물을 확인할 수 있게 함.

  • 명령어 한 번으로 선정부터 내부 테스트·승인·붙여넣기 자료·미리보기까지 자동으로 세팅되는 데모를 구성함. 전 과정 55개 테스트를 통과함.

시행착오 ⚠️

  • SMTP로 직접 발송하는 것을 전제로 v1.0까지 만들었으나, 실제 발송 주체는 veasly admin의 '홍보 메일 쓰기'였음을 뒤늦게 확인하여 붙여넣기 방식으로 방향을 전환함.

  • veasly.com으로 메일 발송을 시도했을 때 연결이 계속 타임아웃되어, DNS 조회로 해당 도메인이 메일 서버가 아닌 웹 앱임을 확인하고 원인을 파악함.

  • 실제 고객에게 보낼 메일 서버와 자격증명이 준비되지 않아 직접 발송은 완료하지 못했고, 이 한계를 숨기지 않고 그대로 공유함.

배운 점 📚

  • 나만의 에이전트를 만들 때는 모델 성능보다 무엇을, 어떤 순서로, 어떤 안전장치와 함께 만들지를 명확히 설계하고 지시하는 것이 훨씬 중요하다는 것을 배움.

  • 버전마다 기능을 별도 모듈로 분리하며 키워가니, 새 기능을 더해도 이전에 검증한 것이 깨지지 않아 안정적으로 확장할 수 있었음.

  • 테스트가 사람이 놓친 빈틈(이미지 대체 처리, 발송 불가 표시)을 먼저 잡아줘서, 만들고·테스트하고·검증하고·디버깅하는 과정의 가치를 다시 확인함.

  • 실제로 발송하기 전에 "어떻게 보이는지" 미리보기로 확인하고, 외부 시스템의 실제 발송 구조를 먼저 파악하는 것이 시간을 아껴준다는 것을 깨달음.

향후 계획 🧭

  • veasly에 외부에서 발송을 호출할 수 있는 API가 있는지 확인하여, 있으면 완전 자동화로, 없으면 현재의 수동 붙여넣기 방식을 안정화할 계획임.

  • '인기 상품' 기준을 단순 판매량에서 마진과 신선도까지 반영한 가중치 방식으로 고도화할 계획임.

  • 실제 메일 서버 자격증명을 연결해 내부 주소로 한 통을 실제 발송하여 끝까지 검증할 계획임.

도움이 필요한 점 🤝

  • veasly admin의 '홍보 메일 쓰기'가 외부에서 호출 가능한 API를 제공하는지, 그리고 본문 붙여넣기 사양이 어떻게 되는지 아시는 분의 도움이 필요함.

2
2개의 답글

뉴스레터 무료 구독