Ciao a tutti! L'argomento della creazione di bot per Telegram è un po' banale e sono state scritte molte guide (ad esempio questa ) . Pertanto, è meglio dare un'occhiata più da vicino al lavoro con alcune API di terze parti, poiché questa è un'abilità fondamentale per qualsiasi sviluppatore web. Dirò subito che l'applicazione non si propone di fornire le previsioni più funzionali e utili, non ha senso competere con i siti meteorologici, era importante imparare a lavorare con connessioni remote e analisi dei dati utilizzando Java. Quindi, scopriamo prima di cosa abbiamo bisogno. La nostra applicazione è composta essenzialmente da tre parti logiche:
- accettare il messaggio dall'utente
- elaborare il messaggio e, se si tratta di un comando valido, preparare i dati per la risposta. Nel nostro caso, prepara una previsione del tempo se l'utente ha inserito la città corretta
- inviare informazioni pronte all'utente in chat
https://api.openweathermap.org/data/2.5/forecast?q=(город)&APPID=(уникальный токен, полученный при регистрации)
Puoi vedere come appare la risposta a tale richiesta nel browser: abbiamo già scoperto che, infatti, basta seguire il collegamento corretto e il server fornirà i dati necessari. Non resta che imparare a farlo utilizzando Java. Una semplice richiesta GET in Java assomiglia a questa:
//создаём строку со ссылкой на нужную 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();
Se la richiesta era corretta e il server era disponibile, riceveremo una scheda in cui si mescolano informazioni utili con informazioni che ora non servono. Per estrarre comodamente i dati necessari da JSON e XML, sono state scritte tantissime librerie per Java per soddisfare tutti i gusti. Dato che preferivo JSON, ho scelto una libreria molto popolare chiamata Jackson per elaborarlo. A proposito, è studiato un po' in JavaRush ad alcuni livelli elevati. Per elaborare grandi quantità di dati JSON, è importante comprendere la struttura del documento. Siti utili come questo vengono in soccorso . A sinistra abbiamo il JSON originale, a destra quello strutturato: si può vedere che la risposta è composta da 5 oggetti JSON di primo livello, 2 dei quali sono complessi e sono nodi per i rami successivi. I dati che ci interessano vengono memorizzati nel nodo elenco . All'interno dell'elenco è presente una serie di 38 righe JSON, ciascuna che descrive il tempo in un determinato momento. Cioè, è una sorta di struttura ad albero, dove c'è una radice, rami, ramoscelli e persino foglie :) E ai nodi avviene la ramificazione. Fortunatamente, Jackson può rappresentare qualsiasi JSON valido come un albero. Pertanto, conoscendo il nome dell'attributo di cui abbiamo bisogno (ad esempio, la temperatura dell'aria) e a quale livello dell'albero si trova, ottenerlo non sarà un grosso problema. Innanzitutto ho estratto tutte le righe dall'array "list" e le ho aggiunte a un elenco separato. In parole povere, ho tagliato il foglio con i dati in pezzi, ognuno dei quali è una previsione separata. Le parti piccole sono più facili da tenere a mente e da utilizzare.
//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());
}
}
}
Quindi abbiamo ottenuto un elenco di stringhe, in cui ciascuna riga rappresenta un bollettino meteorologico JSON in un determinato momento. Non resta che estrarre ciò che desideri e formattarlo. Se abbiamo una riga come questa:
"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}
allora questo è un nodo chiamato "principale". Per ricavarne qualche dato, ad esempio il livello del mare, è sufficiente il seguente codice:
ObjectMapper objectMapper = new ObjectMapper();
//line - это наша JSON-строка
mainNode = objectMapper.readTree(line).get("main");
String seaLevel = mainNode.get("sea_level");
Jackson permette di rappresentare immediatamente i dati in formato numerico:
double seaLevel = mainNode.get("sea_level").asDouble();
Ora possiamo estrarre tutti i dati dalla previsione e non resta che incollarli insieme come desiderato e inviarli all'utente in Telegram. Il codice sorgente completo è sul mio github , ma puoi provare il bot in azione utilizzando il link o trovando @denifoBot nella ricerca di Telegram. Il nome della città deve essere scritto in traslitterazione latina, ad esempio "Kiev" o "Mosca". Grazie, se sei arrivato alla fine, accetto critiche ragionevoli, dato che sto solo imparando e sviluppando semplici progetti su GitHub per competere con i talenti affamati della mia città :) Ciao a tutti! PS Credo che qui potrebbero esserci degli errori di battitura, quindi puoi inviare tutto in un messaggio privato, o in un commento se sei davvero arrabbiato :)
GO TO FULL VERSION