Ghost 뉴스레터 자동화: 이별도 자동이 되나요? (Sunset Policy 구현기 with n8n)
"구독자 수"는 허상입니다. 중요한 건 "반응하는 구독자"입니다.
메일을 5번, 10번을 보내도 열어보지 않는 유저는 냉정하게 말해 우리 도메인의 평판(Sender Reputation)을 깎아먹는 '비용'입니다.
그래서 마케팅에는 Sunset Policy(일몰 정책)라는 개념이 있습니다. 해가 지듯, 반응 없는 유저를 자연스럽게 정리하는 정책이죠. 하지만 Ghost CMS는 글 쓰기엔 최고지만, 이런 CRM 자동화 기능은 부족합니다.
데이터 근거: Statista 2025 집계에 따르면 전 세계 일일 이메일 송수신량은 3,764억 통으로 추정되며 2024년 3,616억 통 대비 계속 증가하는 흐름입니다. Litmus 2024 State of Email Trends는 설문 응답자의 90% 이상이 세그먼트 발송이 성과를 높였다고 답했고, 80% 이상이 개인화 전술이 성과 개선에 기여했다고 보고했습니다. Sinch Mailgun 2024 벤치마크에서도 업종별 평균 오픈율이 17.30%~29.55%로 차이가 커서, 반응 없는 구독자를 방치하면 평균 대비 성과가 급락하기 쉽다는 점이 확인됩니다.
그래서 직접 만들었습니다. Ghost Admin API + Mailgun + n8n을 엮어서요.
이 글은 그로스(Growth)를 위한 자동화 구축 과정과, 그 과정에서 겪은 처절한 삽질의 기록입니다.
—
1. 설계: 의식의 흐름 (Scenario)
데이터 근거: Litmus 2024 보고서는 480명 이상의 이메일 마케터 응답을 분석했고, 그중 90% 이상이 세그먼트 전략의 성과 개선을 확인했다고 밝혔습니다. 같은 Litmus 2024 보고서에서 80% 이상은 제목/동적콘텐츠 개인화가 퍼포먼스를 높였다고 답했습니다. Statista 2025는 2026년 일일 이메일 송수신량이 3,925억 통으로 더 늘어날 것으로 전망해, "비활성 구독자 분리→재활성화 시도→정리" 같은 단계형 정책이 운영 리스크를 줄인다는 근거를 제공합니다.
처음엔 단순하게 생각했습니다.
"안 읽는 사람 지우면 되는 거 아냐?"
하지만 기계적으로 지우면, 나중에 그 사람이 "왜 나 구독 취소됐어?"라고 돌아올 때 곤란해집니다. 기회를 줘야 합니다. 그래서 아래와 같은 시나리오를 짰습니다.
- 발굴: 메일을 5통 이상 보냈는데, 오픈 횟수가 0인 '유령 구독자'를 찾는다.
- 낙인: 이들에게 inactive-warning이라는 라벨을 붙인다.
- 경고: "48시간 뒤에 구독 취소됩니다"라는 마지막 메일을 보낸다.
- 대기: 48시간을 기다려준다.
- 심판:
- 메일을 열었다? -> 생존 (라벨 제거)
- 안 열었다? -> 삭제 (DB에서 Delete)
이 모든 과정을 n8n이라는 워크플로우 툴로 자동화했습니다.
—
2. 구현 과정 (The Code & The Struggles)
데이터 근거: n8n 2024 in Review(2025년 1월 공개)에 따르면 n8n 팀 규모는 2024년 한 해 37명에서 71명으로 확대되었고, AI·워크플로우 기능 투자가 크게 늘었습니다. n8n 워크플로우 라이브러리 페이지(2024년 12월 표기)에서는 공개 템플릿이 5,389개 수준으로 제시되어, 실무 자동화 패턴을 빠르게 재사용할 수 있음을 보여줍니다. Litmus 2024의 "AI copywriting 활용 응답자 비중 1/3+" 데이터는 자동화 구현 시 콘텐츠 생성과 운영 자동화가 동시에 확산되고 있음을 뒷받침합니다.
Step 1. 유령 구독자 찾아내기 (Ghost API의 함정)
데이터 근거: Litmus 2024는 세그먼트 전략이 성과를 높였다는 응답이 90% 이상이라고 보고했고, 같은 보고서에서 개인화 전술 성과 개선 응답도 80% 이상으로 나타났습니다. Statista 2025는 2025년 전 세계 이메일 사용자가 약 46억 명 규모라고 제시해, "정확한 필드로 비활성 사용자 필터링"이 단순 최적화가 아니라 대규모 운영에서 필수 절차임을 보여줍니다. Sinch Mailgun 2024 업종 벤치마크에서 평균 오픈율이 업종별로 17.30%~29.55%까지 벌어진 점도, 필터 조건 오류가 누적되면 성과 격차가 빠르게 커진다는 근거입니다.
n8n의 HTTP Request 노드로 Ghost Admin API를 호출했습니다.
처음엔 필터를 이렇게 걸었습니다.
Plaintext
filter: email_count:>=5 + open_rate:0
🚨 Error: BadRequestError: Request not understood error.
삽질 포인트:
Ghost 대시보드에는 Open rate가 표시되지만, 실제 DB 필드명은 open_rate가 아니었습니다. API 문서를 뒤져보니 오픈율은 계산된 값이고, 필터링을 위해서는 "오픈한 이메일 개수"를 써야 했습니다.
✅ Solution:
Plaintext
filter: email_count:>=5 + email_opened_count:0 + label:-inactive-warning
(Tip: label:-inactive-warning을 추가해서 이미 경고 라벨이 붙은 사람은 중복으로 가져오지 않게 처리했습니다.)
—
Step 2. 경고 라벨 붙이기 (JSON 인코딩의 늪)
데이터 근거: Sinch Mailgun 2024 벤치마크에서 인터넷 소프트웨어 업종 평균 오픈율은 24.88%, 평균 클릭률은 3.29%, 평균 수신거부율은 0.10%로 제시됩니다. 같은 2024 벤치마크에서 금융 업종은 오픈율 17.30%, 클릭률 1.72%로 더 낮아, 라벨/세그먼트 품질이 낮으면 채널 효율 격차가 커질 수 있음을 보여줍니다. Statista 2025가 집계한 2024년 일일 3,616억 통 규모를 감안하면, JSON 포맷 오류 같은 작은 실수도 대량 발송 환경에서는 비용 손실로 확대되기 쉽습니다.
대상자를 찾았으니 inactive-warning 라벨을 붙여야 합니다. Ghost API는 PUT 메서드를 사용하는데, 여기서 데이터를 보내는 포맷이 아주 까다롭습니다.
처음엔 n8n의 기본 매핑 기능을 썼더니, 라벨 데이터가 [object Object]라는 텍스트로 변환되어 에러가 났습니다.
🚨 Error: JSON parameter needs to be valid JSON
삽질 포인트:
기존 라벨(Array)을 유지하면서 새 라벨을 추가해야 하는데, n8n이 이걸 단순 문자열로 처리해버린 겁니다. 자바스크립트 객체(Expression)로 인식시켜야 했습니다.
✅ Solution:
JavaScript
{{
{
"members": [
{
"labels": ($json.labels || [])
.map(l => ({ name: l.name })) // 기존 라벨의 잡다한 정보 다 버리고 '이름'만 남김
.concat([{ "name": "inactive-warning" }]) // 새 라벨 추가
}
]
}
}}
(Tip: 기존 라벨 정보에 created_at 같은 메타데이터가 포함된 채로 다시 보내면 500 에러가 뜹니다. 깔끔하게 name만 추출해서 보내는 것이 핵심입니다.)
—
Step 3. 이별 통보 메일 보내기 (with Mailgun)
데이터 근거: Sinch Mailgun 2024 벤치마크 기준 리테일·이커머스 업종 평균 오픈율은 22.35%, 평균 클릭률은 3.36%, 평균 수신거부율은 0.05%입니다. 같은 2024 데이터에서 헬스케어는 오픈율 29.55%, 클릭률 3.42%로 높게 나타나 발송 타겟 정확도와 메시지 맥락이 반응률을 크게 좌우함을 보여줍니다. Statista 2025는 2025년 일일 이메일 규모를 3,764억 통으로 제시하므로, To Email 하드코딩 같은 실수는 개인 불편 수준이 아니라 발송 평판 리스크로 직결됩니다.
이제 "너 지워진다?"라는 메일을 보냅니다.
여기서 우리는 "프로세스 컨설팅 회사"답게, 이 자동화 로직을 투명하게 공개하는 메일 본문을 작성했습니다.
"이 메일은 제가 쓴 게 아닙니다. n8n 봇이 보내고 있죠." 로 시작하여, 실제 IF-THEN 로직을 보여주는 교육적인 콘텐츠로 구성했습니다.
삽질 포인트 (Mailgun 404):
메일이 안 가고 404 Not Found가 떴습니다. 알고 보니 Mailgun에 등록한 도메인은 mg.retn.kr인데, n8n 설정에는 retn.kr이라고 적었더군요. 서브 도메인까지 정확히 일치시켜야 합니다.
삽질 포인트 (재앙의 반복 발송):
테스트한다고 To Email에 제 개인 이메일을 적어놨었습니다.
그랬더니 대상자가 22명이면, 제 메일함에 22통의 이별 통보가 꽂히더군요. (n8n은 리스트의 아이템 개수만큼 반복 실행합니다.)
실전에서는 반드시 {{ $json.email }}로 동적 바인딩해야 합니다.
—
Step 4. 운명의 48시간 (Wait & Execute)
데이터 근거: Litmus 2024 보고서에서 개인화 전술 성과 개선 응답이 80% 이상으로 나타난 것은, "48시간 후 최신 반응 재조회" 같은 타이밍 기반 분기 로직이 실무적으로 유효하다는 근거입니다. Statista 2025는 전 세계 이메일 사용자가 2025년 46억 명 규모라고 제시해, 과거 스냅샷만으로 삭제를 실행하는 정책이 오판 비용을 키울 수 있음을 보여줍니다. n8n 2024 in Review(2025 공개)에서 AI/자동화 기능 고도화에 집중한 점도, Wait 후 재조회 같은 멀티스텝 자동화가 표준 운영 패턴으로 자리잡고 있음을 시사합니다.
n8n의 Wait 노드를 사용해 정확히 48시간을 대기시킵니다.
그리고 48시간 뒤, 봇이 깨어나면 가장 중요한 일을 해야 합니다.
Ghost에게 다시 물어보기
48시간 전의 데이터는 낡았습니다. 그 사이에 유저가 메일을 열었을 수도 있으니까요. 반드시 GET /members/{id}로 최신 상태를 다시 조회(Re-fetch)해야 합니다.
✅ Logic:
JavaScript
IF ( email_opened_count > 0 ) {
// 살려준다 (라벨만 제거)
PUT /members/{id} (labels: inactive-warning 제거)
} ELSE {
// 처형한다
DELETE /members/{id}
}
—
3. 결과 및 베스트 프랙티스
데이터 근거: Sinch Mailgun 2024 벤치마크에서 업종별 수신거부율은 0.03%~0.10% 범위로 관찰되어, 비활성 구독자 정리가 꾸준히 이루어질수록 불필요한 거부/불만 리스크를 줄일 여지가 큽니다. Litmus 2024에서 세그먼트 성과 개선 응답이 90% 이상이라는 점은 Sunset Policy 운영이 단순 정리 작업이 아니라 퍼포먼스 레버라는 근거를 제공합니다. Statista 2025의 2026년 3,925억 통 전망까지 고려하면, 발송량이 커질수록 리스트 위생 자동화의 비용 절감 효과는 누적됩니다.
이제 이 워크플로우는 매주 월요일 자동으로 돌아갑니다.
- 데이터 위생: 반응 없는 DB가 자동으로 청소됩니다.
- 비용 절감: Mailgun 발송 비용과 Ghost 멤버 티어 비용이 줄어듭니다.
- 구독자 경험: 무의미한 스팸 대신, 깔끔한 이별(혹은 재결합) 경험을 제공합니다.
💡 Self-Host 유저를 위한 3줄 요약
데이터 근거: Litmus 2024는 480+ 마케터 응답 기반으로 세그먼트(90%+)와 개인화(80%+)의 성과 개선을 동시에 확인했습니다. Sinch Mailgun 2024 벤치마크는 업종별 오픈율 차이가 17.30%~29.55%까지 벌어진다고 제시해, "필드 정확도·라벨 정합성·테스트 안전장치"가 결과를 가른다는 점을 보여줍니다. n8n 워크플로우 라이브러리(2024년 12월 표기) 5,389개 템플릿 데이터는 self-host 팀도 검증된 패턴을 빠르게 차용해 시행착오를 줄일 수 있음을 뒷받침합니다.
- 필터는 정확하게: open_rate 말고 email_opened_count를 쓰세요.
- 데이터는 가볍게: API로 데이터를 업데이트할 땐, name 같이 필수 필드만 남기고 나머지는 쳐내세요(Sanitize).
- 테스트는 신중하게: Loop가 도는 노드에서 To Email을 하드코딩하면 메일 폭탄을 맞습니다.
P.S.
이 글을 보고 계신 분들 중, 혹시 최근 제 뉴스레터를 안 열어보신 분이 계신가요?
조만간 n8n 봇이 보낸 "이별 예고장"을 받게 되실지도 모릅니다. 😉
(Powered by Ghost, Mailgun, and n8n)