Cómo integrar Dialogflow en BigQuery

1. Introducción

En este artículo, aprenderemos cómo Dialogflow se conecta con BigQuery y almacena la información recopilada durante la experiencia conversacional. Usaremos el mismo agente que creamos en los labs anteriores "Appointment Scheduler". En el proyecto de GCP del agente, crearemos un conjunto de datos y una tabla en BigQuery. Luego, editaremos el cumplimiento original con los IDs del conjunto de datos y la tabla de BigQuery. Por último, probaremos si las interacciones se registran en BigQuery.

A continuación, se muestra el diagrama de secuencia de los eventos desde el usuario hasta el cumplimiento y BigQuery.

538029740db09f49.png

Qué aprenderás

  • Cómo crear un conjunto de datos y una tabla en BigQuery
  • Cómo configurar los detalles de conexión de BigQuery en el cumplimiento de Dialogflow
  • Cómo probar la entrega

Requisitos previos

  • Conceptos básicos y constructos de Dialogflow; Para ver videos instructivos introductorios de Dialogflow que abarcan el diseño conversacional básico, consulta los siguientes videos:
  • Compila un chatbot de programador de citas con Dialogflow.
  • Comprender las entidades en Dialogflow
  • Completar la acción: Integra Dialogflow con el Calendario de Google.

2. Crea un conjunto de datos y una tabla en BigQuery

  1. Navega a la consola de Google Cloud.
  2. En la consola de Cloud, ve al ícono de menú ☰ > Macrodatos > BigQuery.
  3. En Recursos, en el panel izquierdo, haz clic en el ID del proyecto. Una vez que lo selecciones, verás CREAR CONJUNTO DE DATOS a la derecha.
  4. Haz clic en CREAR CONJUNTO DE DATOS y asígnale un nombre.

be9f32a18ebb4a5b.png

  1. Una vez que se cree el conjunto de datos, haz clic en él en el panel izquierdo. Verás CREATE TABLE a la derecha.
  2. Haz clic en CREATE TABLE, proporciona un nombre para la tabla y haz clic en Create table en la parte inferior de la pantalla.

d5fd99b68b7e62e0.png

  1. Una vez que se cree la tabla, haz clic en ella en el panel izquierdo. Verás el botón "Editar esquema" en el lado derecho.
  2. Haz clic en el botón Editar esquema y, luego, en el botón Agregar campo. Agrega el campo "date" y repite el mismo proceso para "time" y "type".
  3. Toma nota del "DatasetID" y el "tableID".

e9d9abbe843823df.png

3. Agrega los detalles de la conexión de BigQuery a Dialogflow Fulfillment

  1. Abre el agente de Dialogflow y habilita el editor directo de Fulfillment. Consulta el lab anterior si necesitas ayuda con esto .
  1. Asegúrate de que "package.json" en el editor intercalado de la entrega de Dialogflow contenga una dependencia de BigQuery. "@google-cloud/bigquery": "0.12.0". Asegúrate de usar la versión más reciente de BigQuery cuando sigas este artículo.
  2. En index.js, crea la función "addToBigQuery" para agregar la fecha, la hora y el tipo de cita en la tabla de BigQuery.
  3. Agrega projectID, datasetID y tableID en la sección TODO del archivo index.js para conectar correctamente tu tabla de BigQuery y el conjunto de datos a tu cumplimiento.
{
  "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);
        }
        );
      }
    });
  });
}

Comprende la secuencia de eventos del código

  1. El mapa de intents llama a la función "makeAppointment" para programar una cita en el Calendario de Google.
  2. Dentro de la misma función, se realiza una llamada a la función "addToBigQuery" para enviar los datos que se registrarán en BigQuery.

4. Prueba tu chatbot y la tabla de BigQuery

Probemos nuestro chatbot. Puedes probarlo en el simulador o usar la integración de la Web o de Google Home que aprendimos en artículos anteriores.

  • Usuario: "Establece una cita para el registro del vehículo mañana a las 2 p.m."
  • Respuesta del chatbot: "De acuerdo, déjame ver si podemos incluirte. El 6 de agosto a las 2 p.m. está bien".

96d3784c103daf5e.png

  • Verifica la tabla de BigQuery después de la respuesta. Usar la consulta "SELECT * FROM projectID.datasetID.tableID"

dcbc9f1c06277a21.png

5. Limpieza

Si planeas realizar los otros labs de esta serie, no realices la limpieza ahora. Hazlo después de completar todos los labs de la serie.

Borra el agente de Dialogflow

  • Haz clic en el ícono de ajustes 30a9fea7cfa77c1a.png junto a tu agente existente.

520c1c6bb9f46ea6.png

  • En la pestaña General, desplázate hasta la parte inferior y haz clic en Borrar este agente.
  • Escribe BORRAR en la ventana que aparece y haz clic en Borrar.

6. ¡Felicitaciones!

Creaste un chatbot y lo integraste en BigQuery para obtener estadísticas. Ya eres un desarrollador de chatbots.

Revise estos otros recursos:

1217326c0c490fa.png