Files
tg_tinder_bot/docs/LOCALIZATION_SYSTEM.md
2025-11-24 17:00:20 +09:00

11 KiB
Raw Blame History

Система локализации Telegram Tinder Bot

Обзор

Реализована полноценная система мультиязычной поддержки бота с возможностью выбора языка интерфейса.

Реализованные функции

1. База данных

Миграция: sql/add_user_language.sql

Добавлена колонка lang в таблицу users:

  • Тип: VARCHAR(5)
  • Значение по умолчанию: 'ru' (Русский)
  • NOT NULL constraint
  • Индекс для быстрого поиска: idx_users_lang
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 содержит:

{
  "language": {
    "select": "🌍 Выберите язык...",
    "changed": "✅ Язык изменен на...",
    "ru": "🇷🇺 Русский",
    "en": "🇬🇧 English",
    ...
  },
  "welcome": {
    "greeting": "Добро пожаловать...",
    "description": "...",
    "getStarted": "..."
  },
  "profile": { ... },
  "search": { ... },
  "buttons": { ... },
  "errors": { ... },
  ...
}

6. Интеграция в код

Импорт функции перевода

import { getUserTranslation } from '../services/localizationService';

Использование в коде

// Асинхронный вызов
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. Запуск миграции

# Применить миграцию добавления колонки 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. Удалите свой профиль из БД:
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;
  1. Отправьте /start боту
  2. Должно появиться меню выбора из 10 языков
  3. Выберите любой язык
  4. Проверьте, что приветствие отображается на выбранном языке

Проверка сохранения языка:

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: Кнопка смены языка в настройках

Добавить в меню "⚙️ Настройки" кнопку:

{ 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

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: Приветственное сообщение

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: Кнопки с переводом

const keyboard: InlineKeyboardMarkup = {
    inline_keyboard: [
        [{
            text: localizationService.t('buttons.save'),
            callback_data: 'save_profile'
        }],
        [{
            text: localizationService.t('buttons.cancel'),
            callback_data: 'cancel'
        }]
    ]
};

Пример 3: Ошибки

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():
const newLangTranslations = JSON.parse(
    fs.readFileSync(path.join(localesPath, овый_код.json'), 'utf8')
);
  1. Добавьте в resources объект
  2. Добавьте в getSupportedLanguages()
  3. Добавьте кнопку в LanguageHandlers.showLanguageSelection()

Статус: Система локализации активна и работает

Версия: 1.0.0

Дата: 06.11.2025