Как вызвать API внутри облачной функции?

#node.js #google-cloud-platform #google-cloud-functions #dialogflow-es #dialogflow-es-fulfillment

#node.js #google-облачная платформа #google-cloud-функции #диалоговые потоки #диалоговый поток-это выполнение

Вопрос:

Я работаю над действиями в Google chatbot с использованием Dialogflow и облачных функций. Среда выполнения является Node.js 6.

Почему эта функция возвращает пустую строку?

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

Это намерение, с помощью которого я хочу получить доступ к данным json:

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

Ответ №1:

Вы можете попробовать использовать 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. Хорошо, можете ли вы объяснить, как получить доступ к объекту JSON внутри моего намерения?

Ответ №2:

Функция возвращает пустую строку, потому что https настраивает функцию обратного вызова, но поток программы продолжается до инструкции return перед вызовом обратного вызова.

В общем, при работе с обработчиками намерений Dialogflow вы должны возвращать обещание вместо использования обратных вызовов или событий. Попробуйте вместо этого использовать request-promise-native.

Два уточняющих момента:

  • Вы должны вернуть обещание. В противном случае Dialogflow будет считать, что обработчик завершен. Если вы вернете обещание, оно будет ждать завершения обещания.
  • Все, что вы хотите отправить обратно, должно быть сделано внутри 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);
    });
  

Комментарии:

1. Спасибо! Я все еще не понимаю, как получить доступ к данным json. Я добавил код моего тестового намерения к своему вопросу.

2. Надеюсь, прояснено.

Ответ №3:

Вы также можете использовать Axios

Для установки Axios : npm install axios

или

Вы можете добавить его в package.json как зависимость

  "dependencies": {
     "axios": "^0.27.2",
  }
  

index.js

 const axios = require('axios').default;

exports.makeRequest = async (req, res) => {

  axios.get('https://jsonplaceholder.typicode.com/todos/1')// Dummy URL
  .then(function (response) {
    // handle success
  res.status(200).json({
  success:true,
  result:response.data
  })
   
})
  .catch(function (error) {
    // handle error
    
    console.log(error);
  })
};
  

или

  const Axios = require("axios");

  exports.makeRequest = async (req, res) => {
  const { data } = await 
  Axios.get('https://jsonplaceholder.typicode.com/todos/1')
    res.status(200).send({data})
 };