Files
new_lottery_bot/test_chat_fix.md
Andrew K. Choi 6b2e915452
All checks were successful
continuous-integration/drone/push Build is passing
fix: Fix chat message broadcasting to all users
- Fixed get_all_active_users() to broadcast to ALL users regardless of registration status
- Merged duplicate text message handlers (check_exit_keywords and handle_text_message)
- Added detailed logging for chat message broadcasting
- Now users can receive messages in chat without full registration

Resolves: Messages not being delivered to unregistered users in chat
2026-02-17 01:03:36 +09:00

7.3 KiB
Raw Blame History

Исправление функции чата

🔴 Проблема

При переходе в чат, сообщения не отправлялись другим участникам. Пользователи не получали сообщения друг от друга.

🔍 Корневые причины (найдено ДВЕ)

Причина 1: Неправильная фильтрация активных пользователей

В функции get_all_active_users() (строка 189-192) рассылка осуществлялась только:

  • Зарегистрированным пользователям (u.is_registered == True)
  • ИЛИ админам

Это означало, что обычные пользователи, не прошедшие полную регистрацию, не получали сообщения в чате.

Статус в БД: Было 7 пользователей, из них только 2 зарегистрированы, остальные 5 не получали сообщения.

Причина 2: Дублирующиеся обработчики текстовых сообщений

В файле src/handlers/chat_handlers.py было ДВА обработчика для текстовых сообщений в состоянии ChatStates.in_chat:

  1. check_exit_keywords() (строка 140):

    • Декоратор: @router.message(StateFilter(ChatStates.in_chat), F.text)
    • Функция: проверяла ключевые слова для выхода (/start, start, старт, /exit)
    • ПРОБЛЕМА: если сообщение не было ключевым словом, функция просто заканчивалась без return, но это НЕ означало, что выполнение продолжится в следующем обработчике. Aiogram использует первый подходящий обработчик, и второй никогда не вызывался.
  2. handle_text_message() (строка 663) - дублирующий обработчик:

    • Декоратор: @router.message(F.text, StateFilter(ChatStates.in_chat))
    • Функция: содержала вся логика для рассылки сообщений
    • ПРОБЛЕМА: эта функция НИКОГДА не вызывалась, потому что первый обработчик check_exit_keywords() перехватывал все текстовые сообщения.

Сделанные исправления

Исправление 1: Изменена логика получения активных пользователей

# ДО (неправильно):
async def get_all_active_users(session: AsyncSession) -> List:
    """Получить всех пользователей для рассылки (зарегистрированные + админы)"""
    users = await UserService.get_all_users(session)
    return [u for u in users if u.is_registered or u.telegram_id in ADMIN_IDS]

# ПОСЛЕ (правильно):
async def get_all_active_users(session: AsyncSession) -> List:
    """Получить всех пользователей для рассылки (всем, кто когда-либо общался с ботом)"""
    users = await UserService.get_all_users(session)
    return users

Исправление 2: Объединены дублирующиеся обработчики

  • Объединена вся логика обработки сообщений в check_exit_keywords() (теперь переименована концептуально, но осталась в коде)
  • Удален дублирующий обработчик handle_text_message()
  • Новая логика:
    1. Проверяются ключевые слова для выхода (/start, start, старт, /exit)
    2. Если это не ключевое слово → продолжается обработка как обычного сообщения чата
    3. Выполняется полная логика рассылки/пересылки

Исправление 3: Добавлено логирование для отладки

Добавлены логи в broadcast_message_with_scheduler():

logger.info(f"[CHAT] broadcast_message_with_scheduler: всего пользователей для рассылки: {len(users)}")
logger.info(f"[CHAT] После исключения отправителя: {len(users)} пользователей")
logger.info(f"[CHAT] broadcast_message_with_scheduler завершена: успешно={success_count}, ошибок={fail_count}")

📊 Измененные файлы

  • src/handlers/chat_handlers.py:
    • Строка 189-192: Функция get_all_active_users() теперь возвращает всех пользователей
    • Строка 140-358: Объединена вся логика обработки текстовых сообщений в функцию check_exit_keywords()
    • Строка 663-857: Удален дублирующий обработчик handle_text_message()

🧪 Тестирование

Инструкции для тестирования:

  1. Убедитесь, что есть минимум 2 пользователя в системе (заказывали с 7 пользователями)
  2. Первый пользователь: отправляет /chat или нажимает "Войти в чат"
  3. Второй пользователь: отправляет /chat или нажимает "Войти в чат"
  4. Первый пользователь: отправляет текстовое сообщение в чат
  5. Второй пользователь: должен получить сообщение с заголовком типа:
    • Для админов: 📨 Сообщение от [nickname] (карта: XXXX):
    • Для обычных пользователей: 📨 [nickname]:

Проверка логов:

docker compose logs -f bot | grep "\[CHAT\]"

Должны быть строки:

  • [CHAT] check_exit_keywords вызван для обработки: user=...
  • [CHAT] broadcast_message_with_scheduler: всего пользователей для рассылки: N
  • [CHAT] После исключения отправителя: N пользователей
  • [CHAT] broadcast_message_with_scheduler завершена: успешно=N, ошибок=M

🎯 Ожидаемый результат

После применения этого исправления: Все пользователи будут получать сообщения в чате Сообщения будут рассылаться независимо от статуса регистрации Логирование позволит отследить проблемы при возникновении Система корректно проверяет ключевые слова для выхода из чата Сообщения рассылаются всем пользователям, включая незарегистрированных