카카오톡 플러스친구 스마트채팅 만들기 2 - 구조 설계

카카오톡 플러스친구 스마트채팅 만들기 2 - 구조 설계

Flask 를 사용하여 구현하였으며, 데이터베이스로 firestore를 사용하였습니다.
전체 구조는 아래와 같습니다.

필요한 라이브러리를 설치합니다.

1
$ pip install Flask Flask_RESTful firebase-admin

kakatalk_lunch_bot.py

flask를 생성하고 시작합니다.
Flask-RESTful을 사용하여 요청을 처리하였습니다.

사용자 입력처리만 하고 관리는 하지 않으므로
두 가지 /keyboard, /message만 구현하였습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# kakatalk_lunch_bot.py

from flask import Flask
from flask_restful import Api

from resources.keyboard import Keyboard
from resources.message import Message

app = Flask(__name__)
app.config['JSON_AS_ASCII'] = False
api = Api(app)


@app.route('/')
def hello_world():
return 'Hello World!'


api.add_resource(Keyboard, '/keyboard')
api.add_resource(Message, '/message')

if __name__ == '__main__':
app.run()

resources/keyboard.py

/keyboard 요청을 처리합니다. GET 메소드를 사용합니다. 채팅을 시작할 때의 화면이므로 항상 같은 값을 반환하게 됩니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# resources/keyboard.py

from flask import json, Response
from flask_restful import Resource


class Keyboard(Resource):
@classmethod
def get(cls):
rst = {
"type": "buttons",
"buttons": ["#점심 선택", "#결과 보기", '#설정']
}
json_string = json.dumps(rst)
response = Response(json_string, content_type="application/json; charset=utf-8")
return response

버튼 이름 앞에 #을 붙여서, 사용자가 텍스트로 입력한 경우와 구분하였습니다. 사용자가 버튼을 눌렀을 때 버튼 이름과 비교 하여 처리하기 위해 버튼 이름을 변수로 만들어서 사용합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# resources/keyboard.py

from flask import json, Response
from flask_restful import Resource

from conf.const import Const


class Keyboard(Resource):
@classmethod
def get(cls):
rst = {
"type": "buttons",
"buttons": Const.DEFAULT_KEYBOARD
}
json_string = json.dumps(rst)
response = Response(json_string, content_type="application/json; charset=utf-8")
return response

conf/const.py

버튼 이름, 컬럼 명, 상태 값, 파라미터 명 등을 관리합니다.

1
2
3
4
5
6
7
8
9
# conf/const.py

class Const:
## buttons
BTN_SELECT_LUNCH = "#점심 선택"
BTN_SEE_RESULT = "#결과 보기"
BTN_SETTING = '#설정'

DEFAULT_KEYBOARD = [BTN_SELECT_LUNCH, BTN_SEE_RESULT, BTN_SETTING]

여기까지만 구현을 해도, API테스트에서 결과를 확인할 수 있습니다.

resources/message.py

/message 요청을 처리합니다. 이 때는 POST 메소드를 사용합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# resources/message.py

from flask_restful import reqparse

from conf.firebaseInit import fs
from conf.util import Util
from events.result import Result
from events.select import Select
from events.setting import Setting
from resources.keyboard import *

parser = reqparse.RequestParser()
parser.add_argument('user_key', type=str, required=True)
parser.add_argument('type', type=str, required=True)
parser.add_argument('content', type=str, required=True)


class Message(Resource):
def __init__(self):
self.args = parser.parse_args()
self.user_key = self.args[Const.ARG_USER_KEY]
self.req_type = self.args[Const.ARG_TYPE]
self.content = self.args[Const.ARG_CONTENT]

def post(self):
# 버튼 입력을 처리합니다.

# 사용자 입력을 처리합니다.

# 시작 메뉴로 이동합니다.

파라미터 처리를 위한 변수를 추가합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
# conf/const.py

class Const:
## buttons
BTN_SELECT_LUNCH = "#점심 선택"
BTN_SEE_RESULT = "#결과 보기"
BTN_SETTING = '#설정'

DEFAULT_KEYBOARD = [BTN_SELECT_LUNCH, BTN_SEE_RESULT, BTN_SETTING]

ARG_USER_KEY = "user_key"
ARG_TYPE = 'type'
ARG_CONTENT = 'content'

/message로 들어온 사용자 입력 데이터를 처리합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# resources/message.py

class Message(Resource):
# ... 생략...

def post(self):
select = Select(self.args)

# 버튼 입력을 처리합니다.
if self.content == Const.BTN_SELECT_LUNCH:
return select.show_restaurant_list()

# 사용자 입력을 처리합니다.

# default
return Util.show_start_menu()

self.content 에는 사용자가 선택한 내용이 들어 있습니다. 이를 비교하여 처리합니다.

각각 선택, 결과, 설정을 처리하기 위한 클래스를 생성합니다.

  • events/select
  • events/result
  • events/setting
공유하기