JavaRush /Java Blog /Random-IT /Creiamo un semplice bot meteo per Telegram in poche sere
Philip J.
Livello 40
Днепр

Creiamo un semplice bot meteo per Telegram in poche sere

Pubblicato nel gruppo Random-IT
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
Il primo e il terzo punto sono abbastanza semplici e riguardano esclusivamente il funzionamento con le API di Telegram; chi è interessato può studiare il link lasciato sopra. Ci concentreremo sul secondo punto. Le API vengono utilizzate quando alcuni sviluppatori desiderano fornire l'accesso ai propri dati ad altri sviluppatori. Prendiamo ad esempio VKontakte. Ognuno ha un elenco di amici, è archiviato da qualche parte in un database sui server VK. Diciamo che qualche programmatore ha deciso di creare un gioco di dama con gli amici. Perché la sua applicazione funzioni correttamente, il programma deve essere in grado di ottenere la lista degli amici di qualsiasi giocatore. Per fare ciò, il programmatore trova la documentazione per l'API VK e esamina quale richiesta è necessaria per ottenere questo elenco. Questa richiesta è chiamata richiesta HTTP. E le due richieste HTTP più comuni sono GET e POST. Ce n'è abbastanza anche su Internet, non ti fermerò. Per i nostri scopi, ovvero ottenere i dati delle previsioni meteo, sarà sufficiente una semplice richiesta GET. Se facciamo una richiesta GET a un normale server web, spesso restituirà codice html, che il browser converte in una pagina user-friendly, applicando stili, script, ecc. Se facciamo tale richiesta al server API, la risposta di solito vengono restituiti solo i dati grezzi senza stili e script. Nella finestra del browser appare più o meno così: Creiamo un semplice bot meteo per Telegram in poche sere - 1Questi dati non sono destinati a persone, ma ad altri programmi, quindi in tali pagine non c'è nulla in più tranne le informazioni stesse. I dati grezzi vengono spesso inviati utilizzando uno dei due standard: JSON o XML. Ognuno ha i suoi pro e i suoi contro, tuttavia è importante comprenderli entrambi. Hai già visto JSON nello screenshot qui sopra e XML assomiglia a questo: Creiamo un semplice bot meteo per Telegram in poche sere - 2Dopo una breve ricerca, è stato trovato il progetto Open Weather Map in lingua inglese, che fornisce dati gratuitamente se non si effettuano più di 50 richieste al minuto. Questo ci basta, ci registriamo, riceviamo un token (codice) univoco grazie al quale il server saprà che non siamo impostori, ma futuri sviluppatori decenti. Andiamo alla pagina con la documentazione API ( tyts ), e scopriamo che è possibile ottenere una previsione a 5 giorni per qualsiasi città inviando una richiesta del modulo.
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: Creiamo un semplice bot meteo per Telegram in poche sere - 3 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 :)
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION