결제 알림을 텔레그램·디스코드 이중화하고 비즈니스 로직에서 분리
목차
알림 채널 이중화하면서 깨달은 것
운영 중 결제 이벤트가 발생하면 텔레그램으로만 쏘던 구조였는데, 채널이 한 곳이라 알림이 묻히거나 봇 토큰 만료 시 통째로 깜깜해지는 게 늘 마음에 걸렸음. 이번에 디스코드 웹훅을 추가하고, 기존 텔레그램 유틸도 손봤음.
왜 디스코드를 골랐나
후보가 슬랙/디스코드/이메일이었는데, 결정 기준은 단순했음.
| 항목 | 텔레그램 | 디스코드 | 슬랙 |
|---|---|---|---|
| 인증 부담 | 봇 토큰 + chat_id | 웹훅 URL 1개 | 워크스페이스 토큰 |
| 메시지 포맷 | 마크다운 제한적 | Embed 풍부 | Block Kit 무거움 |
| 운영 친화도 | 모바일 푸시 강함 | 데스크톱 알림 강함 | 채널 정리 편함 |
웹훅 한 줄이면 끝나는 단순함, 그리고 Embed 로 색상/필드 구분이 가능해서 "충전 성공/실패/지연" 같은 상태별 시각 분리가 잘 됐음. 모바일은 텔레그램, 데스크톱은 디스코드로 역할을 쪼갰음.
구현하면서 막힌 지점
- 두 채널을 동기로 쏘면 외부 API 응답이 결제 콜백 처리 시간을 잡아먹음. 결국 알림 호출은 비동기 큐로 빼고, 실패해도 본 트랜잭션엔 영향 없게 분리.
- 동일 이벤트가 두 채널로 가니까 메시지 빌더가 채널마다 분기됨 → 공통 DTO 하나 만들고, 각 어댑터에서 포맷팅만 다르게 가져가도록 정리.
- 입금 처리 핸들러에서 알림 호출이 비즈니스 로직 한가운데 박혀있던 걸 이벤트 발행 → 리스너 구조로 빼냄. 결제대행사 응답 파싱 로직과 알림 코드가 섞여있던 게 가장 큰 냄새였음.
[입금 이벤트] → publish → [알림 라우터]
├─ 텔레그램 어댑터
└─ 디스코드 어댑터
텔레그램 쪽도 같이 손봄
- 토큰을 코드에 박아두던 잔재를 환경변수로 통일.
- 재시도 로직이 무한루프 가능성 있어서 지수 백오프 + 최대 3회로 캡.
- 메시지 길이 4096자 초과 시 잘리던 버그 → 청크 분할 후 순차 전송.
회고
가장 크게 배운 건 알림은 본 비즈니스 로직과 결합되면 안 된다는 것. 이번에 이벤트 기반으로 떼어내면서, 다음에 카카오워크나 이메일 채널 추가할 때 어댑터 하나만 붙이면 되는 구조로 바뀜. 채널 다중화보다 분리 자체가 진짜 수확이었음.
운영팀 피드백도 좋았음 — "텔레그램 안 와도 디스코드 보고 알아챔" 한 줄이면 충분.
끝
댓글 0
첫 댓글 달아줘.