איך משלבים את Dialogflow עם BigQuery

1. מבוא

במאמר הזה נסביר איך Dialogflow מתקשר עם BigQuery ומאחסן את המידע שנאסף במהלך השיחה. נשתמש באותו סוכן שיצרנו בשיעורי ה-Lab הקודמים " לוח זמנים לפגישות". בפרויקט GCP של הסוכן ניצור מערך נתונים וטבלה ב-BigQuery. לאחר מכן נערוך את מילוי ההזמנות המקורי באמצעות מזהה מערך הנתונים ומזהי הטבלאות של BigQuery. לבסוף, נבדוק אם האינטראקציות מתועדות ב-BigQuery.

זהו תרשים רצף של האירועים מהמשתמש למילוי ההזמנות ול-BigQuery.

538029740db09f49.png

מה תלמדו

  • איך יוצרים מערך נתונים וטבלה ב-BigQuery
  • איך מגדירים את פרטי החיבור ל-BigQuery במילוי האוטומטי של Dialogflow.
  • איך בודקים את מילוי ההזמנות

דרישות מוקדמות

  • המושגים והמבנים הבסיסיים של Dialogflow. לקבלת סרטוני הדרכה מבוא של Dialogflow שעוסקים בעיצוב שיחה בסיסי, כדאי לצפות בסרטונים הבאים:
  • יצירת צ'אט בוט שמתזמן פגישות באמצעות Dialogflow.
  • הבנת ישויות ב-Dialogflow.
  • מילוי הזמנות: שילוב של Dialogflow עם יומן Google.

2. יצירת מערך נתונים וטבלה ב-BigQuery

  1. נכנסים אל מסוף Google Cloud
  2. במסוף Cloud, לוחצים על סמל התפריט Backspace > Big Data > BigQuery
  3. בקטע 'משאבים' בחלונית הימנית, לוחצים על מזהה הפרויקט. אחרי הבחירה, האפשרות CREATE DATASET תופיע בצד שמאל.
  4. לוחצים על CREATE DATASET ונותנים את השם.

be9f32a18ebb4a5b.png

  1. אחרי שמערך הנתונים נוצר, לוחצים עליו בחלונית הימנית. האפשרות CREATE TABLE תופיע משמאל.
  2. לוחצים על 'יצירת טבלה', נותנים שם לטבלה ולוחצים על 'יצירת טבלה' בתחתית המסך.

d5fd99b68b7e62e0.png

  1. אחרי יצירת הטבלה, לוחצים עליה בחלונית הימנית. הלחצן עריכת סכימה יופיע בצד שמאל.
  2. יש ללחוץ על הלחצן 'עריכת סכימה' ואז על הלחצן 'הוספת שדה'. מוסיפים את תאריך. וחוזרים על אותה פעולה עבור 'time'. ו-type.
  3. חשוב לשים לב לפרמטרים DatasetID" ו-DatasetID"

e9d9abbe843823df.png

3. הוספת פרטי החיבור ל-BigQuery ל-Dockflow Fulfillment

  1. פותחים את Dialogflow Agent ומפעילים את העורך המוטבע של Fulfillment. אם אתם צריכים עזרה בנושא הזה, כדאי לעיין בשיעור ה-Lab הקודם .
  1. צריך לוודא שהשדה package.json" בעורך המוטבע למילוי הזמנות של Dialogflow מכיל תלות ב-BigQuery. "@google-cloud/bigquery": "0.12.0". חשוב לוודא שאתם משתמשים בגרסה העדכנית ביותר של BigQuery בזמן ביצוע המאמר הזה.
  2. ב-index.js, יוצרים את "addToBigQuery" כדי להוסיף את התאריך, השעה וסוג הפגישה לטבלה ב-BigQuery.
  3. מוסיפים את projectID, datasetID ו-tableID בקטע TODO שבקובץ index.js כדי לחבר כראוי את טבלת 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&quot; כדי לקבוע פגישה ביומן Google
  2. במסגרת אותה פונקציה, מתבצעת קריאה אל addToBigQuery כדי לשלוח את הנתונים להתחברות ל-BigQuery.

4. בדיקת הצ'אט בוט ואת טבלת BigQuery!

בואו נבדוק את הצ'אט בוט שלנו. תוכלו לבדוק אותו בסימולטור או להשתמש בשילוב של האינטרנט או Google Home שלמדנו במאמרים קודמים.

  • משתמש: "Set an – [קביעת פגישה לרישום רכב בשעה 14:00] מחר]"
  • תגובת צ'אט בוט: "אוקיי, אבדוק אם נוכל להתאים לך. 6 באוגוסט, 14:00 זה בסדר!".

96d3784c103daf5e.png

  • אחרי התגובה צריך לבדוק את הטבלה ב-BigQuery. שימוש בשאילתה 'SELECT * FROM projectID.datasetID.tableID'

dcbc9f1c06277a21.png

5. הסרת המשאבים

אם אתם מתכננים לעשות את שאר שיעורי ה-Lab בסדרה הזו, אל תעשו את הניקיון הזה עכשיו, כשתסיימו את כל שיעורי ה-Lab בסדרה.

מחיקת הנציג של Dialogflow

  • לוחצים על סמל גלגל השיניים 30a9fea7cfa77c1a.png לצד הנציג הקיים

520c1c6bb9f46ea6.png

  • בכרטיסייה כללי, גוללים למטה ולוחצים על מחיקת הנציג.
  • מקלידים מחיקה בחלון שמופיע ולוחצים על מחיקה.

6. מעולה!

יצרתם צ'אט בוט שילבתם אותו עם BigQuery כדי לקבל תובנות. הפכת למפתחי צ'אט בוט!

תוכלו לעיין במקורות המידע הנוספים הבאים:

1217326c0c490fa.png