# Система чата пользователей ## Описание Система чата позволяет пользователям общаться между собой через бота с двумя режимами работы: - **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 Установить ID канала/группы для пересылки. **Как узнать chat_id:** 1. Добавьте бота в канал/группу 2. Напишите любое сообщение в канале 3. Перешлите его боту @userinfobot 4. Он покажет chat_id (например: -1001234567890) **Пример:** ``` /set_forward -1001234567890 → ID канала для пересылки установлен! ``` ### /ban [причина] Забанить пользователя. **Способы использования:** 1. Ответить на сообщение: `/ban Спам` 2. Указать ID: `/ban 123456789 Нарушение правил` ### /unban Разбанить пользователя. **Способы использования:** 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. **Поиск** - поиск по истории сообщений