feat: добавлена система чата с модерацией
Some checks reported errors
continuous-integration/drone/push Build encountered an error
Some checks reported errors
continuous-integration/drone/push Build encountered an error
Реализована полнофункциональная система чата с двумя режимами работы: ## Режимы работы: - 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 строк)
This commit is contained in:
355
docs/CHAT_SYSTEM.md
Normal file
355
docs/CHAT_SYSTEM.md
Normal file
@@ -0,0 +1,355 @@
|
||||
# Система чата пользователей
|
||||
|
||||
## Описание
|
||||
|
||||
Система чата позволяет пользователям общаться между собой через бота с двумя режимами работы:
|
||||
- **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. **Поиск** - поиск по истории сообщений
|
||||
Reference in New Issue
Block a user