먹고 기도하고 코딩하라

파이썬 장고로 카카오 i 오픈빌더 챗봇 만들기 (3) - 챗봇 자동답변 구현 본문

개발일지

파이썬 장고로 카카오 i 오픈빌더 챗봇 만들기 (3) - 챗봇 자동답변 구현

사과먹는사람 2020. 2. 25. 18:17
728x90
728x90

이전 글 보기

 

파이썬 장고로 카카오 i 오픈빌더 챗봇 만들기 (2) - 프로젝트 셋팅: Apache2 + mod-wsgi로 Django 앱 배포

이전 글 보기 파이썬 장고로 카카오 i 오픈빌더 챗봇 만들기 (1) - 가상환경 설정, Django 프로젝트와 앱 만들기 Python Django 카카오 i 오픈빌더 챗봇 만들기 튜토리얼에 오신 것을 환영합니다. 이 시��

dev-dain.tistory.com

 

 

이번 포스팅에서는 예상되는 url 요청 패턴을 등록하고 views에서 카카오톡 챗봇 스펙에 맞게 함수들을 구현해 보겠습니다.

기본 위치는 /home/ubuntu 이며 가상 환경을 활성화한 상태여야 합니다.

다음을 입력합니다.

 

$ cd [base_name]/[project_name]
$ vi urls.py

# urls.py
from django.conf.urls import url
from [app_name] import views

urlpatterns = [
  url(r'^keyboard/?$', views.keyboard),
  url(r'^message', views.message)
]

일단 app_name 에서 views 파일을 import 해줍니다. python 을 다뤄본 사람이라면 이것이 app_name 디렉토리에서 views 파일을 통으로 import 하는 것임을 알 수 있을 것입니다.

그 다음 urlpatterns 에 url 패턴을 추가해줍니다.

url 메소드는 첫 번째 매개변수로 url 패턴과 두 번째 매개변수로 그 URL 요청이 들어왔을 때 실행될 함수 이름을 추가하게 됩니다. url 메소드 첫 번째 매개변수의 생김새는 확실히 우리가 알던 것들과 다르게 생겼습니다. 정규표현식이라고 하는데 복잡하게 다루려면 얼마든지 복잡하게 다룰 수 있으므로 간단하게만 설명하겠습니다.

' ' 안에 예상되는 url 패턴을 넣을 수 있습니다. ^은 문자열의 시작이고, ?는 바로 앞의 한 글자가 있을지 없을지 모른다는 뜻입니다. $는 문자열의 마지막을 의미하는 문자인데 생략할 수 있습니다.

이것에 따르면 첫 번째 url은 'http://IP주소/keyboard/'나 'http://IP주소/keyboard' 요청이 왔을 때 views.keyboard 함수를 실행하게 됩니다. 마찬가지로 두 번째 url은 'http://IP주소/message'일 때 views.message 함수를 실행합니다.

url 맵핑을 완료했습니다. 다음을 입력합니다.

 

cd ../[app_name]
vi views.py

# views.py
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
import json

# Create your views here.
def keyboard(request):
    return JsonResponse({
        'type': 'text'
    })

 

 

일단 django.http 모듈에서 JsonResponse 를 import 합니다. 이유는 조금 이따가 message 함수가 호출되면 챗봇에서 조건에 따라 사용자에게 응답을 줘야 하는데 카카오톡 채팅봇 특성상 JSON 파일을 HTTP POST 방식으로 주고받기 때문에 JsonResponse 가 필요합니다.

그 다음 csrf_exempt 를 하는데 이것은 django 에서 CSRF 토큰을 이용해 CSRF 공격을 방지하기 때문입니다. 자세한 설명은 여기에서 확인하십시오. 쉽게 말해 보안을 위한 장치인데요. HTTP POST 에서는 csrf verification failed 하면서 해당 코드가 먹통이 됩니다. 이에 따라 @csrf_exempt 를 붙여주는데 이것은 데코레이터로 message view에만 csrf를 비활성화시켜 줍니다.

