1. 事前準備
在本程式碼研究室中,您將瞭解 Dialogflow 如何與後端系統連線,為使用者提供豐富多元的動態回應問題。
必要條件
請先完成下列程式碼研究室,才能繼續操作:
您也需要瞭解 Dialogflow 的基本概念和建構,請參考以下使用 Dialogflow 建構聊天機器人課程的影片。
課程內容
- 什麼是執行要求
- 如何為 Google 日曆設定服務帳戶
- 如何設定日曆
- 如何在 Dialogflow 中啟用執行要求
- 如何測試執行要求
建構項目
- 使用 Cloud Functions 執行執行要求
- Dialogflow 和 Google 日曆之間的整合
軟硬體需求
- 用於登入 Dialogflow 控制台的網路瀏覽器和電子郵件地址
- 用來存取 Google 日曆的 Google 帳戶
2. 什麼是執行要求?
「執行要求」是以 Webhook 形式部署的程式碼,可讓您的 Dialogflow 代理程式按意圖呼叫業務邏輯。在對話期間,執行要求可讓您使用由 Dialogflow 自然語言處理擷取的資訊,在後端產生動態回應或觸發動作。大多數 Dialogflow 代理程式都會使用執行要求。
以下列舉幾個可以使用執行要求擴充代理程式的範例:
- 根據從資料庫查詢的資訊產生動態回應
- 根據客戶要求的產品下單
- 導入遊戲規則和獲勝條件
3. 啟用 Calendar API
- 在 Dialogflow 控制台中,按一下 。
- 在「一般」分頁中,捲動至「專案 ID」,然後按一下「Google Cloud」圖示 。
- 在 Google Cloud 控制台中,按一下「導覽選單」圖示 ⋮ >API 與服務 >媒體庫。
- 搜尋「Google Calendar API」。接著按一下「啟用」,即可在 Google Cloud 專案中使用 API。
4. 設定服務帳戶
- 依序點選「導覽選單」圖示 ⋮ >API 與服務 >憑證。
- 按一下「建立憑證」>服務帳戶。
- 在「服務帳戶詳細資料」中,輸入「appointment-scheduler」做為「服務帳戶名稱」,然後按一下「建立」。
- 在顯示「將專案存取權授予這個服務帳戶」的位置,按一下「繼續」略過該專案。
- 按一下「將存取權授予使用者 (選用)」旁邊的「建立金鑰」,然後選取「JSON」並點選「建立」。
JSON 檔案會下載到您的電腦,您在下列設定章節中會用到這個檔案。
5. 日曆設定
- 輸入「預約日曆」做為日曆的名稱,然後按一下 [建立日曆]。
- 重新載入頁面,然後按一下「預約日曆」,捲動至「與特定使用者共用」,接著點選「新增成員」。
- 請從您在服務帳戶設定過程中下載的 JSON 檔案,複製
client_email
,然後貼到對話方塊中。
- 按一下「權限」下拉式清單,然後點選「變更事件」>傳送。
- 在「設定」中捲動至「整合日曆」,然後複製「日曆 ID」。
6. 在 Dialogflow 中設定執行要求
在執行要求中加入服務帳戶和日曆 ID
- 前往 AppointmentScheduler Dialogflow 代理程式,然後按一下「Fulfillment」(執行要求)。
- 啟用內嵌編輯器。
- 使用下列程式碼更新
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);
}
);
}
});
});
}
- 將
<INSERT YOUR CALENDAR ID>
替換為您在上一節複製的日曆 ID。 - 將
<INSERT CONTENTS OF YOUR JSON FILE HERE>
替換為 JSON 檔案的內容。 - (選用)根據 Appointment Calendar 的時區變更 const timeZone 和 const timeZoneOffset。
- 按一下「部署」。
啟用執行要求回應
- 前往 Dialogflow 主控台,然後按一下 [Intents] (意圖)。
- 按一下「Schedule Appointment Intent」。
- 向下捲動至「Fulfillment」,然後開啟「Enable Webhook call for the intent」。
- 按一下 [儲存]。
- 按一下「部署」。
7. 測試聊天機器人
你可以使用動作模擬器測試聊天機器人,或者使用先前學到的網路或 Google Home 整合工具。
- 使用者:「設定明天下午 2 點的車輛登記預約。」
- 聊天機器人:「好,我來試試看。4 月 24 日下午 2 點沒問題!」
- Google 日曆會預訂回應。
8. 清除所用資源
如果您要完成其他 Dialogflow 程式碼研究室,請暫時略過這部分,稍後再回來查看。
刪除 Dialogflow 虛擬服務專員
- 按一下現有服務專員旁邊的 。
- 在「General」分頁中,捲動至底部,然後按一下 [Delete this Agent]。
- 在對話方塊中輸入「Delete」,然後點選「Delete」。
9. 恭喜
您已在 Dialogflow 中建立聊天機器人,並將其與 Google 日曆整合。你已成為聊天機器人開發人員!
瞭解詳情
如要瞭解詳情,請前往 Dialogflow GitHub 頁面查看程式碼範例。