Google 上的操作 - 处理来自 dialogflow 的轮播响应
Actions on Google - handling carousel responses from dialogflow
我创建了一个简单的 Google 助手界面,使用 DialogFlow 和几个我希望能够链接在一起的传送带。但是,每当我触摸轮播选项时,它总是会转到指定了 actions_intent_OPTION 事件的第一个 Intent。我可以使用语音命令访问我的所有屏幕,但我不确定如何处理触摸命令以将用户发送到正确的 Intent。
webhook 中的当前代码:
const party = 'party';
const cocktail = 'cocktail';
const SELECTED_ITEM_RESPONSES = {
[party]: 'You selected party',
[cocktail]: 'You selected cocktail',
};
function carousel(agent) {
//agent.add(`Item selected`);
app.intent('actions.intent.OPTION', (conv, params, option) => {
let response = 'You did not select any item from the list or carousel';
if (option && SELECTED_ITEM_RESPONSES.hasOwnProperty(option)) {
response = SELECTED_ITEM_RESPONSES[option];
} else {
response = 'You selected an unknown item from the list or carousel';
}
conv.ask(response);
});
}
如果我保留 agent.add() 行,那么我会得到 "Item selected"... 但是如果我尝试使用 app.intent 代码,它说我只是收到空的语音响应。
我试图创建 1 个名为 CarouselHandler 的意图来处理所有菜单选择。当该意图被事件击中时,我使用示例代码调用 carousel() 函数。
let intentMap = new Map();
intentMap.set('Default Welcome Intent', welcome);
intentMap.set('Default Fallback Intent', fallback);
intentMap.set('CarouselHandler', carousel);
agent.handleRequest(intentMap);
您在这里有几个关于使用选项的问题。让我们试着弄清楚一些事情。
我可以为每个选项触发不同的 Intent 吗?
没有。向 Dialogflow 报告选项的方式是所有选项都将触发相同的 Intent。您负责查看发送的选项字符串并根据需要调用另一个函数。
如您所述,您需要使用事件创建 Intent actions_intent_OPTION
。
您处理此问题的代码可能看起来像这样,尽管还有其他方法可以处理它:
app.intent('list.reply.click', (conv, params, option) => {
// Get the user's selection
// Compare the user's selections to each of the item's keys
if (!option) {
conv.ask('You did not select any item from the list or carousel');
} else if (option === 'OPTION_1') {
handleOption1( conv );
} else if (option === 'OPTION_2') {
handleOption2Or3( conv );
} else if (option === 'OPTION_3') {
handleOption2Or3( conv );
} else {
conv.ask('You selected an unknown item from the list, or carousel');
}
});
我可以为每个轮播触发不同的 Intent 吗?
是的。为此,当您发送轮播时,您将设置一个 OutgoingContext 并删除您为轮播创建的任何其他 OutgoingContext(将它们的生命周期设置为 0)。然后您将创建一个将此上下文作为 IncomingContext 的 Intent。
如果您使用的是 actions-on-google 库
,则发送轮播的代码可能看起来像这样
conv.ask("Here is menu 2");
conv.ask(new List({
title: "Menu 2",
items: {
"OPTION_1": {
title: "Option 1",
description: "Description 1"
},
"OPTION_2": {
title: "Option 2",
description: "Description 2"
},
"OPTION_3": {
title: "Option 3",
description: "Description 3"
},
}
});
conv.contexts.set("menu_2",99);
conv.contexts.delete("menu_1");
conv.contexts.delete("menu_3");
// Don't forget to add suggestions, too
如果您使用的是 dialogflow-fulfillment 库,它会很相似,尽管存在一些差异:
let conv = agent.conv();
conv.ask("Here is menu 2");
conv.ask(new List({
title: "Menu 2",
items: {
"OPTION_1": {
title: "Option 1",
description: "Description 1"
},
"OPTION_2": {
title: "Option 2",
description: "Description 2"
},
"OPTION_3": {
title: "Option 3",
description: "Description 3"
},
}
});
agent.add(conv);
agent.setContext({name:"menu_1", lifespan:0});
agent.setContext({name:"menu_2", lifespan:99});
agent.setContext({name:"menu_3", lifespan:0});
如果您使用的是 multivocal,响应配置可能如下所示:
{
Template: {
Text: "Here is menu 2",
Option: {
Type: "carousel",
Title: "Menu 2",
Items: [
{
Title: "Option 1",
Body: "Description 1"
},
{
Title: "Option 2",
Body: "Description 2"
},
{
Title: "Option 3",
Body: "Description 3"
}
]
}
},
Context: [
{
name: "menu_1",
lifetime: 0
},
{
name: "menu_2",
lifetime: 99
},
{
name: "menu_3",
lifetime: 0
}
]
}
捕获此选项建议的 Intent 可能如下所示:
除了使用不同的 Intent 名称外,您处理此问题的代码与上面类似。
如果处理程序之间存在重叠选项,它们可以调用实际执行工作的同一函数(同样,如上所述)。
如何以相同的方式处理语音和选项响应?
AoG在某些情况下会使用语音响应来触发选项。这就是别名的用途。但除此之外,如果您有捕获用户短语的 Intent 和与选项一起使用的 Intent,您需要做的就是让实现代码调用相同的函数。
为什么代码不起作用?
行
app.intent('actions.intent.OPTION', (conv, params, option) => {
可能并不像您认为的那样。除非这是 Dialogflow 中 Intent 的名称,否则字符串 actions.intent.OPTION
不会出现在您的处理程序中。这也是您向 actions-on-google 库注册 Intent 处理程序的方式。
您似乎也在将注册 Intent 处理程序的 dialogflow-fulfillment 库方式与通过 carousel()
函数注册 Intent 处理程序的 actions-on-google 库方式混合在一起。不要这样做。 (这也可能是回复未正确返回的部分原因。)
我创建了一个简单的 Google 助手界面,使用 DialogFlow 和几个我希望能够链接在一起的传送带。但是,每当我触摸轮播选项时,它总是会转到指定了 actions_intent_OPTION 事件的第一个 Intent。我可以使用语音命令访问我的所有屏幕,但我不确定如何处理触摸命令以将用户发送到正确的 Intent。
webhook 中的当前代码:
const party = 'party';
const cocktail = 'cocktail';
const SELECTED_ITEM_RESPONSES = {
[party]: 'You selected party',
[cocktail]: 'You selected cocktail',
};
function carousel(agent) {
//agent.add(`Item selected`);
app.intent('actions.intent.OPTION', (conv, params, option) => {
let response = 'You did not select any item from the list or carousel';
if (option && SELECTED_ITEM_RESPONSES.hasOwnProperty(option)) {
response = SELECTED_ITEM_RESPONSES[option];
} else {
response = 'You selected an unknown item from the list or carousel';
}
conv.ask(response);
});
}
如果我保留 agent.add() 行,那么我会得到 "Item selected"... 但是如果我尝试使用 app.intent 代码,它说我只是收到空的语音响应。
我试图创建 1 个名为 CarouselHandler 的意图来处理所有菜单选择。当该意图被事件击中时,我使用示例代码调用 carousel() 函数。
let intentMap = new Map();
intentMap.set('Default Welcome Intent', welcome);
intentMap.set('Default Fallback Intent', fallback);
intentMap.set('CarouselHandler', carousel);
agent.handleRequest(intentMap);
您在这里有几个关于使用选项的问题。让我们试着弄清楚一些事情。
我可以为每个选项触发不同的 Intent 吗?
没有。向 Dialogflow 报告选项的方式是所有选项都将触发相同的 Intent。您负责查看发送的选项字符串并根据需要调用另一个函数。
如您所述,您需要使用事件创建 Intent actions_intent_OPTION
。
您处理此问题的代码可能看起来像这样,尽管还有其他方法可以处理它:
app.intent('list.reply.click', (conv, params, option) => {
// Get the user's selection
// Compare the user's selections to each of the item's keys
if (!option) {
conv.ask('You did not select any item from the list or carousel');
} else if (option === 'OPTION_1') {
handleOption1( conv );
} else if (option === 'OPTION_2') {
handleOption2Or3( conv );
} else if (option === 'OPTION_3') {
handleOption2Or3( conv );
} else {
conv.ask('You selected an unknown item from the list, or carousel');
}
});
我可以为每个轮播触发不同的 Intent 吗?
是的。为此,当您发送轮播时,您将设置一个 OutgoingContext 并删除您为轮播创建的任何其他 OutgoingContext(将它们的生命周期设置为 0)。然后您将创建一个将此上下文作为 IncomingContext 的 Intent。
如果您使用的是 actions-on-google 库
,则发送轮播的代码可能看起来像这样conv.ask("Here is menu 2");
conv.ask(new List({
title: "Menu 2",
items: {
"OPTION_1": {
title: "Option 1",
description: "Description 1"
},
"OPTION_2": {
title: "Option 2",
description: "Description 2"
},
"OPTION_3": {
title: "Option 3",
description: "Description 3"
},
}
});
conv.contexts.set("menu_2",99);
conv.contexts.delete("menu_1");
conv.contexts.delete("menu_3");
// Don't forget to add suggestions, too
如果您使用的是 dialogflow-fulfillment 库,它会很相似,尽管存在一些差异:
let conv = agent.conv();
conv.ask("Here is menu 2");
conv.ask(new List({
title: "Menu 2",
items: {
"OPTION_1": {
title: "Option 1",
description: "Description 1"
},
"OPTION_2": {
title: "Option 2",
description: "Description 2"
},
"OPTION_3": {
title: "Option 3",
description: "Description 3"
},
}
});
agent.add(conv);
agent.setContext({name:"menu_1", lifespan:0});
agent.setContext({name:"menu_2", lifespan:99});
agent.setContext({name:"menu_3", lifespan:0});
如果您使用的是 multivocal,响应配置可能如下所示:
{
Template: {
Text: "Here is menu 2",
Option: {
Type: "carousel",
Title: "Menu 2",
Items: [
{
Title: "Option 1",
Body: "Description 1"
},
{
Title: "Option 2",
Body: "Description 2"
},
{
Title: "Option 3",
Body: "Description 3"
}
]
}
},
Context: [
{
name: "menu_1",
lifetime: 0
},
{
name: "menu_2",
lifetime: 99
},
{
name: "menu_3",
lifetime: 0
}
]
}
捕获此选项建议的 Intent 可能如下所示:
除了使用不同的 Intent 名称外,您处理此问题的代码与上面类似。
如果处理程序之间存在重叠选项,它们可以调用实际执行工作的同一函数(同样,如上所述)。
如何以相同的方式处理语音和选项响应?
AoG在某些情况下会使用语音响应来触发选项。这就是别名的用途。但除此之外,如果您有捕获用户短语的 Intent 和与选项一起使用的 Intent,您需要做的就是让实现代码调用相同的函数。
为什么代码不起作用?
行
app.intent('actions.intent.OPTION', (conv, params, option) => {
可能并不像您认为的那样。除非这是 Dialogflow 中 Intent 的名称,否则字符串 actions.intent.OPTION
不会出现在您的处理程序中。这也是您向 actions-on-google 库注册 Intent 处理程序的方式。
您似乎也在将注册 Intent 处理程序的 dialogflow-fulfillment 库方式与通过 carousel()
函数注册 Intent 处理程序的 actions-on-google 库方式混合在一起。不要这样做。 (这也可能是回复未正确返回的部分原因。)