ferdj40

Repost bot advanced

Jul 22nd, 2026
14,847
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.19 KB | None | 0 0
  1. from telethon import TelegramClient, events
  2. import asyncio
  3. import logging
  4. import os
  5. from pathlib import Path
  6.  
  7. # Intentar cargar variables de entorno desde .env
  8. try:
  9. from dotenv import load_dotenv
  10. load_dotenv()
  11. logger_init = logging.getLogger(__name__)
  12. logger_init.info("✅ Variables de entorno cargadas desde .env")
  13. except ImportError:
  14. pass # python-dotenv no está instalado, usar valores directos
  15.  
  16. # Configuración de logging
  17. logging.basicConfig(
  18. format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
  19. level=logging.INFO
  20. )
  21. logger = logging.getLogger(__name__)
  22.  
  23. # ===================== CONFIGURACIÓN =====================
  24. # Opción 1: Usar variables de entorno (recomendado para seguridad)
  25. API_ID = os.getenv('API_ID') or 'TU_API_ID'
  26. API_HASH = os.getenv('API_HASH') or 'TU_API_HASH'
  27. BOT_TOKEN = os.getenv('BOT_TOKEN') or 'TU_BOT_TOKEN'
  28.  
  29. SOURCE_CHANNEL = os.getenv('SOURCE_CHANNEL') or '@canal_origen'
  30. TARGET_CHANNEL = os.getenv('TARGET_CHANNEL') or '@canal_destino'
  31.  
  32. # Extensiones de archivo a repostear (puedes agregar más)
  33. ALLOWED_EXTENSIONS = ('.zip', '.rar', '.7z', '.tar', '.gz', '.3mf', '.stl', '.gcode')
  34.  
  35. # Opciones adicionales
  36. FORWARD_AS_COPY = False # Si True, copia el mensaje sin mostrar "Forwarded from"
  37. ADD_WATERMARK = False # Si True, agrega un texto al repostear
  38. WATERMARK_TEXT = "\n\n📦 Reposteado automáticamente"
  39. # =========================================================
  40.  
  41.  
  42. # Crear el cliente del bot
  43. bot = TelegramClient('bot_session', API_ID, API_HASH)
  44.  
  45.  
  46. def is_allowed_file(file_name):
  47. """
  48. Verifica si el archivo tiene una extensión permitida
  49. """
  50. if not file_name:
  51. return False
  52. return any(file_name.lower().endswith(ext) for ext in ALLOWED_EXTENSIONS)
  53.  
  54.  
  55. async def get_file_info(message):
  56. """
  57. Extrae información del archivo del mensaje
  58. """
  59. if not message.document:
  60. return None
  61.  
  62. file_name = None
  63. file_size = message.document.size
  64. mime_type = message.document.mime_type
  65.  
  66. for attribute in message.document.attributes:
  67. if hasattr(attribute, 'file_name'):
  68. file_name = attribute.file_name
  69. break
  70.  
  71. return {
  72. 'name': file_name,
  73. 'size': file_size,
  74. 'mime_type': mime_type
  75. }
  76.  
  77.  
  78. def format_file_size(size_bytes):
  79. """
  80. Convierte bytes a formato legible (KB, MB, GB)
  81. """
  82. for unit in ['B', 'KB', 'MB', 'GB']:
  83. if size_bytes < 1024.0:
  84. return f"{size_bytes:.2f} {unit}"
  85. size_bytes /= 1024.0
  86. return f"{size_bytes:.2f} TB"
  87.  
  88.  
  89. @bot.on(events.NewMessage(chats=SOURCE_CHANNEL))
  90. async def repost_handler(event):
  91. """
  92. Maneja los nuevos mensajes del canal origen y los repostea al destino
  93. """
  94. try:
  95. message = event.message
  96.  
  97. # Verificar si el mensaje tiene un archivo
  98. if message.media and message.document:
  99. file_info = await get_file_info(message)
  100.  
  101. if not file_info or not file_info['name']:
  102. logger.debug("⏭️ Mensaje sin nombre de archivo, ignorado")
  103. return
  104.  
  105. file_name = file_info['name']
  106.  
  107. # Verificar si es una extensión permitida
  108. if is_allowed_file(file_name):
  109. file_size = format_file_size(file_info['size'])
  110. logger.info(f"📥 Reposteando archivo: {file_name} ({file_size})")
  111.  
  112. if FORWARD_AS_COPY:
  113. # Opción: Enviar como copia (sin "Forwarded from")
  114. caption = message.message or ""
  115. if ADD_WATERMARK:
  116. caption += WATERMARK_TEXT
  117.  
  118. await bot.send_file(
  119. TARGET_CHANNEL,
  120. file=message.media,
  121. caption=caption
  122. )
  123. else:
  124. # Opción: Forward directo (muestra "Forwarded from")
  125. await bot.forward_messages(
  126. entity=TARGET_CHANNEL,
  127. messages=message.id,
  128. from_peer=SOURCE_CHANNEL
  129. )
  130.  
  131. logger.info(f"✅ Archivo reposteado exitosamente: {file_name}")
  132. else:
  133. logger.debug(f"⏭️ Archivo ignorado (extensión no permitida): {file_name}")
  134. else:
  135. logger.debug("⏭️ Mensaje sin archivo, ignorado")
  136.  
  137. except Exception as e:
  138. logger.error(f"❌ Error al repostear mensaje: {e}", exc_info=True)
  139.  
  140.  
  141. @bot.on(events.NewMessage(pattern='/start'))
  142. async def start_handler(event):
  143. """
  144. Comando /start para verificar que el bot funciona
  145. """
  146. await event.respond(
  147. "🤖 **Bot de Reposteo Activo**\n\n"
  148. f"📡 Canal origen: `{SOURCE_CHANNEL}`\n"
  149. f"📤 Canal destino: `{TARGET_CHANNEL}`\n"
  150. f"📁 Extensiones: {', '.join(ALLOWED_EXTENSIONS)}\n\n"
  151. "✅ El bot está funcionando correctamente."
  152. )
  153.  
  154.  
  155. @bot.on(events.NewMessage(pattern='/status'))
  156. async def status_handler(event):
  157. """
  158. Comando /status para verificar el estado del bot
  159. """
  160. try:
  161. # Verificar acceso a los canales
  162. source_entity = await bot.get_entity(SOURCE_CHANNEL)
  163. target_entity = await bot.get_entity(TARGET_CHANNEL)
  164.  
  165. await event.respond(
  166. "📊 **Estado del Bot**\n\n"
  167. f"✅ Canal origen: {source_entity.title}\n"
  168. f"✅ Canal destino: {target_entity.title}\n"
  169. f"✅ Extensiones activas: {len(ALLOWED_EXTENSIONS)}\n"
  170. f"✅ Bot funcionando correctamente"
  171. )
  172. except Exception as e:
  173. await event.respond(f"❌ Error: {e}")
  174.  
  175.  
  176. async def main():
  177. """
  178. Función principal para iniciar el bot
  179. """
  180. logger.info("🤖 Iniciando bot...")
  181.  
  182. # Validar configuración
  183. if API_ID == 'TU_API_ID' or API_HASH == 'TU_API_HASH':
  184. logger.error("❌ ERROR: Debes configurar API_ID y API_HASH")
  185. return
  186.  
  187. if BOT_TOKEN == 'TU_BOT_TOKEN':
  188. logger.error("❌ ERROR: Debes configurar BOT_TOKEN")
  189. return
  190.  
  191. # Conectar con el token del bot
  192. await bot.start(bot_token=BOT_TOKEN)
  193.  
  194. # Obtener información del bot
  195. me = await bot.get_me()
  196. logger.info(f"✅ Bot conectado: @{me.username}")
  197. logger.info(f"📡 Escuchando mensajes en: {SOURCE_CHANNEL}")
  198. logger.info(f"📤 Reposteando a: {TARGET_CHANNEL}")
  199. logger.info(f"📁 Extensiones permitidas: {', '.join(ALLOWED_EXTENSIONS)}")
  200. logger.info(f"🔄 Modo: {'Copia' if FORWARD_AS_COPY else 'Forward'}")
  201. logger.info("🟢 Bot funcionando. Presiona Ctrl+C para detener.")
  202. logger.info("💡 Tip: Envía /start o /status al bot para verificar su estado")
  203.  
  204. # Mantener el bot corriendo
  205. await bot.run_until_disconnected()
  206.  
  207.  
  208. if __name__ == '__main__':
  209. try:
  210. asyncio.run(main())
  211. except KeyboardInterrupt:
  212. logger.info("\n🛑 Bot detenido por el usuario")
  213. except Exception as e:
  214. logger.error(f"❌ Error fatal: {e}", exc_info=True)
Tags: bot
Advertisement