import asyncio from datetime import datetime, timedelta from telethon import TelegramClient from telethon.errors import FloodWaitError import os import configparser class TelegramMessageExporter: def __init__(self, session_name='session_name'): """Initialize with proper credential handling""" self.api_id, self.api_hash, self.phone = self.read_credentials() if not all([self.api_id, self.api_hash, self.phone]): raise ValueError("Missing API credentials") self.client = TelegramClient(session_name, self.api_id, self.api_hash) def read_credentials(self): """Read credentials from config.ini or credentials.txt""" # Try config.ini first (Telethon standard) config = configparser.ConfigParser() if os.path.exists('config.ini'): config.read('config.ini') try: return ( config.getint('telegram', 'api_id'), config.get('telegram', 'api_hash'), config.get('telegram', 'phone') ) except (configparser.NoSectionError, configparser.NoOptionError): pass # Fall back to credentials.txt (your format) try: with open("credentials.txt", "r") as f: lines = [line.strip() for line in f.readlines() if line.strip()] if len(lines) >= 3: return int(lines[0]), lines[1], lines[2] except (FileNotFoundError, ValueError): pass return None, None, None async def authenticate(self): """Handle authentication with proper error checking""" if not await self.client.is_user_authorized(): print("Authentication required...") try: await self.client.send_code_request(self.phone) code = input("Enter the code you received: ") await self.client.sign_in(self.phone, code) print("Successfully authenticated!") except Exception as e: print(f"Authentication failed: {e}") return False return True async def export_messages(self, channel_id, start_date, end_date, output_file): """Export messages with comprehensive error handling""" try: await self.client.connect() if not await self.authenticate(): return False # Convert and validate dates try: start_dt = datetime.strptime(start_date, '%Y-%m-%d') end_dt = datetime.strptime(end_date, '%Y-%m-%d') + timedelta(days=1) except ValueError as e: print(f"Invalid date format: {e}") return False # Get channel entity with error handling try: channel = await self.client.get_entity(channel_id) print(f"\nExporting from: {getattr(channel, 'title', str(channel_id))}") except Exception as e: print(f"Failed to access channel: {e}") print("Please verify:") print("1. You have joined the channel") print("2. The channel ID is correct") print("3. You have proper access rights") return False # Export messages with open(output_file, 'w', encoding='utf-8') as f: f.write(f"Messages from: {getattr(channel, 'title', str(channel_id))}\n") f.write(f"Period: {start_date} to {end_date}\n\n") f.write("="*60 + "\n\n") total = 0 async for message in self.client.iter_messages(channel, offset_date=end_dt): if message.date.replace(tzinfo=None) < start_dt: break # Write message metadata f.write(f"ID: {message.id}\n") f.write(f"Date: {message.date}\n") if hasattr(message, 'sender_id') and message.sender_id: f.write(f"Sender: {message.sender_id}\n") # Write message content content = message.text or "[media message]" f.write(f"Content:\n{content}\n") # Additional info if message.reply_to_msg_id: f.write(f"Reply to: {message.reply_to_msg_id}\n") if message.edit_date: f.write(f"Edited at: {message.edit_date}\n") f.write("\n" + "="*60 + "\n\n") total += 1 if total % 50 == 0: print(f"Exported {total} messages...") print(f"\nSuccess! Saved {total} messages to {output_file}") return True except FloodWaitError as e: print(f"Flood wait: Please wait {e.seconds} seconds before trying again") return False except Exception as e: print(f"Export failed: {e}") return False finally: await self.client.disconnect() async def main(): # ===== CONFIGURATION ===== CHANNEL_ID = -1002354693226 # Replace with your channel ID or @username START_DATE = '2024-07-01' # Format: YYYY-MM-DD END_DATE = '2025-04-30' # Format: YYYY-MM-DD OUTPUT_FILE = 'channel_messages.txt' SESSION_NAME = 'session_name' # Must match your forwarder's session name # ===== END CONFIGURATION ===== print("\nTelegram Message Exporter") print("=" * 40) try: exporter = TelegramMessageExporter(SESSION_NAME) if os.path.exists(OUTPUT_FILE): print(f"Warning: {OUTPUT_FILE} already exists!") if input("Overwrite? (y/n): ").lower() != 'y': return if await exporter.export_messages(CHANNEL_ID, START_DATE, END_DATE, OUTPUT_FILE): print("\nExport completed successfully!") else: print("\nExport failed - see error messages above") except ValueError as e: print(f"\nConfiguration error: {e}") print("Please ensure you have:") print("1. A valid config.ini or credentials.txt file") print("2. Proper API credentials from my.telegram.org") print("3. The correct session name from your forwarder") except Exception as e: print(f"\nFatal error: {e}") if __name__ == "__main__": try: asyncio.run(main()) except KeyboardInterrupt: print("\nOperation cancelled by user")