Criando um Bot do Telegram (Parte 3)

Depois de um grande tempo em standby, eu retomei a minha busca pelo bot concurseiro. Resolvi tentar criar um bot bem simples (@RodrigoLiraBot no Telegram) só para testar a API do telegram.

bot

Para isso eu dei uma olhada no site do próprio Telegram . Nele eu encontrei um módulo para  Python chamada twx.botapi . Sua utilização é bem simples e por isso resolvi usá-la.

A instalação é usando o pip

$ sudo pip install twx.botapi

No próprio do github tem um exemplo que guiou o meu desenvolvimento.

from twx.botapi import TelegramBot, ReplyKeyboardMarkup

"""
Setup the bot
"""

bot = TelegramBot('')
bot.update_bot_info().wait()
print(bot.username)

"""
Send a message to a user
"""
user_id = int()

result = bot.send_message(user_id, 'test message body').wait()
print(result)

"""
Get updates sent to the bot
"""
updates = bot.get_updates().wait()
for update in updates:
    print(update)

"""
Use a custom keyboard
"""
keyboard = [
    ['7', '8', '9'],
    ['4', '5', '6'],
    ['1', '2', '3'],
         ['0']
]
reply_markup = ReplyKeyboardMarkup.create(keyboard)

bot.send_message(user_id, 'please enter a number', reply_markup=reply_markup).wait()

O API TOKEN é um token que é gerado polo BotFather na criação do Bot. Lembrando que isso é uma informação secreta do seu bot. O legal desse exemplo é que ele também mostra como o teclado do bot pode ser customizado para atender a um determinado bot.

Abaixo segue um exemplo de update que é retornado pela função get_updates(). Um update é uma interação com o bot. Ele contém a mensagem e o usuário que realizou a interação.

Update(update_id=194163476, message=Message(message_id=288, sender=User(id=31616677, first_name=u'Rodrigo Lira', last_name=None, username=u'rodrigoclira'), date=1458837621, chat=Chat(id=31616677, type=u'private', title=None, username=u'rodrigoclira', first_name=u'Rodrigo Lira', last_name=None), forward_from=None, forward_date=None, reply_to_message=None, text=u'teste', audio=None, document=None, photo=None, sticker=None, video=None, voice=None, caption=None, contact=None, location=None, new_chat_participant=None, left_chat_participant=None, new_chat_title=None, new_chat_photo=None, delete_chat_photo=None, group_chat_created=None, supergroup_chat_created=None, channel_chat_created=None, migrate_to_chat_id=None, migrate_from_chat_id=None), inline_query=None, chosen_inline_result=None)

No meu caso, eu modifiquei um pouco esse código para criar um bot que fica respondendo sempre a mesma mensagem independente do que foi escrito para ele. A cada 30 segundos, ele responde a quem falou com ele com uma mensagem determinada por mim.

Para evitar mensagens repetidas, eu coloquei uma funcionalidade que evita o envio de mensagem para o mesmo update. A cada resposta do bot é guardada os identificadores das mensagem que foram respondidas usando a biblioteca pickle de Python. Se por acaso o programa for encerrado, o arquivo será lido na sua inicialização. Essa foi a alternativa mais rápida que encontrei mas creio que haja formas melhores de contornar isso.

No momento esse script está sendo executando num servidor que tenho na Dreamhost, mas é possível executar ele em qualquer máquina que tenha acesso a internet. O código do final do @RodrigoLiraBot é o seguinte:


from twx.botapi import TelegramBot, ReplyKeyboardMarkup
from time import sleep
import pickle
from os import path

CURR_PATH = path.dirname(path.realpath(__file__))
DUMP_FILE = path.join(CURR_PATH, "data.pkl")


"""
Configurando o bot
"""

BOTAPI='API_AQUI'
bot = TelegramBot(BOTAPI)
bot.update_bot_info().wait()

print(bot.username)

