1. 소개
이 문서에서는 Dialogflow가 BigQuery와 연결하고 대화 환경 중에 수집한 정보를 저장하는 방법을 알아봅니다. 이전 실습에서 만든 것과 동일한 에이전트를 사용합니다. " 약속 스케줄러'. 에이전트의 GCP 프로젝트에서 BigQuery에 데이터 세트와 테이블을 만듭니다. 그런 다음 BigQuery 데이터 세트와 테이블 ID로 원래 처리를 수정합니다. 마지막으로 상호작용이 BigQuery에 기록되는지 테스트합니다.
다음은 사용자에서 처리 및 BigQuery로 이어지는 이벤트의 시퀀스 다이어그램입니다.
학습할 내용
- BigQuery에서 데이터 세트 및 테이블을 만드는 방법
- Dialogflow fulfillment에서 BigQuery 연결 세부정보를 설정하는 방법
- 처리를 테스트하는 방법
기본 요건
- Dialogflow의 기본 개념 및 구성 기본 대화 디자인을 다루는 Dialogflow 입문용 튜토리얼 동영상을 보려면 다음 동영상을 확인하세요.
- Dialogflow를 사용하여 약속 스케줄러 챗봇을 빌드합니다.
- Dialogflow의 항목 이해
- 처리: Dialogflow를 Google Calendar와 통합합니다.
2. BigQuery에서 데이터 세트 및 테이블 만들기
- Google Cloud 콘솔로 이동합니다.
- Cloud 콘솔에서 메뉴 아이콘 ☰ >으로 이동합니다. 빅데이터 > BigQuery
- 왼쪽 창의 리소스에서 프로젝트 ID를 클릭합니다. 프로젝트 ID를 선택하면 오른쪽에 데이터 세트 만들기가 표시됩니다.
- '데이터 세트 만들기'를 클릭하고 이름을 지정합니다.
- 데이터 세트가 생성되면 왼쪽 패널에서 데이터 세트를 클릭합니다. 오른쪽에 CREATE TABLE이 표시됩니다.
- '테이블 만들기'를 클릭하고 '테이블 이름'을 입력한 다음 화면 하단에서 '테이블 만들기'를 클릭합니다.
- 테이블이 생성되면 왼쪽 패널에서 테이블을 클릭합니다. 오른쪽에 '스키마 수정' 버튼이 표시됩니다.
- '스키마 수정' 버튼을 클릭하고 '필드 추가' 버튼을 클릭합니다. 'date' 추가 'time'에 대해서도 같은 작업을 반복합니다. 'type'이 포함됩니다.
- 'DatasetID" 및 'DatasetID"를 기록해 둡니다.
3. Dialogflow fulfillment에 BigQuery 연결 세부정보 추가
- Dialogflow 에이전트를 열고 fulfillment 인라인 편집기를 사용 설정합니다. 도움이 필요한 경우 이전 실습을 참조하세요 .
- Dialogflow fulfillment 인라인 편집기의 'package.json"에 BigQuery 종속 항목이 포함되어 있는지 확인합니다. '@google-cloud/bigquery': '0.12.0' 이 도움말을 따를 때는 최신 버전의 BigQuery를 사용해야 합니다.
- index.js에서 'addToBigQuery'를 만듭니다. 함수를 사용하여 BigQuery 테이블에 날짜, 시간, 약속 유형을 추가합니다.
- index.js 파일의 TODO 섹션에 projectID, datasetID, tableID를 추가하여 BigQuery 테이블과 데이터 세트를 fulfillment에 올바르게 연결합니다.
{
"name": "dialogflowFirebaseFulfillment",
"description": "Dialogflow fulfillment for the bike shop sample",
"version": "0.0.1",
"private": true,
"license": "Apache Version 2.0",
"author": "Google Inc.",
"engines": {
"node": "6"
},
"scripts": {
"lint": "semistandard --fix \"**/*.js\"",
"start": "firebase deploy --only functions",
"deploy": "firebase deploy --only functions"
},
"dependencies": {
"firebase-functions": "2.0.2",
"firebase-admin": "^5.13.1",
"actions-on-google": "2.2.0",
"googleapis": "^27.0.0",
"dialogflow-fulfillment": "0.5.0",
"@google-cloud/bigquery": "^0.12.0"
}
}
'use strict';
const functions = require('firebase-functions');
const {google} = require('googleapis');
const {WebhookClient} = require('dialogflow-fulfillment');
const BIGQUERY = require('@google-cloud/bigquery');
// Enter your calendar ID below and service account JSON below
const calendarId = "XXXXXXXXXXXXXXXXXX@group.calendar.google.com";
const serviceAccount = {}; // Starts with {"type": "service_account",...
// Set up Google Calendar Service account credentials
const serviceAccountAuth = new google.auth.JWT({
email: serviceAccount.client_email,
key: serviceAccount.private_key,
scopes: 'https://www.googleapis.com/auth/calendar'
});
const calendar = google.calendar('v3');
process.env.DEBUG = 'dialogflow:*'; // enables lib debugging statements
const timeZone = 'America/Los_Angeles';
const timeZoneOffset = '-07:00';
exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request, response) => {
const agent = new WebhookClient({ request, response });
console.log("Parameters", agent.parameters);
const appointment_type = agent.parameters.AppointmentType;
// Function to create appointment in calendar
function makeAppointment (agent) {
// Calculate appointment start and end datetimes (end = +1hr from start)
const dateTimeStart = new Date(Date.parse(agent.parameters.date.split('T')[0] + 'T' + agent.parameters.time.split('T')[1].split('-')[0] + timeZoneOffset));
const dateTimeEnd = new Date(new Date(dateTimeStart).setHours(dateTimeStart.getHours() + 1));
const appointmentTimeString = dateTimeStart.toLocaleString(
'en-US',
{ month: 'long', day: 'numeric', hour: 'numeric', timeZone: timeZone }
);
// Check the availability of the time, and make an appointment if there is time on the calendar
return createCalendarEvent(dateTimeStart, dateTimeEnd, appointment_type).then(() => {
agent.add(`Ok, let me see if we can fit you in. ${appointmentTimeString} is fine!.`);
// Insert data into a table
addToBigQuery(agent, appointment_type);
}).catch(() => {
agent.add(`I'm sorry, there are no slots available for ${appointmentTimeString}.`);
});
}
let intentMap = new Map();
intentMap.set('Schedule Appointment', makeAppointment);
agent.handleRequest(intentMap);
});
//Add data to BigQuery
function addToBigQuery(agent, appointment_type) {
const date_bq = agent.parameters.date.split('T')[0];
const time_bq = agent.parameters.time.split('T')[1].split('-')[0];
/**
* TODO(developer): Uncomment the following lines before running the sample.
*/
//const projectId = '<INSERT your own project ID here>';
//const datasetId = "<INSERT your own dataset name here>";
//const tableId = "<INSERT your own table name here>";
const bigquery = new BIGQUERY({
projectId: projectId
});
const rows = [{date: date_bq, time: time_bq, type: appointment_type}];
bigquery
.dataset(datasetId)
.table(tableId)
.insert(rows)
.then(() => {
console.log(`Inserted ${rows.length} rows`);
})
.catch(err => {
if (err && err.name === 'PartialFailureError') {
if (err.errors && err.errors.length > 0) {
console.log('Insert errors:');
err.errors.forEach(err => console.error(err));
}
} else {
console.error('ERROR:', err);
}
});
agent.add(`Added ${date_bq} and ${time_bq} into the table`);
}
// Function to create appointment in google calendar
function createCalendarEvent (dateTimeStart, dateTimeEnd, appointment_type) {
return new Promise((resolve, reject) => {
calendar.events.list({
auth: serviceAccountAuth, // List events for time period
calendarId: calendarId,
timeMin: dateTimeStart.toISOString(),
timeMax: dateTimeEnd.toISOString()
}, (err, calendarResponse) => {
// Check if there is a event already on the Calendar
if (err || calendarResponse.data.items.length > 0) {
reject(err || new Error('Requested time conflicts with another appointment'));
} else {
// Create event for the requested time period
calendar.events.insert({ auth: serviceAccountAuth,
calendarId: calendarId,
resource: {summary: appointment_type +' Appointment', description: appointment_type,
start: {dateTime: dateTimeStart},
end: {dateTime: dateTimeEnd}}
}, (err, event) => {
err ? reject(err) : resolve(event);
}
);
}
});
});
}
코드에서 발생하는 이벤트 순서 이해하기
- 인텐트 맵은 'makeAppointment" 함수를 호출하여 Google Calendar에서 약속을 예약합니다.
- 동일한 함수 내에서 'addToBigQuery'가 호출됩니다. 함수를 사용하여 BigQuery에 로그인할 데이터를 보냅니다.
4. 챗봇 및 BigQuery 테이블 테스트
챗봇을 테스트해 보겠습니다. 시뮬레이터에서 테스트하거나 이전 도움말에서 배운 웹 또는 Google Home 통합을 사용할 수 있습니다.
- 사용자: "내일 오후 2시에 차량 등록 일정 예약해 줘"
- 챗봇 응답: "네, 연결해 드릴 수 있는지 알아보겠습니다. 8월 6일 오후 2시는 괜찮아요!"
- 응답 후 BigQuery 테이블을 확인하세요. 'SELECT * FROM
projectID.datasetID.tableID
' 쿼리 사용
5. 삭제
이 시리즈의 다른 실습을 수행할 계획이라면 지금 정리하지 말고 시리즈의 모든 실습을 완료한 후에 정리를 진행하세요.
Dialogflow 에이전트 삭제
- 기존 에이전트 옆에 있는 톱니바퀴 아이콘
을 클릭합니다.
- General 탭에서 하단으로 스크롤한 후 Delete this Agent를 클릭합니다.
- 표시되는 창에 DELETE를 입력하고 삭제를 클릭합니다.
6. 축하합니다.
유용한 정보를 얻기 위해 챗봇을 만들고 BigQuery와 통합했습니다. 챗봇 개발자가 되셨습니다!
다른 리소스도 확인해 보세요.
- Dialogflow GitHub 페이지에서 코드 샘플을 확인합니다.