在开发语音应用程序时映射数据流时无法处理其他情况
Trouble handling else condition when mapping data stream while developing voice app
我目前正在开发一个带有 Google 动作的语音应用程序。基本上,用户必须在以下 data stream 中询问信息,语音应用程序应根据该数据流中的信息进行回复。目前,应用程序可以根据以下代码匹配用户的请求和流中的数据:
// From here, there are all the required libraries to be loaded
const { conversation } = require('@assistant/conversation'); // This the app coversation
const functions = require('firebase-functions'); //These are the firebase functions
require('firebase-functions/lib/logger/compat'); // console.log compact
const axios = require('axios'); // This is axios to retrieve the data stream
// To here, there all the required libraries to be loaded
const app = conversation({debug: true}); // This instantiate the conversation
/* This function retrieve the data from the file stream */
async function getItem() {
const res = await axios.get('https://sheetdb.io/api/v1/n3ol4hwmfsmqd');
return res.data; // To use in your Action's response
}
/* This is the fuction to match user's responses and data stream*/
app.handle('getItem', async conv => { //getItem is the weekhook name used in Google Actions, conv is the conversation
const data = await getItem(); // Here the data stream is retrieved and send to the data variable
// console.log(data);
const itemParam = conv.intent.params.Item.resolved; // This is the user's response, in other words, what item the user's want to know from the data.
const itemIDParam = conv.intent.params.Item_ID.resolved.replace(/\s/g, ''); //This is the user's response for item ID
const itemFromUser = itemParam + " " + itemIDParam;
console.log(itemParam);
console.log(itemIDParam);
console.log(itemFromUser);
// conv.add(`This test to see if we are accessing the webhook for ${itemParam}`); // This is to know if I was getting the correct item from the user. Currently this is working
// console.log(data);
data.map(item => { //Then, I am trying to map the data stream to recognize the data headers and identify items
// console.log(data);
// console.log(item);
if (item.Name.toLowerCase() === itemFromUser.toLowerCase()){
console.log(item);
conv.add(`These are the details for ${itemFromUser}. It is located in zone ${item.Zone}, at level ${item.Level}.`);
// console.log(conv);
// console.log(data);
}
else {
conv.add(`I am sorry. I could not find any information about that object. Please try with another construction object.`);
}
});
});
exports.ActionsOnGoogleFulfillment = functions.https.onRequest(app);
data.map 函数有一个 if else 语句来管理何时匹配数据,何时不匹配。
data.map(item => { //Then, I am trying to map the data stream to recognize the data headers and identify items
// console.log(data);
// console.log(item);
if (item.Name.toLowerCase() === itemFromUser.toLowerCase()){
console.log(item);
conv.add(`These are the details for ${itemFromUser}. It is located in zone ${item.Zone}, at level ${item.Level}.`);
// console.log(conv);
// console.log(data);
}
else {
conv.add(`I am sorry. I could not find any information about that object. Please try with another construction object.`);
}
});
当条件为真时,if 在没有else 语句的情况下起作用。但是由于某些原因,当添加 else 语句并且数据没有匹配到任何用户时,它使应用程序表现得很奇怪,在控制台中显示以下错误:
Error: Error adding simple response: Two simple responses already defined
无论数据是否匹配,我都会收到此错误。
我正在做的测试是评论 else 语句。这使我能够获得数据的匹配项,但当数据不匹配时应用程序会原地切入。但理想情况下,我希望应用程序告诉用户查询没有找到任何匹配项。
在此先感谢,我希望有人能给我一些提示。
您看到的错误是:
Error: Error adding simple response: Two simple responses already defined
您的操作响应只能包含 two simple responses。例如,每个响应都呈现为 phone 上的单独文本气泡。
所以看起来 item.Name === itemParam
可能 运行 一次,但在 else
条件下你最终会创建太多。您可能想要 re-evaluate 如何 运行 您的条件。
但据我所知,有两种快速方法可以解决此问题:
字符串生成器方法
在这种方法中,您可以在循环之前创建一个字符串变量,而不是立即添加到 conv
,您只需继续附加到字符串直到完成。然后你添加整个东西。
这种方法的缺点是无论如何您最终都可能会得到一个巨大的字符串,并且平台将运行将字符串分类为最多 640 个字符。
app.handle('getItem', async conv => {
const data = await getItem();
const itemParam = conv.intent.params.Item.resolved;
let res = '';
data.map(item => {
if (item.Name === itemParam);
res += `These are the datails for ${itemParam}. It is located in zone ${item.Zone}, at level ${item.Level}`;
});
if (res !== '') {
conv.add(res);
} else {
conv.add('No items were found.')
}
});
提前退出方法
您还可以将循环编写为不使用函数式编程方法,而是识别条件为真的第一个实例,然后提前退出处理程序。这将使您进入 for-of
循环,然后添加一个 return
来结束执行。
缺点是您的处理程序随后已完成,您将无法执行任何其他逻辑。或者,您可以将此子例程粘贴到它自己的函数中进行调用。然后您自己在处理程序中捕获该响应。
function getItemDetails(data) {
for (const item of data) {
if (item.Name === itemParam) {
return item
}
}
return undefined
}
app.handle('getItem', async conv => {
const data = await getItem();
const itemParam = conv.intent.params.Item.resolved;
const item = getItemDetails(data)
if (item !== undefined) {
conv.add(`These are the datails for ${itemParam}. It is located in zone ${item.Zone}, at level ${item.Level}`);
} else {
conv.add('No items were found.')
}
});
我目前正在开发一个带有 Google 动作的语音应用程序。基本上,用户必须在以下 data stream 中询问信息,语音应用程序应根据该数据流中的信息进行回复。目前,应用程序可以根据以下代码匹配用户的请求和流中的数据:
// From here, there are all the required libraries to be loaded
const { conversation } = require('@assistant/conversation'); // This the app coversation
const functions = require('firebase-functions'); //These are the firebase functions
require('firebase-functions/lib/logger/compat'); // console.log compact
const axios = require('axios'); // This is axios to retrieve the data stream
// To here, there all the required libraries to be loaded
const app = conversation({debug: true}); // This instantiate the conversation
/* This function retrieve the data from the file stream */
async function getItem() {
const res = await axios.get('https://sheetdb.io/api/v1/n3ol4hwmfsmqd');
return res.data; // To use in your Action's response
}
/* This is the fuction to match user's responses and data stream*/
app.handle('getItem', async conv => { //getItem is the weekhook name used in Google Actions, conv is the conversation
const data = await getItem(); // Here the data stream is retrieved and send to the data variable
// console.log(data);
const itemParam = conv.intent.params.Item.resolved; // This is the user's response, in other words, what item the user's want to know from the data.
const itemIDParam = conv.intent.params.Item_ID.resolved.replace(/\s/g, ''); //This is the user's response for item ID
const itemFromUser = itemParam + " " + itemIDParam;
console.log(itemParam);
console.log(itemIDParam);
console.log(itemFromUser);
// conv.add(`This test to see if we are accessing the webhook for ${itemParam}`); // This is to know if I was getting the correct item from the user. Currently this is working
// console.log(data);
data.map(item => { //Then, I am trying to map the data stream to recognize the data headers and identify items
// console.log(data);
// console.log(item);
if (item.Name.toLowerCase() === itemFromUser.toLowerCase()){
console.log(item);
conv.add(`These are the details for ${itemFromUser}. It is located in zone ${item.Zone}, at level ${item.Level}.`);
// console.log(conv);
// console.log(data);
}
else {
conv.add(`I am sorry. I could not find any information about that object. Please try with another construction object.`);
}
});
});
exports.ActionsOnGoogleFulfillment = functions.https.onRequest(app);
data.map 函数有一个 if else 语句来管理何时匹配数据,何时不匹配。
data.map(item => { //Then, I am trying to map the data stream to recognize the data headers and identify items
// console.log(data);
// console.log(item);
if (item.Name.toLowerCase() === itemFromUser.toLowerCase()){
console.log(item);
conv.add(`These are the details for ${itemFromUser}. It is located in zone ${item.Zone}, at level ${item.Level}.`);
// console.log(conv);
// console.log(data);
}
else {
conv.add(`I am sorry. I could not find any information about that object. Please try with another construction object.`);
}
});
当条件为真时,if 在没有else 语句的情况下起作用。但是由于某些原因,当添加 else 语句并且数据没有匹配到任何用户时,它使应用程序表现得很奇怪,在控制台中显示以下错误:
Error: Error adding simple response: Two simple responses already defined
无论数据是否匹配,我都会收到此错误。
我正在做的测试是评论 else 语句。这使我能够获得数据的匹配项,但当数据不匹配时应用程序会原地切入。但理想情况下,我希望应用程序告诉用户查询没有找到任何匹配项。
在此先感谢,我希望有人能给我一些提示。
您看到的错误是:
Error: Error adding simple response: Two simple responses already defined
您的操作响应只能包含 two simple responses。例如,每个响应都呈现为 phone 上的单独文本气泡。
所以看起来 item.Name === itemParam
可能 运行 一次,但在 else
条件下你最终会创建太多。您可能想要 re-evaluate 如何 运行 您的条件。
但据我所知,有两种快速方法可以解决此问题:
字符串生成器方法
在这种方法中,您可以在循环之前创建一个字符串变量,而不是立即添加到 conv
,您只需继续附加到字符串直到完成。然后你添加整个东西。
这种方法的缺点是无论如何您最终都可能会得到一个巨大的字符串,并且平台将运行将字符串分类为最多 640 个字符。
app.handle('getItem', async conv => {
const data = await getItem();
const itemParam = conv.intent.params.Item.resolved;
let res = '';
data.map(item => {
if (item.Name === itemParam);
res += `These are the datails for ${itemParam}. It is located in zone ${item.Zone}, at level ${item.Level}`;
});
if (res !== '') {
conv.add(res);
} else {
conv.add('No items were found.')
}
});
提前退出方法
您还可以将循环编写为不使用函数式编程方法,而是识别条件为真的第一个实例,然后提前退出处理程序。这将使您进入 for-of
循环,然后添加一个 return
来结束执行。
缺点是您的处理程序随后已完成,您将无法执行任何其他逻辑。或者,您可以将此子例程粘贴到它自己的函数中进行调用。然后您自己在处理程序中捕获该响应。
function getItemDetails(data) {
for (const item of data) {
if (item.Name === itemParam) {
return item
}
}
return undefined
}
app.handle('getItem', async conv => {
const data = await getItem();
const itemParam = conv.intent.params.Item.resolved;
const item = getItemDetails(data)
if (item !== undefined) {
conv.add(`These are the datails for ${itemParam}. It is located in zone ${item.Zone}, at level ${item.Level}`);
} else {
conv.add('No items were found.')
}
});