كيفية دمج Dialogflow مع BigQuery

1. مقدمة

في هذه المقالة، سنتعرّف على كيفية ربط Dialogflow بـ BigQuery وتخزين المعلومات التي يتم جمعها أثناء تجربة المحادثة. سنستخدم "الوكيل" نفسه الذي أنشأناه في المختبرات السابقة " أداة جدولة المواعيد". في مشروع GCP الخاص بالوكيل، سننشئ مجموعة بيانات وجدولاً في BigQuery. بعد ذلك، سنعدّل عملية التنفيذ الأصلية باستخدام أرقام تعريف مجموعة البيانات والجدول في BigQuery. أخيرًا، سنختبر ما إذا كان يتم تسجيل التفاعلات في BigQuery.

في ما يلي مخطط تسلسلي للأحداث من المستخدم إلى التنفيذ وBigQuery.

538029740db09f49.png

أهداف الدورة التعليمية

  • كيفية إنشاء مجموعة بيانات وجدول في BigQuery
  • كيفية إعداد تفاصيل ربط BigQuery في تنفيذ Dialogflow
  • كيفية اختبار عملية التنفيذ

المتطلبات الأساسية

  • المفاهيم الأساسية لبنية Dialogflow للحصول على فيديوهات تعليمية تمهيدية حول Dialogflow تتناول تصميم المحادثات الأساسي، يمكنك الاطّلاع على الفيديوهات التالية:
  • إنشاء روبوت دردشة لجدولة المواعيد باستخدام Dialogflow
  • التعرّف على الكيانات في Dialogflow
  • التنفيذ: دمج Dialogflow مع "تقويم Google"

2. إنشاء مجموعة بيانات وجدول في BigQuery

  1. انتقِل إلى Google Cloud Console.
  2. في Cloud Console، انتقِل إلى رمز القائمة ☰ > البيانات الضخمة > BigQuery
  3. ضمن "الموارد" في اللوحة اليمنى، انقر على رقم تعريف المشروع، وبعد تحديده، سيظهر لك الخيار "إنشاء مجموعة بيانات" على اليسار.
  4. انقر على CREATE DATASET (إنشاء مجموعة بيانات) وأدخِل اسمًا لها.

be9f32a18ebb4a5b.png

  1. بعد إنشاء مجموعة البيانات، انقر عليها من اللوحة اليمنى. سيظهر لك الخيار CREATE TABLE (إنشاء جدول) على يسار الشاشة.
  2. انقر على CREATE TABLE (إنشاء جدول)، وأدخِل اسم الجدول، ثم انقر على Create table (إنشاء جدول) في أسفل الشاشة.

d5fd99b68b7e62e0.png

  1. بعد إنشاء الجدول، انقر عليه من اللوحة اليمنى. سيظهر لك الزر تعديل المخطط على يسار الصفحة.
  2. انقر على الزر "تعديل المخطط" (Edit Schema)، ثم انقر على الزر "إضافة حقل" (Add Field). أضِف الحقل "date" وكرِّر الخطوة نفسها للحقلَين "time" و "type".
  3. دوِّن DatasetID وtableID.

e9d9abbe843823df.png

3- إضافة تفاصيل ربط BigQuery إلى ميزة "الوفاء بالطلبات" في Dialogflow

  1. افتح وكيل Dialogflow وفعِّل محرِّر التنفيذ المضمّن. يمكنك الرجوع إلى المختبر السابق إذا كنت بحاجة إلى مساعدة في هذا الشأن .
  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 لجدولة موعد في "تقويم Google".
  2. يتم إجراء طلب إلى الدالة "addToBigQuery" ضمن الدالة نفسها لإرسال البيانات التي سيتم تسجيلها في BigQuery.

4. اختبار Chatbot وجدول BigQuery

لنختبر الآن روبوت الدردشة، يمكنك اختباره في المحاكي أو استخدام عملية الدمج مع الويب أو Google Home التي تعلّمنا كيفية إجرائها في المقالات السابقة.

  • المستخدم: "تحديد موعد لتسجيل المركبة في الساعة 2 ظهرًا غدًا"
  • ردّ برنامج الدردشة الآلي: "حسنًا، سأرى ما إذا كان بإمكاننا توفير موعد لك. "الموعد في 6 أغسطس الساعة 2 بعد الظهر مناسب".

96d3784c103daf5e.png

  • تحقَّق من جدول BigQuery بعد تلقّي الردّ. استخدام الاستعلام "SELECT * FROM projectID.datasetID.tableID"

dcbc9f1c06277a21.png

5- تنظيف

إذا كنت تخطّط لإجراء الدروس التطبيقية الأخرى في هذه السلسلة، لا تنفِّذ عملية التنظيف الآن، بل بعد الانتهاء من جميع الدروس التطبيقية في السلسلة.

حذف وكيل Dialogflow

  • انقر على رمز الترس 30a9fea7cfa77c1a.png بجانب الوكيل الحالي

520c1c6bb9f46ea6.png

  • في علامة التبويب الإعدادات العامة، انتقِل إلى أسفل الصفحة وانقر على حذف هذا الوكيل.
  • اكتب DELETE في النافذة التي تظهر وانقر على حذف.

6. تهانينا!

أنشأتَ برنامج دردشة آليًا ودمجته مع BigQuery للحصول على إحصاءات. أصبحت الآن مطوّر برامج محادثة مبرمَجة.

يمكنك الاطّلاع على المراجع التالية:

  • يمكنك الاطّلاع على عيّنات الرموز في صفحة Dialogflow Github.

1217326c0c490fa.png