Dialogflow와 BigQuery 통합 방법

이 도움말에서는 Dialogflow를 BigQuery와 연결하고 대화 중에 수집한 정보를 저장하는 방법을 알아봅니다. 이전 실습&\'t;Appointment Scheduler"에서 생성한 것과 동일한 에이전트를 사용합니다. 에이전트의 GCP 프로젝트에서 BigQuery에 데이터 세트와 테이블을 만듭니다. 그런 다음 BigQuery 데이터 세트와 테이블 ID로 원래 처리를 수정합니다. 마지막으로 BigQuery에 상호작용이 기록되는지 테스트합니다.

다음은 사용자 처리와 BigQuery의 이벤트 순서도입니다.

학습할 내용

  • BigQuery에서 데이터 세트 및 테이블을 만드는 방법
  • Dialogflow 처리에서 BigQuery 연결 세부정보를 설정하는 방법
  • 처리를 테스트하는 방법

기본 요건

  • Dialogflow의 기본 개념과 구성 기본적인 대화 디자인을 다룬 Dialogflow 가이드 소개 동영상은 다음 동영상에서 확인하세요.
  • Dialogflow를 사용하여 예약 스케줄러 챗봇을 빌드합니다.
  • Dialogflow의 항목 이해하기
  • 처리: Dialogflow를 Google Calendar와 통합
  1. Google Cloud Console로 이동합니다.
  2. Cloud Console에서 메뉴 아이콘 ☰ &gt, 빅데이터 및 BigQuery로 이동합니다.
  3. 왼쪽 창의 리소스 아래에서 프로젝트 ID를 클릭합니다. 프로젝트 ID를 선택하면 오른쪽에 '데이터 세트 만들기'가 표시됩니다.
  4. 데이터 세트 만들기를 클릭하고 이름을 지정합니다.

  1. 데이터 세트가 생성되면 왼쪽 패널에서 데이터 세트를 클릭합니다. 오른쪽에 CREATE TABLE이 표시됩니다.
  2. 표 만들기를 클릭하고 표 이름을 입력한 후 화면 하단의 표 만들기를 클릭합니다.

  1. 테이블이 생성되면 왼쪽 패널에서 표를 클릭합니다. 오른쪽에 'Edit Schema"' 버튼이 표시됩니다.
  2. '스키마 수정' 버튼을 클릭하고 '필드 추가' 버튼을 클릭합니다. 'date" 필드를 추가하고 'quot;time' 및 'type"에 동일하게 적용합니다.
  3. "DatasetID" "tableID"

  1. Dialogflow 에이전트를 열고 Fulfillment 인라인 편집기를 사용 설정합니다. 도움이 필요하면 이전 실습을 참고하세요 .
  1. Dialogflow 처리 인라인 편집기의 '"package.json"'에 BigQuery 종속 항목이 포함되어 있는지 확인하세요. "@google-google/cloud": "0.12.0" 이 도움말을 따를 때는 BigQuery의 최신 버전을 사용해야 합니다.
  2. index.js에서 BigQuery 테이블에 날짜, 시간, 약속 유형을 추가하는 addToBigQuery" 함수를 만듭니다.
  3. index.js 파일의 TODO 섹션에 projectID, datasetID, tableID를 추가하여 BigQuery 테이블과 데이터 세트를 처리에 연결합니다.
{
  "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);
        }
        );
      }
    });
  });
}

코드에서 이벤트 시퀀스 이해

  1. 인텐트 맵은 "makeAppointment" 함수를 호출하여 Google Calendar에서 약속을 예약합니다.
  2. 동일한 함수 내에서 'addToBigQuery" 함수'를 호출하여 BigQuery에 로그인할 데이터를 전송합니다.

챗봇을 테스트해 보세요. 시뮬레이터에서 테스트하거나 이전 도움말에서 배운 웹 또는 Google Home 통합을 사용할 수 있습니다.

  • 사용자: "내일 오후 2시에 차량 등록 예약하기"
  • 챗봇 응답: "확인해 주시겠어요? 8월 6일 오후 2시는 괜찮습니다.

  • 응답 후에 BigQuery 테이블을 확인합니다. query "SELECT * FROM `projectID.datasetID.tableID`"

이 시리즈의 다른 실습을 수행할 계획이라면 지금 정리하지 말고 시리즈의 모든 실습을 완료한 후에 정리하세요.

Dialogflow 에이전트 삭제

  • 기존 에이전트 옆의 톱니바퀴 아이콘 을 클릭합니다.

  • General(일반) 탭에서 하단으로 스크롤하여 Delete Agent(에이전트 삭제)를 클릭합니다.
  • 표시되는 창에 삭제를 입력하고 삭제를 클릭합니다.

챗봇을 만들고 BigQuery와 통합하여 통계를 얻었습니다. 이제 챗봇 개발자가 되셨습니다!

다음과 같은 다른 리소스를 확인해 보세요.