keyboard 함수를 만듭니다. 이것은 사용자가 최초로 채팅방에 들어갔을 때 보이게 되는 것입니다. 사실상 이건 쓸 일이 없어서(더구나 API형이 중지되고 i 빌더로 넘어와서는 쓸 일이 없어짐) 브라우저 테스트를 하기 좋게 간단하게 JsonResponse 를 하도록 해봤습니다.

JSON은 {}, [], key:value 로 구성되는 데이터 통신을 위한 객체임을 알아두십시오. 앞으로 JsonResponse 를 아주 많이 작성하게 될 것입니다.

여기까지 하셨다면 잠시 창을 내리고 이 블로그 탭 옆에 탭 하나를 더 엽니다. 그리고 http://IP주소/keyboard 를 입력해 보십시오. 뭐가 보이시나요?

 

 

위와 같은 응답이 나오신다면 모든 게 잘 되고 있다는 증거입니다. 만약 제대로 되지 않고 500 이나 403 이나 에러 페이지가 뜬다면 다시 돌아가서 다음을 입력해보세요.

 

$ python3 views.py

 

views 파일의 실행을 권하는 것은 이것이 기본적인 신택스 에러를 탐지하는 방법이기 때문입니다. 여기서 바로 배시 입력을 할 수 없고 에러 메시지가 뜬다면 신택스 에러가 있는 것이니 고쳐야 합니다. 여기서 에러가 없고 이전 포스팅까지 모든 게 잘 됐다면 views 파일에 문제가 있을 가능성이 아주 높으므로 뭔가 잘못 쓰지 않았는지 살펴봅니다. 특히 python 은 인덴트가 아주 중요한 언어이므로 인덴트 잘했는지 보도록 합니다(사실 이건 신택스 에러에서 잡는 부분이긴 합니다).

여기까지 됐다면 다시 views 를 열어 이번에는 message 함수를 작성해 보겠습니다.

message 함수는 사용자가 채팅창으로 텍스트나 사진 등을 입력해서 전송했을 때 그것의 값에 따라 응답하도록 하는 함수입니다. 어떻게 하냐고요? 이제 만들 겁니다. ^^

다음을 입력합니다.

 

@csrf_exempt
def message(request):
    answer = ((request.body).decode('utf-8'))
    return_json_str = json.loads(answer)
    return_str = return_json_str['userRequest']['utterance']

    if return_str == '테스트':
        return JsonResponse({
            'version': "2.0",
            'template': {
                'outputs': [{
                    'simpleText': {
                        'text': "테스트 성공입니다."
                    }
                }],
                'quickReplies': [{
                    'label': '처음으로',
                    'action': 'message',
                    'messageText': '처음으로'
                }]
            }
        })

@csrf_exempt 데코레이터를 붙이고 message 함수도 작성합니다. 

 

일단 request가 뭔지 살펴봐야겠습니다. 공식 문서를 보면 봇 시스템은 스킬 서버에 HTTP POST Request(body는 json)을 보내고 스킬 서버는 HTTP Response(body json)을 요청한 봇 시스템으로 보내 줍니다. message 에서 받는 request 가 POST Request 인 것을 알 수 있습니다. 이 request.body 를 까보면 json 형식의 payload 인데 이것을 utf-8 방식으로 디코딩해서 answer 라는 변수에 집어넣는 게 첫 줄의 의미입니다. 그리 까다롭진 않습니다.

이것을 return_json_str 이라는 변수에 대입해 줍니다. 그런 다음엔 이 json에서 ['userRequest']['utterance']만 빼내게 되는데요. 이건 뭘 의미할까요? payload 에 무엇이 있는지 살펴보면 이것은 쉽습니다.

 

 

