Halo semua! Topik membuat bot untuk Telegram agak ketinggalan jaman, dan banyak panduan telah ditulis (misalnya, yang ini ) . Oleh karena itu, sebaiknya kita melihat lebih dekat cara bekerja dengan beberapa API pihak ketiga, karena ini adalah keterampilan penting bagi pengembang web mana pun. Saya akan segera mengatakan bahwa aplikasi ini tidak dirancang untuk memberikan ramalan cuaca yang paling fungsional dan berguna; tidak ada gunanya bersaing dengan situs cuaca; penting untuk mempelajari cara bekerja dengan koneksi jarak jauh dan penguraian data menggunakan Java. Jadi, mari kita cari tahu apa yang kita butuhkan terlebih dahulu. Aplikasi kita pada dasarnya terdiri dari tiga bagian logis:
- menerima pesan dari pengguna
- memproses pesan, dan, jika itu adalah perintah yang valid, siapkan data untuk responsnya. Dalam kasus kami, siapkan ramalan cuaca jika pengguna memasukkan kota yang benar
- mengirim informasi siap kepada pengguna dalam obrolan
https://api.openweathermap.org/data/2.5/forecast?q=(город)&APPID=(уникальный токен, полученный при регистрации)
Anda dapat melihat bagaimana respons terhadap permintaan tersebut terlihat di browser. Kami telah mengetahui bahwa sebenarnya Anda hanya perlu mengikuti tautan yang benar dan server akan menyediakan data yang diperlukan. Yang tersisa hanyalah mempelajari cara melakukan ini menggunakan Java. Permintaan GET sederhana di Java terlihat seperti ini:
//создаём строку со ссылкой на нужную 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();
Jika permintaan benar dan server tersedia, kami akan menerima lembar data yang berisi informasi berguna yang dicampur dengan informasi yang tidak diperlukan saat ini. Untuk mengekstrak data yang diperlukan dengan mudah dari JSON dan XML, banyak sekali perpustakaan telah ditulis untuk Java untuk memenuhi setiap selera. Karena saya lebih suka JSON, saya memilih perpustakaan yang sangat populer bernama Jackson untuk memprosesnya. Omong-omong, ini dipelajari sedikit di JavaRush pada beberapa level tinggi. Untuk memproses data JSON dalam jumlah besar, penting untuk memahami struktur dokumen. Situs bermanfaat seperti ini datang untuk menyelamatkan . Di sebelah kiri kita memiliki JSON asli, di sebelah kanan - yang terstruktur: Terlihat bahwa respon terdiri dari 5 objek JSON tingkat atas, 2 di antaranya kompleks dan merupakan node untuk cabang berikut. Data yang kami minati disimpan di node daftar . Daftar di dalamnya terdapat larik 38 baris JSON, masing-masing menggambarkan cuaca pada waktu tertentu. Artinya, itu adalah sejenis struktur seperti pohon, di mana ada akar, cabang, ranting, dan bahkan daun :) Dan pada simpulnya terjadi percabangan. Untungnya, Jackson dapat mewakili JSON yang valid sebagai pohon. Jadi, mengetahui nama atribut yang kita perlukan (misalnya suhu udara), dan di tingkat pohon mana letaknya, mendapatkannya tidak akan menjadi masalah. Pertama, saya mengekstrak semua baris dari array "daftar" dan menambahkannya ke daftar terpisah. Secara kasar, saya memotong lembar data menjadi beberapa bagian, yang masing-masing merupakan perkiraan terpisah. Bagian-bagian kecil lebih mudah diingat dan dioperasikan.
//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());
}
}
}
Jadi kita mendapatkan daftar string, yang setiap barisnya mewakili laporan cuaca JSON pada waktu tertentu. Yang tersisa hanyalah mengekstrak apa yang Anda inginkan dan memformatnya. Jika kita memiliki garis seperti ini:
"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}
maka ini adalah node yang disebut "utama". Untuk mendapatkan data apa pun darinya, misalnya permukaan laut, cukup kode berikut:
ObjectMapper objectMapper = new ObjectMapper();
//line - это наша JSON-строка
mainNode = objectMapper.readTree(line).get("main");
String seaLevel = mainNode.get("sea_level");
Jackson memungkinkan Anda untuk segera merepresentasikan data dalam format numerik:
double seaLevel = mainNode.get("sea_level").asDouble();
Sekarang kita dapat mengekstrak data apa pun dari perkiraan, dan yang tersisa hanyalah merekatkannya sesuai keinginan dan mengirimkannya ke pengguna di Telegram. Kode sumber lengkap ada di github saya , tetapi Anda dapat mencoba aksi bot menggunakan tautan , atau dengan menemukan @denifoBot di pencarian Telegram. Nama kota harus ditulis dalam transliterasi Latin, misalnya "Kyiv" atau "Moskow". Terima kasih, jika Anda berhasil sampai akhir, saya menerima kritik yang masuk akal, karena saya baru belajar dan mengembangkan proyek sederhana di GitHub untuk bersaing dengan talenta lapar dari kota saya :) Sampai jumpa semuanya! PS Saya yakin mungkin ada kesalahan ketik di sini, jadi Anda bisa mengirimkan semuanya melalui pesan pribadi, atau di komentar jika Anda benar-benar marah :)
GO TO FULL VERSION