Add Translator Bot for Telegram
This commit is contained in:
parent
5821636a01
commit
fbecbbf0a1
10
catch-all/06_bots_telegram/03_translator_bot/Dockerfile
Normal file
10
catch-all/06_bots_telegram/03_translator_bot/Dockerfile
Normal file
@ -0,0 +1,10 @@
|
||||
FROM python:3.10-alpine
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY . /app/
|
||||
|
||||
RUN pip install -r requirements.txt
|
||||
|
||||
CMD ["python", "translator.py"]
|
||||
|
19
catch-all/06_bots_telegram/03_translator_bot/config.py
Normal file
19
catch-all/06_bots_telegram/03_translator_bot/config.py
Normal file
@ -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)
|
63
catch-all/06_bots_telegram/03_translator_bot/logger.py
Normal file
63
catch-all/06_bots_telegram/03_translator_bot/logger.py
Normal file
@ -0,0 +1,63 @@
|
||||
"""
|
||||
# Ejemplo de uso del logger
|
||||
|
||||
if __name__ == "__main__":
|
||||
logger.info('Logger configurado correctamente.')
|
||||
logger.debug('Este es un mensaje de depuración.')
|
||||
logger.warning('Este es un mensaje de advertencia.')
|
||||
logger.error('Este es un mensaje de error.')
|
||||
logger.critical('Este es un mensaje crítico.')
|
||||
"""
|
||||
|
||||
# logger.py
|
||||
# Este módulo configura el logging con rotación de archivos.
|
||||
|
||||
|
||||
import logging
|
||||
import os
|
||||
from logging.handlers import RotatingFileHandler
|
||||
|
||||
|
||||
def setup_logger():
|
||||
# Crear el directorio de logs si no existe
|
||||
log_directory = 'logs'
|
||||
if not os.path.exists(log_directory):
|
||||
os.makedirs(log_directory)
|
||||
|
||||
# Ruta del archivo de log
|
||||
log_file = os.path.join(log_directory, 'bot.log')
|
||||
|
||||
# Formato de los mensajes de log
|
||||
log_formatter = logging.Formatter(
|
||||
'%(asctime)s - %(name)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 StreamHandler para la consola
|
||||
console_handler = logging.StreamHandler()
|
||||
console_handler.setFormatter(log_formatter)
|
||||
|
||||
# Puedes cambiar este nivel según tus necesidades
|
||||
console_handler.setLevel(logging.DEBUG)
|
||||
|
||||
# Configurar el logger
|
||||
logger = logging.getLogger('telegram_bot')
|
||||
# Configurar el nivel del logger a DEBUG para capturar todos los mensajes
|
||||
logger.setLevel(logging.DEBUG)
|
||||
logger.addHandler(file_handler)
|
||||
logger.addHandler(console_handler)
|
||||
|
||||
# Evitar que los mensajes se dupliquen en el log
|
||||
logger.propagate = False
|
||||
|
||||
return logger
|
||||
|
||||
|
||||
# Inicializar el logger
|
||||
logger = setup_logger()
|
@ -0,0 +1,3 @@
|
||||
python-telegram-bot==21.3
|
||||
translate==3.6.1
|
||||
python-dotenv==1.0.1
|
211
catch-all/06_bots_telegram/03_translator_bot/translator.py
Normal file
211
catch-all/06_bots_telegram/03_translator_bot/translator.py
Normal file
@ -0,0 +1,211 @@
|
||||
"""
|
||||
Este módulo contiene el código para un bot de Telegram que realiza tareas de traducción.
|
||||
|
||||
El bot utiliza la API de Telegram Bot para interactuar con los usuarios y la API de Google Translate para la traducción.
|
||||
|
||||
La función principal inicializa el bot y comienza a escuchar los mensajes entrantes.
|
||||
|
||||
Para ejecutar el bot, asegúrese de tener las credenciales y la configuración de la API necesarias configuradas en el módulo `config`.
|
||||
|
||||
Extraido del tutorial de youtube y luego actualizado: https://www.youtube.com/watch?v=8buZAq148gk&ab_channel=SBDeveloper
|
||||
|
||||
Autor: manuelver
|
||||
"""
|
||||
|
||||
import signal
|
||||
|
||||
from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup
|
||||
from telegram.ext import ApplicationBuilder, MessageHandler, CommandHandler, CallbackContext, filters, CallbackQueryHandler
|
||||
|
||||
from translate import Translator
|
||||
|
||||
import config
|
||||
from logger import logger
|
||||
|
||||
|
||||
def def_handler(sig, frame):
|
||||
"""
|
||||
Función manejadora de señales para salir del programa de manera elegante.
|
||||
"""
|
||||
logger.info("Saliendo del programa...")
|
||||
exit(1)
|
||||
|
||||
|
||||
# Configurar el manejador de señal para SIGINT (Ctrl+C)
|
||||
signal.signal(signal.SIGINT, def_handler)
|
||||
|
||||
|
||||
async def select_origin_lang(update: Update, context: CallbackContext) -> None:
|
||||
"""
|
||||
Función para seleccionar el idioma de origen para la traducción.
|
||||
"""
|
||||
keyboard = [
|
||||
[
|
||||
InlineKeyboardButton("Español", callback_data='es'),
|
||||
InlineKeyboardButton("Catalán", callback_data='ca'),
|
||||
InlineKeyboardButton("English", callback_data='en'),
|
||||
InlineKeyboardButton("Français", callback_data='fr')
|
||||
],
|
||||
[
|
||||
InlineKeyboardButton("Deutsch", callback_data='de'),
|
||||
InlineKeyboardButton("Italiano", callback_data='it'),
|
||||
InlineKeyboardButton("Português", callback_data='pt')
|
||||
],
|
||||
[
|
||||
InlineKeyboardButton("Русский (Ruso)", callback_data='ru'),
|
||||
InlineKeyboardButton("日本語 (Japonés)", callback_data='ja'),
|
||||
InlineKeyboardButton("中文 (Chino)", callback_data='zh')
|
||||
],
|
||||
[
|
||||
InlineKeyboardButton("(Árabe) العربية", callback_data='ar'),
|
||||
InlineKeyboardButton("हिन्दी (Hindi)", callback_data='hi'),
|
||||
InlineKeyboardButton("עברית (Hebreo)", callback_data='he')
|
||||
]
|
||||
]
|
||||
|
||||
reply_markup = InlineKeyboardMarkup(keyboard)
|
||||
|
||||
await update.message.reply_text(
|
||||
'Por favor, selecciona el idioma de origen:', reply_markup=reply_markup)
|
||||
|
||||
|
||||
async def select_dest_lang(update: Update, context: CallbackContext) -> None:
|
||||
"""
|
||||
Función para seleccionar el idioma de destino para la traducción.
|
||||
"""
|
||||
keyboard = [
|
||||
[
|
||||
InlineKeyboardButton("Español", callback_data='es'),
|
||||
InlineKeyboardButton("Catalán", callback_data='ca'),
|
||||
InlineKeyboardButton("English", callback_data='en'),
|
||||
InlineKeyboardButton("Français", callback_data='fr')
|
||||
],
|
||||
[
|
||||
InlineKeyboardButton("Deutsch", callback_data='de'),
|
||||
InlineKeyboardButton("Italiano", callback_data='it'),
|
||||
InlineKeyboardButton("Português", callback_data='pt')
|
||||
],
|
||||
[
|
||||
InlineKeyboardButton("Русский (Ruso)", callback_data='ru'),
|
||||
InlineKeyboardButton("日本語 (Japonés)", callback_data='ja'),
|
||||
InlineKeyboardButton("中文 (Chino)", callback_data='zh')
|
||||
],
|
||||
[
|
||||
InlineKeyboardButton("(Árabe) العربية", callback_data='ar'),
|
||||
InlineKeyboardButton("हिन्दी (Hindi)", callback_data='hi'),
|
||||
InlineKeyboardButton("עברית (Hebreo)", callback_data='he')
|
||||
]
|
||||
]
|
||||
|
||||
reply_markup = InlineKeyboardMarkup(keyboard)
|
||||
|
||||
await update.message.reply_text(
|
||||
f'Por favor, selecciona el idioma de destino:', reply_markup=reply_markup)
|
||||
|
||||
|
||||
|
||||
async def button(update: Update, context: CallbackContext) -> None:
|
||||
"""
|
||||
Función para manejar los botones de idioma seleccionados.
|
||||
"""
|
||||
query = update.callback_query
|
||||
await query.answer()
|
||||
|
||||
if 'origin_lang' not in context.user_data:
|
||||
context.user_data['origin_lang'] = query.data
|
||||
await query.edit_message_text(text=f"Idioma de origen seleccionado.\n\nAhora selecciona el idioma de destino con el comando /langTo")
|
||||
await select_dest_lang(update, context)
|
||||
else:
|
||||
context.user_data['dest_lang'] = query.data
|
||||
await query.edit_message_text(text=f"Idioma de destino seleccionado.\n\nEnvía tu texto para traducir.")
|
||||
|
||||
logger.info(f"Idioma seleccionado: {query.data}")
|
||||
|
||||
|
||||
async def lang_translator(user_input, from_lang, to_lang):
|
||||
|
||||
try:
|
||||
translator = Translator(from_lang=from_lang, to_lang=to_lang)
|
||||
translation = translator.translate(user_input)
|
||||
|
||||
return translation
|
||||
|
||||
except TranslationError as e:
|
||||
logger.error(f"Error en la traducción: {str(e)}")
|
||||
return "Error en la traducción. Por favor, intenta de nuevo más tarde."
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error inesperado al traducir el texto: {str(e)}")
|
||||
return "Error inesperado al traducir el texto."
|
||||
|
||||
|
||||
async def reply(update: Update, context: CallbackContext):
|
||||
|
||||
user_input = update.message.text
|
||||
from_lang = context.user_data.get(
|
||||
'origin_lang', 'es') # Español por defecto
|
||||
to_lang = context.user_data.get('dest_lang', 'en') # Inglés por defecto
|
||||
|
||||
translation = await lang_translator(user_input, from_lang, to_lang)
|
||||
await update.message.reply_text(translation)
|
||||
|
||||
logger.info(f"Mensaje recibido: {user_input}")
|
||||
logger.info(f"Texto traducido: {translation}")
|
||||
|
||||
|
||||
async def start(update: Update, context: CallbackContext):
|
||||
|
||||
await update.message.reply_text("¡Hola! Soy un bot de traducción.\n\nSi necesitas ayuda: /help.")
|
||||
|
||||
logger.info("Comando /start recibido.")
|
||||
|
||||
|
||||
async def help_command(update: Update, context: CallbackContext):
|
||||
"""
|
||||
Función para mostrar los comandos disponibles.
|
||||
"""
|
||||
commands = [
|
||||
"/start - Iniciar el bot",
|
||||
"/langFrom - Seleccionar idioma de origen",
|
||||
"/langTo - Seleccionar idioma de destino",
|
||||
"/help - Mostrar este mensaje de ayuda"
|
||||
]
|
||||
help_text = "\n".join(commands)
|
||||
|
||||
await update.message.reply_text(f"El idioma por defecto origen es español y el de destino el Inglés.\nPuedes configurar otras opciones.\nUna vez lo tengas listo tan solo tienes que enviar el texto con el idioma origen.\n\nOpciones:\n{help_text}")
|
||||
|
||||
logger.info("Comando /help recibido.")
|
||||
|
||||
|
||||
def main():
|
||||
"""
|
||||
Función principal para inicializar el bot y comenzar a escuchar los mensajes.
|
||||
"""
|
||||
api = config.BOT_TOKEN
|
||||
|
||||
application = ApplicationBuilder().token(api).build()
|
||||
|
||||
# Manejadores de comandos y mensajes
|
||||
application.add_handler(CommandHandler('start', start))
|
||||
application.add_handler(CommandHandler('langFrom', select_origin_lang))
|
||||
application.add_handler(CommandHandler('langTo', select_dest_lang))
|
||||
application.add_handler(CommandHandler('help', help_command))
|
||||
application.add_handler(CommandHandler('command', help_command))
|
||||
application.add_handler(MessageHandler(
|
||||
filters.TEXT & ~filters.COMMAND, reply))
|
||||
application.add_handler(CallbackQueryHandler(button))
|
||||
|
||||
# Iniciar el bot
|
||||
logger.info("Bot iniciado.")
|
||||
|
||||
# Iniciar el bucle de eventos
|
||||
application.run_polling()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
main()
|
||||
except Exception as e:
|
||||
logger.error(f'Error en la ejecución del bot: {str(e)}')
|
||||
except KeyboardInterrupt:
|
||||
def_handler(None, None)
|
@ -1,16 +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 |
|
||||
| Nombre | Descripción | Nivel |
|
||||
| ----------------------------------------- | ----------------------------------------- | ---------- |
|
||||
| [Bot id del chat](./01_id_bot/) | Bot que devuelve el id del bot | básico |
|
||||
| [Bot mensajes](./02_pruebas_bot/) | Bot que devuelve mensajes básicos. Loggin | intermedio |
|
||||
| [Bot de traducción](./03_translator_bot/) | Bot que traduce mensajes a varios idiomas | avanzado |
|
||||
| **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 |
|
||||
|
Loading…
Reference in New Issue
Block a user