일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 4주 기초 군사 훈련
- 프리센스 커넥트
- 카카오톡 챗봇
- 메이들리
- 익스플로전
- 캬루
- 카카오 아이 오픈 빌더
- 폭렬 마법
- 이종족 리뷰어즈
- 그림
- 홀로라이브
- 케이짱
- 여고생쟝
- 훈련소
- 산업기능요원
- Kakao i open builder
- 던만추
- 명일방주
- Custom domain
- 핼로윈
- 블루아카이브
- 아미야
- 니논
- 헤스티아
- 흥국마망
- 일러스트
- 프리코네
- 네없찐
- 소녀전선
- 그림 그리기
- Today
- Total
모에모에 코딩
카카오톡 아이 오픈 빌더를 이용한 번역 봇 제작기 본문
본 게시물은 Kakao i open builder 를 이용하여 언어 번역 채팅 봇을 제작 하는 과정을 일기 형태로 작성하였습니다.
시작하기 앞서 불평불만
Kakao i open builder의 OBT 시작은 기존 스마트 API 형 채팅봇에게 시한부 선고를 내리는 말과 같았습니다. 지금 이 글을 작성하고 있는 필자도 OBT 이전부터 서비스를 이미 해왔고, 유지보수에만 신경쓰고 있었습니다.
당시 운영했던 서비스 Github 링크 https://github.com/stories2/KangnamShuttle
하지만 위와 같이 카카오톡 챗봇에 중대 업데이트가 올라 왔고, 2019년 말 까지 새로운 형태의 카카오톡 챗봇 서비스를 도입하지 않으면 서비스 중단이라는 공지까지 하면서 어쩔 수 없이 추가 개발을 해야 되는 상황이 되었습니다. 그래도 기존 API 형태랑 많이 다르지 않을 것이라 기대 했던 부분은 새로운 API 스펙을 보자 물거품이 되어버렸고, 다시 처음부터 프로젝트를 새로 만들는게 더 이득이라 생각될 정도였습니다.
다행이도 지금은 어느정도 지지고 볶은 덕분에 현재는 어느정도 서비스를 복구 할 수 있었습니다.
https://github.com/stories2/KangnamShuttle-3.0
번역 채팅 봇 제작기
들어가기 앞서
사용할 서비스 / 기술
완성된 모습 미리보기
하단에 표시된 번역을 부탁해~! 버튼을 제네릭 메뉴라고 합니다. 제네릭 메뉴를 누르면 유저에게 어떤 언어로 번역을 할 것 인지 선택할 수 있는 퀵 메뉴를 제공할 것입니다.
또한 퀵 메뉴 (한국어, 영어, 일본어) 를 눌렀을 시 해당 언어로 번역을 시작한다는 문구를 보여주며, 이 문구 이후 부터 사용자가 입력하는 내용을 번역해줍니다.
번역을 마치고 싶을 땐 2가지 방법이 주어지는데 퀵 메뉴 (홈) 을 누르거나 제네릭 메뉴 (번역을 부탁해~!) 를 누를 시 초기 메뉴인 번역 될 언어 선택 상태로 돌아오게끔 합니다.
위 기능이 전부입니다.
TODO
할일 |
내용 |
비고 |
Kakao plus 프로필 만들기 |
사용자가 카카오에서 채팅을 할 프로필 생성 |
|
Kakao i open builder 프로필 만들기 |
챗봇을 만들기 위한 프로필 생성 |
|
Firebase 프로젝트 만들기 |
챗봇 어플리케이션을 호스팅할 프로젝트 생성 |
|
언어 선택 스킬 응답 만들기 |
사용자가 번역할 언어 선택지를 스킬을 이용해 생성 |
|
언어 번역 스킬 응답 만들기 |
Google API를 이용하여 사용자가 입력한 내용 번역 |
|
언어 번역 시나리오 및 블럭 연동 |
스킬과 블럭을 연동시켜 서비스 구현 |
|
베포 및 테스트 |
사용자에게 직접 서비스 |
|
개발 시작!
본격적으로 개발을 시작하여 봅니다.
Kakao plus 프로필 만들기
시작하기 버튼을 눌러 프로필 관리 화면으로 이동할 수 있습니다.
새 플러스 친구 만들기 버튼을 눌러 새 프로필을 만들게 됩니다.
필수 추가요소 및 프로필 정보를 입력한 후 확인을 누르면 플러스 친구 프로필이 만들어 집니다.
왼쪽 메뉴에서 관리 -> 상세설정 -> 플러스친구 홈
에서 홈 공개, 검색 허용을 토글하면 카카오 검색시 프로필이 노출될지를 정할 수 있습니다.
Kakao i open builder 프로필 만들기
Kakao i open builder 에서 프로필을 만들기 위해 https://i.kakao.com/openbuilder 로 이동합니다.
프로필 이름까지 정하면 위와 같은 화면이 보여지게 됩니다.
간단한 설정이 필요합니다. 위에서 만들었던 카카오 Plus 프로필과 방금 만든 Kakao i open builder 프로파일을 서로 연결시켜주어야 합니다.
설정 탭 -> 플러스친구 계정 연결에서 플러스 친구 계정 드롭다운을 눌러 우리가 만들었던 카카오 Plus 프로필을 선택한 후 우측 상단의 저장 버튼을 꼭! 눌러줍니다.
저장완료 후 다시 카카오 Plus 프로필로 돌아가보겠습니다.
카카오 Plus 친구 -> 스마트 채팅 -> 챗봇 매뉴에 들어가면 상단에
챗봇
kakaobot ~~~과 연동됨 이라는 상태 표시 문구가 작성되어있습니다. 이때 연동 되었다는 문구가 보인다면 카카오Plus 프로필과 kakao i open builder 프로젝트가 서로 연결이 된 것입니다.
Firebase 프로젝트 만들기
프로젝트 이름을 입력하면 자동으로 프로젝트 ID가 작성되며 위치 설정시 서비스할 대상이 위치한 가장 가까운 지역을 선택합니다.
위치 리스트는 https://firebase.google.com/docs/functions/locations?hl=ko 에서 확인할 수 있습니다.
이후 동의, 프로젝트 만들기를 눌러주면 됩니다.
Firebase에서는 많은 서비스를 제공하는데 이번에 사용할 서비스는 다음과 같습니다.
- Realtime database
- Cloud functions
- Hosting (option)
각각의 서비스의 시작 튜토리얼은 Firebase 에서 제공하고 있으므로 생략하겠습니다.
또한 외부 네트워크 연결이 필요하므로 Firebase 가격정책상 https://firebase.google.com/pricing/?hl=ko 종량제를 사용해야 합니다.
스킬응답을 위해 미리 개발한 프로젝트를 이용하도록 하겠습니다.
https://github.com/stories2/Kakao-Translate/tree/6df33334a13eae1e91ab91baf4a3cf4eb6abab2f 여기에서 프로젝트를 다운받을 수 있습니다.
해당 프로젝트는 아직 번역 기능이 추가되지 않은 프로젝트입니다.
스킬 개발 전 Kakao i open builder 응답 처리 형태
Kakao i open builder 에서는 이미 자세한 튜토리얼을 제공하고 있습니다. https://i.kakao.com/docs/getting-started-overview#%EC%98%A4%ED%94%88%EB%B9%8C%EB%8D%94-%EC%86%8C%EA%B0%9C
모든 내용을 이해하면 좋지만 쉽게 보면
- 시나리오에서 블럭을 만들었을 때 하나의 블럭에는 크게 발화와 응답으로 나누어집니다.
- 발화는 사용자가 카톡을 날리는 행위
- 응답은 그 행위에 장단맞춰주기
라고 보면 될것 같습니다.
응답에서 더 자세히 보자면
- 파라미터는 스킬 실행
- 응답 형태는 텍스트, 이미지, 컴포넌트, 스킬응답
으로 구성되어있습니다.
스킬 개발 전 프로젝트 구조
사용자가 발화를 만들어내면 블럭에 따라 처리를 하며, 이때 스킬이 해당 유저의 상태를 저장을 합니다.
그 상태를 확인 하면서 다음 발화를 만들어 낼 시 이전 상태값을 참고하여 그 결과를 스킬로 만들어 응답하면 동적으로 응답을 구현 할 수 있게됩니다.
언어 선택 스킬 응답 만들기
{
"actions": {
"1": {
"nextAction": [ "1000", "2000", "3000" ],
"quickReplies": [
{
"action": "message",
"label": "🇰🇷한국어",
"messageText": "한국어로 번역을 시작해줘"
},
{
"action": "message",
"label": "🇺🇸영어",
"messageText": "영어로 번역을 시작해줘"
},
{
"action": "message",
"label": "🇯🇵일본어",
"messageText": "일본어로 번역을 시작해줘"
}
],
"response": [
{
"simpleText": {
"text": "새로운 번역은 언제나 환영이야!"
}
}
]
}
}
}
Firebase Realtime database 에 다음의 내용을 작성하면 언어 선택 스킬응답은 완료입니다.
위 내용을 해석하자면 다음과 같습니다.
- actions: 여러 스킬 응답 탬플릿 액션들을 가지는 object 입니다.
- 1: 임의로 정의한 action의 고유 번호입니다. 본 과정에선 언어 선택 부분의 스킬응답 고유 번호가 1이 됩니다.
- nextAction: 퀵 응답을 눌렀을 시 이동할 다음 action의 고유 번호 리스트입니다.
- quickReplies: 퀵 응답의 object 리스트입니다.
- response: 스킬 응답 템플릿 object 리스트입니다.
언어 번역 스킬 응답 만들기
{
"actions" : {
"1" : {
"nextAction" : [ "1000", "2000", "3000"],
"quickReplies" : [ {
"action" : "message",
"label" : "🇰🇷한국어",
"messageText" : "한국어로 번역을 시작해줘"
}, {
"action" : "message",
"label" : "🇺🇸영어",
"messageText" : "영어로 번역을 시작해줘"
}, {
"action" : "message",
"label" : "🇯🇵일본어",
"messageText" : "일본어로 번역을 시작해줘"
} ],
"response" : [ {
"simpleText" : {
"text" : "새로운 번역은 언제나 환영이야!"
}
} ]
},
"1000" : {
"lang" : "ko",
"nextAction" : [ "1" ],
"quickReplies" : [ {
"action" : "message",
"label" : "🏠홈",
"messageText" : "다시 메인으로 돌아가줘 "
} ],
"response" : [ {
"simpleText" : {
"text" : "%s"
}
}, "다시 홈으로 돌아가욧!" ]
},
"2000" : {
"lang" : "en",
"nextAction" : [ "1" ],
"quickReplies" : [ {
"action" : "message",
"label" : "🏠홈",
"messageText" : "다시 메인으로 돌아가줘 "
} ],
"response" : [ {
"simpleText" : {
"text" : "%s"
}
}, "다시 홈으로 돌아가욧!" ]
},
"3000" : {
"lang" : "ja",
"nextAction" : [ "1" ],
"quickReplies" : [ {
"action" : "message",
"label" : "🏠홈",
"messageText" : "다시 메인으로 돌아가줘 "
} ],
"response" : [ {
"simpleText" : {
"text" : "%s"
}
}, "다시 홈으로 돌아가욧!" ]
}
}
위 내용을 Firebase realtime database에 덮어 씌워주세요.
이번에는 새로운 action object 와 해당 action object 에 lang 키가 추가되었습니다.
사용자가 영어 번역을 요청했을 시 해당 사용자의 상태값은 2000이 되어있을 것이며 이때 모든 발화를 번역할 타겟 언어는 lang 에 정의된 en 이다 라는 것을 구현하기 위함입니다.
본격적인 번역을 시작하겠습니다. 다운받은 소스의 functions 폴더에서
npm i -save @vitalets/google-translate-api
를 작성하여 구글 번역 api npm 모듈을 설치합니다.
functions/Action/translateAction.js 에 다음 소스를 작성합니다.
exports.translateStringToOtherLang = function (request, response, callbackFunc) {
const action = JSON.parse(JSON.stringify(request.action))
const reqText = request.body["userRequest"]["utterance"]
const translate = require('@vitalets/google-translate-api')
global.log.debug("translateAction", "translateStringToOtherLang", "user data: " + JSON.stringify(request.user) + " action data: " + JSON.stringify(action))
global.log.debug("translateAction", "translateStringToOtherLang", "req text: " + reqText)
var makeResponseTemplate = function(responseText) {
const responseManager = request.responseManager
const util = require('util')
var actionText = action["response"][global.define.DEFAULT_RESPONSE_TYPE_ZERO]["simpleText"]["text"]
actionText = util.format(actionText, responseText)
action["response"][global.define.DEFAULT_RESPONSE_TYPE_ZERO]["simpleText"]["text"] = actionText
responseManager.pushTemplate(action["response"][global.define.DEFAULT_RESPONSE_TYPE_ZERO])
for(var index in action["quickReplies"]) {
responseManager.pushQuickReply(action["quickReplies"][index])
}
}
translate(reqText, {to: action.lang})
.then(result => {
global.log.debug("translateAction", "translateStringToOtherLang", "translate result: " + JSON.stringify(result))
makeResponseTemplate(result["text"])
callbackFunc()
})
.catch(error => {
global.log.error("translateAction", "translateStringToOtherLang", "cannot translate: " + JSON.stringify(error))
makeResponseTemplate("이런, 번역 요정이 장난을 쳐버렸군요.")
callbackFunc()
})
}
request 로 부터 사용자 상태에 따른 현재 응답할 action 템플릿이 포함되서 들어오며, 사용자의 발화 내용은 reqest.body["userRequest"]["utterance"] 에 있습니다. 이후로는 action 템플릿에 사용자 발화 내용을 번역한 결과를 쓰고, 응답 관리자(responseManager)에게 템플릿을 전달한 다음 callbackFunc 을 호출함으로써 action 처리를 마무리 짓고 있습니다.
functions/Core/actionManager.js 에 다음 소스를 다음과 같이 수정합니다.
exports.executeOrder = function (request, response, actionIndex, callbackFunc) {
const basicAction = require('../Action/basicAction')
const translateAction = require('../Action/translateAction')
const actionTable = {
"1": basicAction.hello,
"1000": translateAction.translateStringToOtherLang,
"2000": translateAction.translateStringToOtherLang,
"3000": translateAction.translateStringToOtherLang,
}
global.log.debug("actionManager", "executeOrder", "execute action #" + actionIndex)
actionTable[actionIndex](request, response, callbackFunc) // <-- pass request, response, callbackFunc(flush response data)
}
여기서는 action 번호와 그 action 을 실행할 메소드를 매칭하는 작업을 합니다. 번역 action의 번호를 1000, 2000, 3000 으로 DB에 정의 했었기 때문에 1000, 2000, 3000 을 작성한 후 그 값을 번역 매소드인 translateAction.translateStringToOtherLang 으로 설정합니다.
이로써 스크립트 작업이 모두 끝났습니다.
스킬으로 사용하기 위해 firebase functions 에 배포를 합니다. 배포 한 후 자동으로 endpoint 가 생성됩니다.
언어 번역 시나리오 및 블럭 연동
스킬은 다음과 같이 작성하면 됩니다.
url 은 action/ 스킬 번호를 쓰면 됩니다.
1: 번역 선택
1000: 한국어 번역
2000: 영어 번역
3000: 일본어 번역
continue 스킬은
/v3KakaoApi/continue
형식으로 작성하면 됩니다.
그럼 다음과 갈은 스킬들이 생성됩니다.
폴백블럭 설정
초기화 후 continue 스킬과 밑에 스킬데이터 사용을 허용합니다.
사용자가 선택한 언어로 모든 발화가 번역되는 부분입니다.
번역/환영 블럭 설정
번역할 언어 선택 부분입니다.
환영 스킬을 적용 후 스킬데이터를 응답으로 설정합니다.
번역 블럭(영어) 설정
번역 스킬을 적용 후 응답은 번역 시작한다는 문구를 작성합니다.
이 경우 스킬과 응답이 동시에 실행되어 사용자 상태는 영어 번역 모드로, 카카오톡 화면에서는 번역 시작하겠다는 피드백 문구가 보여지게 됩니다.
베포 및 테스트
'개발 일기 > 카카오톡 챗봇' 카테고리의 다른 글
강남대학교 달구지봇 개발기 (0) | 2019.02.15 |
---|