import os import logging from aiogram import Bot, Dispatcher, types, F from aiogram.filters import Command from aiogram.utils.keyboard import InlineKeyboardBuilder from deep_translator import GoogleTranslator import sqlite3 from datetime import datetime from dotenv import load_dotenv # Загрузка переменных окружения load_dotenv() API_TOKEN = os.getenv('TELEGRAM_BOT_TOKEN') # Инициализация бота bot = Bot(API_TOKEN) dp = Dispatcher() logging.basicConfig(level=logging.INFO) # Инициализация БД DB_NAME = 'translator_bot.db' def init_db(): conn = sqlite3.connect(DB_NAME) c = conn.cursor() c.execute('''CREATE TABLE IF NOT EXISTS users (user_id INT PRIMARY KEY, target_lang TEXT DEFAULT 'en', active INT DEFAULT 1)''') c.execute('''CREATE TABLE IF NOT EXISTS history (id INTEGER PRIMARY KEY AUTOINCREMENT, user_id INT, original TEXT, translated TEXT, direction TEXT, timestamp DATETIME)''') conn.commit() conn.close() init_db() # Языки с эмодзи LANGUAGES = { 'en': '🇬🇧 Английский', 'es': '🇪🇸 Испанский', 'fr': '🇫🇷 Французский', 'de': '🇩🇪 Немецкий', 'zh-CN': '🇨🇳 Китайский', 'ja': '🇯🇵 Японский', 'ru': '🇷🇺 Русский', 'ar': '🇦🇪 Арабский', 'hi': '🇮🇳 Хинди', 'ko': '🇰🇷 Корейский', 'it': '🇮🇹 Итальянский', 'pt': '🇵🇹 Португальский', 'tr': '🇹🇷 Турецкий' } # Клавиатуры def main_keyboard(): builder = InlineKeyboardBuilder() builder.button(text="⚙️ Настройки", callback_data="settings") builder.button(text="📜 История", callback_data="history") builder.button(text="❌ Выключить", callback_data="toggle_off") builder.button(text="✅ Включить", callback_data="toggle_on") builder.adjust(2) return builder.as_markup() def settings_keyboard(): builder = InlineKeyboardBuilder() for code, name in LANGUAGES.items(): builder.button(text=name, callback_data=f"set_{code}") builder.button(text="🔙 Назад", callback_data="main_menu") builder.adjust(3) return builder.as_markup() # Управление пользователями def get_user_settings(user_id): conn = sqlite3.connect(DB_NAME) c = conn.cursor() c.execute("SELECT target_lang, active FROM users WHERE user_id=?", (user_id,)) user = c.fetchone() conn.close() if user: return {'target_lang': user[0], 'active': bool(user[1])} else: # Создаем нового пользователя set_user_settings(user_id, 'en', 1) return {'target_lang': 'en', 'active': True} def set_user_settings(user_id, target_lang=None, active=None): conn = sqlite3.connect(DB_NAME) c = conn.cursor() c.execute("SELECT * FROM users WHERE user_id=?", (user_id,)) user = c.fetchone() if user: if target_lang: c.execute("UPDATE users SET target_lang=? WHERE user_id=?", (target_lang, user_id)) if active is not None: c.execute("UPDATE users SET active=? WHERE user_id=?", (int(active), user_id)) else: c.execute("INSERT INTO users (user_id, target_lang, active) VALUES (?, ?, ?)", (user_id, target_lang or 'en', int(active) if active is not None else 1)) conn.commit() conn.close() def save_history(user_id, original, translated, direction): conn = sqlite3.connect(DB_NAME) c = conn.cursor() c.execute("INSERT INTO history (user_id, original, translated, direction, timestamp) VALUES (?, ?, ?, ?, ?)", (user_id, original, translated, direction, datetime.now())) conn.commit() conn.close() def get_history(user_id, limit=10): conn = sqlite3.connect(DB_NAME) c = conn.cursor() c.execute("SELECT original, translated, direction, timestamp FROM history WHERE user_id=? ORDER BY timestamp DESC LIMIT ?", (user_id, limit)) history = c.fetchall() conn.close() return history # Обработчики команд @dp.message(Command('start')) async def start_cmd(message: types.Message): user_id = message.from_user.id set_user_settings(user_id, active=1) welcome_text = ( "🚀 Ultra Translator - мгновенный переводчик\n\n" "Просто отправьте текст и получите перевод!\n\n" "• Автоопределение языка\n" "• Поддержка 15+ языков\n" "• История переводов\n\n" "⚙️ Настройте язык перевода через меню" ) await message.answer(welcome_text, reply_markup=main_keyboard(), parse_mode='HTML') @dp.message(Command('toggle')) async def toggle_cmd(message: types.Message): user_id = message.from_user.id settings = get_user_settings(user_id) new_status = not settings['active'] set_user_settings(user_id, active=new_status) if new_status: await message.answer("✅ Переводчик включен. Отправьте текст для перевода!") else: await message.answer("❌ Переводчик выключен. Используйте /toggle для включения.") # Основной обработчик текста @dp.message(F.text) async def handle_text(message: types.Message): user_id = message.from_user.id settings = get_user_settings(user_id) # Проверка активности if not settings['active']: return text = message.text target_lang = settings['target_lang'] # Перевод try: # Автоопределение языка и перевод translated = GoogleTranslator(source='auto', target=target_lang).translate(text) # Определение языка источника detected_lang = GoogleTranslator(source='auto').detect(text) lang_name = LANGUAGES.get(detected_lang, detected_lang) # Сохранение в историю direction = f"{detected_lang}→{target_lang}" save_history(user_id, text, translated, direction) # Форматирование ответа response = ( f"🌐 Перевод ({lang_name} → {LANGUAGES[target_lang]}):\n" f"{translated}" ) await message.reply(response, parse_mode='HTML') except Exception as e: logging.error(f"Translation error: {e}") await message.reply("⚠️ Ошибка перевода. Попробуйте другой текст.") # Обработчики инлайн-кнопок @dp.callback_query(F.data == "settings") async def settings_menu(callback: types.CallbackQuery): user_id = callback.from_user.id settings = get_user_settings(user_id) current_lang = LANGUAGES.get(settings['target_lang'], settings['target_lang']) await callback.message.edit_text( f"⚙️ Настройки\nТекущий язык: {current_lang}\nВыберите новый язык:", reply_markup=settings_keyboard(), parse_mode='HTML' ) await callback.answer() @dp.callback_query(F.data == "history") async def show_history(callback: types.CallbackQuery): user_id = callback.from_user.id history = get_history(user_id) if not history: await callback.message.answer("📭 История переводов пуста") await callback.answer() return response = "🕒 Последние переводы:\n\n" for i, (original, translated, direction, timestamp) in enumerate(history): response += f"▫️ {original[:50]}{'...' if len(original) > 50 else ''}\n" response += f" → {translated[:50]}{'...' if len(translated) > 50 else ''}\n\n" await callback.message.answer(response, parse_mode='HTML') await callback.answer() @dp.callback_query(F.data.startswith("set_")) async def set_language(callback: types.CallbackQuery): lang_code = callback.data.split('_')[1] user_id = callback.from_user.id if lang_code in LANGUAGES: set_user_settings(user_id, target_lang=lang_code) lang_name = LANGUAGES[lang_code] await callback.answer(f"✅ Язык перевода: {lang_name}") else: await callback.answer("⚠️ Неподдерживаемый язык") # Возвращаемся в главное меню await callback.message.edit_text( "Настройки сохранены!", reply_markup=main_keyboard() ) @dp.callback_query(F.data == "main_menu") async def main_menu(callback: types.CallbackQuery): await callback.message.edit_text( "Выберите действие:", reply_markup=main_keyboard() ) await callback.answer() @dp.callback_query(F.data == "toggle_on") async def toggle_on(callback: types.CallbackQuery): user_id = callback.from_user.id set_user_settings(user_id, active=True) await callback.answer("✅ Переводчик включен") await main_menu(callback) @dp.callback_query(F.data == "toggle_off") async def toggle_off(callback: types.CallbackQuery): user_id = callback.from_user.id set_user_settings(user_id, active=False) await callback.answer("❌ Переводчик выключен") await main_menu(callback) # Запуск бота async def main(): await dp.start_polling(bot) if __name__ == "__main__": import asyncio asyncio.run(main())