http请求另一个外部URL

时间:2017-07-07 21:44:52

标签: node.js google-cloud-functions actions-on-google

所以现在我已经实现了我的Webhook,它可以通过使用动作触发功能来回答用户的基本问题。但是,如果我想从网址发出外部http请求,例如" http://api.open-notify.org/iss-now.json"该怎么办?我使用请求模块,它在我发出请求的行之后似乎没有工作/响应,或者使用来自请求的任何东西,例如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);
        }
    }
}

2 个答案:

答案 0 :(得分:1)

基本问题是你对request()的调用没有在回调函数中完成工作。在这种情况下,我不完全确定request()返回的是什么,但听起来它是意味着被送入管道的东西,而不是在它返回并包含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循环,因为你只是测试以确保属性名称等于item。只需得到input[item]的值和使用该值。循环令人困惑,因为它表明您可能不止一次地调用assistant.ask() - 这是您无法做到的。)

答案 1 :(得分:0)

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