对话流完成情况和Firebase响应时间

时间:2018-08-20 11:24:01

标签: node.js firebase dialogflow

我正在尝试使用DialogFlow构建一个简单的聊天机器人。

我的目的是从用户问题中提供信息,例如:在克罗地亚,我在哪里可以放宽水面?我有两个参数(croatiawaterline)和一个松弛线位置列表。

因此,我需要一个数据库来从参数检索信息。 DialogFlow允许使用Firebase来实现。我建立了一个包含地点(名称,国家/地区,闲置类型)的数据库,并启用webhook调用来表达我的意图。

我使用内联编辑器和 index.js

const parameters = request.body.queryResult.parameters;
var country = parameters.country.toString();

function show(snap) {
   console.log('snap');
   agent.add(JSON.stringify(snap.val(),null,2));
}

function slkplc(agent) {
     var testRef;
     firebase.database().ref('slackplace').once('value',show);
}

// Run the proper function handler based on the matched Dialogflow intent name
let intentMap = new Map();
intentMap.set('slack place', slkplc);
agent.handleRequest(intentMap);

但是在DialogFlow或Google Assistant上尝试时没有得到预期的结果。函数show被异步调用,但为时已晚,并且响应不适用于 DialogFlow

firebase log

我看到了解决此问题的三种方法:

  1. 使用对数据库的阻塞调用:另一个数据库?
  2. 使用DialogFlow处理异步消息???
  3. 响应用户发生错误。

我选择的第三个,但是总是出错。

尝试了几件事以等待数据库响应中的数据后,我唯一要做的就是冻结响应,因此DialogFlow的超时时间为5s,而Firebase的超时时间为60s。

解决方法

另一种实现方法是将数据库获取和请求/响应与DialogFlow分开。数据库数据是在dialogflowFirebaseFulfillment

之外收集的
var data;
var inidata = firebase.database().ref().on('value',function(snap) {
     console.log('snap');
     data = snap.val();
 });

exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request, response) => {
 const agent = new WebhookClient({ request, response });
 ...
 function slkplc(agent) {
     agent.add(JSON.stringify(data,null,2));
 }

  // Run the proper function handler based on the matched Dialogflow intent name
  let intentMap = new Map();
  intentMap.set('slack place', slkplc);
  agent.handleRequest(intentMap);
}

现在我可以使用数据做我想做的事,而且我能够找到可以在克罗地亚练习吃水线的地方。但是总有些奇怪,数据库的数据是重复的...

1 个答案:

答案 0 :(得分:2)

“正确”的解决方案是您建议的选项2:由于您正在执行异步调用,因此在使用dialogflow-fillfillment库时,您需要正确处理此问题。

基本上,如果您的处理程序进行了异步调用,则它也必须是异步的。要向handleRequest()方法指示处理程序是异步的,您需要返回一个Promise对象。

Firebase的once()方法如果未传递回调函数,则会返回Promise。您可以利用此功能,返回承诺,并作为.then()子句的一部分来处理您希望它执行的操作。它可能看起来像这样:

function slkplc(agent) {
  var testRef;
  return firebase.database().ref('slackplace').once('value')
    .then( snap => {
      var val = snap.val();
      return agent.add( JSON.stringify( val, null, 2 ) );
    });
}

重要的部分不仅在于您使用Promise,而且还归还了Promise。