Chatterbox는 카카오톡 플러스친구 자동응답 API를 활용하여 챗봇을 만들 때 사용되는 파이썬 라이브러리입니다.
Table of Contents
$ pip install chatterbox.py
더 다양한 예제는 examples를 참고해주세요.
from flask import Flask, request, jsonify
from chatterbox import Chatter
from chatterbox.response import Text, Keyboard, MessageButton
app = Flask(__name__)
chatter = Chatter()
@chatter.base(name='홈')
def home_keyboard():
home_buttons = ['자기소개', '사이트로 이동하기']
return Keyboard(home_buttons)
@chatter.rule(action='자기소개', src='홈', dest='홈')
def intro(data):
message = 'chatterbox를 통해 더 쉽게 카카오톡 봇을 만들 수 있습니다!'
return Text(message) + chatter.home()
@chatter.rule(action='사이트로 이동하기', src='홈', dest='홈')
def web(data):
text = Text('자세한 정보를 보고싶으면 사이트로 이동해주세요!')
msg_button = MessageButton(label='이동하기',
url='https://github.com/jungwinter/chatterbox')
keyboard = chatter.home()
return text + msg_button + keyboard
@app.route('/keyboard', methods=['GET'])
def keyboard():
return jsonify(chatter.home())
@app.route('/message', methods=['POST'])
def message():
return jsonify(chatter.route(request.json))
if __name__ == '__main__':
app.run(debug=True)
FSM(finite-state machine)을 사용해 유저들의 state를 내부에 저장하고, 요청에 맞는 response를 반환합니다.
카카오톡 자동응답 api 명세에 맞는 json 데이터를 인자로 받습니다. user_key
로 가져온 state와 content
값을 action으로 적절한 rule을 찾아 등록된 함수를 실행한 후 api 명세에 맞는 response를 반환합니다. rule에 관해선 아래에 서술되어 있습니다.
@app.route('/message', methods=['POST'])
def message():
response = chatter.route(request.json)
return jsonify(response)
input 데이터로 다음과 같은 형식의 dict 객체를 인자로 받습니다.
{
"user_key": "encryptedUserKey",
"type": "text",
"content": "자기소개"
}
output 데이터로 다음과 같은 형식의 Response 객체(dict로 동작함)를 반환합니다.
{
"message": {
"text": "안녕하세요! 무엇을 도와드릴까요?"
},
"keyboard": {
"buttons": [
"오늘의 날씨",
"취소"
],
"type": "buttons"
}
}
chatterbox.response
에서 카카오톡 response object 명세를 만족하는 클래스를 가져올 수 있습니다.
다음과 같은 dict like 객체를 반환합니다. 멤버 변수로 text
, message
를 갖습니다.
Text(text='안녕!')
{
"message": {
"text": "안녕!"
}
}
다음과 같은 dict like 객체를 반환합니다. 멤버 변수로 url
, width
, height
, message
를 갖습니다.
Photo(url='https://image/url.png',
width=500,
height=400)
{
"message": {
"photo": {
"url": "https://image/url.png",
"width": 500,
"height": 400
}
}
}
다음과 같은 dict like 객체를 반환합니다. 멤버 변수로 label
, url
, message
를 갖습니다.
MessageButton(label='이동하기',
url='https://github.com/jungwinter/chatterbox')
{
"message": {
"message_button": {
"label": "이동하기",
"url": "https://github.com/jungwinter/chatterbox"
}
}
}
자세한 명세는 Keyboard object 문서에서 확인할 수 있습니다. 멤버 변수로 type
, buttons
, keyboard
를 갖습니다.
Keyboard(type='text')
{
"keyboard": {
"type": "text"
}
}
Keyboard(['버튼1', '버튼2']) # type='buttons'는 생략할 수 있음
{
"keyboard": {
"buttons": [
"버튼1",
"버튼2"
],
"type": "buttons"
}
}
def intro():
text = Text('안녕!')
photo = Photo('https://image/url.png', 500, 400)
keyboard = Keyboard(['날씨', '시간'])
return text + photo + keyboard
위 코드는 아래와 같은 dict 객체를 반환합니다.
{
"message": {
"text": "안녕!",
"photo": {
"url": "https://image/url.png",
"width": 500,
"height": 400
}
},
"keyboard": {
"buttons": [
"날씨",
"시간"
],
"type": "buttons"
}
}
Response
├── Message
│ ├── Text
│ ├── Photo
│ └── MessageButton
└── Keyboard
├── ButtonType
└── TextType
Message + Message = Message
Message + Keyboard = Response
Response + Message = Response
name
으로 유저가 시작할 state 이름을 지정할 수 있습니다.
func
은 인자가 없어야하며Keyboard
를 반환해야합니다.
def func():
return Keyboard(['버튼1', '버튼2'])
chatter.add_base(name='홈', func=func)
Chatter.add_base()
의 wrapper입니다. 데코레이터로 사용할 수 있습니다.
@chatter.base(name='홈')
def func():
return Keyboard(['버튼1', '버튼2'])
Chatter.add_base()
를 통해 등록된 함수 func
을 실행해 Keyboard
를 반환합니다.
>>> chatter.home()
{
"keyboard": {
"buttons": [
"버튼1",
"버튼2"
],
"type": "buttons"
}
}
유저의 현재 state가 src
이고 input으로 받은 데이터에서 content가 action
일 때, func
함수를 실행하고 유저의 state를 dest
로 변경합니다. state를 활용하여 1 depth 이상의 자동응답 시나리오를 구성할 수 있습니다.
func
함수는 반드시data
를 인자로 받아야하며Response
를 반환해야합니다.
def intro(data):
message = 'chatterbox를 통해 더 쉽게 카카오톡 봇을 만들 수 있습니다!'
return Text(message) + chatter.home()
chatter.add_rule(action='자기소개', src='홈', dest='홈', func=intro)
Chatter.add_rule()
의 wrapper입니다. 데코레이터로 사용할 수 있습니다.
@chatter.rule(action='자기소개', src='홈', dest='홈')
def intro(data):
message = 'chatterbox를 통해 더 쉽게 카카오톡 봇을 만들 수 있습니다!'
return Text(message) + chatter.home()
Keyboard(type='text')
를 반환해 유저의 주관식 답변을 받는 경우 action='*'
을 사용해 처리할 수 있습니다. 자세한 방법은 examples/flask_advance.py를 참고해주세요.
src='*'
를 사용해 유저가 어떤 state에 있더라도 특정 dest로 이동시킬 수 있습니다.
@chatter.rule(action='취소', src='*', dest='홈')
def cancel(data):
message = '취소하셨습니다.'
return Text(message) + chatter.home()
CONTRIBUTING.md을 참고해주세요.