개발 slecs

Discord 메시지 종류 판단 로직을 단일 함수로 통합해 봇 모듈 중복

목차

텔레봇 시스템에서 여러 봇 모듈이 Discord 메시지를 처리할 때 반복되던 종류(kind) 판단 로직을 discord_kind() 함수로 통합하는 리팩토링을 진행했다.

산재된 로직, 일관성의 문제

review_loop.py, takedown_bot.py, design_review.py 세 파일을 보니 각각 Discord의 메시지 종류를 판단하고 라우팅하는 로직이 비슷하면서도 조금씩 다르게 산재되어 있었다. 어떤 파일은 문자열 비교를 직접 했고, 어떤 파일은 약간 다른 조건 분기를 거쳤다. 단순해 보이는 작업이지만, 이런 산재가 쌓이면:

  • 유지보수성 저하: Discord API가 바뀌거나 새로운 메시지 타입을 지원하게 되면 세 곳을 모두 수정해야 한다
  • 버그 증식: 한 곳에서만 고쳐지고 다른 곳에선 빠질 가능성
  • 온보딩 비용: 새 팀원이 이 로직을 이해하려면 여러 파일을 오가야 함

특히 우리 팀의 경우 여러 명이 각각 다른 봇 로직을 담당하고 있었기 때문에, 하나의 진실 공급원(single source of truth)이 있으면 커뮤니케이션과 리뷰가 훨씬 수월할 것으로 봤다.

기능 추출, 세 파일을 한 함수로

이번 작업의 핵심은 각 파일에서 "Discord 메시지의 종류를 판단하고 어느 브랜치로 갈지 결정하는" 부분을 뽑아내서 discord_kind() 함수 하나로 만드는 것이었다. 변경 전후 흐름은 대략:

구분 변경 전 변경 후
review_loop.py 직접 조건문으로 종류 판단 discord_kind(msg) 호출
takedown_bot.py 유사하지만 다른 조건 로직 discord_kind(msg) 호출
design_review.py 또 다른 변형의 판단 로직 discord_kind(msg) 호출

세 모듈이 이제 공통 함수를 거쳐 가므로:

review_loop.py → discord_kind(msg) → 메시지 타입 반환 → 해당 핸들러 실행
takedown_bot.py → discord_kind(msg) → 메시지 타입 반환 → 해당 핸들러 실행
design_review.py → discord_kind(msg) → 메시지 타입 반환 → 해당 핸들러 실행

로직이 중앙화되고, 각 봇은 자신의 비즈니스 로직(리뷰 처리, 테이크다운, 디자인 검수)에만 집중하게 된다.

마이그레이션의 관점

이런 멀티 파일 리팩토링을 할 때 몇 가지 신경 썼던 부분들:

  • 단계적 진행: 한 번에 모든 파일을 바꾸기보다, 각 파일의 테스트 커버리지를 먼저 확인하고 변경을 진행
  • 호환성: 새로운 discord_kind() 함수가 기존의 모든 케이스를 정확히 처리하는지 검증 (기존 파일들의 로직을 다시 한 번 읽고 비교)
  • 이름과 시그니처: 함수 이름(discord_kind)이 명확하고, 각 모듈에서 사용할 때 혼동이 없는지 확인

팀 관점에서는 이런 리팩토링이 "기술 부채 상환"의 성격이 강하지만, 단순한 정리가 아니라 다음 분기의 새 기능(예: 새로운 Discord 메시지 타입 지원)의 토대가 되기도 한다. 따라서 코드리뷰 때 "왜 이 순간에?"라는 질문이 나오지 않도록 맥락을 잘 전달하려 했다.

회고

이 정도 규모의 리팩토링을 몇 번 겪으면서 깨달은 건, 작은 중복도 누적되면 큰 기술 부채가 된다는 것. 특히 텔레봇처럼 여러 봇이 유사한 로직을 가지는 구조라면, 초기에 공통 유틸리티를 분리하는 것보다 일단 동작하게 한 후 나중에 정리하는 게 현실적일 수 있다. 하지만 "정리하자"는 결정을 한 순간, 빠르게 진행하고 명확한 테스트 케이스를 남기는 게 다음 사람(또는 미래의 나)의 시간을 크게 아낄 수 있다.


🛒 이 글과 어울리는 추천 상품

*위 링크는 쿠팡파트너스 활동의 일환이며, 일정액의 수수료를 제공받을 수 있습니다.

댓글 0

첫 댓글 달아줘.