JavaRush /Java блогу /Random-KY /Биз бир нече кечинде Telegram үчүн жөнөкөй аба ырайы боту...
Philip J.
Деңгээл
Днепр

Биз бир нече кечинде Telegram үчүн жөнөкөй аба ырайы ботун түзөбүз

Группада жарыяланган
Баарына салам! Telegrams үчүн ботторду түзүү темасы бир аз бузулган жана көптөгөн гиддер жазылган (мисалы, бул ) . Ошондуктан, биз кээ бир үчүнчү тарап API менен иштөөнү жакшыраак карап чыкканыбыз жакшы, анткени бул ар бир веб-иштеп чыгуучу үчүн өтө маанилүү жөндөм. Мен дароо айтайын, колдонмо эң функционалдык жана пайдалуу прогнозду камсыз кылуу үчүн коюлган эмес; аба ырайы сайттары менен атаандашуунун кереги жок; Java аркылуу алыскы туташуу жана маалыматтарды талдоо менен кантип иштөөнү үйрөнүү маанилүү болчу. Андыктан, келгиле, алгач бизге эмне керек экенин аныктап алалы. Биздин колдонмо негизинен үч логикалык бөлүктөн турат:
  • колдонуучунун билдирүүсүн кабыл алуу
  • кабарды иштетип, эгер ал жарактуу буйрук болсо, жооп үчүн маалыматтарды даярдаңыз. Биздин учурда, эгер колдонуучу туура шаарга кирсе, аба ырайын даярдаңыз
  • чатта колдонуучуга даяр маалыматты жөнөтүү
