Escrever um cliente de Telegram é fácil


Qual é a diferença entre o Telegram e outros mensageiros populares? Ele está aberto!
Outros mensageiros também têm uma API, mas, por algum motivo, o telegrama é conhecido como o mais aberto dos mais populares?


Para começar, o Telegram tem um cliente verdadeiramente totalmente aberto
código . Infelizmente, não vemos confirmações todos os dias diretamente no GitHub, mas temos um código sob uma licença aberta. A arquitetura do Telegram implica que o Bot e a API têm quase os mesmos métodos - https://core.telegram.org/methods .


De fato, o Telegram não é apenas um mensageiro de bate-papo, mas uma plataforma social, cujo acesso é aberto para vários tipos de aplicativos. Eles podem fornecer chips adicionais aos usuários, ao invés de usar uma rede pronta de usuários e servidores para entrega de mensagens. Parece tão atraente que queríamos tentar escrever nosso "cliente" para os telegramas.


A essência da aplicação


Lidamos principalmente com mapas e navegação, então analisamos imediatamente algo relacionado à geolocalização. Gostei muito que no Telegram, antes de todas as outras aplicações, houvesse uma maneira conveniente de compartilhar sua localização em tempo real ( https://telegram.org/blog/live-locations ) e eu a uso frequentemente: ajude-me a me orientar, mostre meu caminho e o mais importante é responder à pergunta principal "Quando você estará?". Em princípio, isso é suficiente para a maioria das pessoas, mas como sempre, existem cenários em que oportunidades simples não são suficientes. Por exemplo, pode ser um grupo de mais de 10 pessoas, com dispositivos diferentes (alguns dispositivos podem não ser telefones) e pessoas diferentes. Seria conveniente para essas pessoas trocarem mensagens em um grupo e também se verem se movendo em um mapa.


Nós nos concentramos na tarefa de criar valor adicional para o Telegram, e não tentar usá-lo para outros fins. Não queríamos que pessoas que não tinham um cliente especial do Telegram vissem uma bagunça de mensagens no bate-papo ou algo ininteligível. Pessoas com um cliente "aprimorado" têm oportunidades adicionais, por exemplo:


  1. Melhor gerenciamento de tempo ao enviar locais em tempo real para conversar.
  2. Veja a localização dos contatos no mapa.
  3. Conectando-se ao bate-papo de dispositivos beacon através de uma API externa (Bot).

Como fizemos


Felizmente, todo o código que escrevemos é de código aberto, para que eu possa fornecer imediatamente um link para sua implementação - Implementação de Bot e Implementação de Cliente Telegram no Kotlin .


Bot - o básico

Há muita documentação e exemplos sobre a implementação do Bot, mas ainda quero falar sobre algumas das armadilhas. Para começar, escrevemos o lado do servidor
em Java e escolheu a biblioteca org.telegram: telegrambots. Como nosso servidor é um SpringBoot regular, a inicialização é extremamente simples:


// Gradle implementation "org.telegram:telegrambots:3.6" TelegramBotsApi telegramBotsApi = new TelegramBotsApi(); telegramBotsApi.registerBot(new TelegramLongPollingBot() {...}); 

A principal característica da transferência de localização é que ela precisa ser atualizada com frequência e o bot precisa editar as mensagens já enviadas. Se não houvesse essa oportunidade, Bot apenas enviaria spam ao bate-papo e, claro, seria Epic Fail. Graças a Deus, o Telegram dá ao bot o direito de editar mensagens por 24 horas (mínimo, possivelmente mais).


Existem várias maneiras de enviar uma mensagem. Existem tipos de Texto Simples, Local, Local, Jogo, Contato, Fatura, etc. Parecia que o local era perfeito para a nossa tarefa, mas um recurso desagradável foi revelado. A localização só pode ser transferida de um dispositivo para uma conta ou bot de cada vez! Imagine que você tem 2 telefones e, em dois telefones, você enviou seu local em um bate-papo. Portanto, ocorrerá um erro no servidor e o primeiro compartilhamento de local simplesmente será interrompido. Parece que esse é claramente um caso neural, mas imagine que você tenha muitos beacons chineses que podem enviar Location para um determinado URL, mas eles não podem enviar diretamente para o Telegram. Você escreve Bot, que pega no servidor e envia telegramas. É aqui que o Bot não poderá enviar mais de uma mensagem de beacon com o tipo Localização. Acontece que isso é ótimo para o envio único, mas não é adequado para o Live Location.


A solução é simples - envie mensagens de texto e o cliente analisará o texto e mostrará os locais no mapa. Infelizmente, apenas as mensagens de texto estarão visíveis no cliente Telegram padrão, mas você pode inserir um link para abrir o mapa.


Bot - Armadilhas

Infelizmente, o Bot teve que reescrever até 2,5 vezes. O principal problema é o design errado da comunicação.


  1. Por alguma razão, a princípio parecia uma boa idéia se o bot fosse um participante de pleno direito no bate-papo e enviasse mensagens. Mas isso é ruim tanto em termos de privacidade da correspondência quanto em termos de interação com o bot. A decisão certa, use robôs Inline . Assim, é garantido que o bot não vê nada além de sua localização e pode ser usado em qualquer bate-papo. Humanamente falando, não é cultural arrastar seu bot para algum tipo de bate-papo geral, mas você precisa conversar com o bot individualmente e configurá-lo, e ele poderá enviar as mensagens necessárias para qualquer bate-papo selecionado.
  2. Historicamente, existem dois tipos de interação na API de mensagem de telegrama: botões abaixo do texto ((botões em linha) [ https://core.telegram.org/bots/2-0-intro#switch-to-inline-buttons ]) e respostas diretamente ao bot texto. Em geral, as respostas do bot estão irremediavelmente desatualizadas. Os botões são um pouco mais complicados do ponto de vista da implementação, mas isso é totalmente pago pela facilidade de uso e deve ser usado para todas as entradas que não sejam de texto.
  3. Como exemplo de um bot, você pode ver o popular @vote_bot ou nosso @osmand_bot.

Cliente de telegrama

Não conseguimos encontrar exemplos de cliente de telegrama pronto, exceto o principal, mas a estrutura tdlib bastante simples nos ajudou a criar um cliente básico em apenas alguns dias.


Configuração Gradle:
 task downloadTdLibzip { doLast { ant.get(src: 'https://core.telegram.org/tdlib/tdlib.zip', dest: 'tdlib.zip', skipexisting: 'true') ant.unzip(src: 'tdlib.zip', dest: 'tdlib/') } } task copyNativeLibs(type: Copy) { dependsOn downloadTdLibzip from "tdlib/libtd/src/main/libs" into "libs" } task copyJavaSources(type: Copy) { dependsOn downloadTdLibzip from "tdlib/libtd/src/main/java/org/drinkless/td" into "src/org/drinkless/td" } dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) } 

Quase todas as partes internas do Telegram são escritas em C ++ e, do ponto de vista do Android, apenas a classe API é visível nos métodos de proxy TdApi.java de 1,5 MB. Comparando a documentação dos bots e o nome dos métodos, você pode simplesmente descobrir para onde se mover.


Inicialização do cliente com manipulador global:
 fun init(): Boolean { return if (libraryLoaded) { // create client client = Client.create(UpdatesHandler(), null, null) true } else { false } } 

Pedido de foto do usuário:
 private fun requestUserPhoto(user: TdApi.User) { val remotePhoto = user.profilePhoto?.small?.remote if (remotePhoto != null && remotePhoto.id.isNotEmpty()) { downloadUserFilesMap[remotePhoto.id] = user client!!.send(TdApi.GetRemoteFile(remotePhoto.id, null)) { obj -> when (obj.constructor) { TdApi.Error.CONSTRUCTOR -> { val error = obj as TdApi.Error val code = error.code if (code != IGNORED_ERROR_CODE) { listener?.onTelegramError(code, error.message) } } TdApi.File.CONSTRUCTOR -> { val file = obj as TdApi.File client!!.send(TdApi.DownloadFile(file.id, 10), defaultHandler) } else -> listener?.onTelegramError(-1, "Receive wrong response from TDLib: $obj") } } } } 

Cliente de telegrama - armadilhas

  1. Registro / Login e Logout. Ao se registrar, é necessário levar em consideração diferentes cenários: quando o código de acesso é enviado por SMS ou para outro cliente de telegrama, autorização de dois fatores etc. O maior desafio é testar. Qualquer autorização mais de três vezes levou ao bloqueio de conta por 24 horas, portanto, testar o Logout foi especialmente divertido. Apesar do registro ser necessário apenas uma vez, esta é provavelmente a parte mais difícil da integração.
  2. Determine como e em que ordem ler as mensagens. Qualquer cliente tem acesso a todas as mensagens em todos os bate-papos, mas deve ser lido em sequência. No nosso caso, 99% das mensagens precisam ser descartadas. Primeiro, por algum motivo, lemos todas as mensagens nos últimos 3 dias com um login, mas mais tarde causou problemas e, quando reiniciamos, as mensagens desapareceram. Portanto, agora apenas lemos novas mensagens e, para as que precisamos, salvamos o ID no banco de dados interno.

O que aconteceu


Provavelmente, conhecendo todas as armadilhas, era possível fazer tudo muitas vezes mais rápido, mas resultou em cerca de um a dois meses para três pessoas. O aplicativo final pode ser encontrado no Google Play .



A principal questão nesta história é quão corretamente essa interação é do ponto de vista do Telegram e se os usuários gostam desse tipo de integração. De qualquer forma, a ideia em si é um nicho e já encontrou clientes individuais.


Ficarei feliz em responder suas perguntas.

Source: https://habr.com/ru/post/pt424245/


All Articles