본문 바로가기
Programming/Python

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

by NAMP 2018. 5. 4.

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

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

 

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

$ pip install Flask Flask_RESTful firebase-admin

kakatalk_lunch_bot.py

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

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

# 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 메소드를 사용합니다. 채팅을 시작할 때의 화면이므로 항상 같은 값을 반환하게 됩니다.

# 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

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

# 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

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

# 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 메소드를 사용합니다.

# 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):
        # 버튼 입력을 처리합니다.

        # 사용자 입력을 처리합니다. 
        
        # 시작 메뉴로 이동합니다.        

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

# 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로 들어온 사용자 입력 데이터를 처리합니다.

# 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

댓글