1. 프로젝트 개요
나는 매일 오딘 길드의 보스 스케줄을 공지하는 역할을 맡고 있었다. 하지만 이 작업은 생각보다 꽤 번거롭고, 매일 밤마다 수동으로 시간을 확인하고 텍스트를 작성해야 했기 때문에, 반복적이고 소모적인 작업이 되었다. 길드 내에서 이 역할을 대신할 사람이 없었기에, **“차라리 이걸 자동화할 수는 없을까?”**라는 생각을 갖게 되었고, 이것이 챗봇 프로젝트의 출발점이었다. GPT와의 대화를 통해 이 아이디어를 구체화하면서, 단순히 스케줄 공지에 그치지 않고 오딘 전용 AI 비서 챗봇으로도 확장 가능성이 있다는 걸 깨달았다. 예를 들어, /boss 명령으로 보스 시간을 확인하거나, /ask로 사냥터를 추천받는 기능까지 가능할 수 있겠다는 생각이 들었고, 그때부터 이 프로젝트를 본격적으로 시작하게 되었다.
2. 구현 환경
Python 버전 | 3.8.8 |
백엔드 프레임워크 | Flask |
데이터 저장 | Google Sheet (스케줄 관리) |
챗봇 플랫폼 | 카카오 i 오픈빌더 |
외부 공개 | ngrok |
기타 | pandas, gspread, oauth2client 등 사용 |
3. Google Sheet 연동
보스 스케줄 데이터는 Google Sheet를 사용해서 관리했다. 그 이유는 간단하다:
- 내가 혼자 개발하고 있는 사이드 프로젝트였고,
- 직접 DB 서버를 따로 구축하거나 관리하고 싶지 않았으며,
- 평소에 익숙한 Excel 스타일로 데이터를 보고, 수정하고, 공유할 수 있는 환경이 필요했기 때문이다.
Google Sheet는 웹에서 실시간으로 접근할 수 있고, Python에서는 gspread 라이브러리를 통해 쉽게 데이터를 읽고 쓸 수 있다. 덕분에 보스명, 남은시간, 리젠주기, 계산방식, 공지여부 등의 정보를 직관적으로 관리하면서도 프로그램과 연동할 수 있었다. 또한 나중에 다른 길드원이 데이터를 입력하거나 수정해야 하는 경우에도, Google Sheet라면 접근성이 좋아서 공유 관리 측면에서도 유리하다고 판단했다.
컬럼 구성은 다음과 같다:
- 통제구분
- 지역
- 보스명
- 남은시간 (예: "04:12")
- 리젠주기
- 계산방식
- 공지여부
- 비고
남은시간은 실시간으로 수정되며, Python에서 해당 값을 읽어 출현시간을 계산해준다.
4. Flask 서버 구축
챗봇에서 사용자가 /boss 명령어를 입력하면, 내 서버가 요청을 받아 보스 스케줄 메시지를 생성해 응답해야 한다. 이 역할을 수행할 웹 서버 프레임워크로 나는 Flask를 선택했다. 물론 Python에는 Django, FastAPI 같은 프레임워크들도 있지만, Flask를 선택한 이유는 다음과 같다:
- 빠르게 가볍게 시작할 수 있는 구조였고
- 챗봇 Webhook처럼 단순한 HTTP POST 요청만 처리하면 되는 MVP 프로젝트에
Flask의 단순함이 오히려 더 적합했기 때문
Django는 구조적으로 프로젝트를 꽤 크게 잡아야 하고, FastAPI는 비동기 처리에 강하지만 초기 진입장벽이 있는 반면,
Flask는 app.route() 하나만으로도 바로 Webhook을 받을 수 있어 빠르게 기능을 붙이기에 안성맞춤이었다.
MVP 단계를 지나 나중에 구조가 복잡해지거나 확장할 일이 많아진다면 FastAPI로 마이그레이션하는 것도 고려할 수 있겠지만, 이번 프로젝트에서는 Flask가 딱 적절한 선택이었다고 생각한다.
Flask는 카카오 오픈빌더에서 보내는 POST 요청을 받아서 Google Sheet에서 데이터를 조회하고, 메시지를 구성한 뒤 다시 응답하는 역할을 한다.
@app.route('/webhook', methods=['POST'])
def webhook():
utterance = request.json['userRequest']['utterance'].strip()
if utterance == "/boss":
message = generate_boss_schedule_message()
else:
message = "❓ 알 수 없는 명령입니다."
return jsonify({
"version": "2.0",
"template": {
"outputs": [{"simpleText": {"text": message}}]
}
})
5. ngrok을 통한 외부 접속
Flask 서버는 내 로컬 컴퓨터(127.0.0.1)에서 실행되기 때문에
기본적으로 인터넷 상의 다른 서비스(예: 카카오 오픈빌더) 가 이 서버에 접근할 수 없다.
그래서 외부에서도 내 로컬 Flask 서버에 접근할 수 있도록
ngrok이라는 툴을 사용했다.
💡 ngrok이란?
ngrok은 로컬 서버를 외부에서 접근 가능한 URL로 노출시켜주는 터널링 도구다.
쉽게 말하면, "내 컴퓨터에서 실행 중인 서버를 인터넷에서 접속할 수 있게 해주는 다리" 같은 역할을 한다.
✅ 사용 흐름
- Flask 서버 실행 → http://localhost:5000에서 대기
- ngrok http 5000 실행
- https://xxxx.ngrok.io 같은 공개 URL이 발급됨
- 이 URL을 카카오 오픈빌더의 Webhook 주소로 등록
ngrok http 5000
예시 출력:
Forwarding https://3e1d-abc-123.ngrok.io → http://localhost:5000
카카오 오픈빌더에서는 Flask 서버의 /webhook 주소에 요청을 보내야 하므로,
Webhook URL에는 다음과 같이 입력한다:
https://3e1d-abc-123.ngrok.io/webhook
이렇게 하면 카카오톡에서 사용자가 /boss를 입력했을 때,
카카오 서버 → ngrok 주소 → 내 로컬 Flask 서버로 요청이 전달되고,
Flask가 응답을 돌려주는 구조가 된다.
⚠️ 주의사항
- ngrok는 재실행할 때마다 주소가 바뀐다
→ 오픈빌더에 등록한 Webhook 주소도 함께 다시 바꿔줘야 함
6. 오픈빌더 연동
카카오 i 오픈빌더에서는 사용자의 발화에 따라 Webhook으로 연결된 서버에 요청을 보내고, 그 응답을 받아 유저에게 메시지를 전달하는 방식으로 동작한다. 나는 /boss라는 명령어를 시나리오 블록으로 등록하고, Webhook 응답을 받는 방식으로 챗봇을 구성했다. Webhook URL은 앞서 ngrok을 통해 발급받은 외부 주소를 사용했다. 오픈빌더에서의 설정은 다음과 같은 순서로 진행했다:
- 발화 패턴으로 /boss 등록
- 응답 방식으로 “스킬데이터(외부 Webhook)” 선택
- Webhook URL 입력 (예: https://xxxxx.ngrok.io/webhook)
- 챗봇 배포 후 테스트 진행
이렇게 설정하고 나면, 카카오톡에서 챗봇에게 /boss 명령어를 입력했을 때 Flask 서버에서 Google Sheet 데이터를 읽고 출현시간을 계산하여 사용자에게 보스 스케줄 메시지를 보내주는 구조가 완성된다. Webhook 설정 시 가장 주의할 점은,
ngrok 주소가 변경될 때마다 오픈빌더에 등록된 URL도 반드시 갱신해줘야 한다는 것이다. 주소가 바뀐 채로 테스트하면 챗봇이 응답하지 않는다.

7. 회고
이번 프로젝트를 진행하면서 단순한 자동화 도구를 만들려던 계획이, 오딘 전용 챗봇 시스템으로 확장 가능하다는 걸 깨달은 계기가 되었다. 처음에는 매일 반복적으로 보스 스케줄을 공지하는 게 번거로워 “그냥 자동으로 알려주면 좋겠다”는 생각이 출발점이었다. 하지만 구현을 진행하면서 Flask, Google Sheet API, 오픈빌더, ngrok 등 다양한 기술을 연결해보게 되었고, 자연스럽게 챗봇 구조를 이해하고, 확장성까지 고민하게 되었다. 다만 아쉬운 점도 있었다. 나는 이 챗봇을 카카오톡 오픈채팅방 단톡방에 초대해서 사용하고 싶었지만, 카카오의 구조적 제약으로 인해 오픈빌더 챗봇은 1:1 채팅에서만 작동하며, 단톡방에서는 사용할 수 없다는 걸 알게 되었다. 이는 내가 원하는 방식(길드 단톡방에서 /boss 입력 시 스케줄 응답받기)과는 구조적으로 맞지 않았기에, 결국 다른 플랫폼(예: 디스코드, 텔레그램)이나 카카오톡 PC버전 자동화(pyautogui 등)를 이용한 우회 방법을 고려해야겠다는 결론에 이르렀다.
'project' 카테고리의 다른 글
이상금융거래 탐지 시스템 구축 프로젝트 회고 (2) | 2025.03.24 |
---|