만들게 된 이유
최근 특정 프로그램에서 멘토링을 많이 하고 있는데, 멘토링 보고서를 제출할 때마다 타입폼 페이지에 들어가 동일한 항목을 반복 입력해야 하는 상황에 직면했다.
업무 난이도는 높지 않았지만.. 나레기 짱 게으르죠? 이런 간단한 것도 하기 싫죠? 애초에 사이트 들어가기 귀찮죠? 들어가더라도 맨날 똑같은 데이터 입력하기 짱짱 싫죠?
그래서 “디스코드에서 멘토링 내용을 입력하면 나머지 부분을 알아서 채워주고 보고서를 제출해주는 디스코드 봇”을 만들었다.
프로젝트 목표
이 프로젝트의 목표는 세 가지였다.
- 운영자가 디스코드에서 빠르게 등록하고 보고할 수 있어야 했다.
- 등록 데이터는 일관된 형식으로 저장되고 자동 정리되어야 했다.
- 멘토링/수업 운영 규칙이 바뀌어도 코드 수정량을 최소화해야 했다.
전체 구조
현재 구조는 아래와 같다.
discord/mentoring-bot
├─ main.py # 봇 시작점, cogs 자동 로딩, 로그/명령어 sync
├─ cogs/
│ ├─ enroll.py # /enroll 메인 로직 (질문/검증/요약/스레드/저장)
│ ├─ maintenance.py # 매일 자정 만료 데이터 정리 + 저장 반영
│ └─ company1/
│ ├─ reporting.py # 멘토링 보고 메시지 감지 + 타입폼 자동 제출
│ └─ scheduler.py # 수업 리마인드 (평일 09:30, 기간/공휴일 조건)
├─ data/
│ ├─ enrollment_profiles.json # 회사별 질문 순서/문구/조건/템플릿 설정
│ └─ company1.json # 등록 데이터 저장소(JSON)
└─ utils/
├─ storage_manager.py # load/find/cleanup 같은 저장 유틸
├─ git_utils.py # JSON 저장 후 Git 반영 유틸
└─ scraper.py # 타입폼 제출 자동화 유틸
핵심은 코드와 운영 정책을 분리한 점이다.
로직은 공통 엔진으로 두고, 질문/문구/분기 조건은 프로필 파일에서 바꿀 수 있게 만들었다.
왜 DB 대신 JSON을 썼는가
처음부터 DB를 도입하지는 않았다. 어차피 나 혼자 쓸, 아주 자그마한 아이기 때문이었다.
그래서 초기에 바로 JSON 저장소를 선택했다.
- 장점: 구축 속도가 빨랐고, 데이터 구조 확인/수정이 직관적이었다.
- 장점: Git 기반 백업 및 변경 추적이 쉬웠다.
- 단점: 동시성, 트랜잭션, 대량 데이터 처리에는 불리하다.
현재 단계에서는 장점이 단점을 상회한다고 판단했다.
대신 파일 구조와 저장 포맷을 명확히 해두어, 추후 DB로 이관하기 쉽게 설계했다.
주요 기능
1) 등록 자동화 (/enroll)
- 회사 코드 기반으로 등록 플로우를 시작한다.
- 등록 유형(멘토링/수업), 트랙, 기수, 시작일/종료일, URL 등을 순차 입력받는다.
- 입력 검증(선택지/숫자/날짜 형식)을 통과한 데이터만 저장한다.
- 등록 완료 후 요약 메시지와 보고 스레드를 자동 생성한다.
2) 멘토링 보고 자동 제출
- 보고 스레드에서 지정된 양식 메시지를 감지한다.
- 필요한 항목을 파싱해 타입폼 제출 함수로 전달한다.
- 성공/실패를 이모지와 답장으로 피드백한다.
3) 수업 알림 자동화
- 평일 오전 9:30(KST)에만 알림을 보낸다.
start_date <= 오늘 <= expiry구간에서만 동작한다.- 주말 및 대한민국 법정 공휴일은 스킵한다.
4) 만료 데이터 정리
- 매일 자정 만료 항목을 정리한다.
- 만료 스레드는 잠그고 아카이브 처리한다.
- 정리 결과를 JSON에 반영하고 저장소에 반영한다.
트러블슈팅: Docker + JSON 자동 커밋/푸시
가장 오래 걸린 문제는 Docker 환경에서 JSON 파일을 갱신하고 Git으로 자동 반영하는 과정이었다.
문제 1) 저장 경로가 이중으로 생기는 문제
JSON 파일이 의도하지 않은 경로에 중복 생성되는 문제가 있었다.
원인은 컨테이너 마운트 경로와 실제 Git 추적 루트가 어긋났기 때문이다.
해결은 레포 루트를 기준으로 볼륨을 다시 잡고, 컨테이너 working_dir를 명확히 맞추는 방식으로 진행했다.
문제 2) git pull --rebase 충돌
서버에서 직접 파일을 수정하는 상황과 봇의 자동 저장이 겹치면서 rebase가 자주 실패했다.
해결은 --autostash 적용과 저장 타이밍 정리였다.
또한 Git 루트를 탐색해 git -C <repo_root> 형태로 명령을 고정해 경로 오류를 줄였다.
문제 3) Docker의 dubious ownership
마운트된 레포 소유권이 컨테이너 유저와 달라 Git 보안 검증에 걸렸다.
해결은 컨테이너에서 safe directory를 명시하는 방식으로 처리했다.
이 과정을 통해 “코드가 맞아도 배포 환경이 다르면 자동화가 실패할 수 있다”는 점을 크게 체감했다.
결과
대충 이런식으로 적으면 알아서 멘토링 팀을 관리해주고 일정 리마인드를 해준다. 또한 보고서 내용을 간략히 입력하면 알아서 타입폼의 데이터를 세팅 후 제출해준다!
이번 작업에서 얻은 결론
작은 불편을 자동화하는 작업은 생각보다 가치가 컸다.
반복 입력을 줄인 것 자체보다, 운영 절차를 코드로 표준화한 효과가 더 컸기 때문이다.
그리고 기능을 늘릴수록 “하드코딩보다 설정 기반 구조가 장기적으로 유리하다”는 점이 명확해졌다.
다음 확장 계획
다음 단계에서는 아래 항목을 확장할 계획이다.
- 회사별 타입폼 매핑 규칙 완전 분리
- 공휴일/예외일 커스텀 캘린더 지원
- 관리자용 상태 조회 커맨드(등록 현황, 만료 예정, 알림 대상)
- JSON에서 DB로 무중단 이관 가능한 저장 계층 추상화
- AI API를 연결하여 더 정갈한 보고서 생성
아직은 초기라서 이정도로 생각하고 있지만, 나중에 쓰다보면 더 생기지 않을까 싶다,,,