1. 准备工作
在此 Codelab 中,您将了解 Dialogflow 如何与后端系统连接,以便为用户提供丰富的动态响应问题。
前提条件
在继续操作之前,您需要完成以下 Codelab:
您还需要了解 Dialogflow 的基本概念和结构,您可以从使用 Dialogflow 构建聊天机器人在线课程中的以下视频中获得这些信息。
学习内容
- 什么是 fulfillment
- 如何为日历设置服务账号
- 如何设置日历
- 如何在 Dialogflow 中启用 fulfillment
- 如何测试 fulfillment
构建内容
- 使用 Cloud Functions 的 Fulfillment
- Dialogflow 和日历之间的集成
所需条件
- 用来登录 Dialogflow 控制台的网络浏览器和电子邮件地址
- 用于访问日历的 Google 账号
2. 什么是 fulfillment?
Fulfillment 是部署为 webhook 的代码,可让 Dialogflow 代理逐个意图地调用业务逻辑。在对话过程中,fulfillment 允许您使用通过 Dialogflow 的自然语言处理操作提取的信息,在后端生成动态响应或触发操作。大多数 Dialogflow 代理都使用 fulfillment。
以下是一些有关在什么情况下可以使用 fulfillment 来扩展代理的示例:
- 根据从数据库中查找的信息生成动态响应
- 根据客户要求的商品下订单
- 实现游戏规则和获胜条件
3. 启用日历 API
- 在 Dialogflow 控制台中,点击 。
- 在常规标签页中,滚动到项目 ID,然后点击 Google Cloud。
- 在 Google Cloud Console 中,点击导航菜单 ☰ > API 和服务 > 库。
- 搜索“Google 日历 API”,然后点击启用,以便在您的 Google Cloud 项目中使用该 API。
4. 设置服务账号
- 依次点击导航菜单 ☰ > API 和服务 > 凭据。
- 点击创建凭据 > 服务账号。
- 在服务账号详情中,输入“appointment-scheduler”作为服务账号名称,然后点击创建。
- 在显示向此服务账号授予对项目的访问权限的位置,点击继续以跳过它。
- 在显示向用户授予对此服务账号的访问权限(可选)的位置,点击创建密钥,然后选择 JSON,并点击创建。
系统会将 JSON 文件下载到您的计算机上,您在后续设置部分需要用到此文件。
5. 日历设置
- 导航至日历,然后点击主菜单 ☰ >添加其他日历 >创建新日历。
- 输入“预约日历”作为日历名称,然后点击创建日历。
- 重新加载页面,然后点击预约日历,滚动到与特定人员共享,然后点击添加人员。
- 从在服务账号设置过程中下载的 JSON 文件中复制
client_email
,并将其粘贴到对话框中。
- 点击权限下拉列表,然后点击更改活动 > 发送。
- 在设置中,滚动到集成日历并复制日历 ID。
6. 在 Dialogflow 中设置 fulfillment
将服务账号和日历 ID 添加到 fulfillment
- 导航到 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 文件的内容。 - (可选)根据预约日历的时区更改 const timeZone 和 const timeZoneOffset。
- 点击部署。
启用 fulfillment 响应
- 导航到 Dialogflow 控制台并点击意图。
- 点击安排预约意图。
- 向下滚动到 Fulfillment 并开启为此意图启用网络钩子调用。
- 点击保存。
- 点击部署。
7. 测试聊天机器人
您可以在 Actions 模拟器中测试聊天机器人,也可以使用之前了解的 Web 或 Google Home 集成。
- 用户:“Set an appointment for vehicle registration at 2 PM tomorrow.”
- 聊天机器人:“Ok, let me see if we can fit you in.April 24, 2 PM is fine!"
- 日历会预订回复。
8. 清理
如果您计划完成其他 Dialogflow Codelab,请暂时跳过此部分,稍后再回来查看。
删除 Dialogflow 代理
- 点击现有代理旁边的 。
- 在常规标签页中,滚动到底部,然后点击删除此代理。
- 在对话框中输入 Delete,然后点击删除。
9. 恭喜
您在 Dialogflow 中创建了一个聊天机器人,并将它与日历集成。您现在已经是聊天机器人开发者了!
了解详情
如需了解详情,请查看 Dialogflow GitHub 页面上的代码示例。