Files
new_lottery_bot/docs/CHAT_SYSTEM.md
Andrew K. Choi b6c27b7b70
Some checks reported errors
continuous-integration/drone/push Build encountered an error
feat: добавлена система чата с модерацией
Реализована полнофункциональная система чата с двумя режимами работы:

## Режимы работы:
- Broadcast: рассылка сообщений всем пользователям
- Forward: пересылка сообщений в указанную группу/канал

## Функционал:
- Поддержка всех типов сообщений: text, photo, video, document, animation, sticker, voice
- Система банов: личные баны пользователей и глобальный бан чата
- Модерация: удаление сообщений с отслеживанием в БД
- История сообщений с сохранением ID пересланных сообщений

## Структура БД (миграция 005):
- chat_settings: настройки чата (режим, ID канала, глобальный бан)
- banned_users: история банов с причинами и информацией о модераторе
- chat_messages: история сообщений с типами, файлами и картой доставки (JSONB)

## Сервисы:
- ChatSettingsService: управление настройками чата
- BanService: управление банами пользователей
- ChatMessageService: работа с историей сообщений
- ChatPermissionService: проверка прав на отправку сообщений

## Обработчики:
- chat_handlers.py: обработка сообщений пользователей (7 типов контента)
- admin_chat_handlers.py: админские команды управления чатом

## Админские команды:
- /chat_mode - переключение режима (broadcast/forward)
- /set_forward <chat_id> - установка ID канала для пересылки
- /ban <user_id> [причина] - бан пользователя
- /unban <user_id> - разбан пользователя
- /banlist - список забаненных
- /global_ban - включение/выключение глобального бана
- /delete_msg - удаление сообщения (ответ на сообщение)
- /chat_stats - статистика чата

## Документация:
- docs/CHAT_SYSTEM.md: полное описание системы с примерами использования

Изменено файлов: 7 (2 modified, 5 new)
- main.py: подключены chat_router и admin_chat_router
- src/core/models.py: добавлены модели ChatSettings, BannedUser, ChatMessage
- migrations/versions/005_add_chat_system.py: миграция создания таблиц
- src/core/chat_services.py: сервисный слой для чата (267 строк)
- src/handlers/chat_handlers.py: обработчики сообщений (447 строк)
- src/handlers/admin_chat_handlers.py: админские команды (369 строк)
- docs/CHAT_SYSTEM.md: документация (390 строк)
2025-11-16 14:25:09 +09:00

