Files
new_lottery_bot/docs/BROADCAST_SYSTEM.md
Andrey K. Choi 0fdad07d82
Some checks failed
continuous-integration/drone/pr Build is failing
refactor
2026-02-17 00:22:42 +09:00

11 KiB
Raw Blame History

Система рассылок с 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 deactivateddeactivated
  • user not foundnot_found
  • chat not foundchat_not_found
  • Остальные → bad_request

TelegramRetryAfter (FloodWait)

Автоматическая задержка и повторная попытка отправки.

Другие ошибки

Логируются как unknown_error.

Конфигурация

Переменные окружения

# Redis
REDIS_URL=redis://localhost:6379/0  # По умолчанию

Docker Compose

Redis автоматически запускается при использовании docker-compose:

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):

BATCH_SIZE = 30  # Сообщений в пакете
BATCH_DELAY = 1.0  # Задержка между пакетами (секунды)
RETRY_AFTER_DELAY = 5.0  # Дополнительная задержка при FloodWait

Миграция базы данных

Для применения новых таблиц:

# Применить миграцию
python -m alembic upgrade head

# Откатить миграцию
python -m alembic downgrade -1

Мониторинг

Логи

Все операции рассылки логируются:

  • Успешные отправки (уровень DEBUG)
  • Блокировки пользователей (уровень INFO)
  • FloodWait задержки (уровень WARNING)
  • Ошибки отправки (уровень ERROR)

База данных

Проверка статистики через 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
  • Кэширование заблокированных пользователей ускоряет рассылку