아하! 그러니까 json 에 userRequest 라는 필드가 있고 그 안에 또 utterance 라는 필드가 있는데 이게 바로 사용자의 발화(입력)인 것입니다. 그럼 return_str 에는 사용자가 입력한 알맹이만 남게 되는 거죠. 이렇게 세 줄짜리 코드 분석을 했습니다.

 

저는 사용자가 '테스트'라고 입력했을 때 "테스트 성공입니다."라는 출력이 나오도록 봇을 꾸며보고 싶습니다. 그래서 if 문을 등장시켜 조건을 만족할 때 JsonResponse 를 return 하도록 했습니다.

스크롤을 위아래로 계속 올리기 힘들 테니 다시 한 번 적겠습니다.

 

return JsonResponse({
    'version': "2.0",
    'template': {
        'outputs': [{
            'simpleText': {
                'text': "테스트 성공입니다."
            }
        }],
        'quickReplies': [{
            'label': '처음으로',
            'action': 'message',
            'messageText': '처음으로'
        }]
    }
})

 

인덴트에 주목해 주십시오. 일단 version 과 template 은 가장 외곽에 있고, outputs과 quickReplies가 template 안에 들어가 있습니다. 하나씩 설명하겠습니다. 더 자세한 설명을 보고 싶다면 공식 문서를 확인하시기 바랍니다.

  • version: 스킬 응답의 version 입니다. major.minor 로 구성되어 2.0, 2.1, 3.0 식으로 되어 있습니다.

  • template: 스킬 응답의 출력을 담습니다. outputs 는 필수이며 quickReplies 는 생략이 가능합니다.

    • outputs: template 안의 필수 요소인 출력 그룹입니다. simpleText, simpleImage, basicCard 등의 요소를 포함하며 하나 이상을 골라 쓸 수 있습니다.

      • simpleText: outputs 의 한 요소인 간단한 텍스트형 출력입니다. text 를 필드로 갖습니다.

    • quickReplies: template 안의 요소인 바로가기 그룹입니다. 기존 API 형에서의 버튼과 비슷한 역할을 하며 사용자의 특정 발화 이후 기대되는 발화에 대한 힌트를 줄 수 있습니다.

      • label: 사용자에게 보이는 버튼의 텍스트입니다.

      • action: 바로가기 응답의 기능입니다. message 이거나 block 입니다.

      • messageText: action 이 message 일 때 해당 버튼을 누르게 되면 messageText 의 value 값이 사용자의 다음 발화가 됩니다. 

quickReplies 를 제외한 JsonReponse 의 가장 간단한 구성은 version 과 template, 그리고 template 안의 outputs 입니다.

위 코드는 스킬 응답 버전은 2.0, 출력은 텍스트로 "테스트 성공입니다."가 챗봇의 발화가 되며 '처음으로'라는 버튼이 올라옵니다. 그리고 이 버튼을 누르게 되면 사용자가 '처음으로'라고 말하는 것과 똑같은 효과를 나타냅니다.

 

자, 그렇다면 이제 어떻게 카카오톡 챗봇에 적용할 수 있을까요? 이건 다음 포스팅에서 다뤄보도록 하겠습니다. 다음 포스팅에서는 카카오 i 오픈빌더의 기본인 시나리오, 블록, 스킬 서버 적용, 배포 등에 대해서 간단히 알아보고 적용하며 시리즈를 마치도록 하겠습니다.

고맙습니다. ^^

 

 

다음 글 보기

 

파이썬 장고로 카카오 i 오픈빌더 챗봇 만들기 (4) - 카카오 오픈빌더와 챗봇 서버 연동하기

이 포스팅에서는 전에 설정 다 해둔 챗봇 서버와 카카오톡 채널을 연동하는 방법을 다뤄보겠습니다. 여기서 카카오 i 오픈빌더 로그인을 하십시오. 기본적으로 이미 OBT 승인을 받았다는 가정 하

dev-dain.tistory.com

 

 

Reference

Django CSRF 공격

카카오 i 오픈빌더 도움말

 

 

728x90
반응형
Comments