Биринчи жана үчүнчү пункттар абдан жөнөкөй жана бир гана Telegram API менен иштөөгө тиешелүү; кызыккандар жогоруда калган шилтемени изилдей алышат. Биз экинчи пунктка токтолобуз. API'лер кээ бир иштеп чыгуучулар башка иштеп чыгуучуларга өз маалыматтарына кирүү мүмкүнчүлүгүн бергиси келгенде колдонулат. Мисалы, ВКонтактеди алалы. Ар бир адамдын досторунун тизмеси бар, ал VK serverлериндеги маалымат базасында бир жерде сакталат. Кандайдыр бир программист достору менен шашки оюнун түзүүнү чечти дейли. Анын арызы туура иштеши үчүн, программа каалаган оюнчунун досторунун тизмесин ала алышы керек. Бул үчүн, программист VK API үчүн documentтерди табат жана бул тизмени алуу үчүн кандай суроо-талап керек экенин карайт. Бул суроо HTTP сурамы деп аталат. Ал эми эң кеңири таралган эки HTTP сурамдары - GET жана POST. Алар жөнүндө Интернетте да жетиштүү, мен сени токтотпойм. Биздин максаттарыбыз үчүн, тактап айтканда, аба ырайы маалыматтарын алуу үчүн, жөнөкөй GET суроо-талабы жетиштүү болот. Эгерде биз кадимки веб-serverге GET өтүнүчүн жасасак, анда ал көбүнчө html codeун кайтарып берет, аны браузер колдонуучуга ыңгайлуу бетке айландырат, стилдерди, скрипттерди ж.б. колдонот. Эгер API serverине ушундай суроо-талап кылсак, жооп адатта стилдери жана скрипттери жок чийки маалыматтар гана кайтарылат. Браузердин терезесинде ал төмөнкүдөй көрүнөт: Биз бир нече кечинде Telegram үчүн жөнөкөй аба ырайы ботун түзөбүз - 1Бул маалымат адамдар үчүн эмес, башка программалар үчүн арналган, андыктан мындай баракчаларда маалыматтын өзүнөн башка эч нерсе жок. Чийки маалыматтар көбүнчө эки стандарттын бири аркылуу жөнөтүлөт: JSON же XML. Ар биринин жакшы жана жаман жактары бар, бирок экөөнү тең түшүнүү маанилүү. Сиз буга чейин жогорудагы скриншотто JSON көрдүңүз жана XML төмөнкүдөй көрүнөт: Биз бир нече кечинде Telegram үчүн жөнөкөй аба ырайы ботун түзөбүз - 2Кыска издөөдөн кийин, англис тorндеги Ачык Аба ырайы картасы долбоору табылды, ал эгер сиз мүнөтүнө 50дөн ашык сурам жасабасаңыз, маалыматтарды акысыз камсыз кылат. Бул бизге жетиштүү, биз катталабыз, уникалдуу белгини (codeду) алабыз, анын жардамы менен server биздин алдамчылар эмес, келечектеги татыктуу иштеп чыгуучулар экенибизди билет. Биз API documentтери бар баракка барабыз ( tyts ) жана формага суроо-талапты жөнөтүү аркылуу каалаган шаар үчүн 5 күндүк божомолду алууга болорун билебиз.
https://api.openweathermap.org/data/2.5/forecast?q=(город)&APPID=(уникальный токен, полученный при регистрации)
Мындай суроо-талапка жооп браузерде кандай болорун көрө аласыз.Чындыгында , сиз жөн гана туура шилтемени ээрчишиңиз керек экенин жана server керектүү маалыматтарды берерин билдик. Муну Java аркылуу кантип жасоону үйрөнүү гана калды. Javaдагы жөнөкөй GET сурамы төмөнкүдөй көрүнөт:
//создаём строку со ссылкой на нужную 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();
Эгер суроо-талап туура болсо жана server жеткorктүү болсо, биз пайдалуу маалымат менен азыр кереги жок маалымат аралашкан маалымат барагын алабыз. JSON жана XMLден керектүү маалыматтарды ыңгайлуу алуу үчүн Java үчүн ар кандай табитке ылайыктуу көптөгөн китепканалар жазылган. Мен JSONга артыкчылык бергендиктен, аны иштетүү үчүн Джексон деген абдан популярдуу китепкананы тандадым. Айтмакчы, ал JavaRushта бир аз жогорку деңгээлде изилденет. JSON маалыматтарынын чоң көлөмүн иштетүү үчүн documentтин структурасын түшүнүү маанилүү. Ушул сыяктуу пайдалуу сайттар жардамга келет . Сол жакта бизде оригиналдуу JSON бар, оң жакта - структураланган: Биз бир нече кечинде Telegram үчүн жөнөкөй аба ырайы ботун түзөбүз - 3 Жооп 5 жогорку деңгээлдеги JSON an objectисинен турат, алардын 2си татаал жана төмөнкү бутактар ​​үчүн түйүн болуп саналат. Бизди кызыктырган маалыматтар тизме түйүнүндө сакталат . Ички тизме 38 JSON сызыктарынын массивинен турат, алардын ар бири белгилүү бир убактагы аба ырайын сүрөттөйт. Башкача айтканда, бул дарак сымал түзүлүштүн бир түрү, анда тамыры, бутактары, бутактары жана ал тургай жалбырактары бар :) Ал эми түйүндөрдө бутактануу болот. Бактыга жараша, Джексон ар кандай жарактуу JSONди дарак катары көрсөтө алат. Ошентип, бизге керек болгон атрибуттун атын билүү (мисалы, абанын температурасы) жана ал дарактын кайсы деңгээлинде жайгашканын билүү, аны алуу көп деле көйгөй болбойт. Биринчиден, мен "тизме" массивинен бардык саптарды чыгарып, өзүнчө тизмеге коштум. Орой айтканда, мен маалыматтар жазылган баракты бөлүктөргө бөлдүм, алардын ар бири өзүнчө прогноз. Кичинекей бөлүктөрдү эстеп калуу жана иштетүү оңой.
//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());
            }
      }
}
Ошентип, биз саптардын тизмесин алдык, анда ар бир сап белгилүү бир убакта 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}
анда бул "негизги" деп аталган түйүн. Андан кандайдыр бир маалыматты алуу үчүн, мисалы, деңиз деңгээлинен төмөнкү code жетиштүү:
ObjectMapper objectMapper = new ObjectMapper();
//line - это наша JSON-строка
mainNode = objectMapper.readTree(line).get("main");
String seaLevel = mainNode.get("sea_level");
Джексон дароо сандык форматта маалыматтарды көрсөтүүгө мүмкүндүк берет:
double seaLevel = mainNode.get("sea_level").asDouble();
Эми биз прогноздон каалаган маалыматты чыгара алабыз, калганы аны каалагандай жабыштырып, Telegramдагы колдонуучуга жөнөтүү. Толук булак codeу менин github'умда , бирок сиз ботту шилтеме аркылуу же Telegram издөөсүндө @denifoBot табуу менен аракет кылып көрүңүз . Шаардын аталышы латын транслитерациясында жазылууга тийиш, мисалы "Киев" же "Москва". Рахмат, эгер сиз аягына чейин жеткизсеңиз, негиздүү сындарды кабыл алам, анткени мен GitHub'да өзүмдүн шаарымдагы ач таланттар менен атаандашуу үчүн жөнөкөй долбоорлорду жаңыдан үйрөнүп, иштеп жатам :) Бар болуңуз! PS Бул жерде каталар болушу мүмкүн деп ишенем, андыктан баарын купуя катка жөнөтсөңүз болот, же чындап ачуулансаңыз комментарийге жазсаңыз болот :)
Комментарийлер
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION