All checks were successful
continuous-integration/drone/push Build is passing
- 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
102 lines
7.3 KiB
Markdown
102 lines
7.3 KiB
Markdown
# Исправление функции чата
|
||
|
||
## 🔴 Проблема
|
||
При переходе в чат, сообщения не отправлялись другим участникам. Пользователи не получали сообщения друг от друга.
|
||
|
||
## 🔍 Корневые причины (найдено ДВЕ)
|
||
|
||
### Причина 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: Изменена логика получения активных пользователей
|
||
```python
|
||
# ДО (неправильно):
|
||
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()`:
|
||
```python
|
||
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]:`
|
||
|
||
### Проверка логов:
|
||
|
||
```bash
|
||
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`
|
||
|
||
## 🎯 Ожидаемый результат
|
||
|
||
После применения этого исправления:
|
||
✅ Все пользователи будут получать сообщения в чате
|
||
✅ Сообщения будут рассылаться **независимо от статуса регистрации**
|
||
✅ Логирование позволит отследить проблемы при возникновении
|
||
✅ Система корректно проверяет ключевые слова для выхода из чата
|
||
✅ Сообщения рассылаются **всем** пользователям, включая незарегистрированных
|