How to call an API inside a cloud function?

时间:2019-03-06 11:33:38

标签: node.js google-cloud-platform google-cloud-functions dialogflow dialogflow-fulfillment

I'm working on an Actions on Google chatbot using Dialogflow and Cloud Functions. The runtime is Node.js 6.

Why does this function return the empty string?

function getJSON(url) {
  var json = "";
  var request = https.get(url, function(response) {
    var body = "";
    json = 'response';
    response.on("data", function(chunk) {
      body += chunk;
      json = 'chunk';
    });
    response.on("end", function() {
      if (response.statusCode == 200) {
        try {
          json = 'JSON.parse(body)';
          return json;
        } catch (error) {
          json = 'Error1';
          return json;
        }
      } else {
        json = 'Error2';
        return json;
      }
    });
  });
  return json;
}

This is the intent in which I want to access the json data:

app.intent('test', (conv) => {
conv.user.storage.test = 'no change';
const rp = require("request-promise-native");
var options = {
    uri: 'https://teamtreehouse.com/joshtimonen.json',
    headers: {
        'User-Agent': 'Request-Promise'
    },
    json: true // Automatically parses the JSON string in the response
};

rp(options)
    .then(function (user) {
        conv.user.storage.test = user.name;
    })
    .catch(function (err) {
        conv.user.storage.test = 'fail';
    });
conv.ask(conv.user.storage.test);
});

2 个答案:

答案 0 :(得分:0)

您可以尝试将request模块用于node.js,我尝试自我复制您的用例,并正常工作。该代码应类似于以下内容:

const request = require('request');

request(url, {json: true}, (err, res, body) => {
  if (err) { res.send(JSON.stringify({ 'fulfillmentText': "Some error"})); }
    console.log(body);
  });

此外,您需要在"request": "2.81.0"文件内的dependencies部分中添加package.json

答案 1 :(得分:0)

该函数返回空字符串,因为https设置了一个回调函数,但是程序流程在调用该回调之前继续执行return语句。

通常,在使用Dialogflow意向处理程序时,您应该返回一个Promise,而不是使用回调或事件。考虑改用request-promise-native

两个澄清点:

  • 必须退还承诺。否则,Dialogflow将假定处理程序已完成。如果您返回了Promise,它将等待Promise完成。
  • 您要发送回的所有邮件都必须在then()块内完成。这包括设置任何响应。 then()块在异步操作(Web API调用)完成后运行。这样就可以得到调用的结果,您可以在调用conv.ask()的过程中返回这些结果。

所以它可能看起来像这样:

  return rp(options)
    .then(function (user) {
      conv.add('your name is '+user.name);
    })
    .catch(function (err) {
      conv.add('something went wrong '+err);
    });