Olá a todos! O tópico de criação de bots para Telegramas é um tanto banal e muitos guias foram escritos (por exemplo, este ) . Portanto, é melhor olharmos mais de perto para trabalhar com alguma API de terceiros, já que esta é uma habilidade crítica para qualquer desenvolvedor web. Direi desde já que o aplicativo não se propôs a fornecer a previsão mais funcional e útil; não adianta competir com sites meteorológicos; foi importante aprender a trabalhar com conexões remotas e análise de dados usando Java. Então, vamos descobrir o que precisamos primeiro. Nosso aplicativo consiste essencialmente em três partes lógicas:
- aceitar mensagem do usuário
- processar a mensagem e, se for um comando válido, preparar os dados para a resposta. No nosso caso, prepare uma previsão do tempo se o usuário digitou a cidade correta
- enviar informações prontas para o usuário no chat
https://api.openweathermap.org/data/2.5/forecast?q=(город)&APPID=(уникальный токен, полученный при регистрации)
Você pode ver como fica a resposta a tal solicitação no navegador, já descobrimos que, na verdade, basta seguir o link correto e o servidor fornecerá os dados necessários. Resta aprender como fazer isso usando Java. Uma solicitação GET simples em Java se parece com isto:
//создаём строку со ссылкой на нужную 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 a solicitação estiver correta e o servidor estiver disponível, receberemos uma planilha de dados na qual informações úteis se misturam com informações desnecessárias no momento. Para extrair convenientemente os dados necessários de JSON e XML, inúmeras bibliotecas foram escritas para Java para todos os gostos. Como preferi JSON, escolhi uma biblioteca muito popular chamada Jackson para processá-lo. Aliás, é estudado um pouco no JavaRush em alguns níveis elevados. Para processar grandes quantidades de dados JSON, é importante compreender a estrutura do documento. Sites úteis como este vêm em socorro . À esquerda temos o JSON original, à direita - o estruturado: Pode-se observar que a resposta consiste em 5 objetos JSON de nível superior, 2 dos quais são complexos e são nós para as ramificações seguintes. Os dados que nos interessam são armazenados no nó da lista . A lista interna é uma matriz de 38 linhas JSON, cada uma descrevendo o clima em um determinado horário. Ou seja, é uma espécie de estrutura em forma de árvore, onde tem raiz, galhos, galhos e até folhas :) E nos nós ocorre a ramificação. Felizmente, Jackson pode representar qualquer JSON válido como uma árvore. Assim, sabendo o nome do atributo que precisamos (por exemplo, temperatura do ar) e em que nível da árvore ele está localizado, obtê-lo não será um grande problema. Primeiro, extraí todas as linhas do array “list” e as adicionei a uma lista separada. Grosso modo, cortei a planilha com os dados em pedaços, cada um deles uma previsão separada. Peças pequenas são mais fáceis de lembrar e operar.
//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());
}
}
}
Isso nos dá uma lista de strings, em que cada string representa um relatório JSON do clima em um determinado horário. Só falta extrair o que você deseja e formatá-lo. Se tivermos uma linha como esta:
"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}
então este é um nó chamado "principal". Para obter quaisquer dados dele, por exemplo, o nível do mar, basta o seguinte código:
ObjectMapper objectMapper = new ObjectMapper();
//line - это наша JSON-строка
mainNode = objectMapper.readTree(line).get("main");
String seaLevel = mainNode.get("sea_level");
Jackson permite representar dados imediatamente em formato numérico:
double seaLevel = mainNode.get("sea_level").asDouble();
Agora podemos extrair quaisquer dados da previsão, resta apenas colá-los conforme desejado e enviá-los ao usuário no Telegram. O código fonte completo está no meu github , mas você pode testar o bot em ação usando o link , ou encontrando @denifoBot na busca do Telegram. O nome da cidade deve ser escrito em transliteração latina, por exemplo "Kyiv" ou "Moscou". Obrigado, se vocês chegaram até o fim, aceito críticas razoáveis, pois estou apenas aprendendo e desenvolvendo projetos simples no GitHub para competir com talentos famintos da minha cidade :) Tchau a todos! PS Acredito que pode haver erros de digitação aqui, então você pode mandar tudo em mensagem privada, ou em comentário se estiver realmente bravo :)
GO TO FULL VERSION