\n\n\n\n Minha Jornada com a API do Bot do Telegram: Além de Notificações Simples - AI7Bot \n

Minha Jornada com a API do Bot do Telegram: Além de Notificações Simples

📖 13 min read2,501 wordsUpdated Apr 2, 2026

Olá a todos, aqui é o Marcus do ai7bot.com. É 20 de março de 2026 e tenho pensado muito ultimamente sobre algo que se tornou um pouco um cavalo de batalha silencioso no mundo dos bots: a API do Bot do Telegram. Não é a novidade da vez, nem tão chamativa quanto algumas das estruturas de IA que estão nas manchetes, mas, caramba, é poderosa e, mais importante, incrivelmente acessível. Hoje, quero falar sobre como a API do Bot do Telegram não é mais apenas para notificações simples. Vamos explorar como você pode usá-la para construir ferramentas interativas surpreendentemente sofisticadas – especificamente, uma experiência multi-etapas para coleta de dados ou execução de comandos complexos. Esqueça aqueles exemplos de “enviar uma mensagem”; vamos para algo mais substancial.

Eu lembro da minha primeira incursão nos bots do Telegram em 2018. Eu criei um bot super básico que apenas ecoava de volta tudo o que você enviava. Revolucionário, eu sei. Mas mesmo naquele momento, a simplicidade de começar com a API era notável. Avançando até hoje, eu a usei para tudo, desde ferramentas internas de equipe que rastreiam atualizações de projetos até um bot que me ajuda a gerenciar meu backlog crescente de artigos para escrever. O que muitas vezes é negligenciado é o quão bem o Telegram desenvolveu sua API para lidar com interações complexas sem fazer você arrancar os cabelos. Estamos falando de gerenciamento de estado, teclados inline e teclados personalizados – todos os ingredientes para uma experiência de bot realmente envolvente.

Além de Comandos Simples: Construindo um Fluxo de Trabalho Multi-Etapas

A maior dificuldade que as pessoas enfrentam ao passar dos básicos “comandos de barra” é gerenciar o contexto. Se o seu bot faz uma pergunta, como ele sabe que a próxima mensagem do usuário é a resposta para aquela pergunta específica, e não um novo comando ou um pensamento aleatório? É aqui que o gerenciamento de estado entra. Não estamos falando de um banco de dados completo aqui, embora você certamente pudesse integrar um. Para muitas aplicações, um simples dicionário em memória ou um leve armazenador de chave-valor é perfeitamente suficiente.

Vamos imaginar que queremos construir um bot que ajuda um usuário a registrar uma nova “tarefa” ou “ideia”. Ele precisa pedir um título, depois uma descrição, e então talvez um nível de prioridade. Três etapas distintas, três peças distintas de informação que precisamos coletar na ordem. Se tivermos apenas um monte de comandos /start e /log, rapidamente se torna complicado.

A Ideia Central: Estado do Usuário e Fluxo da Conversa

Minha abordagem geralmente envolve manter um dicionário onde a chave é o ID do usuário e o valor é um objeto representando o estado atual da conversa dele. Esse objeto de estado pode conter:

  • current_step: Um enum ou string indicando onde ele está no fluxo de trabalho (por exemplo, ‘AGUARDANDO_TÍTULO’, ‘AGUARDANDO_DESCRIÇÃO’).
  • temp_data: Um dicionário para armazenar as informações coletadas até agora para o fluxo de trabalho atual (por exemplo, {'title': 'Minha Nova Ideia', 'description': ''}).

Quando uma mensagem chega, o bot verifica o estado do usuário. Se ele estiver em uma etapa específica do fluxo de trabalho, processa a mensagem como entrada para essa etapa. Caso contrário, trata como um comando geral.

Exemplo Prático: Um Bot Simples para Registro de Tarefas

Vamos colocar a mão na massa. Vamos construir um bot de registro de tarefas muito simplificado. O usuário iniciará um comando de “nova tarefa”, o bot pedirá um título, depois uma descrição e finalmente confirmará. Para simplicidade, vamos armazenar o estado em um dicionário Python. Para produção, você provavelmente gostaria de algo mais persistente, como Redis ou um pequeno banco de dados SQLite.

