將 Dialogflow 與日曆整合,瞭解執行要求

1. 事前準備

在本程式碼研究室中,您將瞭解 Dialogflow 如何與後端系統連線,為使用者提供豐富多元的動態回應問題。

必要條件

請先完成下列程式碼研究室,才能繼續操作:

  1. 使用 Dialogflow 建構預約排程器
  2. 整合 Dialogflow 與 Actions on Google
  3. 瞭解 Dialogflow 中的實體

您也需要瞭解 Dialogflow 的基本概念和建構,請參考以下使用 Dialogflow 建構聊天機器人課程的影片。

課程內容

  • 什麼是執行要求
  • 如何為 Google 日曆設定服務帳戶
  • 如何設定日曆
  • 如何在 Dialogflow 中啟用執行要求
  • 如何測試執行要求

建構項目

  • 使用 Cloud Functions 執行執行要求
  • Dialogflow 和 Google 日曆之間的整合

軟硬體需求

  • 用於登入 Dialogflow 控制台的網路瀏覽器和電子郵件地址
  • 用來存取 Google 日曆的 Google 帳戶

2. 什麼是執行要求?

「執行要求」是以 Webhook 形式部署的程式碼,可讓您的 Dialogflow 代理程式按意圖呼叫業務邏輯。在對話期間,執行要求可讓您使用由 Dialogflow 自然語言處理擷取的資訊,在後端產生動態回應或觸發動作。大多數 Dialogflow 代理程式都會使用執行要求。

以下列舉幾個可以使用執行要求擴充代理程式的範例:

  • 根據從資料庫查詢的資訊產生動態回應
  • 根據客戶要求的產品下單
  • 導入遊戲規則和獲勝條件

3. 啟用 Calendar API

  1. Dialogflow 控制台中,按一下 d7d792687e597dd5.png
  2. 在「一般」分頁中,捲動至「專案 ID」,然後按一下「Google Cloud」圖示 f2bffd4fcdb84fa9.png

34be16fcd4c5aeff.png

  1. 在 Google Cloud 控制台中,按一下「導覽選單」圖示 ⋮ >API 與服務 >媒體庫
  2. 搜尋「Google Calendar API」。接著按一下「啟用」,即可在 Google Cloud 專案中使用 API。

4. 設定服務帳戶

  1. 依序點選「導覽選單」圖示 ⋮ >API 與服務 >憑證
  2. 按一下「建立憑證」>服務帳戶

86f51af0e7886fdd.png

  1. 在「服務帳戶詳細資料」中,輸入「appointment-scheduler」做為「服務帳戶名稱」,然後按一下「建立」

845d25f3e07ff770.png

  1. 在顯示「將專案存取權授予這個服務帳戶」的位置,按一下「繼續」略過該專案。
  2. 按一下「將存取權授予使用者 (選用)」旁邊的「建立金鑰」,然後選取「JSON」並點選「建立」

JSON 檔案會下載到您的電腦,您在下列設定章節中會用到這個檔案。a424cec60144d707.png

5. 日曆設定

  1. 前往「日曆」,然後按一下「主選單」> >新增其他日曆 fbc354048b0a2c6c.png>建立新日曆

d6ec2fcf0bd2ae22.png

  1. 輸入「預約日曆」做為日曆的名稱,然後按一下 [建立日曆]
  2. 重新載入頁面,然後按一下「預約日曆」,捲動至「與特定使用者共用」,接著點選「新增成員」
  3. 請從您在服務帳戶設定過程中下載的 JSON 檔案,複製 client_email,然後貼到對話方塊中。

7927f6fa675e3e87.png

  1. 按一下「權限」下拉式清單,然後點選「變更事件」>傳送

2ee99d3d15eed97b.png

  1. 在「設定」中捲動至「整合日曆」,然後複製「日曆 ID」

df8a731f0713c52.png

6. 在 Dialogflow 中設定執行要求

在執行要求中加入服務帳戶和日曆 ID

  1. 前往 AppointmentScheduler Dialogflow 代理程式,然後按一下「Fulfillment」(執行要求)
  2. 啟用內嵌編輯器

c8574c6ef899393f.png

  1. 使用下列程式碼更新 index.js 檔案:
'use strict';

// Import the Dialogflow module from Google client libraries.
const functions = require('firebase-functions');
const {google} = require('googleapis');
const {WebhookClient} = require('dialogflow-fulfillment');

// Enter your calendar ID below and service account JSON below
const calendarId = "<INSERT YOUR CALENDAR ID>";
const serviceAccount = {<INSERT CONTENTS OF YOUr JSON FILE HERE>}; // 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';

// Set the DialogflowApp object to handle the HTTPS POST request.
exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request, response) => {
 const agent = new WebhookClient({ request, response });
 console.log("Parameters", agent.parameters);
 const appointment_type = agent.parameters.appointment_type;
 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!.`);
   }).catch(() => {
     agent.add(`I'm sorry, there are no slots available for ${appointmentTimeString}.`);
   });
 }

// Handle the Dialogflow intent named 'Schedule Appointment'.
 let intentMap = new Map();
 intentMap.set('Schedule Appointment', makeAppointment);
 agent.handleRequest(intentMap);
});

//Creates calendar event 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. <INSERT YOUR CALENDAR ID> 替換為您在上一節複製的日曆 ID。
  2. <INSERT CONTENTS OF YOUR JSON FILE HERE> 替換為 JSON 檔案的內容。
  3. (選用)根據 Appointment Calendar 的時區變更 const timeZoneconst timeZoneOffset
  4. 按一下「部署」

啟用執行要求回應

  1. 前往 Dialogflow 主控台,然後按一下 [Intents] (意圖)。
  2. 按一下「Schedule Appointment Intent」
  3. 向下捲動至「Fulfillment」,然後開啟「Enable Webhook call for the intent」

a5b41336b5249e44.png

  1. 按一下 [儲存]
  2. 按一下「部署」

7. 測試聊天機器人

你可以使用動作模擬器測試聊天機器人,或者使用先前學到的網路或 Google Home 整合工具。

  1. 使用者:「設定明天下午 2 點的車輛登記預約。」
  2. 聊天機器人:「好,我來試試看。4 月 24 日下午 2 點沒問題!」

96d3784c103daf5e.png

  1. Google 日曆會預訂回應。

b7da9da814271db8.png

8. 清除所用資源

如果您要完成其他 Dialogflow 程式碼研究室,請暫時略過這部分,稍後再回來查看。

刪除 Dialogflow 虛擬服務專員

  1. 按一下現有服務專員旁邊的 dc4ac6f9c0ae94e9.png

520c1c6bb9f46ea6.png

  1. 在「General」分頁中,捲動至底部,然後按一下 [Delete this Agent]
  2. 在對話方塊中輸入「Delete」,然後點選「Delete」

9. 恭喜

您已在 Dialogflow 中建立聊天機器人,並將其與 Google 日曆整合。你已成為聊天機器人開發人員!

瞭解詳情

如要瞭解詳情,請前往 Dialogflow GitHub 頁面查看程式碼範例。