# Telegram Bot Share Image Feature Plan ## Objetivo Добавить в телеграм-бота команду `/share` которая генерирует красивое сообщение и изображение для приглашения друзей использовать бот и приложение. ## Требования ### 1. **Ограничение частоты запросов** - Максимум 1 сообщение на пользователя в день - Лимит должен быть настраиваемым через переменные окружения или config - Хранение последних запросов пользователей в Isar БД ### 2. **Получение исходной карточки** - Случайный выбор карточки из бэкенда (из всех доступных карточек) - Получение через Isar (DBManager будет иметь доступ к карточкам через `isar.gameCardModels`) - Если нет карточек, использовать placeholder или default изображение ### 3. **Обработка изображения** - Загрузка оригинального PNG изображения карточки из файловой системы бэкенда - Добавление красивой рамки вокруг изображения - Размер рамки: ~30-50px с обеих сторон - Цвет рамки: тёмный или с градиентом (TBD в процессе разработки) - Замена текста на карточке или добавление наложения с названием приложения "mnemo cards" ### 4. **Формирование сообщения** - Текст без эмодзи - Включение referral code пользователя - Профессиональный, дружеский тон - Примерный формат: ``` Приветствую! Я тестирую приложение mnemo cards для изучения языков. Присоединяйся и начни учиться вместе со мной! Referral code: [CODE_HERE] ``` ### 5. **Отправка результата** - Отправить сообщение с текстом - Отправить сгенерированное изображение к сообщению - Удобство: в одном сообщении или отдельно (TBD) ## Архитектура решения ### Структура данных Isar ```dart // Для отслеживания количества поделиться за день class ShareRequestModel { Id? id; late String telegramUserId; late DateTime requestedAt; // Возможные поля для будущего аналитика late String? generatedCardId; } ``` ### Компоненты для реализации #### 1. **ImageGenerator** (`lib/image_generator.dart`) Класс для генерации изображения с рамкой - `Future> generateShareImage(GameCardModel card)` - генерирует PNG с рамкой - Использует `image` package для обработки изображений - Работает с файловой системой для чтения оригинальных карточек #### 2. **ReferralCodeManager** (в `db_manager.dart`) Методы для работы с referral кодами - `Future getUserReferralCode(String telegramUserId)` - получить или сгенерировать код - Хранение в Isar или вызов бэкенда #### 3. **ShareRateLimiter** (в `db_manager.dart`) Контроль частоты запросов - `Future canShareToday(String telegramUserId)` - проверка лимита - `Future recordShareRequest(String telegramUserId, int? cardId)` - сохранение запроса - Конфигурируемый лимит (дефолт 1 раз в день) #### 4. **ShareCommand** (в `main.dart`) Новая команда `/share` - Обработка команды в `teledart.onCommand('share')` - Проверка лимита - Получение случайной карточки - Генерация изображения - Отправка сообщения с изображением ## Этапы реализации ### Этап 1: Подготовка инфраструктуры 1. Добавить зависимость `image: ^4.0.0` в pubspec.yaml 2. Создать миграцию Isar: добавить `ShareRequestModel` 3. Расширить `DBManager` методами для율 лимитирования и referral кодов ### Этап 2: Реализация обработки изображений 1. Создать `ImageGenerator` класс 2. Реализовать: - Загрузку карточки из файловой системы - Добавление рамки - Добавление текста с названием приложения 3. Написать unit тесты ### Этап 3: Реализация rate limiting 1. Реализовать методы в `DBManager` 2. Написать unit тесты ### Этап 4: Реализация команды /share 1. Добавить команду в `main.dart` 2. Интегрировать все компоненты 3. Обработка ошибок ### Этап 5: Конфигурация 1. Добавить переменные окружения 2. Обновить `BotConfig` 3. Документация ### Этап 6: Тестирование и отладка 1. Ручное тестирование в Telegram 2. Проверка лимитирования 3. Проверка качества изображения ## Переменные окружения ```bash # Количество поделиться в день (дефолт: 1) BOT_SHARE_DAILY_LIMIT=1 # Путь к бэкенду для получения referral кода (опционально) BACKEND_URL=http://localhost:8443 ``` ## Возможные улучшения (Future) - Выбор темы рамки (светлая/тёмная) - Кастомизация текста приложения - Сохранение сгенерированных изображений для кэширования - Аналитика использования feature - Поддержка мультиязычного текста ## Технические заметки ### Получение случайной карточки ```dart final allCards = await isar.gameCardModels.where().findAll(); final random = Random(); final card = allCards[random.nextInt(allCards.length)]; ``` ### Пути к изображениям - Оригинальные изображения хранятся в: `../mnemo_cards_backend/data/cards/` - Имя файла в карточке: `GameCardModel.image` (например: "1234_word.png") ### Обработка изображений в Dart - Package `image` для обработки PNG - Методы: `copyResize()`, `drawString()`, `drawRect()` и т.д. - Примеры использования есть в `mnemo_cards_backend/lib/packs/pack_manager.dart` ## Деньги на: Quality Assurance - Проверить работу при отсутствии карточек - Проверить работу при отсутствии файла изображения - Проверить корректность rate limiting через несколько дней - Проверить качество генерируемого изображения на мобильных устройствах - Проверить производительность при работе с большим количеством карточек