Configurando Seu Bot e Obtendo o Token da API

Primeiro, você precisa de um bot. Vá até o BotFather no Telegram (procure por @BotFather), envie /newbot, siga as instruções e ele te dará um token da API. Mantenha esse token em segredo!

Usaremos a biblioteca python-telegram-bot, que simplifica muito a interação com a API do Bot do Telegram. Instale-a com pip install python-telegram-bot.

A Estrutura do Código: Gerenciamento de Estado e Manipuladores

Aqui está um esqueleto básico para nosso bot. Observe como usaremos um dicionário global user_states para acompanhar onde cada usuário está em sua conversa. Em uma situação do mundo real, você gostaria de persistir isso entre as reinicializações do bot.


from telegram import Update, ForceReply
from telegram.ext import Application, CommandHandler, MessageHandler, filters, ContextTypes

# Substitua pelo seu token real do bot
BOT_TOKEN = "YOUR_BOT_TOKEN_HERE"

# --- Gerenciamento de Estado do Usuário ---
# Em um aplicativo real, isso seria persistente (por exemplo, Redis, banco de dados)
user_states = {}

# Defina os estados para nosso fluxo de trabalho
STATE_NONE = 0
STATE_AWAITING_TITLE = 1
STATE_AWAITING_DESCRIPTION = 2

# --- Comandos do Bot ---

async def start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
 """Envia uma mensagem de boas-vindas quando o comando /start é emitido."""
 user_id = update.effective_user.id
 user_states[user_id] = {'current_step': STATE_NONE, 'task_data': {}}
 await update.message.reply_text('Olá! Eu sou seu bot de registro de tarefas. Use /new_task para começar a registrar uma tarefa.')

async def new_task(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
 """Inicia o fluxo de trabalho de nova tarefa."""
 user_id = update.effective_user.id
 user_states[user_id] = {'current_step': STATE_AWAITING_TITLE, 'task_data': {}}
 await update.message.reply_text('Certo, vamos criar uma nova tarefa. Qual é o título?')

# --- Manipulador de Mensagens para Passos do Fluxo de Trabalho ---

async def handle_message(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
 """Lida com todas as mensagens recebidas e direciona com base no estado do usuário."""
 user_id = update.effective_user.id
 text = update.message.text

 current_state = user_states.get(user_id, {'current_step': STATE_NONE})['current_step']
 task_data = user_states.get(user_id, {'task_data': {}})['task_data']

 if current_state == STATE_AWAITING_TITLE:
 task_data['title'] = text
 user_states[user_id]['task_data'] = task_data
 user_states[user_id]['current_step'] = STATE_AWAITING_DESCRIPTION
 await update.message.reply_text(f'Entendi. Título: "{text}". Agora, por favor, forneça uma descrição para a tarefa.')
 
 elif current_state == STATE_AWAITING_DESCRIPTION:
 task_data['description'] = text
 user_states[user_id]['task_data'] = task_data
 user_states[user_id]['current_step'] = STATE_NONE # Reinicia o estado
 
 # Aqui você normalmente salvaria o task_data em um banco de dados ou arquivo
 await update.message.reply_text(
 f'Tarefa criada!\nTítulo: {task_data["title"]}\nDescrição: {task_data["description"]}\n\n'
 f'Você pode iniciar uma nova tarefa com /new_task.'
 )
 # Limpa os dados da tarefa para este usuário
 user_states[user_id]['task_data'] = {}
 
 else:
 # Se nenhum fluxo de trabalho específico estiver ativo, responda com uma mensagem padrão
 await update.message.reply_text('Não entendo isso. Tente /new_task para começar a criar uma tarefa.')

# --- Configuração Principal do Bot ---

def main() -> None:
 """Inicia o bot."""
 application = Application.builder().token(BOT_TOKEN).build()

 # Registra manipuladores
 application.add_handler(CommandHandler("start", start))
 application.add_handler(CommandHandler("new_task", new_task))
 application.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, handle_message))

 # Executa o bot até que o usuário pressione Ctrl-C
 application.run_polling(allowed_updates=Update.ALL_TYPES)

if __name__ == "__main__":
 main()