356 lines
15 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Система чата пользователей
## Описание
Система чата позволяет пользователям общаться между собой через бота с двумя режимами работы:
- **Broadcast (Рассылка)** - сообщения пользователей рассылаются всем остальным пользователям
- **Forward (Пересылка)** - сообщения пользователей пересылаются в указанную группу/канал
## Режимы работы
### Режим Broadcast (Рассылка всем)
В этом режиме сообщения от одного пользователя автоматически рассылаются всем остальным активным пользователям бота.
**Особенности:**
- Отправитель не получает копию своего сообщения
- Сообщение доставляется только активным пользователям (is_active=True)
- В базу сохраняется статистика доставки (кому доставлено, кому нет)
- ID отправленных сообщений сохраняются в `forwarded_message_ids` (JSONB)
**Пример работы:**
1. Пользователь А отправляет фото с текстом "Привет всем!"
2. Бот копирует это сообщение пользователям B, C, D...
3. В базу сохраняется: `{telegram_id_B: msg_id_1, telegram_id_C: msg_id_2, ...}`
4. Пользователю А показывается статистика: "✅ Сообщение разослано! 📤 Доставлено: 15, ❌ Не доставлено: 2"
### Режим Forward (Пересылка в канал)
В этом режиме сообщения от пользователей пересылаются в указанную группу или канал.
**Особенности:**
- Бот должен быть администратором канала/группы с правом публикации
- Сохраняется оригинальное авторство сообщения (пересылка, а не копия)
- ID канала хранится в `chat_settings.forward_chat_id`
- В базу сохраняется ID сообщения в канале
**Пример работы:**
1. Пользователь отправляет видео
2. Бот пересылает это видео в канал (сохраняя имя отправителя)
3. В базу сохраняется: `{channel: message_id_in_channel}`
4. Пользователю показывается: "✅ Сообщение переслано в канал"
## Поддерживаемые типы сообщений
Система поддерживает все основные типы контента:
| Тип | Поле `message_type` | Поле `file_id` | Описание |
|-----|---------------------|----------------|----------|
| Текст | `text` | NULL | Обычное текстовое сообщение |
| Фото | `photo` | file_id | Изображение (сохраняется самое большое) |
| Видео | `video` | file_id | Видео файл |
| Документ | `document` | file_id | Файл любого типа |
| GIF | `animation` | file_id | Анимированное изображение |
| Стикер | `sticker` | file_id | Стикер из набора |
| Голосовое | `voice` | file_id | Голосовое сообщение |
**Примечание:** Для всех типов кроме `text` и `sticker` может быть указан `caption` (подпись), который сохраняется в поле `text`.
## Система банов
### Личный бан пользователя
Администратор может забанить конкретного пользователя:
```
/ban 123456789 Спам в чате
/ban (ответ на сообщение) Нарушение правил
```
**Эффекты:**
- Пользователь не может отправлять сообщения
- При попытке отправки получает: "❌ Вы заблокированы и не можете отправлять сообщения"
- Запись добавляется в таблицу `banned_users` с `is_active=true`
**Разблокировка:**
```
/unban 123456789
/unban (ответ на сообщение)
```
### Глобальный бан чата
Администратор может временно закрыть весь чат:
```
/global_ban
```
**Эффекты:**
- Все пользователи (кроме админов) не могут писать
- При попытке отправки: "❌ Чат временно закрыт администратором"
- Флаг `chat_settings.global_ban` устанавливается в `true`
**Открытие чата:**
```
/global_ban (повторно - переключение)
```
## Модерация сообщений
### Удаление сообщений
Администратор может удалить сообщение из всех чатов:
```
/delete_msg (ответ на сообщение)
```
**Процесс:**
1. Сообщение помечается как удаленное в БД (`is_deleted=true`)
2. Сохраняется кто удалил (`deleted_by`) и когда (`deleted_at`)
3. Бот пытается удалить сообщение у всех пользователей, используя `forwarded_message_ids`
4. Показывается статистика: "✅ Удалено у 12 пользователей"
**Важно:** Удаление возможно только если сообщение было сохранено в БД и есть `forwarded_message_ids`.
## Админские команды
### /chat_mode
Переключение режима работы чата.
**Интерфейс:** Inline-клавиатура с выбором режима.
**Пример использования:**
```
/chat_mode
→ Показывается меню выбора режима
→ Нажимаем "📢 Рассылка всем"
→ Режим изменен
```
### /set_forward <chat_id>
Установить ID канала/группы для пересылки.
**Как узнать chat_id:**
1. Добавьте бота в канал/группу
2. Напишите любое сообщение в канале
3. Перешлите его боту @userinfobot
4. Он покажет chat_id (например: -1001234567890)
**Пример:**
```
/set_forward -1001234567890
→ ID канала для пересылки установлен!
```
### /ban <user_id> [причина]
Забанить пользователя.
**Способы использования:**
1. Ответить на сообщение: `/ban Спам`
2. Указать ID: `/ban 123456789 Нарушение правил`
### /unban <user_id>
Разбанить пользователя.
**Способы использования:**
1. Ответить на сообщение: `/unban`
2. Указать ID: `/unban 123456789`
### /banlist
Показать список всех забаненных пользователей.
**Формат вывода:**
```
🚫 Забаненные пользователи
👤 Иван Иванов (123456789)
🔨 Забанил: Админ
📝 Причина: Спам
📅 Дата: 15.01.2025 14:30
👤 Петр Петров (987654321)
🔨 Забанил: Админ
📅 Дата: 14.01.2025 12:00
```
### /global_ban
Включить/выключить глобальный бан чата (переключатель).
**Статусы:**
- 🔇 Включен - только админы могут писать
- 🔊 Выключен - все могут писать
### /delete_msg
Удалить сообщение (ответ на сообщение).
**Требует:** Ответить на сообщение, которое нужно удалить.
### /chat_stats
Показать статистику чата.
**Информация:**
- Текущий режим работы
- Статус глобального бана
- Количество забаненных пользователей
- Количество сообщений за последнее время
- ID канала (если установлен)
## База данных
### Таблица chat_settings
Одна строка с глобальными настройками чата:
```sql
id = 1 (всегда)
mode = 'broadcast' | 'forward'
forward_chat_id = '-1001234567890' (для режима forward)
global_ban = true | false
```
### Таблица banned_users
История банов пользователей:
```sql
id - уникальный ID бана
user_id - FK на users.id
telegram_id - Telegram ID пользователя
banned_by - FK на users.id (кто забанил)
reason - текстовая причина (nullable)
banned_at - timestamp бана
is_active - true/false (активен ли бан)
```
**Примечание:** При разбане `is_active` меняется на `false`, но запись не удаляется (история).
### Таблица chat_messages
История всех отправленных сообщений:
```sql
id - уникальный ID сообщения
user_id - FK на users.id (отправитель)
telegram_message_id - ID сообщения в Telegram
message_type - text/photo/video/document/animation/sticker/voice
text - текст или caption (nullable)
file_id - file_id медиа (nullable)
forwarded_message_ids - JSONB с картой доставки
is_deleted - помечено ли как удаленное
deleted_by - FK на users.id (кто удалил, nullable)
deleted_at - timestamp удаления (nullable)
created_at - timestamp отправки
```
**Формат forwarded_message_ids:**
```json
// Режим broadcast:
{
"123456789": 12345, // telegram_id: message_id
"987654321": 12346,
"555555555": 12347
}
// Режим forward:
{
"channel": 54321 // ключ "channel", значение - ID сообщения в канале
}
```
## Примеры использования
### Настройка режима broadcast
1. Админ: `/chat_mode` → выбирает "📢 Рассылка всем"
2. Пользователь А пишет: "Привет всем!"
3. Пользователи B, C, D получают это сообщение
4. Пользователь А видит: "✅ Сообщение разослано! 📤 Доставлено: 3"
### Настройка режима forward
1. Админ создает канал и добавляет бота как админа
2. Админ узнает chat_id канала (например: -1001234567890)
3. Админ: `/set_forward -1001234567890`
4. Админ: `/chat_mode` → выбирает "➡️ Пересылка в канал"
5. Пользователь пишет сообщение → оно появляется в канале
### Бан пользователя за спам
1. Пользователь отправляет спам
2. Админ отвечает на его сообщение: `/ban Спам в чате`
3. Пользователь забанен, попытки отправить сообщение блокируются
4. Админ: `/banlist` - видит список банов
5. Админ: `/unban` (ответ на сообщение) - разбан
### Временное закрытие чата
1. Админ: `/global_ban`
2. Все пользователи видят: "❌ Чат временно закрыт администратором"
3. Только админы могут писать
4. Админ: `/global_ban` (повторно) - чат открыт
### Удаление неприемлемого контента
1. Пользователь отправил неприемлемое фото
2. Фото разослано всем (режим broadcast)
3. Админ отвечает на это сообщение: `/delete_msg`
4. Бот удаляет фото у всех пользователей, кому оно было отправлено
5. В БД сообщение помечается как удаленное
## Технические детали
### Порядок подключения роутеров
```python
dp.include_router(registration_router) # Первым
dp.include_router(admin_account_router)
dp.include_router(admin_chat_router) # До chat_router!
dp.include_router(redraw_router)
dp.include_router(account_router)
dp.include_router(chat_router) # ПОСЛЕДНИМ (ловит все сообщения)
dp.include_router(router)
dp.include_router(admin_router)
```
**Важно:** `chat_router` должен быть последним, так как он ловит ВСЕ типы сообщений (text, photo, video и т.д.). Если поставить его раньше, он будет перехватывать команды и сообщения, предназначенные для других обработчиков.
### Проверка прав
```python
can_send, reason = await ChatPermissionService.can_send_message(
session,
telegram_id=user.telegram_id,
is_admin=is_admin(user.telegram_id)
)
```
**Логика проверки:**
1. Если пользователь админ → всегда `can_send=True`
2. Если включен global_ban → `can_send=False`
3. Если пользователь забанен → `can_send=False`
4. Иначе → `can_send=True`
### Миграция 005
При запуске миграции создаются 3 таблицы и вставляется начальная запись:
```sql
INSERT INTO chat_settings (id, mode, global_ban)
VALUES (1, 'broadcast', false);
```
Эта запись будет использоваться всегда (единственная строка в таблице).
## Возможные улучшения
1. **Фильтрация контента** - автоматическая проверка на мат, спам, ссылки
2. **Лимиты** - ограничение количества сообщений в минуту/час
3. **Ответы на сообщения** - возможность отвечать на конкретное сообщение пользователя
4. **Редактирование** - изменение отправленных сообщений
5. **Реакции** - лайки/дизлайки на сообщения
6. **Каналы** - разделение чата на темы/каналы
7. **История** - просмотр истории сообщений через команду
8. **Поиск** - поиск по истории сообщений