我有一个DialogFlow V2 node.js webhook.
我有一个用webhook动作调用的意图:
const { WebhookClient } = require('dialogflow-fulfillment'); const app = new WebhookClient({request: req,response: res}); function exampleIntent(app) { app.add("Speak This Out on Google Home!"); // this speaks out fine. no error. }
现在,如果我有一个成功完成的异步请求,并且我在成功块中执行app.add,如下所示:
function exampleIntent(app) { myClient.someAsyncCall(function(result,err) { app.add("This will not be spoken out"); // no dice :( } // app.add("but here it works... so it expects it immediately"); }
…然后Dialog Flow不会等待语音返回.我在Response对象中得到错误:
"message": "Failed to parse Dialogflow response into AppResponse,exception thrown with message: Empty speech response",
如何使DialogFlow V2等待Webhook的异步操作完成而不是立即期待语音响应?
注意:此问题仅在V2中开始.在V1中,app.ask在异步调用的尾端工作正常.
exampleIntent由应用程序的主映射器调用,如下所示:
let actionMap = new Map(); actionMap.set("my V2 intent name",exampleIntent); app.handleRequest(actionMap);
我在myClient.someAsyncCall中的异步请求正在使用Promises:
exports.someAsyncCall = function someAsyncCall(callback) { var apigClient = getAWSClient(); // uses aws-api-gateway-client apigClient.invokeApi(params,pathTemplate,method,additionalParams,body) .then(function(result){ var result = result.data; var message = result['message']; console.log('SUCCESS: ' + message); callback(message,null); // this succeeds and calls back fine. }).catch( function(error){ console.log('ERROR: ' + error); callback(error,null); }); };
解决方法
它在V1中工作的原因是ask()实际上会发送请求.
使用V2,您可以多次调用add()以在同一回复中将所有内容发送给用户.所以它需要知道什么时候应该发送消息.它是处理处理程序响应的一部分.
如果您的处理程序是同步的,它会立即发送回复.
但是,如果您的处理程序是异步的,它会假定您正在返回Promise并等待Promise在发送回复之前解析.因此,要处理异步调用,您需要返回一个Promise.
既然你的电话已经使用了Promise,那么你的状态非常好!重要的是你还要返回一个Promise并使用它.所以像这样的东西可能是你的异步调用(返回一个Promise):
exports.someAsyncCall = function someAsyncCall() { var apigClient = getAWSClient(); // uses aws-api-gateway-client return apigClient.invokeApi(params,body) .then(function(result){ var result = result.data; var message = result['message']; console.log('SUCCESS: ' + message); return Promise.resolve( message ); }).catch( function(error){ console.log('ERROR: ' + error); return Promise.reject( error ); }); };
然后你的Intent处理程序就像
function exampleIntent(app) { return myClient.someAsyncCall() .then( function( message ){ app.add("You should hear this message": message); return Promise.resolve(); }) .catch( function( err ){ app.add("Uh oh,something happened."); return Promise.resolve(); // Don't reject again,or it might not send the reply }) }
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。