Algumas coisas a serem observadas aqui:

  • user_states: Este dicionário é nossa máquina de estados simples. Cada ID de usuário mapeia para seu passo atual e qualquer dado coletado.
  • start e new_task comandos: Esses iniciam ou redefinem o estado. O new_task especificamente define o estado do usuário para STATE_AWAITING_TITLE.
  • handle_message: Este é o cavalo de batalha. Ele verifica o estado atual do usuário e age de acordo. Se STATE_AWAITING_TITLE, assume que a mensagem é o título. Se STATE_AWAITING_DESCRIPTION, assume que a mensagem é a descrição. Após coletar todas as informações, redefine o estado para STATE_NONE.
  • filters.TEXT & ~filters.COMMAND: Isto é crucial para handle_message. Garante que este manipulador processe apenas mensagens de texto simples que NÃO sejam comandos (como /start ou /new_task), prevenindo conflitos com nossos manipuladores de comandos.

Adicionando um Toque de Interatividade: Teclados Inline para Confirmação

Em vez de apenas pedir uma descrição, e se quiséssemos pedir um nível de prioridade, e dar ao usuário opções predefinidas? É aqui que os Teclados Inline do Telegram brilham. Eles aparecem diretamente anexados a uma mensagem e enviam “dados de callback” quando tocados, em vez de uma mensagem completa.

Vamos modificar nosso fluxo de trabalho para perguntar sobre prioridade usando um teclado inline após a descrição.


from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup
from telegram.ext import Application, CommandHandler, MessageHandler, CallbackQueryHandler, filters, ContextTypes

# ... (BOT_TOKEN, user_states, STATE_NONE, STATE_AWAITING_TITLE, STATE_AWAITING_DESCRIPTION) ...

STATE_AWAITING_PRIORITY = 3 # Novo estado

# ... (os comandos start e new_task permanecem os mesmos) ...

async def handle_message(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
 user_id = update.effective_user.id
 text = update.message.text

 current_state = user_states.get(user_id, {'current_step': STATE_NONE})['current_step']
 task_data = user_states.get(user_id, {'task_data': {}})['task_data']

 if current_state == STATE_AWAITING_TITLE:
 task_data['title'] = text
 user_states[user_id]['task_data'] = task_data
 user_states[user_id]['current_step'] = STATE_AWAITING_DESCRIPTION
 await update.message.reply_text(f'Entendi. Título: "{text}". Agora, por favor, forneça uma descrição para a tarefa.')
 
 elif current_state == STATE_AWAITING_DESCRIPTION:
 task_data['description'] = text
 user_states[user_id]['task_data'] = task_data
 user_states[user_id]['current_step'] = STATE_AWAITING_PRIORITY # Mover para o novo estado
 
 keyboard = [
 [InlineKeyboardButton("Alta", callback_data="priority_high")],
 [InlineKeyboardButton("Média", callback_data="priority_medium")],
 [InlineKeyboardButton("Baixa", callback_data="priority_low")],
 ]
 reply_markup = InlineKeyboardMarkup(keyboard)
 await update.message.reply_text('Obrigado pela descrição! Qual é a prioridade para esta tarefa?', reply_markup=reply_markup)
 
 else:
 await update.message.reply_text('Não entendi isso. Tente /new_task para começar a criar uma tarefa.')

async def handle_callback_query(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
 """Processa os pressionamentos dos botões do teclado inline."""
 query = update.callback_query
 await query.answer() # Sempre responda as consultas de callback, mesmo que vazias

 user_id = query.from_user.id
 data = query.data # Este é o callback_data que definimos nos botões

 current_state = user_states.get(user_id, {'current_step': STATE_NONE})['current_step']
 task_data = user_states.get(user_id, {'task_data': {}})['task_data']

 if current_state == STATE_AWAITING_PRIORITY and data.startswith('priority_'):
 task_data['priority'] = data.split('_')[1] # Extrai 'high', 'medium', 'low'
 user_states[user_id]['task_data'] = task_data
 user_states[user_id]['current_step'] = STATE_NONE # Redefinir estado
 
 # Edita a mensagem para remover o teclado e mostrar a confirmação
 await query.edit_message_text(
 f'Tarefa criada!\nTítulo: {task_data["title"]}\nDescrição: {task_data["description"]}\n'
 f'Prioridade: {task_data["priority"].capitalize()}\n\nVocê pode iniciar uma nova tarefa com /new_task.'
 )
 # Limpa os dados da tarefa para este usuário
 user_states[user_id]['task_data'] = {}
 else:
 await query.edit_message_text('Algo deu errado ou sua sessão expirou. Por favor, comece novamente com /new_task.')

# --- Configuração Principal do Bot (atualizada) ---

def main() -> None:
 application = Application.builder().token(BOT_TOKEN).build()

 application.add_handler(CommandHandler("start", start))
 application.add_handler(CommandHandler("new_task", new_task))
 application.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, handle_message))
 application.add_handler(CallbackQueryHandler(handle_callback_query)) # Novo manipulador para botões inline

 application.run_polling(allowed_updates=Update.ALL_TYPES)

