비즈니스 확장성을 고려한 알림톡 발송 시스템 개선기: 전략 패턴의 실전 적용

2025. 1. 26. 13:10Spring

알림톡이란?

알림톡 예시

알림톡은 카카오톡이 제공하는 기업용 메시징 서비스입니다.

일반적인 카카오톡 메시지와는 달리, 알림톡은 사용자가 해당 카카오톡 채널을
친구로 추가하지 않아도 정보성 메시지를 발송할 수 있다는 특징이 있습니다.
기업들은 주로 주문 내역, 예약 확인, 배송 현황 등 사용자에게 꼭 필요한 정보를 전달하는 용도로 사용됩니다.

알림톡의 장점은 다음과 같습니다:

  • 친구 추가가 없어도 발송 가능
  • 최대 1,000자까지 텍스트 전송 가능
  • 버튼을 통한 액션 유도 (최대 5개)
  • 높은 도달률과 신뢰도
  • 스팸이나 피싱의 위험이 낮음

출장관리시스템에서의 알림톡 활용

저희 회사가 만드는 출장관리시스템(이하 BTMS)에서는
다음과 같은 상황에서 알림톡을 활용하고 있습니다:

  1. 항공권 예약 알림
    • 미확정(예약 실패)
    • 예약 완료 알림
    • 에약 취소
    • 발권 완료
    • 체크인 안내
    • 출발 24시간 전 리마인더
  2. 숙박 예약 알림
    • 미확정(예약 실패)
    • 예약 확정 알림
    • 예약 취소
    • 체크인 시간 안내
    • 예약 취소/변경 알림
  3. 열차/버스 예약 알림
    • 미확정(예약 실패)
    • 예약 완료 알림
    • 예약 취소
    • 출발 임박 알림
    • 예약 변경 사항 안내

각각의 알림톡은 사용자에게 꼭 필요한 정보만을 담아 발송하고 있습니다.
예를 들어, 숙박 이용 무료취소에 대한 알림의 경우 다음과 같은 정보를 포함합니다:

실제 숙박 이용 무료취소 알림톡

  • 예약 번호
  • 공급사 예약번호
  • 숙소/객실명
  • 입실일시
  • 퇴실일시
  • 안내문
  • 고객센터 번호

이제 알림톡과 우리 회사의 기본적인 활용 방식을 이해하셨을 것 같습니다.
그럼 이제 최근 진행한 알림톡 발송 프로세스 개선 프로젝트에 대해 이야기해보겠습니다.

레거시 알림톡 발송 시스템의 문제점과 전략 패턴을 통한 개선

기존 시스템의 문제점과 비즈니스적 배경

알림톡 발송 시스템 개선 프로젝트는
한 고객사의 커스텀 템플릿 알림톡 요청으로 시작되었습니다.

기술적으로만 보면 간단한 if-else 문으로도 해결할 수 있는 요구사항이었지만,
대표님과 기획팀과의 전략 회의에서 다음과 같은 인사이트를 얻었습니다:

  1. 다수의 신규 고객사 영업이 동시 진행 중
  2. 현재 3개 회사와 PoC 진행 중
  3. 향후 2년간 최소 5개 이상의 대기업 고객사 온보딩 예정

이러한 상황에서 기존 코드의 한계가 명확했습니다:

public class UmsTemplateCode {
	// 공통 템플릿
    public static final int COMMON_MAIL_CERTIFY = 100001;
		
	// 항공 템플릿
    public static final int FLIGHT_PENDING = 200001;
    public static final int FLIGHT_CONFIRMED = 200002;

	// 숙박 템플릿
    public static final int HOTEL_PENDING = 300001;

    public static Map<String, Object> getTemplateMap(String sendType, int templateCode) {
        if (100000 <= templateCode && templateCode < 200000) {
			// 공통 템플릿 처리
        } else if (200000 <= templateCode && templateCode < 300000) {
			// 항공 템플릿 처리
        } else if (300000 <= templateCode && templateCode < 400000) {
			// 숙박 템플릿 처리
        }
    }
}

새로운 고객사 추가시마다 점점 더 복잡해지는 if-else 체인:

if (company.equals("companyA")) {
    sendTemplateA();
} else if (company.equals("companyB")) {
    sendTemplateB();
} else if (company.equals("companyC")) {
    sendTemplateC();
}

이러한 구조로는 다음과 같은
비즈니스 요구사항을 수용하기 어려웠습니다:

  • 고객사별 맞춤형 템플릿 처리
  • 각기 다른 브랜딩 요구사항
  • 특정 고객사만의 특별한 알림톡 발송 로직
  • 템플릿 A/B 테스트

전략 패턴을 통한 개선

시스템의 확장성 확보를 위해 전략 패턴을 도입했습니다.
전체적인 구조는 다음과 같습니다:

전략패턴 클래스 다이어그램

각 컴포넌트의 실제 구현을 살펴보겠습니다:

1. 전략 인터페이스 정의

public interface CompanyStrategy {
    void sendAlimtalk(String transactionSetId,
        String key,
        UmsStatusCode umsStatusCode,
        String receiverMobileNo
    );

    void sendMail(String transactionSetId,
        String bookingItemCode,
        UmsStatusCode umsStatusCode,
        String receiverEmail,
        Map<String, Object> dataMap
    );
}

이 인터페이스를 통해 각 고객사별로
완전히 다른 알림톡 발송 로직을 구현할 수 있게 되었습니다.

2. 회사별 전략 구현

@Component
public class HStrategy implements CompanyStrategy {
    @Override
    public void sendAlimtalk(...) {
        CreateAlimtalkOutboxEvent createEvent = new CreateAlimtalkOutboxEvent(
            transactionSetId,
            key,
            umsStatusCode.getTemplateCode(),
            receiverMobileNo,
            umsStatusCode.getCategoryCode().getCode(),
            "HCompany",
            EventStatus.PENDING
        );
        alimtalkOutboxEventMapper.createEvent(createEvent);
    }
}

예를 들어, H사의 경우 자체 메시징 시스템 연동이 필요했는데,
HStrategy에서 이를 쉽게 구현할 수 있었습니다.

3. 전략 결정 및 주입

@Component
public class CompanyStrategyResolver {
    private final Map<CompanyChannel, CompanyStrategy> strategyMap;

    public CompanyStrategyResolver(
        DefaultStrategy defaultStrategy,
        HStrategy hStrategy
    ) {
        this.strategyMap = Map.of(
            CompanyChannel.DEFAULT, defaultStrategy,
            CompanyChannel.HEXPENSE, hStrategy
        );
    }

    public CompanyStrategy resolve(CompanyChannel channel) {
        return strategyMap.getOrDefault(channel, strategyMap.get("DEFAULT"));
    }
}

실제 알림톡 발송 프로세스는 다음과 같이 동작합니다:

알림톡 실행 프로세스

개선 효과

전략 패턴 도입으로 기술적, 비즈니스적으로 다음과 같은 효과를 얻을 수 있었습니다:

  1. 신규 고객사 온보딩 시간 단축
    • 기존: 커스텀 템플릿 적용에 2주 소요
    • 개선 후: 2-3일로 단축
    • 실제 사례: L사의 경우 전용 전략만 구현하여 1주일 만에 온보딩 완료
  2. 비즈니스 로직 격리
    • 각 고객사의 요구사항 변경이 다른 고객사에 영향을 주지 않음
    • H사의 자체 메시징 시스템 연동도 다른 고객사 영향 없이 적용
  3. 운영 리스크 감소
    • 새로운 기능 추가 시 기존 코드 수정 최소화
    • 고객사별 독립적인 테스트 가능

결론 및 향후 계획

이번 프로젝트는 대학교와 책에서만 보던 전략 패턴을
실제 비즈니스 문제 해결에 적용해본 귀중한 경험이었습니다.

디자인 패턴을 단순히 구현하는 것은 어렵지 않았지만,
이를 레거시 코드에 자연스럽게 통합하고 실제 비즈니스 요구사항을 만족시키는 것은 전혀 다른 도전이었습니다.

특히 어려웠던 점들은:

  • 기존의 복잡한 if-else 구문들을 전략 패턴으로 리팩토링하는 과정에서 기존 기능이 깨지지 않도록 하는 것
  • 각 고객사의 비즈니스 로직을 적절한 크기의 전략으로 분리하는 설계 결정
  • 새로운 패턴 도입으로 인한 시스템 복잡도 증가를 팀원들이 수용할 수 있도록 설득하는 과정

하지만 결과적으로 이 도전은 성공적이었습니다.

3개월 만에 2개의 신규 고객사를 무리 없이 온보딩했으며,
현재 진행 중인 3개의 PoC도 순조롭게 진행되고 있습니다.
이론적인 디자인 패턴이 실제 비즈니스 가치 창출로 이어지는 것을 경험할 수 있었던 값진 기회였습니다.

다음 글에서는 이 전략 패턴이 아웃박스 패턴과 어떻게 연계되어
메시지의 신뢰성과 확장성을 동시에 확보할 수 있었는지 설명하도록 하겠습니다.

728x90