如何在BotKit中存储和访问来自外部API请求的会话变量?

时间:2019-06-28 15:32:01

标签: javascript rest botkit

摘要

我正在使用BotKit(使用BotkitConversation API)制作一个网络应用聊天机器人。我想使用来自用户的输入来查询外部API,然后将一些结果数据返回给用户。 我可以将用户的输入作为变量存储在对话框对象上(使用{{vars.key}}模板),并且可以从API访问JSON响应并在控制台中显示,但不能在聊天窗口中显示。

我尝试过的

我正在尝试使用convo.setVar()存储一些JSON数据。我知道API调用是有效的,因为我也console.log拥有相同的值并且符合预期。

一些代码

(请注意:诸如api_keyendpoint之类的内容存储在其他位置,

/* 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);
});

期望与现实

如预期的那样,在聊天窗口中,将用户的查询重复返回给他们:“用户查询为{your_query}”。 但是,下一行显示的是“有结果”,这意味着vars.total中没有存储任何内容。实际输出应该是数字。

1 个答案:

答案 0 :(得分:1)

这里遇到的问题是对fetch的调用返回了一个promise,并且异步处理程序函数会立即解析,而不是等待获取来返回结果并将它们设置到对话框内存空间中。

解决此问题的最简单方法是返回承诺,以便您控制何时解决:

return new Promise(function(resolve, reject) { 

 /// do fetch here
 fetch.then().then().then(resolve)

});