11 KiB
Система локализации 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)
Новый пользователь
- Пользователь отправляет
/start - Автоматически показывается меню выбора языка (10 кнопок с флагами)
- После выбора языка:
- Язык сохраняется в БД
- Показывается приветственное сообщение на выбранном языке
- Предлагается создать профиль
Существующий пользователь
- Пользователь отправляет
/start - Бот использует сохраненный язык из БД
- Показывается главное меню на выбранном языке
Изменение языка в настройках
Запланировано: добавить кнопку "🌍 Язык / 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. Тестирование
Проверка выбора языка для нового пользователя:
- Удалите свой профиль из БД:
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;
- Отправьте
/startботу - Должно появиться меню выбора из 10 языков
- Выберите любой язык
- Проверьте, что приветствие отображается на выбранном языке
Проверка сохранения языка:
SELECT telegram_id, username, lang FROM users;
Следующие шаги
Приоритет 1: Замена всех хардкод-текстов
Необходимо заменить все хардкод-тексты в следующих файлах:
src/handlers/messageHandlers.ts(профиль, регистрация)src/handlers/callbackHandlers.ts(кнопки, меню)src/handlers/commandHandlers.ts(команды)src/services/notificationService.ts(уведомления)
Приоритет 2: Дополнение языковых файлов
Текущие файлы содержат только базовые ключи. Нужно:
- Извлечь все существующие тексты из кода
- Добавить ключи в
ru.json(эталонный файл) - Перевести ключи для остальных 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);
}
Поддержка
Если нужно добавить новый язык:
- Создайте файл
src/locales/{код}.json - Скопируйте структуру из
ru.json - Переведите все ключи
- Добавьте язык в
LocalizationService.initialize():
const newLangTranslations = JSON.parse(
fs.readFileSync(path.join(localesPath, 'новый_код.json'), 'utf8')
);
- Добавьте в
resourcesобъект - Добавьте в
getSupportedLanguages() - Добавьте кнопку в
LanguageHandlers.showLanguageSelection()
Статус: ✅ Система локализации активна и работает
Версия: 1.0.0
Дата: 06.11.2025