Kamusta kayong lahat! Ang paksa ng paglikha ng mga bot para sa Telegrams ay medyo na-hackney, at maraming mga gabay ang naisulat (halimbawa, ito ) . Samakatuwid, mas mabuting tingnan nating mabuti ang pagtatrabaho sa ilang third-party na API, dahil isa itong kritikal na kasanayan para sa anumang web developer. Sasabihin ko kaagad na ang application ay hindi itinakda upang magbigay ng pinaka-functional at kapaki-pakinabang na forecast; walang saysay na makipagkumpitensya sa mga site ng panahon; mahalagang matutunan kung paano magtrabaho sa mga malalayong koneksyon at pag-parse ng data gamit ang Java. Kaya, alamin muna natin kung ano ang kailangan natin. Ang aming aplikasyon ay mahalagang binubuo ng tatlong lohikal na bahagi:
- tumanggap ng mensahe mula sa user
- iproseso ang mensahe, at, kung ito ay isang wastong utos, maghanda ng data para sa tugon. Sa aming kaso, maghanda ng taya ng panahon kung ang gumagamit ay pumasok sa tamang lungsod
- magpadala ng handa na impormasyon sa gumagamit sa chat
https://api.openweathermap.org/data/2.5/forecast?q=(город)&APPID=(уникальный токен, полученный при регистрации)
Можно посмотреть How ответ на такой request выглядит в браузере тыц Мы уже выяснor, что, по сути, нужно просто перейти по правильной ссылке и server выдаст нужные данные. Осталось научиться это делать средствами Java. Простой GET request на Java выглядит так:
//создаём строку со ссылкой на нужную page,
//я тут её склеиваю из заранее определённых констант, меняя только сам город
String urlString = API_CALL_TEMPLATE + city + API_KEY_TEMPLATE;
//создаём an object который будет содержать ссылку
URL urlObject = new URL(urlString);
//создаём соединение, используя an object
HttpURLConnection connection = (HttpURLConnection) urlObject.openConnection();
//выбираем тип requestа (GET)
connection.setRequestMethod("GET");
//тут мы указываем, данные о себе, что мы можем принять всё то,
//что примет и любой современный браузер
connection.setRequestProperty("User-Agent", "Mozilla/5.0");
//В начало ответа server всегда вставляет число, по которому можно судить, прошло ли всё хорошо.
//200 - значит OK
int responseCode = connection.getResponseCode();
//на несуществующий город or город с опечаткой, server выдаст code ответа 404,
//бросаем на него исключение, чтобы обработать на уровне повыше и предложить
//пользователю ввести город заново
if (responseCode == 404) {
throw new IllegalArgumentException();
}
// создаём поток, вычитываем все строки, и склеиваем в одну большую строку,
//которую будем потом обрабатывать в других методах
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
return response.toString();
Если request был корректным, а server - доступным, мы получим простыню данных, в которой полезная информация перемешана с той, которая сейчас не нужна. Whatбы удобно извлекать из JSON и XML нужные данные, под Java написано тонны библиотек на любой вкус. Так How я предпочёл JSON, для его обработки выбрал весьма популярную библиотеку под названием Jackson. Она, кстати немного изучается на JavaRush на Howих-то высоких уровнях. Для обработки больших объёмов JSON-данных важно понимать структуру documentа. На помощь приходят полезные сайты вроде этого . Слева у нас оригинальный JSON, справа - структурированный: Видно что ответ состоит из 5 JSON-an objectов высшего уровня, 2 из которых сложные и являются узлами для следующих ветвей. Интересующие нас данные хранятся в узле list. Внутри list - массив из 38 JSON-строк, в каждой описана погода в определённое время. То есть это такая себе древовидная структура, где есть корень, ветви, веточки и даже листья :) А на узлах How раз и проходит разветвление. К счастью, Jackson умеет представлять любой валидный JSON в виде дерева. Таким образом, зная How называется нужный нам атрибут(например, температура воздуха), и на Howом уровне дерева он находится, достать его не составит особых проблем. Для начала я извлёк все строчки из массива "list" и добавил их в отдельный список. Я, грубо говоря, порезал простыню с данными на куски, каждый из которых - это отдельный прогноз. Маленькие части проще держать в голове и оперировать ими.
//JsonNode - это один из узлов в древовидной иерархии, от которого идут ветви
//получаем узел, который называется "list"
JsonNode arrNode = new ObjectMapper().readTree(data).get("list");
//если это действительно массив узлов
if (arrNode.isArray()) {
//выполняем для каждого узла, который содержится в массиве
for (final JsonNode objNode : arrNode) {
//в атрибуте "dt_txt" каждого маленького узла хранилось время прогноза, я отобрал данные за 9 утра и 6 вечера
String forecastTime = objNode.get("dt_txt").toString();
if (forecastTime.contains("09:00") || forecastTime.contains("18:00")) {
weatherList.add(objNode.toString());
}
}
}
Так мы получor список строк, в котором каждая строка представляет собой JSON-сводку погоды в определённое время. Осталось извлечь желаемое и отформатировать. Если у нас есть такая строка:
"main":{"temp":261.45,"temp_min":259.086,"temp_max":261.45,"pressure":1023.48,"sea_level":1045.39,"grnd_level":1023.48,"humidity":79,"temp_kf":2.37}
то, это узел под названием "main". Whatбы получить из него любые данные, к примеру уровень моря, достаточно такого codeа:
ObjectMapper objectMapper = new ObjectMapper();
//line - это наша JSON-строка
mainNode = objectMapper.readTree(line).get("main");
String seaLevel = mainNode.get("sea_level");
Jackson позволяет сразу представлять данные в числовом формате:
double seaLevel = mainNode.get("sea_level").asDouble();
Теперь мы можем извлекать любые данные из прогноза, и осталось только их склеить, How пожелается, и отправить пользователю в Telegram. Полный исходный code у меня на гитхабе, а вот попробовать бота в действии можно по ссылке, либо найдя @denifoBot в поиске Телеграмм. Название города нужно писать в латинской транслитерации, например "Kyiv" or "Moscow". Спасибо, если осorли до конца, принимаю разумную критику, так How только учусь и нарабатываю простенькие проекты на гитхаб, чтобы конкурировать с голодными талантами из своего города :) Всем пока! P.S Полагаю, что тут могут быть опечатки, поэтому можете всё присылать в личку, ну, or в комментарии, если вы прям очень злые :)
GO TO FULL VERSION