对话流 NodeJs Fulfillment V2 - webhook 方法调用在完成回调之前结束



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

这是 Dialogflow GitHub 存储库

中的问题

法典

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 对话流 src 代码链接 - https://github.com/dialogflow/dialogflow-fulfillment-nodejs/blob/master/src/dialogflow-fulfillment.js

您需要在处理程序函数中返回一个承诺。 函数处理程序现在支持承诺,因此您可以返回承诺并处理承诺中的 HTTP 请求等内容。下面是使用请求库的示例:

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

您还可以将 HTTP 调用移动到另一个返回 promise 的函数。下面是一个 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);
}

使用 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); 
});

最新更新