if path.exists(DUMP_FILE): # Se existe, carregar a lista de mensagens respondidas
    pkl_file = open(DUMP_FILE)
    answered_messages = pickle.load(pkl_file)
else:
    answered_messages = []

bot_message = "Oi, eu sou um bot do http://blog.rodrigolira.net/. Em breve terei mais funcionalidades!"

while (True):
    print ("Getting updates".center(50, '-'))
    
    updates = bot.get_updates().wait()
    for pos, update in enumerate(updates):

        print(str(pos) +" "+  str(update) + "n")

        update_id = update.update_id
        if (update_id not in answered_messages): # Se a mensagem não foi respondida, responda o usuário
            sender_id = update.message.sender.id
            result = bot.send_message(sender_id, bot_message).wait()

            print(result)

            if (result):
                answered_messages.append(update_id)

    output = open(DUMP_FILE, 'wb') 
    pickle.dump(answered_messages, output) # persiste a lista de mensagens respondidas
    sleep(30)

Se você quiser usar com o seu bot simplesmente coloque o APITOKEN recebido na criação dele.
O resultado é algo assim:

bottelegram

| Criando um bot do Telegram (parte 1)
| Criando um bot do Telegram (parte 2)


Warning: Missing argument 1 for cwppos_show_review(), called in /home/rodrigolira/blog.rodrigolira.net/wp-content/themes/flat/content-single.php on line 29 and defined in /home/rodrigolira/blog.rodrigolira.net/wp-content/plugins/wp-product-review/includes/legacy.php on line 18
  • Xinuo

    Fui procurar esse BOT do exemplo ( @RodrigoLiraBot ) e acabei achando outro ( @RodrigoBot), que atualmente têm mais funcionalidade que esse do seu exemplo. Não foi outro teste seu?

    De qq forma é bom começar do básico mesmo. Os links para as partes anteriores (1 e 2) do “Criando um BOT do Telegram” ainda estão ativos? Seria interessante que o atual artigo tivesse os links para as partes anteriores.

    • rodrigoclira

      Oi Xinuo, infelizmente esse não é meu.

  • Italo Medeiros

    Rodrigo, parabéns pela didática e pelo excelente material. Tenho um projeto onde a comunicação da aplicação com os Bots está em perfeita sintonia, queria saber
    se é possível um Bot enviar mensagens para um usuário, seja pelo número
    do telefone, id ou nome do usuário?

    • rodrigoclira

      Italo, eu não sei mas acho que você consegue encontrar essa informação na API

      • Italo Medeiros

        Consultei a documentação da API e vi que não é possível realizar esta implementação. Obrigado pelo feedback.

  • Juan Carlos

    Rodrigo, eu estou começando a mecher com o telegram e programação agora, eu realmente não consigo mudar a linguagem do meu bot, eu utilizo o windows e ao que tudo indica algumas ferramentas so podem ser usadas no linux, estou muito perdido e não acho nenhum tutorial basico de como mudar a linguagem de programação, se puder entrar em contato comigo ajudaria muito. juankjati@gmail.com

    • Maurício Eugênio

      você pode usar o python no windows também porém é muito mais facil utilizar-lo no linux

  • Estevam Furtado

    Rodrigo, eu tô na parte do primeiro teste com o código que você pegou na internet. Coloquei o meu API e ele tá até rodando no IDLE, mas não envia a mensagem… Tá dando erro.

    • rodrigoclira

      Você consegue ver algum erro, Estevam?

  • Fernanda A.

    Opa, muito bom!
    Era isso que eu tava procurando.
    Só uma pergunta, vc sabe como faz pra quebrar a linha na mensagem ?
    Já tentei n e não funcionou..

  • Power Duka

    seu blog me ajudou a tirar uma dúvida, e com isso, melhorar seu programa..
    se colocar o offset (update.update_id + 1) no get_updates, ele marca a última mensagem como lida, assim:
    bot.get_updates(offset=,).wait()
    valeu!