카카오 오픈빌더 사용하기
학식을 알려주는 카카오톡 봇을 만들기 위해 필요한 것만 간단히 알아보자.
먼저 봇 제네릭 메뉴를 설정해 보자. 봇 제네릭 메뉴는 채팅창 하단에 고정되어 있는 버튼이다. 이것을 활성화 시키고, 식당을 선택하는 곳에 써 보자.
왼쪽 상단에 있는 시나리오 설정을 클릭하면, 봇 제네릭 메뉴가 뜬다. 봇 제네릭 메뉴는 채팅 입력 칸 상단에 고정적으로 떠 있는 버튼이다. 봇 제네릭 메뉴 목록을 원하는 대로 추가하면 채팅방에 하단 고정이 되어 계속 뜬다.
다음으로는 시나리오를 추가해야 한다. 챗봇을 위해 하는 이 작업은 사용자가 말한 내용을 기반으로 어떠한 정보를 출력해야 하는지 입력받는 것이다. 사용자 발화를 인식하게 하기 위해서는, 시나리오에 사용자 발화를 적어야 한다. 각 상황이 될 발화를 적어 두자.
스킬
챗봇에서 가장 핵심이 되는 기능인 스킬이다. 스킬은 외부 서비스와 연결하게 해주는 매우 유용한 도구이다.
스킬의 이름과 설명을 원하는 대로 적어 주자.
URL 칸에는 본인이 설정한 스킬 서버의 주소를 적어 주자. 나는 본인 아이피주소:포트번호/message 로 저장해 두었습니다. /message 가 들어간 이유는 스킬 서버의 코드와 관련이 있습니다.
여기서 스킬을 테스트 할 수 있습니다.
우측의 '요청할 파라미터 값 입력' 항목은 사용자가 발화하거나 특정 값을 보낼 수 있다. 좌측의 'JSON' 항목은 스킬 서버로 전송되는 실제 json 이다. 카카오톡 봇과 스킬 서버가 서로 통신을 할 때에는 json 파일을 주고 받는다. Flask를 실행할 때에 서버 메소드를 POST로 설정하는 이유이다. 위에 있는 json 파일은 카카오톡 봇에서 스킬 서버로 전송할 때 보내는 json 양식이다. 자세한 정보는 카카오톡 스킬 가이드에 들어가면 json 양식을 알 수 있다.
발화 (utterance) 에 시나리오에 적었던 문구를 넣고 (또는 key : uttreance , Value : 문구) 스킬서버로 전송을 하면, 정해진 양식의 json 파일이 수신된다. 수신된 json 파일은 스킬 서버에서 직접 코딩해야 한다. 이 양식도 마찬가지로, 스킬 제작 가이드에 나와 있다.
이 정보를 기반으로 파이썬을 이용해 코딩을 해 보았다. 여기 코딩에서는 웹 크롤러 기능을 추가했다. 핵심이 되는 부분은 카카오톡 서버랑 통신하는 구현부이기 때문에, 크롤러 기능은 따로 공부를 해야 한다.
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
|
from flask import Flask,request,jsonify
import bs4
import urllib.request
import time
import os
import sys
app = Flask(__name__)
#식당성정->날짜설정->아침점심저녁 설정->처음으로
Restaurant=["학생식당","푸름관","오름1동","오름3동","교직원 식당"]
ChoiceUrl=""
ChoiceDay=0
ChoiceRes=0
urlStudent="http://www.kumoh.ac.kr/ko/restaurant01.do"
urlProfess="http://www.kumoh.ac.kr/ko/restaurant02.do"
urlPorum="http://dorm.kumoh.ac.kr/dorm/restaurant_menu01.do"
urlorum1="http://dorm.kumoh.ac.kr/dorm/restaurant_menu02.do"
urlorum3="http://dorm.kumoh.ac.kr/dorm/restaurant_menu03.do"
'''
월요일~일요일 중식 : 0~6
월요일~일요일 석식 : 7~13
@@@ 예외적으로 오름 1동은 중식->조식 @@@
'''
jsonChoiceDay = {
"version": "2.0",
"template": {"outputs": [{"simpleText": {"text": "날짜를 선택해 주세요"}}],
"quickReplies": [{"label": "오늘", "action": "message", "messageText": "오늘"},
{"label": "월", "action": "message", "messageText": "월"},
{"label": "화", "action": "message", "messageText": "화"},
{"label": "수", "action": "message", "messageText": "수"},
{"label": "목", "action": "message", "messageText": "목"},
{"label": "금", "action": "message", "messageText": "금"},
{"label": "토", "action": "message", "messageText": "토"},
{"label": "일", "action": "message", "messageText": "일"}
]
}
}
jsonChoiceRes = {
"version": "2.0",
"template": {"outputs": [{"simpleText": {"text": "식당을 선택해 주세요"}}],
"quickReplies": [{"label": "학생식당", "action": "message", "messageText": "학생식당"},
{"label": "푸름관", "action": "message", "messageText": "푸름관"},
{"label": "오름1동", "action": "message", "messageText": "오름1동"},
{"label": "오름3동", "action": "message", "messageText": "오름3동"},
{"label": "교직원", "action": "message", "messageText": "교직원"},
]
}
}
jsonChoiceTime = {
"version": "2.0",
"template": {"outputs": [{"simpleText": {"text": "시간을 선택해 주세요"}}],
"quickReplies": [{"label": "아침", "action": "message", "messageText": "아침"},
{"label": "점심", "action": "message", "messageText": "점심"},
{"label": "저녁", "action": "message", "messageText": "저녁"},
]
}
}
def returnMenu(url,num): #식단을 보여줄수 있게 하는 함수 (링크,식단종류)
html = bs4.BeautifulSoup(urllib.request.urlopen(url), "html.parser")
menus=html.find("td")
menu=str(menus.text) #bs4 자료형을 String 형태로 변환, 식단의 존재 유무 판별
if(menu=="등록된 메뉴가 없습니다."): #식단이 없을경우
return menu
else: #식단이 있을경우
html = bs4.BeautifulSoup(urllib.request.urlopen(url), "html.parser")
menu = html.findAll("ul", {"class": "s-dot"})
return menu[num].text.strip()
def returnAvaliableTimeDormitory(url): #기숙사 식당 이용 시간을 리턴하는 함수
html = bs4.BeautifulSoup(urllib.request.urlopen(url), "html.parser")
Time=html.findAll("div",{"class":"contents-area"})
return Time[3].text + Time[4].text
def returnAvaliableTime(url): #전체식당 이용 시간을 리턴하는 함수
html = bs4.BeautifulSoup(urllib.request.urlopen(url), "html.parser")
Time=html.findAll("ul",{"class":"ul-h-list01"})
return Time[1].text
@app.route('/message', methods=['POST']) #json으로 들어온 사용자 요청을 보고 판단
def bob():
content = request.get_json() #사용자가 보낸 메세지 입력
content = content['userRequest']
content = content['utterance']
global ChoiceUrl
global ChoiceDay
global ChoiceRes
global jsonChoiceDay
global jsonChoiceRes
global jsonChoiceTime
if content==u"학생식당":
response_data=jsonChoiceDay
ChoiceUrl=urlStudent
ChoiceRes=0
elif content==u"푸름관":
response_data=jsonChoiceDay
ChoiceUrl=urlPorum
ChoiceRes = 1
elif content==u"오름1동":
response_data=jsonChoiceDay
ChoiceUrl=urlorum1
ChoiceRes = 2
elif content == u"오름3동":
response_data=jsonChoiceDay
ChoiceUrl=urlorum3
ChoiceRes = 3
elif content==u"교직원":
response_data=jsonChoiceDay
ChoiceUrl=urlProfess
ChoiceRes = 4
elif content==u"오늘":
response_data=jsonChoiceTime
ChoiceDay = time.localtime().tm_wday
elif content==u"월":
response_data=jsonChoiceTime
ChoiceDay = 0
elif content==u"화":
response_data = jsonChoiceTime
ChoiceDay = 1
elif content==u"수":
response_data = jsonChoiceTime
ChoiceDay = 2
elif content==u"목":
response_data = jsonChoiceTime
ChoiceDay = 3
elif content==u"금":
response_data = jsonChoiceTime
ChoiceDay = 4
elif content==u"토":
response_data = jsonChoiceTime
ChoiceDay = 5
elif content==u"일":
response_data = jsonChoiceTime
ChoiceDay = 6
elif content==u"아침":
if(ChoiceUrl==urlorum1): #오름1동 아침일경우 정상 출력
response_data={
"version": "2.0",
"template": {
"outputs": [{"simpleText": {"text": returnMenu(ChoiceUrl,ChoiceDay)}}],
"quickReplies": [{"label": "처음으로", "action": "message", "messageText": "처음으로"},
]
}
}
else: #오름1동 아침이 아닐경우 경고 메시지 출력
response_data = {
"version": "2.0",
"template": {
"outputs": [{"simpleText": {"text": Restaurant[ChoiceRes]+"은 아침이 없습니다. 다시 선택해 주세요."}}],
"quickReplies": [{"label": "아침", "action": "message", "messageText": "아침"},
{"label": "점심", "action": "message", "messageText": "점심"},
{"label": "저녁", "action": "message", "messageText": "저녁"}, ]}
}
elif content == u"점심":
if (ChoiceUrl != urlorum1): #오름1동 점심이 아닐경우 정상출력
response_data = {
"version": "2.0",
"template": {
"outputs": [{"simpleText": {"text": returnMenu(ChoiceUrl, ChoiceDay)}}],
"quickReplies": [{"label": "처음으로", "action": "message", "messageText": "처음으로"},
]
}
}
else: #오름1동 점심일경우 경고 메시지 출력
response_data = {
"version": "2.0",
"template": {
"outputs": [{"simpleText": {"text": Restaurant[ChoiceRes] + "은 아침이 없습니다. 다시 선택해 주세요."}}],
"quickReplies": [{"label": "아침", "action": "message", "messageText": "아침"},
{"label": "점심", "action": "message", "messageText": "점심"},
{"label": "저녁", "action": "message", "messageText": "저녁"}, ]}
}
elif content==u"저녁":
response_data={
"version": "2.0",
"template": {
"outputs": [{"simpleText": {"text": returnMenu(ChoiceUrl,ChoiceDay)}}],
"quickReplies": [{"label": "처음으로", "action": "message", "messageText": "처음으로"},]}
}
elif content==u"처음으로":
response_data=jsonChoiceRes
else :
response_data = jsonChoiceRes
return jsonify(response_data)
if __name__=="__main__":
app.run(host="0.0.0.0", port=5000)
|
cs |
결과값을 표시할 때 simpleText 와 quickReplies 를 이용했다. quickReplies를 이용한 이유는 사용자가 직접 타이핑을 하지 않고 버튼의 클릭으로 정보를 보고, 간단히 정보를 알 수 있어서 선택했다. 주변의 사용자들의 의견도 대화형 응답보다는 버튼을 이용한 대화다 편하다고 했다. 이것 외에 다른 출력 형태는 마찬가지로 카카오톡 스킬 가이드에 가면 여러가지 형태의 출력값을 알 수 있다.
96번째 줄에 @app.route('/message', methods=['POST']) 라는 코드가 있다. 스킬 서버에서 /message 로 json 파일을 보내기 때문에, 수신부인 스킬 코드에서도 /message 로 받아야 한다.
배포
최종적으로 배포를 해야지, 스킬을 적용한 봇이 배포가 된다.
이렇게 간단히 챗봇을 만들어 보았다. 카카오 공식 예제에서는 파이썬이 아닌 자바스크립트를 이용하여 만들어서 초반에는 어려움이 있었으나, 며칠 공부하고 나니 쉽게 만들어 보였다. 컴퓨터공학 비전공자도 간단히 만들 수 있었고, 조금만 더 노력해서 머신러닝을 이용한 실제 챗봇 개발고 가능할 것 같았다.
마지막으로 참고한 사이트와 학식봇 만들기 과정 올리며 포스팅 마칠까 한다.
참고한 사이트
https://has3ong.tistory.com/301?category=831354
https://vmpo.tistory.com/95?category=733430
학식봇 만들기 시리즈
https://tre2man.tistory.com/157
https://tre2man.tistory.com/158
https://tre2man.tistory.com/159
'메이킹 > 메이킹 프로젝트' 카테고리의 다른 글
아두이노 프로를 사용한 스탠드 작동부 제작 (0) | 2020.04.21 |
---|---|
원격 컨트롤 및 알람 기능이 있는 스위치 제작 - 1 (0) | 2020.04.07 |
서보모터를 이용한 간단한 로봇 팔 제작기 (0) | 2020.03.04 |
카카오톡 학식봇 만들기 - 1 (2) | 2020.02.21 |
라즈베리파이 보일러 제어기 제작 (0) | 2019.12.24 |