另一个外部 url 的 http 请求

http request for another external url

所以现在我已经实现了我的 Webhook,它可以通过使用动作触发器功能回答用户的基本问题。但是,如果我想从 url 发出外部 http 请求,例如“http://api.open-notify.org/iss-now.json”,该怎么办?我使用了请求模块,但在我发出请求的行之后似乎没有 working/responding,或者使用请求中的任何内容,例如 req.body(实际上它只是让我在 api.ai 中不可用,当我输入触发意图)。这些功能可以毫无问题地部署,但我只是想知道如何让它工作。提前致谢。

function fetch_query(assistant){
    const intent = assistant.getIntent();
    let item = '';
    if (intent == 'input.loc')
        item = 'iss_position';
    else if (intent == 'input.msg')
        item = 'message';
    else if (intent == 'input.time')
        item = 'timestamp'
    var req = request('http://api.open-notify.org/iss-now.json',
        function (error, response, body){
            if (!error && response.statusCode == 200){
                console.log('request successful!');
            }
        });
    var input = JSON.parse(req.body);
    for (var i in input){
        if (i == item){
            const speech = `<speak> ${input[i]} </speak>`;
            assistant.ask(speech);
        }
    }
}

基本问题是您对 request() 的调用没有在回调函数中完成工作。我不完全确定在这种情况下 request() returns 是什么,但听起来它应该被送入管道,而不是阻塞直到 returns并包含 body 属性.

这部分的解决方案是将您的处理移动到回调中。所以更像这样:

request('http://api.open-notify.org/iss-now.json',
    function (error, response, body){
        if (!error && response.statusCode == 200){
            console.log('request successful!');

            var input = JSON.parse(body);
            // Do something with the body here
            // including calling assistant.ask()
        }
    });

(作为一种风格,您可能不需要 for-in 循环,因为您只是在测试以确保 属性 名称等于项目。只需获取值input[item] 并使用该值。循环令人困惑,因为它表明您可能不止一次调用 assistant.ask() - 您不能这样做。)

感谢@Prisoner 回答这个问题。要通过 firebase 云功能发出外部请求,需要获得付费计划。如果数据不是那么大,不需要使用数据库,我推荐 go blaze: https://firebase.google.com/pricing/ 购买后,再次部署您的功能,它应该适用于 api.ai/action 模拟器动态查询某些内容。