为了提高构建 Action 的灵活性,您可以将逻辑委托给 HTTPS 网络服务(执行方式)。您的 Action 可以触发向 HTTPS 端点发出请求的 webhook。下面列举了一些您可以在执行方式中执行的操作:
- 根据用户提供的信息生成动态提示。
- 在外部系统中下单并确认操作成功。
- 使用后端数据验证槽。
网络钩子触发器和处理程序
您的 Action 可以在调用 intent 或场景中触发网络钩子,从而向执行方式端点发送请求。您的执行方式包含用于处理请求中的 JSON 载荷的 webhook 处理程序。您可以在以下情况下触发网络钩子:
- 调用 intent 匹配之后
- 在场景上进入舞台
- 在场景的条件阶段中条件评估结果为 true 后
- 在场景的槽填充阶段
- 在场景的输入阶段发生 intent 匹配后
在 Action 中触发网络钩子时,Google 助理会向您的执行方式发送包含 JSON 载荷的请求,其中包含用于处理事件的处理程序的名称。您的执行方式端点可以将事件路由到相应的处理程序,以执行逻辑并返回相应的包含 JSON 载荷的响应。
载荷
以下代码段展示了您的 Action 发送到执行方式的请求示例,以及执行方式返回的响应。如需了解详情,请参阅参考文档。
示例请求
{
"handler": {
"name": "handler_name"
},
"intent": {
"name": "actions.intent.MAIN",
"params": {},
"query": ""
},
"scene": {
"name": "SceneName",
"slotFillingStatus": "UNSPECIFIED",
"slots": {}
},
"session": {
"id": "example_session_id",
"params": {},
"typeOverrides": []
},
"user": {
"locale": "en-US",
"params": {
"verificationStatus": "VERIFIED"
}
},
"home": {
"params": {}
},
"device": {
"capabilities": [
"SPEECH",
"RICH_RESPONSE",
"LONG_FORM_AUDIO"
]
}
}
示例响应
{
"session": {
"id": "example_session_id",
"params": {}
},
"prompt": {
"override": false,
"firstSimple": {
"speech": "Hello World.",
"text": ""
}
},
"scene": {
"name": "SceneName",
"slots": {},
"next": {
"name": "actions.scene.END_CONVERSATION"
}
}
}
运行时交互
以下部分介绍了您可以在 webhook 处理程序中执行的常见任务。
发送提示
借助 Interactive Canvas,您可以使用简单的文本、富文本、卡片,甚至是由 Web 应用提供支持的全面 HTML 提示来创建提示。提示文档提供了有关如何在处理 webhook 事件时创建提示的完整信息。以下代码段显示了一个卡片提示:
Node.js
app.handle('rich_response', conv => {
conv.add('This is a card rich response.');
conv.add(new Card({
title: 'Card Title',
subtitle: 'Card Subtitle',
text: 'Card Content',
image: new Image({
url: 'https://developers.google.com/assistant/assistant_96.png',
alt: 'Google Assistant logo'
})
}));
});
响应 JSON
{
"session": {
"id": "example_session_id",
"params": {}
},
"prompt": {
"override": false,
"content": {
"card": {
"title": "Card Title",
"subtitle": "Card Subtitle",
"text": "Card Content",
"image": {
"alt": "Google Assistant logo",
"height": 0,
"url": "https://developers.google.com/assistant/assistant_96.png",
"width": 0
}
}
},
"firstSimple": {
"speech": "This is a card rich response.",
"text": ""
}
}
}
读取 intent 参数
当 Google 助理运行时与 intent 匹配时,它会提取任何已定义的参数。原始属性是用户提供作为输入的内容,已解析的属性是 NLU 根据类型规范将输入解析为的属性。
Node.js
conv.intent.params['param_name'].original
conv.intent.params['param_name'].resolved
请求 JSON
{
"handler": {
"name": "handler_name"
},
"intent": {
"name": "intent_name",
"params": {
"slot_name": {
"original": "1",
"resolved": 1
}
},
"query": ""
},
"scene": {
"name": "SceneName",
"slotFillingStatus": "UNSPECIFIED",
"slots": {},
"next": {
"name": "actions.scene.END_CONVERSATION"
}
},
"session": {
"id": "session_id",
"params": {},
"typeOverrides": []
},
"user": {
"locale": "en-US",
"params": {
"verificationStatus": "VERIFIED"
}
},
"home": {
"params": {}
},
"device": {
"capabilities": [
"SPEECH",
"RICH_RESPONSE",
"LONG_FORM_AUDIO"
]
}
}
读取用户语言区域
此值与 Google 助理的用户语言区域设置相对应。
Node.js
conv.user.locale
JSON
{
"handler": {
"name": "handler_name"
},
"intent": {
"name": "actions.intent.MAIN",
"params": {},
"query": ""
},
"scene": {
"name": "SceneName",
"slotFillingStatus": "UNSPECIFIED",
"slots": {}
},
"session": {
"id": "session_id",
"params": {},
"typeOverrides": []
},
"user": {
"locale": "en-US",
"params": {
"verificationStatus": "VERIFIED"
}
},
"home": {
"params": {}
},
"device": {
"capabilities": [
"SPEECH",
"RICH_RESPONSE",
"LONG_FORM_AUDIO"
]
}
}
读取和写入存储空间
如需全面了解如何使用各种存储功能,请参阅存储文档。
Node.js
//read
conv.session.params.key
conv.user.params.key
conv.home.params.key
// write
conv.session.params.key = value
conv.user.params.key = value
conv.home.params.key = value
请求 JSON
{
"handler": {
"name": "handler_name"
},
"intent": {
"name": "actions.intent.MAIN",
"params": {},
"query": ""
},
"scene": {
"name": "SceneName",
"slotFillingStatus": "UNSPECIFIED",
"slots": {}
},
"session": {
"id": "session_id",
"params": {
"key": "value"
},
"typeOverrides": [],
"languageCode": ""
},
"user": {
"locale": "en-US",
"params": {
"verificationStatus": "VERIFIED",
"key": "value"
}
},
"home": {
"params": {
"key": "value"
}
},
"device": {
"capabilities": [
"SPEECH",
"RICH_RESPONSE",
"LONG_FORM_AUDIO"
]
}
}
响应 JSON
{
"session": {
"id": "session_id",
"params": {
"key": "value"
}
},
"prompt": {
"override": false,
"firstSimple": {
"speech": "Hello world.",
"text": ""
}
},
"user": {
"locale": "en-US",
"params": {
"verificationStatus": "VERIFIED",
"key": "value"
}
},
"home": {
"params": {
"key": "value"
}
}
}
检查设备功能
您可以检查设备能否提供不同的体验或对话流程。
Node.js
const supportsRichResponse = conv.device.capabilities.includes("RICH_RESPONSE");
const supportsLongFormAudio = conv.device.capabilities.includes("LONG_FORM_AUDIO");
const supportsSpeech = conv.device.capabilities.includes("SPEECH");
const supportsInteractiveCanvas = conv.device.capabilities.includes("INTERACTIVE_CANVAS");
请求 JSON
{
"handler": {
"name": "handler_name"
},
"intent": {
"name": "actions.intent.MAIN",
"params": {},
"query": ""
},
"scene": {
"name": "SceneName",
"slotFillingStatus": "UNSPECIFIED",
"slots": {}
},
"session": {
"id": "session_id",
"params": {},
"typeOverrides": [],
"languageCode": ""
},
"user": {
"locale": "en-US",
"params": {
"verificationStatus": "VERIFIED"
}
},
"home": {
"params": {}
},
"device": {
"capabilities": [
"SPEECH",
"RICH_RESPONSE",
"LONG_FORM_AUDIO",
"INTERACTIVE_CANVAS"
]
}
}
如需查看 Surface 功能的完整列表,请参阅 Capability
参考文档。
运行时类型替换
借助运行时类型,您可以在运行时修改类型规范。您可以使用此功能从其他来源加载数据,以填充类型的有效值。例如,您可以使用运行时类型替换项,向调查问卷问题添加动态选项或向菜单添加每日内容。
如需使用运行时类型,请从 Action 中触发网络钩子,该 Action 会调用执行方式中的处理程序。然后,您可以在对您的 Action 的响应中填充 session.typeOverrides
参数。可用模式包括 TYPE_MERGE
(用于保留现有类型条目)或 TYPE_REPLACE
(用于将现有条目替换为替换项)。
Node.js
conv.session.typeOverrides = [{
name: type_name,
mode: 'TYPE_REPLACE',
synonym: {
entries: [
{
name: 'ITEM_1',
synonyms: ['Item 1', 'First item']
},
{
name: 'ITEM_2',
synonyms: ['Item 2', 'Second item']
},
{
name: 'ITEM_3',
synonyms: ['Item 3', 'Third item']
},
{
name: 'ITEM_4',
synonyms: ['Item 4', 'Fourth item']
},
]
}
}];
响应 JSON
{
"session": {
"id": "session_id",
"params": {},
"typeOverrides": [
{
"name": "type_name",
"synonym": {
"entries": [
{
"name": "ITEM_1",
"synonyms": [
"Item 1",
"First item"
]
},
{
"name": "ITEM_2",
"synonyms": [
"Item 2",
"Second item"
]
},
{
"name": "ITEM_3",
"synonyms": [
"Item 3",
"Third item"
]
},
{
"name": "ITEM_4",
"synonyms": [
"Item 4",
"Fourth item"
]
}
]
},
"typeOverrideMode": "TYPE_REPLACE"
}
]
},
"prompt": {
"override": false,
"firstSimple": {
"speech": "This is an example prompt.",
"text": "This is an example prompt."
}
}
}
提供语音纠偏
通过语音自定义调整,您可以指定 NLU 的提示以改进意图匹配。您最多可以指定 1000 个条目。
Node.js
conv.expected.speech = ['value_1', 'value_2']
conv.expected.language = 'locale_string'
响应 JSON
{
"session": {
"id": "session_id",
"params": {}
},
"prompt": {
"override": false,
"firstSimple": {
"speech": "This is an example prompt.",
"text": "This is an example prompt."
}
},
"expected": {
"speech": "['value_1', 'value_2']",
"language": "locale_string"
}
}
过渡场景
除了在 Actions 项目中定义静态过渡之外,您还可以使场景过渡在运行时发生。
Node.js
app.handle('transition_to_hidden_scene', conv => {
// Dynamic transition
conv.scene.next.name = "HiddenScene";
});
响应 JSON
{
"session": {
"id": "session_id",
"params": {}
},
"prompt": {
"override": false,
"firstSimple": {
"speech": "This is an example prompt.",
"text": ""
}
},
"scene": {
"name": "SceneName",
"slots": {},
"next": {
"name": "HiddenScene"
}
}
}
读取场景槽
在槽填充期间,您可以使用执行方式来验证槽位或检查槽填充状态 (SlotFillingStatus
)。
Node.js
conv.scene.slotFillingStatus // FINAL means all slots are filled
conv.scene.slots // Object that contains all the slots
conv.scene.slots['slot_name'].<property_name> // Accessing a specific slot's properties
例如,假设您要从响应中提取时区。在此示例中,槽名称为 datetime1
。如需获取时区,您应使用:
conv.scene.slots['datetime1'].value.time_zone.id
请求 JSON
{
"handler": {
"name": "handler_name"
},
"intent": {
"name": "",
"params": {
"slot_name": {
"original": "1",
"resolved": 1
}
},
"query": ""
},
"scene": {
"name": "SceneName",
"slotFillingStatus": "FINAL",
"slots": {
"slot_name": {
"mode": "REQUIRED",
"status": "SLOT_UNSPECIFIED",
"updated": true,
"value": 1
}
},
"next": {
"name": "actions.scene.END_CONVERSATION"
}
},
"session": {
"id": "session_id",
"params": {
"slot_name": 1
},
"typeOverrides": []
},
"user": {
"locale": "en-US",
"params": {
"verificationStatus": "VERIFIED"
}
},
"home": {
"params": {}
},
"device": {
"capabilities": [
"SPEECH",
"RICH_RESPONSE",
"LONG_FORM_AUDIO"
]
}
}
使场景槽位失效
您可以使槽失效,并让用户提供新值。
Node.js
conv.scene.slots['slot_name'].status = 'INVALID'
响应 JSON
{
"session": {
"id": "session_id",
"params": {
"slot_name": 1
}
},
"prompt": {
"override": false,
"firstSimple": {
"speech": "This is an example prompt.",
"text": ""
}
},
"scene": {
"name": "SceneName",
"slots": {
"slot_name": {
"mode": "REQUIRED",
"status": "INVALID",
"updated": true,
"value": 1
}
},
"next": {
"name": "actions.scene.END_CONVERSATION"
}
}
}
开发选项
Actions Builder 提供了一个名为 Cloud Functions 编辑器的内嵌编辑器,可让您直接在控制台中构建和部署 Cloud Functions for Firebase。您还可以构建执行方式并将其部署到您选择的托管服务提供商,并将 HTTPS 执行方式端点注册为网络钩子处理程序。
內嵌编辑器
如需使用 Cloud Functions 编辑器进行开发,请执行以下操作:
- 打开您的 Actions 项目,然后依次转到 Develop(开发)标签页 > Webhook > 更改 fulfillment 方法。此时将显示 Fulfillment methods 窗口。
- 选择 Inline Cloud Functions,然后点击 Confirm。
外部 HTTPS 端点
本部分介绍如何将 Cloud Functions for Firebase 设置为对话型 Action 的执行方式服务。不过,您可以将执行方式部署到您选择的托管服务中。
设置环境
如需设置您的环境,请按以下步骤操作:
- 下载并安装 Node.js。
设置并初始化 Firebase CLI。如果以下命令失败并显示
EACCES
错误,您可能需要更改 npm 权限。npm install -g firebase-tools
使用您的 Google 帐号对 Firebase 工具进行身份验证:
firebase login
启动您保存了 Actions 项目的项目目录。 系统会要求您选择要为 Actions 项目设置的 Firebase CLI 功能。选择
Functions
以及您可能想使用的其他功能(例如 Firestore),然后按 Enter 键确认并继续:$ cd <ACTIONS_PROJECT_DIRECTORY> $ firebase init
使用箭头键选择 Firebase 工具并在项目列表中导航,将 Firebase 工具与您的 Actions 项目相关联:
选择项目后,Firebase 工具会启动 Functions 设置,并询问您要使用的语言。使用箭头键进行选择,然后按 Enter 键以继续。
=== Functions Setup A functions directory will be created in your project with a Node.js package pre-configured. Functions can be deployed with firebase deploy. ? What language would you like to use to write Cloud Functions? (Use arrow keys) > JavaScript TypeScript
选择是否要使用 ESLint 捕获可能出现的 bug 并通过输入 Y 或 N 来强制执行样式:
? Do you want to use ESLint to catch probable bugs and enforce style? (Y/n)
通过在提示符中输入 Y 来获取项目依赖项:
? Do you want to install dependencies with npm now? (Y/n)
设置完成后,您将看到类似于以下内容的输出:
✔ Firebase initialization complete!
安装 @assistant/conversation 依赖项:
$ cd <ACTIONS_PROJECT_DIRECTORY>/functions $ npm install @assistant/conversation --save
获取执行方式依赖项并部署执行方式函数:
$ npm install $ firebase deploy --only functions
部署需要几分钟时间。完成后,您将看到类似于以下内容的输出。您需要在 Dialogflow 中输入函数网址。
✔ Deploy complete!
Project Console: https://console.firebase.google.com/project/<PROJECT_ID>/overview Function URL (<FUNCTION_NAME>): https://us-central1-<PROJECT_ID>.cloudfunctions.net/<FUNCTION_NAME>复制要在下一部分中使用的执行方式网址。
注册 webhook 处理程序
如需将 Cloud Functions 函数端点注册为 webhook 处理程序,请执行以下操作:
- 在 Actions 控制台中,依次点击 Develop > Webhook。
- 点击更改履单方法。此时会显示 Fulfillment methods 窗口。
- 选择 Webhook,然后点击确认。
- 将您的网络服务网址粘贴到 Webhook 字段中。
- 点击保存。