if __name__ == "__main__":
 main()

As principais adições aqui são:

  • STATE_AWAITING_PRIORITY: Um novo estado para gerenciar.
  • InlineKeyboardButton e InlineKeyboardMarkup: Usados para construir os botões interativos.
  • callback_data: Uma string associada a cada botão. Isso é o que é enviado de volta para o seu bot quando o botão é pressionado. É limitado a 64 bytes, então mantenha-o conciso.
  • CallbackQueryHandler: Um novo tipo de manipulador na nossa configuração principal, especificamente para escutar esses pressionamentos de botões inline.
  • query.answer(): Importante para a experiência do usuário. O Telegram espera uma resposta rápida a uma consulta de callback, mesmo que seja vazia, para mostrar ao usuário que seu toque foi registrado.
  • query.edit_message_text(): Em vez de enviar uma nova mensagem, atualizamos a existente. Isso torna o fluxo da conversa muito mais limpo, pois o teclado inline desaparece assim que uma escolha é feita.

Essa abordagem transforma uma série potencialmente confusa de prompts de texto em uma experiência muito mais intuitiva e amigável. Imagine expandir isso para selecionar categorias, datas de um seletor de calendário (usando mais botões inline) ou confirmar ações antes de serem executadas.

Conclusões Ação para Seu Próximo Projeto de Bot

  1. Abrace a Gestão de Estado Desde o Início: Para qualquer coisa além de bots de comando único, você *precisará* rastrear o estado do usuário. Comece simples com um dicionário, mas planeje a persistência se seu bot precisar lembrar conversas após reinícios.
  2. Use os Elementos de Interface do Telegram: Teclados inline e teclados de resposta personalizados são incrivelmente poderosos para guiar os usuários, oferecer escolhas e simplificar a entrada. Não faça os usuários digitarem tudo, se você puder oferecer um botão.
  3. Modularize Seus Manipuladores: À medida que seu bot cresce, separa sua lógica em funções distintas ou até módulos. Uma única função handle_message rapidamente se torna difícil de gerenciar.
  4. Trate Casos Limite e Restaurações: E se um usuário digitar /new_task no meio de outro fluxo de trabalho? E se ele simplesmente parar de responder? Implemente formas de redefinir conversas de maneira clara ou de reinseri-los no fluxo. Meu exemplo lida com isso implicitamente redefinindo o estado com /new_task.
  5. Teste, Teste, Teste: Use um bot de teste (do BotFather) para desenvolvimento. Teste diferentes fluxos de usuário, entradas inesperadas e uso concorrente.

A API do Bot do Telegram, especialmente com bibliotecas como python-telegram-bot, oferece um fantástico campo de provas para construir aplicações interativas. Não é apenas para enviar fotos de gatos; você pode construir ferramentas realmente úteis com surpreendentemente pouco esforço. Portanto, vá em frente, experimente esses conceitos e crie algo legal!

Artigos Relacionados

🕒 Published:

💬
Written by Jake Chen

Bot developer who has built 50+ chatbots across Discord, Telegram, Slack, and WhatsApp. Specializes in conversational AI and NLP.

Learn more →
Browse Topics: Best Practices | Bot Building | Bot Development | Business | Operations
Scroll to Top