# Система управления кастомными эмодзи ## Обзор Система позволяет администраторам регистрировать премиум эмодзи и использовать их в сообщениях бота. Когда админ отправляет эмодзи боту: 1. Бот получает `emoji_id` от Telegram API 2. Сохраняет эмодзи в таблице `emoji_mappings` 3. При отправке сообщений в чаты бот автоматически использует `emoji_id` вместо текста эмодзи Это обеспечивает, что эмодзи будут выглядеть точно так же, как их отправил админ, даже если это премиум эмодзи. ## Команды администратора ### 1. Добавить новый эмодзи ``` /add_emoji ``` Процесс: 1. Админ запускает команду `/add_emoji` 2. Бот просит отправить эмодзи 3. Админ отправляет эмодзи (например, 🎲) 4. Бот просит описание (для чего используется) 5. Админ отправляет描述 (например, "Для лотереи") 6. Бот сохраняет в БД и подтверждает ### 2. Просмотр своих эмодзи ``` /my_emojis ``` Показывает все эмодзи, добавленные этим админом: - Сам эмодзи - Описание - ID (первые 30 символов) - Дату добавления ### 3. Просмотр всех эмодзи в системе ``` /all_emojis ``` Показывает все эмодзи всех админов с информацией об администраторе ### 4. Удалить эмодзи ``` /delete_emoji ``` Админ может удалить только свои эмодзи. Процесс: 1. Вызвать команду 2. Выбрать эмодзи из список (кнопки) 3. Бот удалит из БД ## Использование в коде ### Простой способ - прямое использование эмодзи ```python from aiogram.types import Message async def handler(message: Message): await message.answer( text="🎲 Добро пожаловать на лотерею! 🏆", parse_mode="HTML" ) ``` ### С обработкой эмодзи ```python from sqlalchemy.ext.asyncio import AsyncSession from src.core.emoji_message_helper import get_emoji_aware_text from aiogram.types import Message async def handler(message: Message, session: AsyncSession): # Текст с эмодзи original_text = "🎲 Выиграли! 🏆" # Обработаны текст (эмодзи заменены на ID для корректного отображения) processed_text = await get_emoji_aware_text(session, original_text) await message.answer(processed_text, parse_mode="HTML") ``` ### Работа с EmojiMessageHelper ```python from sqlalchemy.ext.asyncio import AsyncSession from src.core.emoji_message_helper import EmojiMessageHelper async def handler(message: Message, session: AsyncSession): helper = EmojiMessageHelper(session) # Обработка перед отправкой text = "🎲 Лотерея начинается! 💎" processed = await helper.process_text_before_send(text) await message.answer(processed, parse_mode="HTML") ``` ## Структура БД ### Таблица `emoji_mappings` | Колонка | Тип | Описание | |---------|-----|---------| | `id` | Integer | Primary Key | | `emoji_text` | String(10) | Сам эмодзи (например, 🎲) | | `emoji_id` | String(255) | telegram_emoji_id от API (уникален) | | `admin_id` | Integer | FK на user (администратор) | | `description` | String(255) | Описание назначения эмодзи | | `created_at` | DateTime | Дата добавления | | `last_used_at` | DateTime | Последнее использование | ### Уникальные ограничения - `emoji_id` — уникален во всей системе - `(emoji_text, admin_id)` — один админ не может добавить один эмодзи дважды ## API сервиса EmojiMappingService ### Регистрация эмодзи ```python from sqlalchemy.ext.asyncio import AsyncSession from src.core.emoji_mapping_service import EmojiMappingService async with async_session_maker() as session: service = EmojiMappingService(session) emoji = await service.register_emoji( emoji_text="🎲", emoji_id="telegram_emoji_id_here", admin_id=12345, description="Для лотереи" ) ``` ### Получение эмодзи ```python # По тексту emoji = await service.get_emoji_by_text("🎲") # По emoji_id emoji = await service.get_emoji_by_id("telegram_emoji_id") # Все эмодзи админа emojis = await service.get_all_emoji_by_admin(admin_id=12345) # Все эмодзи all_emojis = await service.get_all_emojis() ``` ### Замена эмодзи в тексте ```python # Текст → с заменой эмодзи на ID processed = await service.replace_emojis_in_text( "🎲 Выиграли! 🏆" ) # Обратно - ID → эмодзи original = await service.restore_emojis_in_text(processed) ``` ### Получить словарь маппинга ```python # {emoji_text: emoji_id} mapping = await service.get_emoji_mapping_dict() # {'🎲': 'telegram_emoji_id_1', '🏆': 'telegram_emoji_id_2', ...} ``` ## Примеры использования в разных рутерах ### В регистрации ```python async def registration_complete(message: Message, session: AsyncSession): text = "✅ Регистрация завершена! 🎉" text = await get_emoji_aware_text(session, text) await message.answer(text, parse_mode="HTML") ``` ### В админ-панели ```python async def lottery_created(callback: CallbackQuery, session: AsyncSession): text = "🎰 Новый розыгрыш создан! 🏆" text = await get_emoji_aware_text(session, text) await callback.message.edit_text(text, parse_mode="HTML") ``` ### В чатовой рассылке ```python async def broadcast_message(message: Message, session: AsyncSession): text = f"📢 Сообщение от админа: {message.text}\n\n💎 Удачи!" text = await get_emoji_aware_text(session, text) for user_id in target_users: await bot.send_message(user_id, text, parse_mode="HTML") ``` ## Важные моменты 1. **Parse Mode**: Всегда используйте `parse_mode="HTML"` при работе с эмодзи 2. **Кеширование ID**: Система не кеширует, каждый раз обращается к БД. Для оптимизации можно добавить кеширование 3. **Лог использования**: `last_used_at` обновляется автоматически при замене в тексте 4. **Удаление**: Удаленный эмодзи больше не будет заменяться в новых сообщениях 5. **Конфликты**: Если два админа добавляют один эмодзи - они сохранятся отдельно (разные admin_id) ## Миграция Таблица создана миграцией: ``` migrations/versions/20260307_0100_add_emoji_mappings.py ``` Применить миграцию: ```bash alembic upgrade head ``` ## Trouble Shooting ### Эмодзи не отображается корректно - Проверьте что используете `parse_mode="HTML"` - Убедитесь что эмодзи зарегистрирован с помощью `/my_emojis` ### Ошибка "Can't parse entities" - Это означает что есть конфликт форматирования - Убедитесь что используете HTML теги (``, ``, и т.д.), а не Markdown (`**`, `__`) ### Эмодзи не заменяется - Проверьте что был зарегистрирован с помощью `/add_emoji` - Убедитесь что используете функцию `get_emoji_aware_text()` перед отправкой