Dialogflow v1 webhook - 语音在异步调用后没有立即返回

Dialogflow v1 webhook - speech not returning immediately after an async call

我正在使用 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;

我的意图被经典地图调用了动作:intentFunction。 我读到 说 ask 方法应该有效,但它不适合我。我尝试了带有 Promise 和回调的版本,但是当我模拟我的代码时,我总是得到答案:

"message": "Failed to parse Dialogflow response into AppResponse, exception thrown with message: Empty speech response

我不明白我做错了什么?我知道问题来自异步请求,但它应该可以与 Promise 或回调一起正常工作,因为现在它 returns instantly?

它 return 是即时的,因为尽管 asyncFunction() 调用了 return 的 Promise,尽管 then()catch() 部分 return 一个承诺... asyncFunction() 本身 不是 return 一个承诺。事实上,它没有 return 任何明确的内容,因此它 return 未定义。

您可能希望该代码是

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

请注意第一行中添加 return 语句的更改。

这是处理需要 return Promise 的异步函数时的常见模式(也是经常被忽视的问题)。