我正在使用DialogFlow V1 node.js webhook,我遇到了问题。 我的意图是连接到Spotify API以获取聊天机器人的曲目:
const {DialogflowApp} = require('actions-on-google');
function spotifyIntent(app) {
//Get search parameters
[...]
return asyncFunction(query).then(function (message) {
this.app.ask(message);
return Promise.resolve();
}).catch(function (err) {
this.app.ask("Une erreur est apparue: "+err);
return Promise.resolve();
})
}
我的异步功能是:
function asyncFunction(query) {
spotifyApi.clientCredentialsGrant()
.then(function(data) {
// spotifyApi.setAccessToken(data.body['access_token']);
return spotifyApi.searchTracks(query);
}).then(function(data) {
const link = data.body.tracks.items[0].preview_url;
let speech = '<speak>Here is the first result found.<audio src="'+ link +'">I didn\'t found it</audio></speak>';
return Promise.resolve(speech);
}).catch(function(err) {
return Promise.reject(err);
});
}
在clientCredentialsGrant()和searchTracks()的调用中隐藏了一个Promise;
我的意图由带有action的经典地图调用:intentFunction。 我读here请问方法应该有效,但对我来说并不适用。我尝试使用Promise和回调版本但是当我模拟我的代码时,我总能得到答案:
"message": "Failed to parse Dialogflow response into AppResponse, exception thrown with message: Empty speech response
我不明白我在这里做错了什么?我知道问题来自请求是异步但它应该可以正常使用Promise或回调,因为它现在立即返回?
答案 0 :(得分:2)
它会立即返回,因为虽然asyncFunction()
会调用返回Promise的内容,但then()
和catch()
部分会返回Promise ... asyncFunction()
本身会< strong>不返回承诺。实际上,它不会显式返回任何内容,因此它返回undefined。
您可能希望代码
function asyncFunction(query) {
return spotifyApi.clientCredentialsGrant()
.then(function(data) {
// spotifyApi.setAccessToken(data.body['access_token']);
return spotifyApi.searchTracks(query);
}).then(function(data) {
const link = data.body.tracks.items[0].preview_url;
let speech = '<speak>Here is the first result found.<audio src="'+ link +'">I didn\'t found it</audio></speak>';
return Promise.resolve(speech);
}).catch(function(err) {
return Promise.reject(err);
});
}
请注意添加返回语句的第一行的更改。
在处理需要返回Promise的异步函数时,这是一种常见模式(以及经常被忽视的问题)。