From 62d0ec78b5273e1d6cea70ca2b9873ca73259540 Mon Sep 17 00:00:00 2001 From: Manuel Vergara Date: Wed, 10 Jul 2024 01:03:15 +0200 Subject: [PATCH] Add bots telegram --- .gitignore | 7 ++ catch-all/06_bot_telegram/01_id_bot/id_bot.py | 16 ++++ .../06_bot_telegram/02_pruebas_bot/bot.py | 43 +++++++++ .../06_bot_telegram/02_pruebas_bot/config.py | 19 ++++ .../02_pruebas_bot/handlers.py | 89 +++++++++++++++++++ .../06_bot_telegram/02_pruebas_bot/logger.py | 23 +++++ .../06_bot_telegram/02_pruebas_bot/utils.py | 15 ++++ catch-all/06_bot_telegram/README.md | 16 ++++ catch-all/README.md | 1 + 9 files changed, 229 insertions(+) create mode 100644 catch-all/06_bot_telegram/01_id_bot/id_bot.py create mode 100644 catch-all/06_bot_telegram/02_pruebas_bot/bot.py create mode 100644 catch-all/06_bot_telegram/02_pruebas_bot/config.py create mode 100644 catch-all/06_bot_telegram/02_pruebas_bot/handlers.py create mode 100644 catch-all/06_bot_telegram/02_pruebas_bot/logger.py create mode 100644 catch-all/06_bot_telegram/02_pruebas_bot/utils.py create mode 100644 catch-all/06_bot_telegram/README.md diff --git a/.gitignore b/.gitignore index 1ef22b9..6341b6b 100644 --- a/.gitignore +++ b/.gitignore @@ -177,3 +177,10 @@ cython_debug/ # Ignore binary files of mitmproxy mitmproxy/ + + +# Logs del bot telegram +bot.log* +logs/ + + diff --git a/catch-all/06_bot_telegram/01_id_bot/id_bot.py b/catch-all/06_bot_telegram/01_id_bot/id_bot.py new file mode 100644 index 0000000..3ab6dca --- /dev/null +++ b/catch-all/06_bot_telegram/01_id_bot/id_bot.py @@ -0,0 +1,16 @@ +import telebot +import os +from dotenv import load_dotenv + +load_dotenv('.env') +BOT_TOKEN = os.getenv('BOT_TOKEN') +bot = telebot.TeleBot(BOT_TOKEN) + + +@bot.message_handler(commands=['get_group_id']) +def get_group_id(message): + chat_id = message.chat.id + bot.reply_to(message, f"El ID de este grupo es: {chat_id}") + + +bot.polling() diff --git a/catch-all/06_bot_telegram/02_pruebas_bot/bot.py b/catch-all/06_bot_telegram/02_pruebas_bot/bot.py new file mode 100644 index 0000000..d456d35 --- /dev/null +++ b/catch-all/06_bot_telegram/02_pruebas_bot/bot.py @@ -0,0 +1,43 @@ +""" +Pruebas con un bot de Telegram +Doc: https://github.com/eternnoir/pyTelegramBotAPI +""" +# bot.py +# Este es el script principal que ejecuta el bot de Telegram. + +import signal +from termcolor import colored +from handlers import bot +from logger import logger + + +def def_handler(sig, frame): + """ + Manejador de señal para cerrar el programa de forma segura. + + Args: + sig: Señal recibida. + frame: Frame actual. + """ + + print(colored( + f"\n\n[!] Saliendo del programa...\n", "red", attrs=["bold"] + )) + logger.info("Bot detenido por el usuario.") + bot.stop_polling() + exit(1) + + +# Configurar el manejador de señal para SIGINT (Ctrl+C) +signal.signal(signal.SIGINT, def_handler) + + +# Iniciar el bot +if __name__ == "__main__": + try: + logger.info("Bot iniciado.") + bot.infinity_polling() + except Exception as e: + logger.error(f"Error en la ejecución del bot: {str(e)}") + except KeyboardInterrupt: + def_handler(None, None) diff --git a/catch-all/06_bot_telegram/02_pruebas_bot/config.py b/catch-all/06_bot_telegram/02_pruebas_bot/config.py new file mode 100644 index 0000000..173fd3d --- /dev/null +++ b/catch-all/06_bot_telegram/02_pruebas_bot/config.py @@ -0,0 +1,19 @@ +# config.py +# Este módulo gestiona la configuración y la carga de variables de entorno. + +import os +from dotenv import load_dotenv + +# Cargar las variables de entorno desde el archivo .env +load_dotenv('.env') + +# Obtener el token del bot y el ID del chat de grupo desde las variables de entorno +BOT_TOKEN = os.getenv('BOT_TOKEN') +GROUP_CHAT_ID = os.getenv('GROUP_CHAT_ID') + +# Validar que las variables de entorno estén configuradas +if not BOT_TOKEN or not GROUP_CHAT_ID: + raise AssertionError("Por favor, configura las variables de entorno BOT_TOKEN y GROUP_CHAT_ID") + +# Convertir GROUP_CHAT_ID a entero +GROUP_CHAT_ID = int(GROUP_CHAT_ID) diff --git a/catch-all/06_bot_telegram/02_pruebas_bot/handlers.py b/catch-all/06_bot_telegram/02_pruebas_bot/handlers.py new file mode 100644 index 0000000..712b073 --- /dev/null +++ b/catch-all/06_bot_telegram/02_pruebas_bot/handlers.py @@ -0,0 +1,89 @@ +# handlers.py +# Este módulo contiene los manejadores de mensajes del bot. + +from telebot import TeleBot +from logger import logger +import config + +# Mensajes de texto del bot en español +text_messages = { + 'welcome': + u'¡Por favor denle la bienvenida a {name}!\n\n' + u'Este chat está destinado a preguntas y discusión sobre la pyTelegramBotAPI.\n' + u'Para permitir que los miembros del grupo respondan a tus preguntas de forma rápida y precisa, asegúrate de ' + u'estudiar la documentación del proyecto (https://github.com/eternnoir/pyTelegramBotAPI/blob/master/README.md) ' + u'y los ejemplos (https://github.com/eternnoir/pyTelegramBotAPI/tree/master/examples) primero.\n\n' + u'¡Espero que disfrutes tu estadía aquí!', + + 'info': + u'Mi nombre es TeleBot,\n' + u'Soy un bot que asiste a estas maravillosas personas que crean bots en este chat del grupo de la librería.\n' + u'Además, todavía estoy en desarrollo. ¡Por favor, mejora mi funcionalidad haciendo una solicitud de pull! ' + u'Las sugerencias también son bienvenidas, solo déjalas en este chat del grupo!', + + 'wrong_chat': + u'¡Hola!\nGracias por probarme. Sin embargo, este bot solo puede usarse en el chat del grupo pyTelegramAPI.\n' + u'¡Únete a nosotros!\n\n' + u'https://telegram.me/joinchat/067e22c60035523fda8f6025ee87e30b' +} + +# Crear una instancia del bot con el token de configuración +bot = TeleBot(config.BOT_TOKEN) + +# Manejador para cuando un nuevo participante se une al chat +@bot.message_handler(func=lambda m: True, content_types=['new_chat_participant']) +def on_user_joins(message): + try: + # Obtener el nombre del nuevo participante + name = message.new_chat_participant.first_name + if hasattr(message.new_chat_participant, 'last_name') and message.new_chat_participant.last_name is not None: + name += f" {message.new_chat_participant.last_name}" + + if hasattr(message.new_chat_participant, 'username') and message.new_chat_participant.username is not None: + name += f" (@{message.new_chat_participant.username})" + + # Enviar mensaje de bienvenida + bot.reply_to(message, text_messages['welcome'].format(name=name)) + except Exception as e: + logger.error(f"Error en on_user_joins: {str(e)}") + +# Manejador para los comandos /info y /help +@bot.message_handler(commands=['info', 'help']) +def on_info(message): + try: + bot.reply_to(message, text_messages['info']) + except Exception as e: + logger.error(f"Error en on_info: {str(e)}") + +# Manejador para el comando /ping +@bot.message_handler(commands=["ping"]) +def on_ping(message): + try: + bot.reply_to(message, "¡Sigo vivo y pateando!") + except Exception as e: + logger.error(f"Error en on_ping: {str(e)}") + + +# Manejador para el comando /tq +@bot.message_handler(commands=["tq"]) +def on_ping(message): + try: + bot.reply_to(message, "¡Te quiero princesa!") + except Exception as e: + logger.error(f"Error en on_tq: {str(e)}") + + +# Manejador para el comando /start +@bot.message_handler(commands=['start']) +def on_start(message): + try: + bot.reply_to(message, "¡Bienvenido! Usa /info para más información.") + except Exception as e: + logger.error(f"Error en on_start: {str(e)}") + +# Listener para registrar todos los mensajes recibidos +def listener(messages): + for m in messages: + logger.info(f"Mensaje recibido: {str(m)}") + +bot.set_update_listener(listener) diff --git a/catch-all/06_bot_telegram/02_pruebas_bot/logger.py b/catch-all/06_bot_telegram/02_pruebas_bot/logger.py new file mode 100644 index 0000000..a9812ed --- /dev/null +++ b/catch-all/06_bot_telegram/02_pruebas_bot/logger.py @@ -0,0 +1,23 @@ +# logger.py +# Este módulo configura el logging con rotación de archivos. + +import logging +from logging.handlers import RotatingFileHandler + +# Ruta del archivo de log +log_file = 'logs/bot.log' + +# Formato de los mensajes de log +log_formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s') + +# Configurar RotatingFileHandler +# maxBytes: tamaño máximo del archivo de log en bytes (5MB en este caso) +# backupCount: número máximo de archivos de respaldo +file_handler = RotatingFileHandler(log_file, maxBytes=5*1024*1024, backupCount=5) +file_handler.setFormatter(log_formatter) +file_handler.setLevel(logging.INFO) + +# Configurar el logger +logger = logging.getLogger() +logger.setLevel(logging.INFO) +logger.addHandler(file_handler) diff --git a/catch-all/06_bot_telegram/02_pruebas_bot/utils.py b/catch-all/06_bot_telegram/02_pruebas_bot/utils.py new file mode 100644 index 0000000..4fd8542 --- /dev/null +++ b/catch-all/06_bot_telegram/02_pruebas_bot/utils.py @@ -0,0 +1,15 @@ +# utils.py +# Este módulo contiene funciones utilitarias. + +def is_api_group(chat_id, group_chat_id): + """ + Verifica si el chat_id proporcionado es el mismo que el ID del grupo API. + + Args: + chat_id (int): El ID del chat a verificar. + group_chat_id (int): El ID del grupo API. + + Returns: + bool: True si chat_id es igual a group_chat_id, de lo contrario False. + """ + return chat_id == group_chat_id diff --git a/catch-all/06_bot_telegram/README.md b/catch-all/06_bot_telegram/README.md new file mode 100644 index 0000000..313ddcd --- /dev/null +++ b/catch-all/06_bot_telegram/README.md @@ -0,0 +1,16 @@ +# Bots de Telegram + +| Nombre | Descripción | Nivel | +| ---------------------------------------------------- | ----------------------------------------- | ---------- | +| [Bot que devuelve id del bot](./01_id_bot/id_bot.py) | Bot que devuelve el id del bot | básico | +| [Bot pruebas](./02_pruebas_bot/bot.py) | Bot que devuelve mensajes básicos | básico | +| **Bot de traducción** (próximamente) | Bot que traduce mensajes a varios idiomas | intermedio | +| **Bot de clima** (próximamente) | Bot que devuelve el clima de una ciudad | intermedio | +| **Bot de noticias** (próximamente) | Bot que devuelve noticias de última hora | intermedio | +| **Bot de mareas** (próximamente) | Bot que devuelve información de mareas | avanzado | +| **Bot de juegos** (próximamente) | Bot con juegos de adivinanzas y preguntas | avanzado | +| **Bot de películas** (próximamente) | Bot que devuelve información de películas | avanzado | +| **Bot de series** (próximamente) | Bot que devuelve información de series | avanzado | +| **Bot de libros** (próximamente) | Bot que devuelve información de libros | avanzado | +| **Bot de recetas** (próximamente) | Bot que devuelve recetas de cocina | avanzado | +| **Bot de deportes** (próximamente) | Bot que devuelve información de deportes | avanzado | diff --git a/catch-all/README.md b/catch-all/README.md index b39cf44..cb31a7e 100644 --- a/catch-all/README.md +++ b/catch-all/README.md @@ -13,3 +13,4 @@ Aquí iré dejando scripts y ejercicios que se me ocurran, con lo que no hay un | [Clima España](./03_clima/) | Script conectado a API AEMET | intermedio | | [acortador de enlaces](./04_acortador_url/) | Script para acortar enlaces y redirigirlos con app Flask | intermedio | | [API Caching](./05_redis_flask_docker) | App Flask con caché en Redis y con una bbdd | intermedio | +| [bots Telegram](./06_bots_telegram/README.md) | Bots de Telegram con Python | avanzado |