# Система рассылок с Redis очередями ## Обзор Расширенная система массовых рассылок с поддержкой трех типов рассылки: - **ЛС пользователям** - массовая рассылка по личным сообщениям с отслеживанием заблокированных - **В канал** - отправка в Telegram канал - **В группу** - отправка в Telegram группу ## Основные возможности ### 1. Рассылка в личные сообщения **Особенности:** - Использование Redis очередей для управления потоком сообщений - Автоматическое отслеживание пользователей, заблокировавших бота - Пакетная отправка с задержками для соблюдения лимитов Telegram - Детальная обработка ошибок (блокировка, деактивация аккаунта, etc.) - Автоматическое повторение при FloodWait ошибках **Технические детали:** - Размер пакета: 30 сообщений - Задержка между пакетами: 1 секунда - Дополнительная задержка при FloodWait: 5 секунд + время из ошибки ### 2. Рассылка в канал/группу **Особенности:** - Управление списком каналов и групп через админ-панель - Проверка прав бота перед добавлением канала - Возможность добавить описание для каждого канала - Активация/деактивация каналов ## Архитектура ### Модели данных #### BroadcastChannel Хранит информацию о каналах и группах для рассылки: - `chat_id` - ID чата в Telegram - `chat_type` - тип (channel/group) - `title` - название - `username` - юзернейм (если есть) - `description` - описание - `is_active` - активен ли для рассылок - `added_by` - кто добавил #### BlockedUser Отслеживание заблокированных/недоступных пользователей: - `telegram_id` - ID пользователя - `error_type` - тип ошибки (blocked_bot, deactivated, not_found, etc.) - `error_message` - полное сообщение об ошибке - `first_blocked_at` - первая попытка - `last_attempt_at` - последняя попытка - `attempt_count` - количество неудачных попыток - `is_active` - активна ли блокировка #### BroadcastLog История рассылок: - `broadcast_type` - тип (direct/channel/group) - `target_id` - ID канала/группы (для соответствующих типов) - `message_type` - тип сообщения - `message_text` - текст - `file_id` - ID файла (если есть) - Статистика: `total_recipients`, `success_count`, `failed_count`, `blocked_count` - `created_by` - кто запустил - `started_at`, `completed_at` - временные метки - `status` - статус (pending/in_progress/completed/failed) ### Сервисы #### BroadcastService Основной сервис для рассылок (`src/core/broadcast_services.py`): **Методы:** - `broadcast_to_users()` - рассылка в ЛС - `broadcast_to_channel()` - отправка в канал/группу - `send_message_to_user()` - отправка одному пользователю с обработкой ошибок - `check_user_blocked()` - проверка блокировки - `mark_user_blocked()` - отметить как заблокированного - `unblock_user()` - разблокировать #### RedisQueue Класс для работы с Redis очередями: **Методы:** - `connect()` - подключение к Redis - `disconnect()` - отключение - `add_to_queue()` - добавить в очередь - `get_from_queue()` - получить из очереди (блокирующая) - `get_queue_length()` - получить длину очереди - `clear_queue()` - очистить очередь ## Использование ### Добавление канала/группы 1. Перейдите в админ-панель → Массовая рассылка → Управление каналами 2. Нажмите "Добавить канал/группу" 3. Получите ID канала: - Добавьте бота в канал/группу как администратора - Перешлите сообщение из канала боту @userinfobot - Скопируйте ID чата (обычно отрицательное число) 4. Отправьте ID боту 5. При успешной проверке отправьте описание или /skip ### Создание рассылки 1. Перейдите в админ-панель → Массовая рассылка → Создать рассылку 2. Выберите тип рассылки: - **ЛС пользователям** - всем зарегистрированным - **В канал** - выберите канал из списка - **В группу** - выберите группу из списка 3. Отправьте сообщение (текст, фото, видео или документ) 4. Дождитесь завершения и получите статистику ### Просмотр статистики Перейдите в админ-панель → Массовая рассылка → Статистика: - Общее количество рассылок - Количество заблокированных пользователей - История последних 5 рассылок с детальной статистикой ## Обработка ошибок Система автоматически обрабатывает следующие типы ошибок: ### TelegramForbiddenError Пользователь заблокировал бота. Помечается как `blocked_bot`. ### TelegramBadRequest - `user is deactivated` → `deactivated` - `user not found` → `not_found` - `chat not found` → `chat_not_found` - Остальные → `bad_request` ### TelegramRetryAfter (FloodWait) Автоматическая задержка и повторная попытка отправки. ### Другие ошибки Логируются как `unknown_error`. ## Конфигурация ### Переменные окружения ```env # Redis REDIS_URL=redis://localhost:6379/0 # По умолчанию ``` ### Docker Compose Redis автоматически запускается при использовании docker-compose: ```yaml services: redis: image: redis:7-alpine container_name: lottery_redis restart: unless-stopped command: redis-server --appendonly yes volumes: - redis_data:/data networks: - lottery_network ``` ### Настройки в коде В `BroadcastService` (`src/core/broadcast_services.py`): ```python BATCH_SIZE = 30 # Сообщений в пакете BATCH_DELAY = 1.0 # Задержка между пакетами (секунды) RETRY_AFTER_DELAY = 5.0 # Дополнительная задержка при FloodWait ``` ## Миграция базы данных Для применения новых таблиц: ```bash # Применить миграцию python -m alembic upgrade head # Откатить миграцию python -m alembic downgrade -1 ``` ## Мониторинг ### Логи Все операции рассылки логируются: - Успешные отправки (уровень DEBUG) - Блокировки пользователей (уровень INFO) - FloodWait задержки (уровень WARNING) - Ошибки отправки (уровень ERROR) ### База данных Проверка статистики через SQL: ```sql -- Количество заблокированных пользователей SELECT COUNT(*) FROM blocked_users WHERE is_active = true; -- Статистика рассылок SELECT broadcast_type, COUNT(*) as total, SUM(success_count) as delivered, SUM(blocked_count) as blocked FROM broadcast_logs GROUP BY broadcast_type; ``` ## Рекомендации 1. **Перед запуском большой рассылки:** - Проверьте количество заблокированных пользователей - Убедитесь, что Redis работает - Проверьте логи на наличие ошибок 2. **При добавлении канала:** - Убедитесь, что бот добавлен как администратор - Проверьте, что бот имеет права на отправку сообщений 3. **Мониторинг производительности:** - Следите за временем выполнения рассылок - При необходимости увеличьте BATCH_SIZE (не более 40) - Уменьшите BATCH_DELAY при стабильной работе (не менее 0.5 сек) ## Troubleshooting ### Проблема: Рассылка зависает **Решение:** 1. Проверьте подключение к Redis 2. Проверьте логи на наличие ошибок 3. Убедитесь, что нет FloodWait ошибок ### Проблема: Не удается добавить канал **Решение:** 1. Убедитесь, что бот добавлен в канал/группу 2. Проверьте права бота (должен быть администратором) 3. Убедитесь, что ID правильный (должен быть отрицательным) ### Проблема: Высокий процент неудач при рассылке **Решение:** 1. Проверьте количество заблокированных пользователей в статистике 2. Увеличьте BATCH_DELAY для снижения нагрузки 3. Проверьте логи на частые FloodWait ошибки ## Безопасность - Все операции рассылки доступны только администраторам - ID каналов/групп хранятся в зашифрованном виде (BigInteger) - История рассылок связана с администратором, который ее запустил - Автоматическое логирование всех операций ## Производительность - Redis очереди обеспечивают асинхронную обработку - Пакетная отправка снижает нагрузку на API Telegram - Автоматическое управление задержками предотвращает FloodWait - Кэширование заблокированных пользователей ускоряет рассылку