Come integrare Dialogflow con BigQuery

1. Introduzione

In questo articolo impareremo come Dialogflow si connette a BigQuery e memorizza le informazioni raccolte durante l'esperienza conversazionale. Utilizzeremo lo stesso agente che abbiamo creato nei lab precedenti "Pianificatore di appuntamenti". Nel progetto GCP dell'agente creeremo un set di dati e una tabella in BigQuery. Poi modificheremo l'evasione originale con gli ID del set di dati e della tabella BigQuery. Infine, verificheremo se le interazioni vengono registrate in BigQuery.

Di seguito è riportato il diagramma di sequenza degli eventi dall'utente all'evasione e a BigQuery.

538029740db09f49.png

Obiettivi didattici

  • Come creare un set di dati e una tabella in BigQuery
  • Come configurare i dettagli della connessione BigQuery nel fulfillment di Dialogflow.
  • Come testare il fulfillment

Prerequisiti

  • Concetti di base di Dialogflow. Per i video tutorial introduttivi di Dialogflow che trattano la progettazione conversazionale di base, guarda i seguenti video:
  • Crea un chatbot per la pianificazione di appuntamenti utilizzando Dialogflow.
  • Informazioni sulle entità in Dialogflow.
  • Fulfillment: integra Dialogflow con Google Calendar.

2. Crea un set di dati e una tabella in BigQuery

  1. Vai alla console Google Cloud.
  2. Nella console Cloud, vai all'icona del menu ☰ > Big Data > BigQuery.
  3. In Risorse nel riquadro a sinistra, fai clic sull'ID progetto. Una volta selezionato, vedrai CREA SET DI DATI a destra.
  4. Fai clic su CREA SET DI DATI e assegnagli un nome.

be9f32a18ebb4a5b.png

  1. Una volta creato il set di dati, fai clic su di esso nel riquadro a sinistra. A destra vedrai CREA TABELLA.
  2. Fai clic su CREA TABELLA, fornisci il nome della tabella e fai clic su Crea tabella nella parte inferiore dello schermo.

d5fd99b68b7e62e0.png

  1. Una volta creata la tabella, fai clic su di essa nel riquadro a sinistra. Sul lato destro vedrai il pulsante "Modifica schema".
  2. Fai clic sul pulsante Modifica schema e poi sul pulsante Aggiungi campo. Aggiungi il campo "data" e ripeti la stessa operazione per "ora" e "tipo".
  3. Prendi nota di "DatasetID" e "tableID"

e9d9abbe843823df.png

3. Aggiungere i dettagli della connessione BigQuery a Dialogflow Fulfillment

  1. Apri l'agente Dialogflow e attiva l'editor incorporato di Fulfillment. Se hai bisogno di aiuto, consulta il lab precedente .
  1. Assicurati che il file package.json nell'editor inline di Dialogflow Fulfillment contenga una dipendenza BigQuery. "@google-cloud/bigquery": "0.12.0". Assicurati di utilizzare l'ultima versione di BigQuery quando segui questo articolo.
  2. In index.js crea la funzione "addToBigQuery" per aggiungere la data, l'ora e il tipo di appuntamento nella tabella BigQuery.
  3. Aggiungi projectID, datasetID e tableID nella sezione TODO del file index.js per connettere correttamente la tabella BigQuery e il set di dati al tuo 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);
        }
        );
      }
    });
  });
}

Comprendere la sequenza di eventi dal codice

  1. La mappa degli intent chiama la funzione "makeAppointment" per programmare un appuntamento su Google Calendar
  2. All'interno della stessa funzione viene effettuata una chiamata alla funzione "addToBigQuery" per inviare i dati da registrare in BigQuery.

4. Testa il chatbot e la tabella BigQuery.

Testiamo il nostro chatbot. Puoi testarlo nel simulatore o utilizzare l'integrazione web o Google Home che abbiamo imparato negli articoli precedenti.

  • Utente: "Fissa un appuntamento per l'immatricolazione del veicolo per domani alle 14:00"
  • Risposta del chatbot: "Ok, vediamo se possiamo fissare un appuntamento. Il 6 agosto alle 14:00 va bene."

96d3784c103daf5e.png

  • Controlla la tabella BigQuery dopo la risposta. Utilizza la query "SELECT * FROM projectID.datasetID.tableID"

dcbc9f1c06277a21.png

5. Esegui la pulizia

Se prevedi di svolgere gli altri lab di questa serie, non eseguire la pulizia ora, ma dopo aver completato tutti i lab della serie.

Elimina l'agente Dialogflow

  • Fai clic sull'icona a forma di ingranaggio 30a9fea7cfa77c1a.png accanto all'agente esistente.

520c1c6bb9f46ea6.png

  • Nella scheda Generali, scorri verso il basso fino in fondo e fai clic su Elimina questo agente.
  • Digita ELIMINA nella finestra visualizzata e fai clic su Elimina.

6. Complimenti!

Hai creato un chatbot e lo hai integrato con BigQuery per ottenere approfondimenti. Ora sei uno sviluppatore di chatbot.

Dai un'occhiata a queste altre risorse:

1217326c0c490fa.png