Salut tout le monde! Le sujet de la création de robots pour Telegrams est quelque peu galvaudé, et de nombreux guides ont été écrits (par exemple, celui-ci ) . Par conséquent, nous ferions mieux d’examiner de plus près la possibilité de travailler avec des API tierces, car il s’agit d’une compétence essentielle pour tout développeur Web. Je dirai tout de suite que l'application n'a pas pour objectif de fournir les prévisions les plus fonctionnelles et les plus utiles ; cela ne sert à rien de rivaliser avec les sites météorologiques ; il était important d'apprendre à travailler avec des connexions à distance et à analyser des données à l'aide de Java. Alors, découvrons d'abord ce dont nous avons besoin. Notre application se compose essentiellement de trois parties logiques :
- accepter le message de l'utilisateur
- traiter le message et, s'il s'agit d'une commande valide, préparer les données pour la réponse. Dans notre cas, préparez une météo si l'utilisateur a saisi la bonne ville
- envoyer des informations prêtes à l'utilisateur dans le chat
https://api.openweathermap.org/data/2.5/forecast?q=(город)&APPID=(уникальный токен, полученный при регистрации)
Vous pouvez voir à quoi ressemble la réponse à une telle demande dans le navigateur. Nous avons déjà découvert qu'en fait, il vous suffit de suivre le lien correct et le serveur fournira les données nécessaires. Il ne reste plus qu'à apprendre à faire cela en utilisant Java. Une simple requête GET en Java ressemble à ceci :
//создаём строку со ссылкой на нужную 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();
Si la demande était correcte et que le serveur était disponible, nous recevrons une feuille de données dans laquelle des informations utiles sont mélangées avec des informations qui ne sont pas nécessaires actuellement. Pour extraire facilement les données nécessaires de JSON et XML, des tonnes de bibliothèques ont été écrites pour Java pour tous les goûts. Comme je préférais JSON, j'ai choisi une bibliothèque très populaire appelée Jackson pour le traiter. À propos, il est un peu étudié dans JavaRush à certains niveaux élevés. Pour traiter de grandes quantités de données JSON, il est important de comprendre la structure du document. Des sites utiles comme celui-ci viennent à la rescousse . A gauche nous avons le JSON original, à droite - le structuré : On peut voir que la réponse se compose de 5 objets JSON de niveau supérieur, dont 2 sont complexes et sont des nœuds pour les branches suivantes. Les données qui nous intéressent sont stockées dans le nœud de liste . La liste intérieure contient un tableau de 38 lignes JSON, chacune décrivant la météo à un moment donné. C'est-à-dire qu'il s'agit d'une sorte de structure arborescente, où se trouvent une racine, des branches, des brindilles et même des feuilles :) Et aux nœuds, la ramification a lieu. Heureusement, Jackson peut représenter n'importe quel JSON valide sous forme d'arbre. Ainsi, connaissant le nom de l'attribut dont nous avons besoin (par exemple, la température de l'air) et à quel niveau de l'arbre il se trouve, l'obtenir ne sera pas vraiment un problème. Tout d'abord, j'ai extrait toutes les lignes du tableau "list" et les ai ajoutées à une liste distincte. En gros, j'ai découpé la feuille contenant les données en morceaux, chacun étant une prévision distincte. Les petites pièces sont plus faciles à garder à l’esprit et à utiliser.
//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());
}
}
}
Nous avons donc obtenu une liste de chaînes dans lesquelles chaque ligne représente un rapport météo JSON à un moment donné. Il ne reste plus qu'à extraire ce que vous voulez et à le formater. Si nous avons une ligne comme celle-ci :
"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}
alors c'est un nœud appelé "main". Pour en récupérer des données, par exemple le niveau de la mer, le code suivant suffit :
ObjectMapper objectMapper = new ObjectMapper();
//line - это наша JSON-строка
mainNode = objectMapper.readTree(line).get("main");
String seaLevel = mainNode.get("sea_level");
Jackson vous permet de représenter immédiatement les données au format numérique :
double seaLevel = mainNode.get("sea_level").asDouble();
Nous pouvons désormais extraire n'importe quelle donnée de la prévision, et il ne reste plus qu'à les coller ensemble comme vous le souhaitez et à les envoyer à l'utilisateur dans Telegram. Le code source complet se trouve sur mon github , mais vous pouvez essayer le bot en action en utilisant le lien , ou en trouvant @denifoBot dans la recherche Telegram. Le nom de la ville doit être écrit en translittération latine, par exemple « Kiev » ou « Moscou ». Merci, si vous êtes arrivé jusqu'au bout, j'accepte les critiques raisonnables, puisque je suis juste en train d'apprendre et de développer des projets simples sur GitHub afin de rivaliser avec les talents affamés de ma ville :) Au revoir à tous ! PS Je pense qu'il peut y avoir des fautes de frappe ici, vous pouvez donc tout envoyer en message privé, ou en commentaire si vous êtes vraiment en colère :)
GO TO FULL VERSION