Artigo original: How to set up push notifications in your Telegram bot
Traduzido em português europeu
Escrito por: Nikita Kholin
O Telegram é uma ótima plataforma com muitos utilizadores – eu próprio sou um utilizador do Telegram. Qual seria a melhor forma para os utilizadores do Telegram receberem notificações? Não podemos ter a certeza. Talvez gostem de receber por e-mail ou de outro forma, mas podemos supor que enviar notificações para o Telegram seria bastante conveniente.
Se gostarias de enviar notificações para o Telegram a partir da tua aplicação, vieste ao sítio certo. Adicionei esta funcionalidade à minha aplicação e adorei.
Uma pequena nota: neste artigo, forneci exemplos de código em Python. As ideias, contudo, não são específicas para o Python e podem ser traduzidas para outra linguagem sem qualquer problema.
Então, sem mais demoras, vamos ver como podemos fazê-lo.
Criar um bot do Telegram
Em primeiro lugar, precisas criar um bot do Telegram. Para fazer isto, tens de utilizar outro bot do Telegram, o BotFather. Começa a falar com ele (clica em start).
Agora, podes ver o que ele pode fazer, mas o que nos interessa é criar um novo bot. Por isso, vamos escolher (/newbot
).
Vamos descobrir rapidamente que o nome do bot deve terminar com "bot". E, visto que és como eu e chegaste à festa muito tarde, maior parte dos nomes de bot já estão ocupados.
Eventualmente, porém, vais encontrar um nome para o teu bot e receber um token de acesso de que vamos precisar.
Agora que tens um bot, os utilizadores do Telegram podem encontrá-lo e utilizá-lo, mas há um problema — não podes associar os utilizadores que vêm do Telegram aos utilizadores da tua aplicação. Permite-me mostrar-te a razão.
Assim que um utilizador clicar no botão "Start" no teu bot, vais receber uma "atualização". Podes verificar todas as atualizações do bot até mesmo no teu browser ao visitar o seguinte URL: https://api.telegram.org/bot{bot_token}/getUpdates
(não te esqueças de utilizar o teu token de acesso no URL). Isto é o que obtive:
Não consegues ler nada? Não te preocupes. Podes corrigir isso ao instalar alguma extensão JSON prettifier no teu navegador. Eu utilizo o JSON Formatter para o Chrome. Tem um aspeto muito melhor.
Então, como podes ver, não recebemos grande informação sobre a pessoa. A partir dessa informação, podes obter o nome completo da pessoa. Seria, no entanto, uma sorte se o utilizador fornecesse o seu nome completo na tua aplicação, e não temos garantia que seja único. Por isso, não podemos utilizar isso para encontra um utilizador nas tuas aplicações.
Outra informação que obtemos é o nome de utilizador. Isto é mais útil porque é único entre todos os utilizadores do Telegram. O mais provável, porém, é que não tenhas isso disponível nas tuas aplicações. Então, teríamos de pedir ao utilizador para inserir o seu nome de utilizador algures na aplicação. É muito trabalho que não tenho a certeza se alguém o faria.
Outra opção para associar um utilizador seria pedir-lhes para fornecer o e-mail que utilizaram para o bot na tua aplicação. Ocorre que isso tem muitas falhas: o utilizador pode enganar-se ao escrever o e-mail, o utilizador pode inserir um e-mail de outro utilizador para se aproveitarem do sistema. Isso é muito mau.
Podemos fazer melhor?
Associar um utilizador
Claro que podemos. Para associar o utilizador, vamos utilizar uma técnica chamada deep linking (texto em inglês).
Primeiro, tens de criar um token aleatório único para cada utilizador. Utilizei o seguinte código para gerar o token, utilizando Python:
from secrets import token_url
safetoken = token_urlsafe(8)
token
# => 'uEDbtJFHxKc'
De seguida, precisas guardar esse token para ser possível encontrar um utilizador com o token mais tarde. Podes guardar o token na tua base de dados ou utilizar outro local, como por exemplo uma cache. Tenho um modelo Notification
, por isso adicionei um campo a uma tabela do modelo.
class Notification(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
# ...
connect_token = models.CharField(max_length=64, null=True)
Então, geramos o token uEDbtJFHxKc
e guardamo-lo. Agora, vamos ter de utilizar este token num URL para o bot do Telegram, que o utilizador tem de clicar para fazer com que tudo funcione:
telegram_url = 'https://www.telegram.me'
bot_name = 'music_notification_bot'
token = 'uEDbtJFHxKc'
url = f'{telegram_url}/{bot_name}?start={token}'
Agora que temos o nosso URL, 'https://telegram.me/music_notification_bot?start=uEDbtJFHxKc'
, está na hora de o exibir ao utilizador. Exibe-o em qualquer sitio da tua aplicação e aguarda que o utilizador clique nele.
Assim que o utilizador morder o isco e clicar em “Start”, deves receber outra atualização:
{
"ok": true,
"result": [
// ...
// atualizações anteriores
// ...
{
"update_id": 599162365,
"message": {
"message_id": 174,
"from": { ... },
"chat": { ... },
"date": 1549788357,
"text": "/start uEDbtJFHxKc",
"entities": [ ... ]
}
}
]
}
Podemos, finalmente, identificar o nosso utilizador. O campo text
contém agora o nosso token de utilizador. Vamos avançar e removê-lo deste campo:
bot_token = 'your_bot_token'
updates_url = f'https://api.telegram.org/bot{bot_token}/getUpdates'
import requests
response = requests.get(updates_url).json()
text = response['result'][0]['message']['text']
text
# => '/start uEDbtJFHxKc'
splitted_text = text.split(' ')
# => ['/start', 'uEDbtJFHxKc']
token = splitted_text[-1]
# => 'uEDbtJFHxKc'
Este token pode ser utilizado para encontrar o utilizador. A tua implementação depende da forma como guardaste o token inicialmente. Mas aqui fica como eu faço:
notification = Notification.objects.get(channel='telegram', connect_token=token)
user = notification.user
Então, o utilizador clicou no botão "Start", mas reparou que nada aconteceu. Vamos dar as boas vindas, pelo menos.
Para dar as boas vindas ao utilizador, precisamos de descobrir se o utilizador iniciou uma conversa com o nosso bot. Existem duas opções para como podemos fazer isso: polling e webhooks.
Já sabes o que é polling. Já o fizeste. Ou pelo menos já me viste a fazê-lo. Assim que consultamos a página https://api.telegram.org/bot{bot_token}/getUpdates
, fizemos uma poll. Polling é verificar constantemente se existem atualizações, a cada 2 segundos, por exemplo. Desta forma podemos saber sempre quando alguém interagiu com o bot.
Os Webhooks vão numa direção um pouco diferente. Em vez de verificar a cada 2 segundos se existem atualizações, simplesmente esperamos que aconteça uma atualização. Quando acontecer, o Telegram enviará um pedido com a informação da atualização para um URL que especificamos. Deste modo, podemos dar algum descanso tanto aos nossos servidores como aos do Telegram, e simplesmente esperar que chegue alguma atualização.
Polling pode ser melhor se tiveres um tráfego elevado mas, infelizmente, é uma exceção, por isso, decidimos utilizar o webhook.
Webhooks
Configurar um webhook no Telegram é muito fácil. Só tens de enviar um pedido para https://api.telegram.org/bot{bot_token}/setWebhook?url={your_server_url}
. Abrir este link no teu browser também funciona. your_server_url
é o URL para onde o Telegram enviará as atualizações. Aqui está o que deves obter como resposta:
{
"ok": true,
"result": true,
"description": "Webhook was set"
}
Se não confiares nas tuas capacidades, podes visitar https://api.telegram.org/bot{bot_token}/getWebhookInfo
apenas para verificar que está tudo OK. Deves ver algo como isto:
{
"ok": true,
"result": {
"url": "https://example.com/your_server_endpoint",
"has_custom_certificate": false,
"pending_update_count": 0,
"max_connections": 40
}
}
Agora, se algo não estiver OK (como teres colocado o URL errado), podes sempre remover o webhook ao visitar https://api.telegram.org/bot{bot_token}/deleteWebhook
e de seguida, configurar novamente o webhook.
Desenvolvimento local
Antes de avançar, gostaria de partilhar algumas palavras sobre o desenvolvimento local. Os webhooks não são muito adequados para isto. Os webhooks são enviados para um URL e muito provavelmente não sabes qual é o URL do teu computador. Além disso, um webhook do Telegram requer que o URL seja seguro (HTTPS).
Existe, no entanto, uma solução para este problema: ngrok. ngrok é uma ferramenta que expõe o teu ambiente local ao mundo. Descarrega o ngrok, faz a instalação e inicia-o com a porta em que o teu servidor está a executar. O meu servidor está a executar na porta 8000
, por isso, teria de executar o seguinte na consola
/path/to/ngrok http 8000
Depois, o ngrok deve fornecer-te um URL que podes utilizar para configurar um webhook.
Dar as boas vindas a um utilizador
Agora que tens tudo pronto para o desenvolvimento, vamos dar as boas vindas ao nosso utilizador — está à espera disso.
Assim que o utilizador clicar em "Start", o teu Telegram enviará uma atualização para o URL do teu servidor. As partes interessantes da atualização devem ter este aspeto:
{
"message": {
"chat": {
"id": 457
},
"text": "/start uEDbtJFHxKc",
}
}
Esta é a altura ideal para associar o utilizador através de uma mensagem de texto. Também existe um pedaço de informação interessante, ID de Chat. O ID de Chat é o que precisamos para enviar uma mensagem a esse utilizador. O Telegram tem um endpoint de API para enviar uma mensagem, que tem este aspeto: https://api.telegram.org/bot{bot_token}/sendMessage?chat_id={chat_id}&text={text}
. Não tenho a certeza se preciso de explicar como utilizá-lo, mas aqui está como fica o meu código que processa o webhook:
import json
import requests
def callback(request):
body = json.loads(request.body)
text = body['message']['text']
token = text.split(' ')[-1]
associate_user_by_token(token)
bot_key = os.environ.get('TELEGRAM_API_KEY')
chat_id = body['message']['chat']['id']
text = "Welcome!"
send_message_url = f'https://api.telegram.org/bot{bot_key}/sendMessage?chat_id={chat_id}&text={text}'
requests.post(send_message_url)
Se enviarmos uma mensagem de boas vindas depois do utilizador ter clicado no famoso botão de "Start", o utilizador não terá dúvidas sobre o funcionamento da aplicação.
Enviar notificações
Por fim, chegamos à razão pela qual estamos a fazer tudo isto — enviar notificações. Podes querer notificar o utilizador sobre algo que tenha acontecido na tua aplicação. Por exemplo, alguém colocou um gosto na publicação do utilizador, ou algo do género. Eu utilizo o Telegram para enviar notificações sobre novos lançamentos de músicas dos artistas favoritos do utilizador.
Já sabes como enviar notificações. Apenas precisas enviar uma mensagem utilizando https://api.telegram.org/bot{bot_token}/sendMessage?chat_id={chat_id}&text={notification_text}
.
Claro, se não estiveres a planear enviar notificações só quando o utilizador interage com o bot, vais ter de guardar o chat_id
na tua base de dados.
Também podes querer incluir links ou outro tipo de formatações na tua mensagem. Neste caso, é necessário adicionares outro parâmetro ao URL de envio da mensagem, o parse_mode
. Existem duas opções de parsing: Markdown ou HTML. Eu utilizei Markdown porque acho mais simples de utilizar. Se não estiveres à vontade com Markdown, podes utilizar HMTL, mas recomendo que leias quão fácil é realmente o Markdown (texto em inglês).
Aqui está o aspeto do URL de envio da mensagem com o parâmetro parse_mode
: https://api.telegram.org/bot{bot_token}/sendMessage?chat_id={chat_id}&text={notification_text}&parse_mode=markdown
.
Eu adiciono links para novas atualizações ao texto das notificações desta forma: {release.date}: {release.artist.name} - [{release.title}]({release.url})
. Podes ler mais sobre como formatar as tuas mensagens aqui (Link em Inglês).
Além disso, existem mais parâmetros disponíveis para o URL de envio da mensagem, como por exemplo o disable_notification
. Existe sempre algo a ser explorado.
Conclusão
Agora, deves saber como:
- Criar um bot no Telegram utilizando o BotFather
- Verificar se existem atualizações (e qual é a melhor forma de o fazer — webhooks ou polling)
- Associar utilizadores utilizando deep linking
- Enviar uma mensagem de boas vindas e continuar a enviar notificações
- Formatar as mensagens que envias
Espero que este artigo tenha sido útil para ti. Esta é a quinta parte de uma série de artigos sobre o MuN (link em inglês). Fica atento/a à parte 6. Podes encontrar o código deste projeto, assim como os meus outros projetos na minha página do GitHub. Segue o autor se tiveres gostado deste artigo.
Publicado originalmente em https://kholinlabs.com/telegram-push-notifications, a 12 de Fevereiro de 2019.