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