Cómo crear un bot para Telegram qué busque en X (Twitter) usando Docker Compose y Python

Tiempo de lectura: 3 minutos

Hoy vamos a crear un bot para un canal de Telegram, qué buscará tweets relevantes sobre un tema y los mostrará en el canal.

BUilding - Pexels

Primero vamos a crear el docker compose encargado de montar el servicio:

services:
  telegram_bot:
    build: .
    container_name: telegram_bot
    restart: always
    environment:
      - TELEGRAM_BOT_TOKEN=${TELEGRAM_BOT_TOKEN}
      - TELEGRAM_CHAT_ID=${TELEGRAM_CHAT_ID}
      - TWITTER_TOKEN=${TWITTER_TOKEN}

Ahora vamos a crear el DockerFile:

FROM python:3.9-slim

RUN pip install --upgrade pip

# Establecer directorio de trabajo
WORKDIR /app

# Copiar los archivos necesarios
COPY requirements.txt .

# Instalar dependencias
RUN pip install --no-cache-dir -r requirements.txt

# Copiar el código fuente
COPY app /app

# Comando para ejecutar el bot
CMD ["python", "telegram_bot.py"]

Este Dockerfile hace lo siguiente:

  1. Usa una imagen base ligera (python:3.9-slim).
  2. Copia los archivos necesarios dentro del contenedor.
  3. Instala las dependencias desde requirements.txt.
  4. Ejecuta el bot automáticamente al iniciar el contenedor.

Y ahora nos falta el .env con esta estructura:

TELEGRAM_BOT_TOKEN=tu_token_de_telegram
TELEGRAM_CHAT_ID=tu_chat_id
TWITTER_TOKEN=token_twitter

Y creamos tambien el archivo requirements.txt

tweepy==4.15.0
python-telegram-bot==20.0
requests==2.31.0
python-dotenv==0.20.0

Este requirements.txt incluye:

  • python-telegram-bot: Para interactuar con la API de Telegram.
  • requests: Para hacer solicitudes HTTP si se necesita.
  • tweepy: Para acceder a la API de Twitter (X).

Ahora necesitamos crear el bot en Telegram, para ello usamos BotFather

Escribe /newbot y sigue los pasos.

Guarda el Token que te da, y lo añades dentro del .env en la variable TELEGRAM_BOT_TOKEN=tu_token_de_telegram

Ahora vamos a crear el código base de Python para poder obtener los tweets.

Usaremos Tweepy

Obtén tu Bearer Token:

  • Ve a Twitter Developer Portal y crea una aplicación si no la has creado.
  • En el panel de la aplicación, encontrarás tu Bearer Token en la sección de «Keys and Tokens».

Generamos un Bearer Token, ya que este nos permitirá leer Tweets.

La añades en el .env en la variable: TWITTER_TOKEN=token_twitter

Creamos una carpeta llamada app y dentro telegram_bot.py

import os
import logging
import tweepy
from telegram import Update, ForceReply
from telegram.ext import Application, CommandHandler,MessageHandler, CallbackContext, filters, ContextTypes

# Configuración de logging para detectar errores
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
                    level=logging.INFO)
logger = logging.getLogger(__name__)

bearer_token = os.getenv("TWITTER_TOKEN")

telegram_token = os.getenv("TELEGRAM_BOT_TOKEN")


# Configurar autenticación de Tweepy (usando Bearer Token para solo lectura)
client = tweepy.Client(bearer_token=bearer_token,wait_on_rate_limit=True)


# Función para obtener el último tweet 
async def obtener_noticia():
    try:
        query = "Nokia lang:es"  # La consulta para buscar tweets relacionados
        tweets = client.search_recent_tweets(query=query, max_results=10)  # Buscar el tweet más reciente
        if tweets.data:
            tweet = tweets.data[0]  # Obtener el primer tweet
            return tweet.text  # Retornar el texto del tweet
        else:
            return "No se encontraron noticias recientes."
    except Exception as e:
        logger.error(f"Error al obtener noticia: {e}")
        return "Hubo un error al intentar obtener las noticias."

# Función para manejar el comando /actualizar_noticias
async def actualizar_noticias(update: Update, context: CallbackContext) -> None:
    noticia = await obtener_noticia()  # Obtener la noticia más reciente
    await update.message.reply_text(noticia)  # Enviar la noticia al grupo
    
async def saludar(update: Update, context: CallbackContext) -> None:
    await update.message.reply_text("Hola! Soy un bot que te ayuda a estar al tanto de las últimas noticias. Usa /actualizar_noticias para recibir la última noticia.")
    # Enviar un saludo al grupo

# Función principal para iniciar el bot
def main():
    application = Application.builder().token(telegram_token).build()

    # Comando para actualizar las noticias
    application.add_handler(CommandHandler('actualizar_noticias', actualizar_noticias))
    application.add_handler(CommandHandler('saludar', saludar))
    application.run_polling(allowed_updates=Update.ALL_TYPES)

if __name__ == '__main__':
    main()

Y ahora tenemos que obtener el id del grupo dónde lo vamos a incluir.

Para obtenerlo podemos usar este código una vez hemos añadido el bot al grupo:

import telegram

bot = telegram.Bot(token='tu_token_de_telegram')
updates = bot.get_updates()
for update in updates:
    print(update.message.chat.id)

O también podemos utilizar Botfather.

Para ello primero añadimos al bot al grupo.

Cuando crees un bot, BotFather te dará un token de acceso.

Para obtener el chat_id de un grupo:

  • Añade tu bot al grupo.
  • Envía un mensaje al grupo.
  • Luego, usa el siguiente enlace en tu navegador:
https://api.telegram.org/bot<tu_token>/getUpdates

*no incluyas los < > al poner el token.

Esto te devolverá un JSON con todos los mensajes recientes de tu bot, donde podrás encontrar el chat_id bajo "chat" -> "id".

Nota: En los canales el id suele ser un número negativo. No hay problema.

Lo copiamos y pegamos dentro de nuestro .env: TELEGRAM_CHAT_ID=tu_chat_id

Ya tenemos todo listo para poder ejecutarlo.

docker compose up -d

Deja un comentario