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

时间:2018-03-27 13:16:25

标签: node.js spotify actions-on-google dialogflow

我正在使用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或回调,因为它现在立即返回?

1 个答案:

答案 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的异步函数时,这是一种常见模式(以及经常被忽视的问题)。