import os import shutil import logging from telegram import Update, ReplyKeyboardMarkup, KeyboardButton from telegram.ext import ( Application, CommandHandler, MessageHandler, filters, ContextTypes, ConversationHandler, ) from telethon.sessions import StringSession from telethon.sync import TelegramClient # Настройка логирования logging.basicConfig( format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO ) logger = logging.getLogger(__name__) # Конфигурация бота BOT_TOKEN = "YOUR_BOT_TOKEN" API_ID = 12345 API_HASH = "your_api_hash_here" # Состояния CHOOSING, INPUT_SESSION, INPUT_TDATA = range(3) # Кнопки BUTTONS = [ [KeyboardButton("Session → TData")], [KeyboardButton("TData → Session")], [KeyboardButton("Инструкция")] ] async def start(update: Update, context: ContextTypes.DEFAULT_TYPE): """Обработка команды /start""" reply_markup = ReplyKeyboardMarkup(BUTTONS, resize_keyboard=True) await update.message.reply_text( "Выберите действие:", reply_markup=reply_markup ) return CHOOSING async def show_instruction(update: Update, context: ContextTypes.DEFAULT_TYPE): """Показ инструкции""" instruction = ( "Инструкция по использованию:\n\n" "1. Session → TData:\n" "- Отправьте строку сессии\n" "- Получите архив TData\n\n" "2. TData → Session:\n" "- Отправьте ZIP архив с TData\n" "- Получите строку сессии\n\n" "Данные автоматически удаляются после обработки" ) await update.message.reply_text(instruction) return CHOOSING async def handle_choice(update: Update, context: ContextTypes.DEFAULT_TYPE): """Обработка выбора действия""" text = update.message.text if text == "Session → TData": await update.message.reply_text("Отправьте строку Session") return INPUT_SESSION elif text == "TData → Session": await update.message.reply_text("Отправьте архив TData (ZIP)") return INPUT_TDATA elif text == "Инструкция": await show_instruction(update, context) return CHOOSING await update.message.reply_text("Используйте кнопки") return CHOOSING async def convert_session_to_tdata(update: Update, context: ContextTypes.DEFAULT_TYPE): """Конвертация Session → TData""" session_str = update.message.text.strip() try: with TelegramClient(StringSession(session_str), API_ID, API_HASH) as client: me = await client.get_me() tdata_path = f"tdata_{me.id}" os.makedirs(tdata_path, exist_ok=True) await client.session.save_to_dir(tdata_path) shutil.make_archive(tdata_path, 'zip', tdata_path) with open(f"{tdata_path}.zip", 'rb') as f: await update.message.reply_document(document=f) shutil.rmtree(tdata_path) os.remove(f"{tdata_path}.zip") except Exception as e: await update.message.reply_text(f"Ошибка: {str(e)}") logger.error(f"Error: {str(e)}") return await start(update, context) async def convert_tdata_to_session(update: Update, context: ContextTypes.DEFAULT_TYPE): """Конвертация TData → Session""" try: file = await update.message.document.get_file() tdata_zip = f"tdata_{update.message.from_user.id}.zip" await file.download_to_drive(tdata_zip) tdata_dir = f"tdata_{update.message.from_user.id}" shutil.unpack_archive(tdata_zip, tdata_dir) with TelegramClient(None, API_ID, API_HASH) as client: await client.session.load_from_dir(tdata_dir) session_str = client.session.save() await update.message.reply_text(session_str) shutil.rmtree(tdata_dir) os.remove(tdata_zip) except Exception as e: await update.message.reply_text(f"Ошибка: {str(e)}") logger.error(f"Error: {str(e)}") return await start(update, context) async def cancel(update: Update, context: ContextTypes.DEFAULT_TYPE): """Отмена операции""" await update.message.reply_text("Отменено") return await start(update, context) def main(): """Запуск бота""" application = Application.builder().token(BOT_TOKEN).build() conv_handler = ConversationHandler( entry_points=[CommandHandler('start', start)], states={ CHOOSING: [MessageHandler(filters.TEXT & ~filters.COMMAND, handle_choice)], INPUT_SESSION: [MessageHandler(filters.TEXT & ~filters.COMMAND, convert_session_to_tdata)], INPUT_TDATA: [MessageHandler(filters.Document.FileExtension("zip"), convert_tdata_to_session)], }, fallbacks=[CommandHandler('cancel', cancel)], ) application.add_handler(conv_handler) application.run_polling() if __name__ == "__main__": main() Python import os import shutil import logging from telegram import Update, ReplyKeyboardMarkup, KeyboardButton from telegram.ext import ( Application, CommandHandler, MessageHandler, filters, ContextTypes, ConversationHandler, ) from telethon.sessions import StringSession from telethon.sync import TelegramClient # Настройка логирования logging.basicConfig( format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO ) logger = logging.getLogger(__name__) # Конфигурация бота BOT_TOKEN = "YOUR_BOT_TOKEN" API_ID = 12345 API_HASH = "your_api_hash_here" # Состояния CHOOSING, INPUT_SESSION, INPUT_TDATA = range(3) # Кнопки BUTTONS = [ [KeyboardButton("Session → TData")], [KeyboardButton("TData → Session")], [KeyboardButton("Инструкция")] ] async def start(update: Update, context: ContextTypes.DEFAULT_TYPE): """Обработка команды /start""" reply_markup = ReplyKeyboardMarkup(BUTTONS, resize_keyboard=True) await update.message.reply_text( "Выберите действие:", reply_markup=reply_markup ) return CHOOSING async def show_instruction(update: Update, context: ContextTypes.DEFAULT_TYPE): """Показ инструкции""" instruction = ( "Инструкция по использованию:\n\n" "1. Session → TData:\n" "- Отправьте строку сессии\n" "- Получите архив TData\n\n" "2. TData → Session:\n" "- Отправьте ZIP архив с TData\n" "- Получите строку сессии\n\n" "Данные автоматически удаляются после обработки" ) await update.message.reply_text(instruction) return CHOOSING async def handle_choice(update: Update, context: ContextTypes.DEFAULT_TYPE): """Обработка выбора действия""" text = update.message.text if text == "Session → TData": await update.message.reply_text("Отправьте строку Session") return INPUT_SESSION elif text == "TData → Session": await update.message.reply_text("Отправьте архив TData (ZIP)") return INPUT_TDATA elif text == "Инструкция": await show_instruction(update, context) return CHOOSING await update.message.reply_text("Используйте кнопки") return CHOOSING async def convert_session_to_tdata(update: Update, context: ContextTypes.DEFAULT_TYPE): """Конвертация Session → TData""" session_str = update.message.text.strip() try: with TelegramClient(StringSession(session_str), API_ID, API_HASH) as client: me = await client.get_me() tdata_path = f"tdata_{me.id}" os.makedirs(tdata_path, exist_ok=True) await client.session.save_to_dir(tdata_path) shutil.make_archive(tdata_path, 'zip', tdata_path) with open(f"{tdata_path}.zip", 'rb') as f: await update.message.reply_document(document=f) shutil.rmtree(tdata_path) os.remove(f"{tdata_path}.zip") except Exception as e: await update.message.reply_text(f"Ошибка: {str(e)}") logger.error(f"Error: {str(e)}") return await start(update, context) async def convert_tdata_to_session(update: Update, context: ContextTypes.DEFAULT_TYPE): """Конвертация TData → Session""" try: file = await update.message.document.get_file() tdata_zip = f"tdata_{update.message.from_user.id}.zip" await file.download_to_drive(tdata_zip) tdata_dir = f"tdata_{update.message.from_user.id}" shutil.unpack_archive(tdata_zip, tdata_dir) with TelegramClient(None, API_ID, API_HASH) as client: await client.session.load_from_dir(tdata_dir) session_str = client.session.save() await update.message.reply_text(session_str) shutil.rmtree(tdata_dir) os.remove(tdata_zip) except Exception as e: await update.message.reply_text(f"Ошибка: {str(e)}") logger.error(f"Error: {str(e)}") return await start(update, context) async def cancel(update: Update, context: ContextTypes.DEFAULT_TYPE): """Отмена операции""" await update.message.reply_text("Отменено") return await start(update, context) def main(): """Запуск бота""" application = Application.builder().token(BOT_TOKEN).build() conv_handler = ConversationHandler( entry_points=[CommandHandler('start', start)], states={ CHOOSING: [MessageHandler(filters.TEXT & ~filters.COMMAND, handle_choice)], INPUT_SESSION: [MessageHandler(filters.TEXT & ~filters.COMMAND, convert_session_to_tdata)], INPUT_TDATA: [MessageHandler(filters.Document.FileExtension("zip"), convert_tdata_to_session)], }, fallbacks=[CommandHandler('cancel', cancel)], ) application.add_handler(conv_handler) application.run_polling() if __name__ == "__main__": main() 1. Конвертация Session String → TData** - Принимает строку сессии (например, из Telethon, Pyrogram) - Генерирует **TData-архив** (ZIP), совместимый с официальными клиентами Telegram - Автоматически определяет **аккаунт** (номер, ID, username) #### **2. Конвертация TData → Session String** - Принимает **ZIP-архив** с папкой TData - Извлекает данные сессии - Возвращает **Session String** для библиотек (Telethon, Pyrogram и др.) #### **3. Проверка валидности сессии** - Определяет, активна ли сессия - Показывает **информацию о привязанном аккаунте**: - Номер телефона - Username - ID - Дата создания #### **4. Автоматическая очистка данных** - **Не хранит** сессии пользователей - Удаляет временные файлы (**TData, ZIP**) сразу после обработки --- ### ** Безопасность** - Работает **локально** (если запущен у пользователя) - **Не требует** доступа к аккаунту (только преобразование данных) - **Рекомендуется** использовать с временными/тестовыми аккаунтами