Dialogflow - 3. Fulfillment
Dialogflow 웹앱 시리즈입니다.
- Dialogflow - 1. Intent
- Dialogflow - 2. Context
- Dialogflow - 3. Fulfillment
- Dialogflow - 4. 외부 사이트 연동
- Dialogflow - 5. Webhook
- Dialogflow - 6. 클라이언트
- Dialogflow - 7. 챗봇 클라이언트
- Dialogflow - 8. Node.js 클라이언트
- Dialogflow - 9. React 클라이언트
지난 시간에는 티키타카를 위한 컨텍스트에 대해 알아봤습니다. 이번 시간에는 Fulfillment에 대해 알아봅시다.
Why Fulfillment?
지금까지는 브라우저로 Dialogflow 콘솔에 접속해서 마치 서류의 빈 칸을 채우듯 쉽고 직관적으로 인텐트를 다뤘는데요, 이 기본 GUI만으로도 상당히 많은 대화를 처리할 수 있습니다.
하지만 마지막에 언급했던 follow-up - no 인텐트 경우와 같이, 색다른 루틴이나 외부 서버와의 연결, 외부 서비스 연동 등 복잡한 기능에 있어서는 프로그래밍으로 커버되는데, 이 부분을 fulfillment라 부릅니다. Fulfillment는 번역된 한국말도 없는데요, 그만큼 처음에는 개념이 혼란스러울 수 있으나, 외부 연동 정도의 느낌으로 기억해도 무난할 것 같네요.
Fulfillment에 대해서는 공식 홈페이지의 가이드에 아래와 같이 알기 쉽게 그림으로 설명하고 있습니다.
그림만 보면 webhook이란 말도 나오고 해서 헷갈릴 수 있는데, 일단 webhook은 기억하지 말고 실습을 통해 체화해 봅시다.
Fulfillment 실습
실습의 목표는 conf-room-reservation - no 인텐트가 불리면, 다시 회의 시간을 물어보도록 conf-room-reservation 인텐트를 호출하는 것입니다.
먼저 conf-room-reservation - no 인텐트의 맨 아래 Fulfillment 옵션에서 Enable webhook call for this intent를 활성화합니다. 그리고 메인 메뉴에서 Fulfillment로 갑니다.
Google Cloud Platform(이하 GCP)에 가입하지 않은 경우, 위와 같은 팝업이 뜹니다. Fulfillment 등 Dialogflow를 온전히 사용하기 위해서는 GCP 프로젝트로 연동해야 하는데, GCP는 유료 서비스지만 최초 가입 시 90일 무료 체험 크레딧을 사용할 수 있습니다. 보다 자세한 내용은 Google Cloud Platform & Firebase 편을 참고하세요.
Fulfillment는 Webhook과 Inline Editor가 제공되는데, Webhook은 다음 편에서 다룰 것이므로 Inline Editor를 선택합니다.
Inline Editor란, 현란한 코드가 보이는 이 창 안에서 프로그래밍을 할 수 있도록 제공되는 것인데요, Fulfillment는 Node 앱이기 때문에 index.js와 package.json을 수정할 수 있습니다.
코드를 고친 후 DEPLOY하면, GCP 내부적으로 이 Node 앱을 빌드해서 배포하는 것이죠. 이해가 잘 안 가도 괜찮아요. 다음 편에서 Webhook을 다룰 때 이해하면 됩니다.
자, 다시 본론으로 들어와서, 아래 코드는 conf-room-reservation - no 인텐트가 발생했을 때 askAgain() 안에서 evt-ask-again이라는 이벤트를 발생시키겠다는 의미입니다. 어렵지 않죠?
exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request, response) => {
...중략...
function askAgain(agent) {
agent.setFollowupEvent({
"name": "evt-ask-again"
});
agent.add('');
}
// Run the proper function handler based on the matched Dialogflow intent name
let intentMap = new Map();
...중략...
intentMap.set('conf-room-reservation - no', askAgain);
agent.handleRequest(intentMap);
});
여기서 중요한 점은 agent.add(''); 를 빼먹으면 안됩니다. agent.add()는 응답을 등록하는 함수인데, 빈 응답이라도 반드시 한 개 이상 등록해줘야 에러가 안 납니다. 위와 같이 askAgain 함수를 추가하고 intentMap.set('conf-room-reservation - no', askAgain); 코드를 추가한 뒤 DEPLOY 버튼을 눌러 배포합니다. 시간이 꽤 걸립니다.
View execution logs를 클릭하면 로그(console.log)도 볼 수 있습니다. 이게 끝이 아니죠. 아직 이벤트를 설정해주지 않았어요. 이벤트를 받을 conf-room-reservation 인텐트를 열고 Events에 evt-ask-again을 추가합니다.
자, 검증의 시간입니다. "오늘 2시 회의실 예약해줘" > "2시 회의 맞나요?" > "아니"
다시 conf-room-reservation 인텐트가 실행되면서 회의가 몇 시인지 물어봅니다.
완료!
다음 편에서는 Webhook으로 외부 시스템과 연동해 보겠습니다.