如何在 BotKit 中存储和访问来自外部 API 请求的对话变量?
How to store and access conversation variables from external API request in BotKit?
总结
我正在使用 BotKit 制作一个网络应用聊天机器人(使用 BotkitConversation API)。我想使用用户的输入查询外部 API,然后 return 一些结果数据给用户。
我能够将用户的输入作为变量存储在对话框对象上(使用 {{vars.key}}
模板)并且我可以从 API 访问 JSON 响应并显示在控制台中,但是不在聊天中 window.
我试过的
我正在尝试使用 convo.setVar()
来存储一些 JSON 数据。我知道 API 调用有效,因为我也 console.log
相同的值并且它符合预期。
一些代码
(注意:api_key
和 endpoint
存储在其他地方,这只是摘录)
/* The Query Dialog */
let DIALOG_ID = 'my_dialog_1';
let query_dialog = new BotkitConversation(DIALOG_ID, controller);
let total = 0;
query_dialog.ask('What search term would you like to search with?', async(queryTerm, query_dialog, bot) => {
query_dialog.setVar('queryTerm', queryTerm);
console.log(`user query is "${ queryTerm }".`);
console.log(`fetching results from: ${endpoint}?api_key=${api_key}&q=${queryTerm}`);
fetch(`${endpoint}?api_key=${api_key}&q=${queryTerm}`)
.then((response) => response.json())
.then((json) => {
query_dialog.setVar('total', json.total);
console.log(`~~total number of results: ${json.total}~~`); // this shows: 2
// bot.say(`there were {{vars.total}} results`); // this never gets called
// bot.say(`there were ${total} results`); // this never gets called
total = json.total;
})
// .then((json) => console.log(`~~total number of results: ${json.total}~~`)) // this shows: 2
// .then((json) => query_dialog.setVar('total', json.total), () => (bot.say(`there were {{vars.total}} results`))) // this doesn't run
.catch(error => console.log(error))
}, 'queryTerm');
query_dialog.say(`user query is {{vars.queryTerm}}.`); // this works as expected
query_dialog.say(`there were {{vars.total}} results`); // shows "" results
// query_dialog.say(`there were ${total} results`); // says "there were 0 results", which is incorrect, and just pulls from whatever `let total` started with
controller.addDialog(query_dialog);
/* End Dialog */
/* Trigger the dialog */
controller.hears('query', 'message', async(bot, message) => {
await bot.beginDialog(DIALOG_ID);
});
期望与现实
正如预期的那样,在聊天 window 中,用户的查询被重复返回给他们:"user query is {your_query}"。
但是,显示的下一行是 "there were results",这意味着 vars.total
中没有存储任何内容。实际输出应该是一个数字。
您在这里遇到的问题是对 fetch
return 的调用是一个承诺,异步处理函数会立即解析,而不是等待获取 return 结果和将它们设置到对话框内存中 space.
解决这个问题的最简单方法是return一个承诺,这样您就可以控制它何时解决:
return new Promise(function(resolve, reject) {
/// do fetch here
fetch.then().then().then(resolve)
});
总结
我正在使用 BotKit 制作一个网络应用聊天机器人(使用 BotkitConversation API)。我想使用用户的输入查询外部 API,然后 return 一些结果数据给用户。
我能够将用户的输入作为变量存储在对话框对象上(使用 {{vars.key}}
模板)并且我可以从 API 访问 JSON 响应并显示在控制台中,但是不在聊天中 window.
我试过的
我正在尝试使用 convo.setVar()
来存储一些 JSON 数据。我知道 API 调用有效,因为我也 console.log
相同的值并且它符合预期。
一些代码
(注意:api_key
和 endpoint
存储在其他地方,这只是摘录)
/* The Query Dialog */
let DIALOG_ID = 'my_dialog_1';
let query_dialog = new BotkitConversation(DIALOG_ID, controller);
let total = 0;
query_dialog.ask('What search term would you like to search with?', async(queryTerm, query_dialog, bot) => {
query_dialog.setVar('queryTerm', queryTerm);
console.log(`user query is "${ queryTerm }".`);
console.log(`fetching results from: ${endpoint}?api_key=${api_key}&q=${queryTerm}`);
fetch(`${endpoint}?api_key=${api_key}&q=${queryTerm}`)
.then((response) => response.json())
.then((json) => {
query_dialog.setVar('total', json.total);
console.log(`~~total number of results: ${json.total}~~`); // this shows: 2
// bot.say(`there were {{vars.total}} results`); // this never gets called
// bot.say(`there were ${total} results`); // this never gets called
total = json.total;
})
// .then((json) => console.log(`~~total number of results: ${json.total}~~`)) // this shows: 2
// .then((json) => query_dialog.setVar('total', json.total), () => (bot.say(`there were {{vars.total}} results`))) // this doesn't run
.catch(error => console.log(error))
}, 'queryTerm');
query_dialog.say(`user query is {{vars.queryTerm}}.`); // this works as expected
query_dialog.say(`there were {{vars.total}} results`); // shows "" results
// query_dialog.say(`there were ${total} results`); // says "there were 0 results", which is incorrect, and just pulls from whatever `let total` started with
controller.addDialog(query_dialog);
/* End Dialog */
/* Trigger the dialog */
controller.hears('query', 'message', async(bot, message) => {
await bot.beginDialog(DIALOG_ID);
});
期望与现实
正如预期的那样,在聊天 window 中,用户的查询被重复返回给他们:"user query is {your_query}"。
但是,显示的下一行是 "there were results",这意味着 vars.total
中没有存储任何内容。实际输出应该是一个数字。
您在这里遇到的问题是对 fetch
return 的调用是一个承诺,异步处理函数会立即解析,而不是等待获取 return 结果和将它们设置到对话框内存中 space.
解决这个问题的最简单方法是return一个承诺,这样您就可以控制它何时解决:
return new Promise(function(resolve, reject) {
/// do fetch here
fetch.then().then().then(resolve)
});