DialogFlow V2 Webhook - 期望语音响应立即而不是在异步请求之后
DialogFlow V2 Webhook - Expects Speech responses Immediately and not after async requests
我有一个 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()
以在同一个回复中将所有内容发送给用户。所以它需要知道什么时候应该发送消息。它作为处理来自您的处理程序的响应的一部分来执行此操作。
如果您的处理程序是同步的,它会立即发送回复。
但是,如果您的处理程序是异步的,它会假设您正在 returning 一个 Promise 并等到 Promise 解决后再发送回复。因此,要处理您的异步调用,您需要 return 一个 Promise。
既然你的调用已经在使用 Promises,那么你的状态非常好!重要的是你还 return 一个 Promise 并使用它。所以像这样的事情可能是你的异步调用(return 是一个 Promise):
exports.someAsyncCall = function someAsyncCall() {
var apigClient = getAWSClient(); // uses aws-api-gateway-client
return apigClient.invokeApi(params, pathTemplate, method, additionalParams, 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
})
}
我有一个 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()
以在同一个回复中将所有内容发送给用户。所以它需要知道什么时候应该发送消息。它作为处理来自您的处理程序的响应的一部分来执行此操作。
如果您的处理程序是同步的,它会立即发送回复。
但是,如果您的处理程序是异步的,它会假设您正在 returning 一个 Promise 并等到 Promise 解决后再发送回复。因此,要处理您的异步调用,您需要 return 一个 Promise。
既然你的调用已经在使用 Promises,那么你的状态非常好!重要的是你还 return 一个 Promise 并使用它。所以像这样的事情可能是你的异步调用(return 是一个 Promise):
exports.someAsyncCall = function someAsyncCall() {
var apigClient = getAWSClient(); // uses aws-api-gateway-client
return apigClient.invokeApi(params, pathTemplate, method, additionalParams, 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
})
}