# Система локализации Telegram Tinder Bot ## Обзор Реализована полноценная система мультиязычной поддержки бота с возможностью выбора языка интерфейса. ## Реализованные функции ### 1. База данных **Миграция:** `sql/add_user_language.sql` Добавлена колонка `lang` в таблицу `users`: - Тип: `VARCHAR(5)` - Значение по умолчанию: `'ru'` (Русский) - NOT NULL constraint - Индекс для быстрого поиска: `idx_users_lang` ```sql ALTER TABLE users ADD COLUMN IF NOT EXISTS lang VARCHAR(5) DEFAULT 'ru' NOT NULL; CREATE INDEX IF NOT EXISTS idx_users_lang ON users(lang); ``` ### 2. Поддерживаемые языки Бот поддерживает **10 языков**: | Код | Язык | Флаг | Файл локализации | |------|-----------|------|------------------| | `ru` | Русский | 🇷🇺 | `ru.json` | | `en` | English | 🇬🇧 | `en.json` | | `es` | Español | 🇪🇸 | `es.json` | | `fr` | Français | 🇫🇷 | `fr.json` | | `de` | Deutsch | 🇩🇪 | `de.json` | | `it` | Italiano | 🇮🇹 | `it.json` | | `pt` | Português | 🇵🇹 | `pt.json` | | `ko` | 한국어 | 🇰🇷 | `ko.json` | | `zh` | 中文 | 🇨🇳 | `zh.json` | | `ja` | 日本語 | 🇯🇵 | `ja.json` | ### 3. Архитектура #### LocalizationService (`src/services/localizationService.ts`) Сервис на базе `i18next`: - Singleton pattern - Автоматическая загрузка всех языковых файлов при инициализации - Методы: - `initialize()` - инициализация сервиса - `t(key, options)` - получение перевода по ключу - `setLanguage(lang)` - смена языка - `getCurrentLanguage()` - получение текущего языка - `getSupportedLanguages()` - список поддерживаемых языков - `getTranslation(key, lang, options)` - получить перевод для конкретного языка без смены текущего #### LanguageHandlers (`src/handlers/languageHandlers.ts`) Обработчик выбора и управления языком: - `showLanguageSelection(chatId, messageId?)` - показать меню выбора языка - `handleSetLanguage(query)` - обработать установку языка - `checkAndShowLanguageSelection(userId, chatId)` - проверить, нужно ли показывать выбор языка #### ProfileService - Расширение (`src/services/profileService.ts`) Добавлены методы для работы с языком пользователя: - `ensureUser(telegramId, userData, language)` - создание/обновление пользователя с сохранением языка - `updateUserLanguage(telegramId, language)` - обновление языка пользователя - `getUserLanguage(telegramId)` - получение языка пользователя ### 4. Пользовательский опыт (UX) #### Новый пользователь 1. Пользователь отправляет `/start` 2. **Автоматически показывается меню выбора языка** (10 кнопок с флагами) 3. После выбора языка: - Язык сохраняется в БД - Показывается приветственное сообщение на выбранном языке - Предлагается создать профиль #### Существующий пользователь 1. Пользователь отправляет `/start` 2. Бот использует сохраненный язык из БД 3. Показывается главное меню на выбранном языке #### Изменение языка в настройках Запланировано: добавить кнопку "🌍 Язык / Language" в раздел "⚙️ Настройки" ### 5. Структура локализационных файлов Каждый файл `src/locales/{lang}.json` содержит: ```json { "language": { "select": "🌍 Выберите язык...", "changed": "✅ Язык изменен на...", "ru": "🇷🇺 Русский", "en": "🇬🇧 English", ... }, "welcome": { "greeting": "Добро пожаловать...", "description": "...", "getStarted": "..." }, "profile": { ... }, "search": { ... }, "buttons": { ... }, "errors": { ... }, ... } ``` ### 6. Интеграция в код #### Импорт функции перевода ```typescript import { getUserTranslation } from '../services/localizationService'; ``` #### Использование в коде ```typescript // Асинхронный вызов const text = await getUserTranslation(userId, 'welcome.greeting'); // Или через сервис const locService = LocalizationService.getInstance(); const text = locService.t('welcome.greeting'); ``` #### Callback для выбора языка Все callback_data для выбора языка имеют формат: ``` set_lang_{код_языка} ``` Например: - `set_lang_ru` - установить русский - `set_lang_en` - установить английский - `set_lang_ko` - установить корейский ### 7. Запуск миграции ```bash # Применить миграцию добавления колонки lang PGPASSWORD='Cl0ud_1985!' psql -h 192.168.0.102 -p 5432 -U trevor -d telegram_tinder_bot -f sql/add_user_language.sql ``` ### 8. Тестирование #### Проверка выбора языка для нового пользователя: 1. Удалите свой профиль из БД: ```sql DELETE FROM profiles WHERE user_id IN ( SELECT id FROM users WHERE telegram_id = YOUR_TELEGRAM_ID ); DELETE FROM users WHERE telegram_id = YOUR_TELEGRAM_ID; ``` 2. Отправьте `/start` боту 3. Должно появиться меню выбора из 10 языков 4. Выберите любой язык 5. Проверьте, что приветствие отображается на выбранном языке #### Проверка сохранения языка: ```sql SELECT telegram_id, username, lang FROM users; ``` ## Следующие шаги ### Приоритет 1: Замена всех хардкод-текстов Необходимо заменить все хардкод-тексты в следующих файлах: 1. **`src/handlers/messageHandlers.ts`** (профиль, регистрация) 2. **`src/handlers/callbackHandlers.ts`** (кнопки, меню) 3. **`src/handlers/commandHandlers.ts`** (команды) 4. **`src/services/notificationService.ts`** (уведомления) ### Приоритет 2: Дополнение языковых файлов Текущие файлы содержат только базовые ключи. Нужно: 1. Извлечь все существующие тексты из кода 2. Добавить ключи в `ru.json` (эталонный файл) 3. Перевести ключи для остальных 9 языков ### Приоритет 3: Кнопка смены языка в настройках Добавить в меню "⚙️ Настройки" кнопку: ```typescript { text: '🌍 Язык / Language', callback_data: 'change_language' } ``` ## Состояние реализации ✅ **Выполнено:** - Добавлена колонка `lang` в таблицу `users` - Создан `LanguageHandlers` для управления языком - Интегрирован выбор языка в `/start` для новых пользователей - Обновлен `LocalizationService` - Добавлены секции `language` в `ru.json` и `en.json` - Методы работы с языком в `ProfileService` ⚠️ **В процессе:** - Замена хардкод-текстов на локализационные ключи - Дополнение всех языковых файлов 📋 **Планируется:** - Кнопка смены языка в настройках - Полный перевод всех 10 языков - Тесты локализации ## Технические детали ### Callback Query Flow ``` Пользователь нажимает кнопку "🇷🇺 Русский" ↓ callback_data: 'set_lang_ru' ↓ callbackHandlers.handleCallback() перехватывает ↓ if (data.startsWith('set_lang_')) ↓ languageHandlers.handleSetLanguage(query) ↓ profileService.updateUserLanguage(userId, 'ru') ↓ localizationService.setLanguage('ru') ↓ Показ приветственного сообщения на русском ``` ### Database Schema ```sql CREATE TABLE users ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), telegram_id BIGINT UNIQUE NOT NULL, username VARCHAR(255), first_name VARCHAR(255), last_name VARCHAR(255), lang VARCHAR(5) DEFAULT 'ru' NOT NULL, -- ← НОВАЯ КОЛОНКА is_active BOOLEAN DEFAULT true, created_at TIMESTAMP DEFAULT NOW(), last_active_at TIMESTAMP DEFAULT NOW() ); CREATE INDEX idx_users_lang ON users(lang); ``` ## Примеры использования ### Пример 1: Приветственное сообщение ```typescript const lang = await profileService.getUserLanguage(userId); localizationService.setLanguage(lang); const greeting = localizationService.t('welcome.greeting'); const description = localizationService.t('welcome.description'); await bot.sendMessage(chatId, `${greeting}\n\n${description}`); ``` ### Пример 2: Кнопки с переводом ```typescript const keyboard: InlineKeyboardMarkup = { inline_keyboard: [ [{ text: localizationService.t('buttons.save'), callback_data: 'save_profile' }], [{ text: localizationService.t('buttons.cancel'), callback_data: 'cancel' }] ] }; ``` ### Пример 3: Ошибки ```typescript try { // ... код } catch (error) { const errorMsg = localizationService.t('errors.serverError'); await bot.sendMessage(chatId, errorMsg); } ``` ## Поддержка Если нужно добавить новый язык: 1. Создайте файл `src/locales/{код}.json` 2. Скопируйте структуру из `ru.json` 3. Переведите все ключи 4. Добавьте язык в `LocalizationService.initialize()`: ```typescript const newLangTranslations = JSON.parse( fs.readFileSync(path.join(localesPath, 'новый_код.json'), 'utf8') ); ``` 5. Добавьте в `resources` объект 6. Добавьте в `getSupportedLanguages()` 7. Добавьте кнопку в `LanguageHandlers.showLanguageSelection()` --- **Статус:** ✅ Система локализации активна и работает **Версия:** 1.0.0 **Дата:** 06.11.2025