【问题标题】:Dialogflow NodeJs Fulfillment V2 - webhook method call ends before completing callbackDialogflow NodeJs Fulfillment V2 - webhook 方法调用在完成回调之前结束
【发布时间】:2018-07-06 11:06:24
【问题描述】:

我正在使用 dialogflow-fulfillment-nodejs 客户端开发一个 Dialogflow webhook 来查找城市的温度。在使用服务获取城市的温度时,一切正常,并且还会生成正确的响应,但即使调用了正确的方法,响应也不会发送给用户。

Here is the issue in the Dialogflow GitHub repo

代码

function getTemp(agent) {
    const timeStart = new Date().getTime();
    console.info(`temp function called`);
    // agent.add(`Temperature in New Delhi is 50 degree Celsius!`); // This works
    serviceRequest.getTemp("New Delhi", function(resp){
        if (resp['status'] === 'Y') {
            // success
            const msg = `Temperature in New Delhi is ${resp['temp']} Celsius!`;
            console.log(`Speech Response -- ${msg}`);
            console.log(`Type of msg -> ${typeof msg}`);
            agent.add(msg);
        } else {
            // failure
            agent.add(`There was some error with the backend. Please try again later.`);
        }
        const timeEnds = new Date().getTime();
        console.log("\nComplete 'getTemp' process took " + (timeEnds - timeStart) + " milliseconds.")
    });
    console.log("------ temperature function ends here ------");
}



'getTemp': function (city, callback) {
        let respBack = {};
        doTimeOutTest(function(resp){
            respBack['temp'] = resp;
            respBack['status'] = 'Y';
            callback(respBack);
        });

    }


function doTimeOutTest(callback){
    // below commented code takes < 10 ms to execute, but does not send any response back to dialogflow as call ends before it is executed
    // setTimeout(function() {
    //     callback("30 degree");
    // }, 1);

    // Below code works even when it takes more time to execute
    for(let i=0; i<10000; i++){
        for(let j=0; j<10000; j++){
            //
        }
    }
    callback("30 degree");
}

控制台日志

注释代码运行时

>>>>>>> S E R V E R   H I T <<<<<<<

temp function called
------ temperature function ends here ------
Speech Response -- Temperature in New Delhi is 30 degree Celsius!
Type of msg -> string

Complete 'getTemp' process took 10 milliseconds.


当未注释的代码运行时

>>>>>>> S E R V E R   H I T <<<<<<<

temp function called
Speech Response -- Temperature in New Delhi is 30 degree Celsius!
Type of msg -> string

Complete 'getTemp' process took 77 milliseconds.
------ temperature function ends here ------

NodeJS Dialogflow src 代码链接 - https://github.com/dialogflow/dialogflow-fulfillment-nodejs/blob/master/src/dialogflow-fulfillment.js

【问题讨论】:

  • 问题可能出在你从这个问题中省略的代码上。
  • 我已经添加了函数和日志跟踪的完整代码
  • 有趣...如果您查看 dialogflow 实现包的代码,您可以看到他们在哪里使用 instanceOf,但它的正确之处在于它定义或导入的东西而不是用户参数。我最好的猜测是核对你的 node_modules 目录并重新安装 npm
  • 删除了项目的Node Module并使用sudo npm install重新安装。还是一样的错误:(
  • 他们的文档说要使用 ^1.0.0 版本,但没有找到我正在使用的 ^0.4.1 以上版本!!

标签: node.js webhooks actions-on-google dialogflow-es


【解决方案1】:

你需要在你的处理函数中返回一个promise。函数处理程序现在支持 Promise,因此您可以返回 Promise 并在 Promise 中处理诸如 http 请求之类的事情。下面是一个使用请求库的例子:

function dialogflowHanlderWithRequest(agent) {
  return new Promise((resolve, reject) => {
    request.get(options, (error, response, body) => {
      JSON.parse(body)
      // processing code
      agent.add(...)
      resolve();
    });
  });
};

您还可以将 HTTP 调用移至另一个返回承诺的函数。这是 axios 库的示例:

function dialogflowHandlerWithAxios(agent) {
  return callApi('www.google.com').then(response => {
    agent.add('My response');
  }).catch (error => {
    // do something
  })
};

function callApi(url) {
    return axios.get(url);
}

【讨论】:

  • 非常感谢马特 :) 我将使用第一种方法。另外,我发现使用 Sync-Request (npmjs.com/package/sync-request) 进行同步调用也可以解决问题。
  • 太棒了!很高兴我能帮上忙。请注意,同步请求包不适合生产使用,可能会影响性能。首选的解决方案是在您的意图处理程序中返回一个承诺。
  • 是的,马特。我只回报一个承诺。
【解决方案2】:

一个使用then-request的例子:

const thenRequest = require('then-request');

function callApi(resolve){

    var req = thenRequest('POST', 'https://api_url_here...',{
      headers: 
       { 
        '.....': '....'
       }
    });

    req.done(function (res) {
        ....
        agent.add("Some text goes here...");
        ...
        resolve();
    });     
}

触发请求:

return new Promise((resolve, reject) => { 
    callApi(resolve); 
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-05
    • 2017-05-28
    • 1970-01-01
    相关资源
    最近更新 更多