JavaRush /Blogue Java /Random-PT /Criamos um bot meteorológico simples para o Telegram em a...
Philip J.
Nível 40
Днепр

Criamos um bot meteorológico simples para o Telegram em algumas noites

Publicado no grupo Random-PT
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
O primeiro e terceiro pontos são bastante simples, e dizem respeito apenas ao trabalho com a API do Telegram; os interessados ​​podem estudar o link deixado acima. Vamos nos concentrar no segundo ponto. APIs são usadas quando alguns desenvolvedores desejam fornecer acesso aos seus dados a outros desenvolvedores. Vejamos o VKontakte, por exemplo. Todo mundo tem uma lista de amigos, ela fica armazenada em algum lugar de um banco de dados nos servidores VK. Digamos que algum programador decidiu criar um jogo de damas com amigos. Para que sua aplicação funcione corretamente, o programa deve ser capaz de obter a lista de amigos de qualquer jogador. Para fazer isso, o programador encontra a documentação da API VK e verifica qual solicitação precisa ser feita para obter essa lista. Essa solicitação é chamada de solicitação HTTP. E as duas solicitações HTTP mais comuns são GET e POST. Também há bastante sobre eles na Internet, não vou impedi-lo. Para os nossos propósitos, nomeadamente a obtenção de dados de previsão meteorológica, um simples pedido GET será suficiente. Se fizermos uma solicitação GET a um servidor web normal, muitas vezes ele retornará código html, que o navegador converte em uma página amigável, aplicando estilos, scripts, etc. Geralmente, apenas os dados brutos são retornados sem estilos e scripts. Na janela do navegador é mais ou menos assim: Criamos um bot meteorológico simples para o Telegram em algumas noites - 1Esses dados não se destinam a pessoas, mas a outros programas, portanto não há nada extra nessas páginas, exceto as próprias informações. Os dados brutos são geralmente enviados usando um dos dois padrões: JSON ou XML. Cada um tem seus prós e contras, porém é importante compreender ambos. Você já viu o JSON na captura de tela acima, e o XML se parece com isto: Criamos um bot meteorológico simples para o Telegram em algumas noites - 2Após uma breve pesquisa, foi encontrado o projeto Open Weather Map em inglês, que fornece dados gratuitamente se você não fizer mais de 50 solicitações por minuto. Isso é o suficiente para nós, nos registramos, recebemos um token (código) único pelo qual o servidor saberá que não somos impostores, mas futuros desenvolvedores decentes. Vamos até a página com a documentação da API ( tyts ), e descobrimos que uma previsão de 5 dias para qualquer cidade pode ser obtida enviando uma solicitação do formulário.
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: Criamos um bot meteorológico simples para o Telegram em algumas noites - 3 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 :)
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION