Cómo crear un bot de Telegram con Python

Publicado el: 11/07/2026
Tempo de leitura: 4 minutos
Criação de bot Telegram com Python

Un bot de Telegram con Python puede responder comandos, recopilar información, enviar avisos y automatizar conversaciones repetitivas. Telegram proporciona la plataforma y la Bot API, mientras que Python controla la lógica. Puedes comenzar con un bot pequeño para el terminal y, más adelante, conectar una base de datos, una API externa o un sistema de notificaciones.

Esta guía utiliza la biblioteca python-telegram-bot y su interfaz asíncrona. Aprenderás a crear el bot con BotFather, proteger el token, registrar comandos, responder mensajes, añadir botones, enviar archivos, almacenar datos temporales, registrar errores y preparar el proyecto para ejecutarse de manera continua.

Cómo funciona un bot de Telegram

Un bot es una cuenta especial controlada mediante la Telegram Bot API oficial. Cuando una persona envía un mensaje o pulsa un botón, Telegram genera una actualización. La aplicación recibe esa actualización y decide qué respuesta enviar.

Existen dos métodos habituales:

  • Long polling: el programa consulta periódicamente si existen actualizaciones nuevas.
  • Webhook: Telegram envía cada actualización a una URL HTTPS pública.

Para aprender y ejecutar un proyecto pequeño, el polling resulta más sencillo porque no exige un servidor público.

Crear el bot con BotFather

  1. Abre Telegram y busca la cuenta verificada @BotFather.
  2. Envía el comando /newbot.
  3. Elige un nombre visible.
  4. Elige un nombre de usuario terminado en bot.
  5. Copia el token generado.

El token permite controlar el bot. No lo publiques en repositorios, imágenes ni mensajes compartidos. Si se filtra, revócalo desde BotFather y crea otro.

Preparar el entorno

Crea un entorno virtual con la guía de venv en Python:

python -m venv .venv
python -m pip install python-telegram-bot python-dotenv

La documentación oficial de python-telegram-bot contiene ejemplos para la versión actual de la biblioteca. Es importante comprobarla porque ejemplos antiguos y síncronos pueden no funcionar con versiones modernas.

Guardar el token fuera del código

Crea un archivo .env:

TELEGRAM_BOT_TOKEN=tu_token_real

Añádelo a .gitignore:

.env
.venv/
__pycache__/

Después carga la variable:

import os
from dotenv import load_dotenv

load_dotenv()
TOKEN = os.getenv("TELEGRAM_BOT_TOKEN")

if not TOKEN:
    raise RuntimeError("Falta TELEGRAM_BOT_TOKEN")

La guía para leer variables de entorno en Python explica cómo proteger secretos y validar la configuración.

Crear el primer bot

import os
from dotenv import load_dotenv
from telegram import Update
from telegram.ext import Application, CommandHandler, ContextTypes

load_dotenv()
TOKEN = os.getenv("TELEGRAM_BOT_TOKEN")


async def inicio(
    update: Update,
    context: ContextTypes.DEFAULT_TYPE,
) -> None:
    usuario = update.effective_user
    await update.message.reply_text(
        f"Hola, {usuario.first_name}. Envía /ayuda."
    )


async def ayuda(
    update: Update,
    context: ContextTypes.DEFAULT_TYPE,
) -> None:
    await update.message.reply_text(
        "/inicio - saludo\n"
        "/ayuda - lista de comandos\n"
        "/acerca - información del bot"
    )


def main() -> None:
    if not TOKEN:
        raise RuntimeError("Token no configurado")

    app = Application.builder().token(TOKEN).build()
    app.add_handler(CommandHandler("inicio", inicio))
    app.add_handler(CommandHandler("ayuda", ayuda))
    app.run_polling()


if __name__ == "__main__":
    main()

Los handlers son asíncronos, por eso usan async def y await. La guía de asyncio en Python explica este modelo.

Responder mensajes normales

from telegram.ext import MessageHandler, filters


async def repetir(
    update: Update,
    context: ContextTypes.DEFAULT_TYPE,
) -> None:
    texto = update.message.text
    await update.message.reply_text(f"Escribiste: {texto}")


app.add_handler(
    MessageHandler(filters.TEXT & ~filters.COMMAND, repetir)
)

Registra primero los handlers específicos y después los generales. Un handler de texto demasiado amplio puede capturar mensajes que deberían procesarse de otra forma.

Crear reglas de conversación

async def conversar(update, context):
    texto = update.message.text.strip().casefold()

    if texto in {"hola", "buenas", "hey"}:
        respuesta = "Hola. ¿En qué puedo ayudarte?"
    elif "horario" in texto:
        respuesta = "Atendemos de lunes a viernes."
    elif "precio" in texto:
        respuesta = "Indica qué producto deseas consultar."
    else:
        respuesta = "No entendí. Envía /ayuda."

    await update.message.reply_text(respuesta)

Los sets y diccionarios ayudan a organizar intenciones y respuestas. Consulta la comparación de listas, tuplas, sets y diccionarios.

Añadir botones

from telegram import InlineKeyboardButton, InlineKeyboardMarkup
from telegram.ext import CallbackQueryHandler


async def menu(update, context):
    teclado = [
        [InlineKeyboardButton("Cursos", callback_data="cursos")],
        [InlineKeyboardButton("Soporte", callback_data="soporte")],
    ]
    await update.message.reply_text(
        "Selecciona una opción:",
        reply_markup=InlineKeyboardMarkup(teclado),
    )


async def pulsar_boton(update, context):
    consulta = update.callback_query
    await consulta.answer()

    if consulta.data == "cursos":
        texto = "Consulta el catálogo de cursos."
    else:
        texto = "Describe tu problema para iniciar el soporte."

    await consulta.edit_message_text(text=texto)

Siempre llama a answer() para cerrar el indicador de carga del botón.

Procesar argumentos de comandos

async def sumar(update, context):
    try:
        numeros = [float(valor) for valor in context.args]
    except ValueError:
        await update.message.reply_text(
            "Usa números: /sumar 10 25"
        )
        return

    if not numeros:
        await update.message.reply_text(
            "Debes enviar al menos un número."
        )
        return

    await update.message.reply_text(
        f"Total: {sum(numeros):g}"
    )

Valida la entrada y explica cómo corregirla. La guía de try y except ayuda a capturar errores específicos sin ocultar fallos inesperados.

Guardar datos temporales

async def guardar_nombre(update, context):
    if not context.args:
        await update.message.reply_text(
            "Usa /nombre seguido de tu nombre."
        )
        return

    nombre = " ".join(context.args).strip()
    context.user_data["nombre"] = nombre
    await update.message.reply_text(f"Guardado: {nombre}")

user_data sirve para información temporal. Los datos pueden desaparecer al reiniciar, salvo que configures persistencia. Para información importante, utiliza una base de datos y define políticas de privacidad y eliminación.

Enviar documentos

from pathlib import Path


async def enviar_informe(update, context):
    ruta = Path("informes") / "mensual.pdf"

    if not ruta.exists():
        await update.message.reply_text(
            "El informe todavía no está disponible."
        )
        return

    with ruta.open("rb") as archivo:
        await update.message.reply_document(document=archivo)

La guía de pathlib en Python explica rutas y archivos portables. Comprueba tamaño, tipo y permisos antes de enviar contenido generado por usuarios.

Registrar eventos y errores

import logging

logging.basicConfig(
    format="%(asctime)s %(levelname)s %(name)s: %(message)s",
    level=logging.INFO,
)
logger = logging.getLogger(__name__)


async def manejar_error(update, context):
    logger.exception(
        "Error no controlado",
        exc_info=context.error,
    )

No registres tokens, contraseñas, mensajes privados ni información personal innecesaria. La guía del módulo logging explica niveles, archivos y rotación.

