# Архитектура TG Autoposter ## Общая структура ``` ┌─────────────────────────────────────────────────────┐ │ Telegram User (в личных сообщениях) │ └──────────────────────┬──────────────────────────────┘ │ ↓ ┌─────────────────────────────────────────────────────┐ │ Telegram Bot (python-telegram-bot) │ │ main.py → app/__init__.py │ └──────────────────┬──────────────────┬──────────────┘ │ │ ┌──────────┘ └────────────┐ ↓ ↓ ┌─────────────┐ ┌──────────────┐ │ Handlers │ │ Callbacks │ │ (команды) │ │ (кнопки) │ └──────┬──────┘ └──────┬───────┘ │ │ └──────────────┬───────────────────────┘ ↓ ┌───────────────────────────────┐ │ Database Repository │ │ (repository.py) │ │ - GroupRepository │ │ - MessageRepository │ │ - MessageGroupRepository │ └──────────────┬────────────────┘ ↓ ┌───────────────────────────────┐ │ SQLAlchemy ORM │ │ (database/__init__.py) │ │ - AsyncSessionLocal │ │ - engine │ └──────────────┬────────────────┘ ↓ ┌───────────────────────────────┐ │ Database (SQLite/PgSQL) │ │ - groups │ │ - messages │ │ - message_groups │ └───────────────────────────────┘ ``` ## Слои приложения ### 1. **Presentation Layer** (Telegram Bot) - Файлы: `handlers/`, `utils/keyboards.py` - Отвечает за взаимодействие с пользователем - Обработка команд и callback'ов - Формирование инлайн кнопок ### 2. **Application Logic Layer** (Handlers) - Файлы: `handlers/commands.py`, `handlers/callbacks.py`, `handlers/sender.py`, `handlers/message_manager.py`, `handlers/group_manager.py` - Бизнес-логика отправки сообщений - Учет slow mode - Управление сообщениями и группами ### 3. **Repository Layer** (Data Access) - Файл: `database/repository.py` - CRUD операции для каждой сущности - Абстракция работы с БД - Защита от прямых SQL запросов ### 4. **ORM Layer** (Object-Relational Mapping) - Файл: `database/__init__.py` - SQLAlchemy для работы с БД - Асинхронные сессии - Управление подключением ### 5. **Data Layer** (Models & Database) - Файлы: `models/`, база данных - Определение структуры данных - Связи между таблицами - Физическое хранилище ## Модели данных ### Group (Группа) ``` ┌──────────────────┐ │ Group │ ├──────────────────┤ │ id (PK) │ │ chat_id (UNQ) │ │ title │ │ slow_mode_delay │ │ last_message_time│ │ is_active │ │ created_at │ │ updated_at │ └──────────────────┘ │ │ 1..N │ └───────────────────┐ │ ┌────────────────┐ │ MessageGroup │ │ (pivot table) │ └────────────────┘ │ │ 1..N │ ┌────────────────┐ │ Message │ │ (Сообщение) │ └────────────────┘ ``` ## Поток данных при отправке сообщения ``` 1. Пользователь нажимает "📤 Отправить" │ ↓ 2. send_message() получает callback │ ├─→ Получить сообщение из БД │ (MessageRepository.get_message) │ ├─→ Получить все связи для отправки │ (MessageGroupRepository.get_message_groups_to_send) │ ↓ 3. Для каждой группы: │ ├─→ Проверить slow mode │ (can_send_message() из utils) │ ├─→ Если нужно, ждать │ (asyncio.sleep) │ ├─→ Отправить сообщение через Bot API │ (context.bot.send_message) │ ├─→ Обновить время последнего сообщения │ (GroupRepository.update_last_message_time) │ ├─→ Отметить как отправленное │ (MessageGroupRepository.mark_as_sent) │ └─→ Обновить статус в UI (query.edit_message_text) 4. Показать итоговое сообщение пользователю ``` ## Поток данных при добавлении бота в группу ``` 1. Бот добавлен в группу │ ↓ 2. Telegram отправляет my_chat_member update │ ↓ 3. my_chat_member() обработчик получает событие │ ├─→ Проверить статус: member или left │ ├─→ Если member: │ │ │ ├─→ Получить информацию о группе │ │ (context.bot.get_chat) │ │ │ ├─→ Получить slow mode │ │ │ ├─→ Проверить есть ли уже в БД │ │ (GroupRepository.get_group_by_chat_id) │ │ │ └─→ Добавить или обновить │ (GroupRepository.add_group) │ └─→ Если left: │ └─→ Деактивировать в БД (GroupRepository.deactivate_group) ``` ## Асинхронность Весь код использует async/await: ```python async def main(): # Инициализация await init_db() # Создание приложения application = Application.builder().token(TOKEN).build() # Добавление обработчиков application.add_handler(...) # Polling (слушаем обновления) await application.run_polling() ``` ## Обработка ошибок ``` ┌─────────────────────────────────────┐ │ Попытка отправки сообщения │ └────────────┬────────────────────────┘ │ ┌──────┴──────┐ │ │ ↓ ↓ SUCCESS EXCEPTION │ │ ├─→ mark_as_sent() ├─→ Сохранить ошибку │ (is_sent=True) mark_as_sent(error=str(e)) │ (is_sent=False) └─────────┬──────────┬──────────┘ │ │ └─────────┘ │ ↓ Показать статус пользователю ``` ## Состояния ConversationHandler При создании сообщения: ``` START │ └─→ CREATE_MSG_TITLE (ввод названия) │ └─→ CREATE_MSG_TEXT (ввод текста, создание в БД) │ └─→ SELECT_GROUPS (выбор групп с кнопками) │ └─→ DONE или CANCEL (завершение) ``` ## Безопасность данных ### Уровни защиты: 1. **Переменные окружения** (.env) - Токен бота не в коде - DATABASE_URL скрыт 2. **Асинхронные сессии** - Каждая операция в собственной транзакции - Автоматический rollback при ошибке 3. **SQL Injection** - SQLAlchemy использует parameterized queries - Защита встроена в ORM 4. **Логирование** - Чувствительные данные не логируются - Ошибки записываются в файл с ротацией ## Масштабируемость ### Текущие возможности: - ✅ Линейная масштабируемость с количеством групп - ✅ Асинхронная обработка не блокирует бота - ✅ БД может быть PostgreSQL для производства - ✅ Логирование с ротацией ### Возможные улучшения: - [ ] Queue (Celery) для больших рассылок - [ ] Cache (Redis) для часто используемых данных - [ ] Webhook вместо polling для масштабирования - [ ] Connection pooling для БД ## Производительность ### Оптимизации: 1. **Асинхронность** - Не блокирует при I/O операциях - Может обрабатывать много групп параллельно 2. **Batch операции** - Отправка в несколько групп одновременно - Кэширование результатов 3. **Индексы в БД** - `chat_id` в таблице Groups (UNIQUE) - Foreign keys оптимизированы ## Тестирование ### Структура для тестирования: ``` tests/ ├── test_models.py # Модели ├── test_repository.py # Репозитории ├── test_handlers.py # Обработчики └── test_integration.py # Интеграция ``` ## Развертывание ### Production deployment: ``` 1. Клонировать репо 2. pip install -r requirements.txt 3. Настроить .env с реальным токеном 4. Использовать PostgreSQL вместо SQLite 5. Запустить с systemd/supervisor 6. Настроить ротацию логов 7. Мониторинг и алерты ``` ## Взаимодействие компонентов ``` ┌────────────────────────────────────────────────────────────┐ │ Telegram Bot (main.py) │ ├────────────────────────────────────────────────────────────┤ │ Application (python-telegram-bot) │ │ ├─ CommandHandler (/start, /help) │ │ ├─ CallbackQueryHandler (callback buttons) │ │ ├─ ChatMemberHandler (my_chat_member events) │ │ └─ ConversationHandler (multi-step flows) │ └────────────────────────────────────────────────────────────┘ ↓ ↓ ↓ ↓ ┌─────────┐ ┌────────────┐ ┌──────────┐ ┌─────────────┐ │ commands │ │ callbacks │ │ sender │ │group_manager│ │ .py │ │ .py │ │ .py │ │ .py │ └────┬─────┘ └──────┬─────┘ └────┬─────┘ └──────┬──────┘ │ │ │ │ └────────────────┼─────────────┼───────────────┘ │ ┌────▼────┐ │ message_ │ │manager.py│ └────┬─────┘ │ ┌──────────┴──────────┐ │ │ ┌────▼────────┐ ┌────▼────────┐ │ Repository │ │ Utils │ │ Layer │ │ - keyboards│ │ │ │ - slow_mode│ └────┬────────┘ └─────────────┘ │ ┌────▼─────────┐ │ SQLAlchemy │ │ ORM │ └────┬─────────┘ │ ┌────▼──────────┐ │ SQLite/PgSQL │ │ Database │ └───────────────┘ ``` Это архитектура позволяет: - ✅ Легко тестировать каждый слой - ✅ Менять БД без изменения логики - ✅ Расширять функциональность - ✅ Масштабировать приложение