Organizar un proyecto mayor

telegram_bot/
├── bot.py
├── handlers/
│   ├── comandos.py
│   └── mensajes.py
├── servicios/
│   └── catalogo.py
├── tests/
├── .env
├── .gitignore
└── requirements.txt

Separa handlers, reglas de negocio y acceso a datos. Así puedes probar funciones sin conectarte a Telegram. La guía de Pytest ayuda a automatizar estas comprobaciones.

Desplegar el bot

Para recibir actualizaciones, el proceso debe mantenerse activo. Puedes usar un servidor virtual, un contenedor o una plataforma administrada. En producción:

  • guarda el token en el gestor de secretos;
  • configura reinicio automático;
  • registra errores sin exponer datos privados;
  • utiliza almacenamiento duradero;
  • actualiza dependencias de forma controlada;
  • supervisa disponibilidad y tiempos de respuesta.

Problemas frecuentes

  • Unauthorized: token incorrecto, revocado o con espacios adicionales.
  • El bot no responde: proceso detenido, handler ausente o filtro incorrecto.
  • Funciona en privado pero no en grupos: revisa privacidad y permisos en BotFather.
  • Ejemplos antiguos fallan: comprueba la versión mayor instalada.
  • Los datos desaparecen: configura persistencia o usa una base de datos.

Conclusión

Crear un bot de Telegram con Python comienza con un token, una aplicación y algunos handlers. A partir de esa base puedes añadir comandos, botones, archivos, estado y servicios externos. Mantén las credenciales fuera del código, valida todas las entradas, separa la lógica de los handlers y añade registros y pruebas antes de ofrecer el bot a usuarios reales.

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Contenido del artículo

    Artículos relacionados

    Automação web com Selenium usando Python
    Automatización y ScriptsDesarrollo Web
    Foto de perfil de Leandro Hirt da Academify

    Selenium con Python: automatización web completa

    Aprende Selenium con Python para controlar navegadores, localizar elementos, usar esperas, completar formularios, tomar capturas y crear pruebas fiables.

    Ler mais

    Tempo de leitura: 5 minutos
    11/07/2026
    Geração de arquivos PDF usando biblioteca FPDF em Python
    Automatización y Scripts
    Foto de perfil de Leandro Hirt da Academify

    Cómo crear archivos PDF con Python y FPDF

    Aprende a crear PDF con Python y fpdf2: páginas, fuentes, párrafos, imágenes, tablas, Unicode, rutas, informes y manejo de errores.

    Ler mais

    Tempo de leitura: 4 minutos
    11/07/2026
    Logos do Python e Excel lado a lado representando a importação de dados do Excel para Python.
    Automatización y Scripts
    Foto de perfil de Leandro Hirt da Academify

    Cómo importar archivos Excel en Python con Pandas

    Importa archivos Excel en Python con Pandas y openpyxl: hojas, columnas, tipos, fechas, valores ausentes, limpieza y exportación.

    Ler mais

    Tempo de leitura: 3 minutos
    11/07/2026
    Python e ícone de e-mail sobre teclado de notebook
    Automatización y Scripts
    Foto de perfil de Leandro Hirt da Academify

    Cómo automatizar correos electrónicos con Python

    Automatiza correos con Python usando EmailMessage y smtplib, variables de entorno, HTML, adjuntos, destinatarios múltiples y manejo de errores.

    Ler mais

    Tempo de leitura: 3 minutos
    11/07/2026
    Logo do Python com o texto 'Python argparse CLI' abaixo
    Automatización y Scripts
    Foto de perfil de Leandro Hirt da Academify

    Cómo crear una CLI en Python con argparse

    Crea una CLI en Python con argparse: argumentos, banderas, tipos, choices, subcomandos, validación, pruebas y empaquetado moderno.

    Ler mais

    Tempo de leitura: 3 minutos
    11/07/2026