# Telethon UserBot Microservice Отдельный микросервис для парсинга Telegram групп и каналов от имени пользователя (UserBot). ## Архитектура ``` Основной бот (Python-Telegram-Bot) ↓ ├─→ Celery задачи (Async парсинг) │ ↓ │ Telethon UserBot Microservice │ ↓ │ PostgreSQL БД │ └─→ HTTP API для управления ``` ## Возможности ### 1. Парсинг групп и каналов - Получение информации о группе (название, описание, кол-во членов) - Парсинг списка участников с информацией: - User ID - Username - Имя и фамилия - Статус (бот/пользователь) - Роль (администратор/участник) ### 2. Сохранение в БД - Автоматическое сохранение информации о группах - Кэширование списков участников - Отслеживание изменений ### 3. Celery интеграция - Асинхронные задачи для парсинга - Очередь задач для управления нагрузкой - Мониторинг через Flower ## Установка и запуск ### 1. Конфигурация Добавьте в `.env`: ```bash # Telethon Configuration USE_TELETHON=true TELETHON_API_ID=your_api_id TELETHON_API_HASH=your_api_hash TELETHON_PHONE=+1234567890 TELETHON_FLOOD_WAIT_MAX=60 ``` Получить API ID и HASH: 1. Перейти на https://my.telegram.org/auth 2. Войти с номером телефона 3. Выбрать "API development tools" 4. Скопировать `api_id` и `api_hash` ### 2. Первый запуск (Авторизация) ```bash # Запустить userbot в интерактивном режиме python userbot_service.py # Следовать инструкциям для авторизации через SMS код ``` Сессия будет сохранена в `sessions/userbot_session.session` ### 3. Запуск в Docker ```bash # Собрать контейнер docker-compose build userbot # Запустить вместе с другими сервисами docker-compose up -d userbot # Просмотр логов docker-compose logs -f userbot ``` ### 4. Запуск как Celery воркер ```bash # В отдельном терминале python userbot_service.py --celery # Или через Docker docker-compose run --rm userbot python userbot_service.py --celery ``` ## API / Использование ### Programmatically ```python from app.userbot.parser import userbot_parser # Инициализировать await userbot_parser.initialize() # Парсить группу group_info = await userbot_parser.parse_group_info(chat_id=-1001234567890) members = await userbot_parser.parse_group_members(chat_id=-1001234567890) # Синхронизировать в БД await userbot_parser.sync_group_to_db(chat_id=-1001234567890) ``` ### Celery задачи ```python from app.userbot.tasks import parse_group_task, sync_all_groups_task # Парсить одну группу result = parse_group_task.delay(chat_id=-1001234567890) # Синхронизировать все группы result = sync_all_groups_task.delay() # Парсить только участников result = parse_group_members_task.delay(chat_id=-1001234567890, limit=5000) ``` ### Через Flower UI 1. Откройте http://localhost:5555 2. Перейдите на вкладку "Tasks" 3. Найдите и запустите нужную задачу: - `app.userbot.tasks.parse_group` - парсить группу - `app.userbot.tasks.sync_all_groups` - синхронизировать все - `app.userbot.tasks.parse_group_members` - парсить участников ## Структура данных ### Group (в БД) ```python { 'id': int, # ID в БД 'chat_id': str, # Telegram chat ID 'title': str, # Название группы 'description': str, # Описание 'members_count': int, # Кол-во членов 'is_active': bool, # Активна ли 'created_at': datetime, # Дата добавления 'updated_at': datetime, # Дата обновления } ``` ### GroupMember (в БД) ```python { 'id': int, # ID в БД 'group_id': int, # ID группы 'user_id': str, # Telegram user ID 'username': str, # Username (@username) 'first_name': str, # Имя 'last_name': str, # Фамилия 'is_bot': bool, # Это бот? 'is_admin': bool, # Администратор? 'is_owner': bool, # Владелец? 'joined_at': datetime, # Когда присоединился 'created_at': datetime, # Дата добавления в БД 'updated_at': datetime, # Дата обновления в БД } ``` ## Обработка ошибок ### FloodWaitError При большом кол-ве запросов Telegram может ограничить доступ. Парсер автоматически: - Перехватывает ошибку FloodWaitError - Записывает в логи время ожидания - Возвращает частично загруженные данные ### PeerIdInvalidError Неверный ID группы - проверьте chat_id ### UserNotParticipantError Бот не участник группы - добавьте его в группу предварительно ### ChatAdminRequiredError Нужны права администратора для парсинга - добавьте бота администратором ## Примеры использования ### Пример 1: Парсить группу через кнопку в боте ```python # В обработчике кнопки from app.userbot.tasks import parse_group_task async def handle_parse_button(update, context): chat_id = -1001234567890 # Отправить в Celery task = parse_group_task.delay(chat_id) await update.callback_query.edit_message_text( f"📊 Парсинг группы запущен (Task ID: {task.id})" ) ``` ### Пример 2: Синхронизировать все группы по расписанию ```python # В celery_tasks.py from celery.schedules import crontab app.conf.beat_schedule = { 'sync-all-groups-daily': { 'task': 'app.userbot.tasks.sync_all_groups', 'schedule': crontab(hour=0, minute=0), # Каждый день в 00:00 }, } ``` ### Пример 3: Получить участников группы ```python from app.userbot.tasks import parse_group_members_task # Запустить задачу task = parse_group_members_task.delay( chat_id=-1001234567890, limit=10000 ) # Дождаться результата result = task.get() # {'status': 'success', 'members_count': 5432} ``` ## Мониторинг ### Через логи ```bash docker-compose logs -f userbot | grep "✅\|❌\|⏳" ``` ### Через Flower http://localhost:5555/dashboard Отслеживайте: - Active tasks - Task history - Worker stats - Pool size ### Метрики ```python # Получить статистику парсинга from app.database.repository import GroupRepository async with AsyncSessionLocal() as session: repo = GroupRepository(session) groups = await repo.get_all_active_groups() for group in groups: print(f"{group.title}: {group.members_count} членов") ``` ## Troubleshooting ### UserBot не авторизован ``` ❌ UserBot не авторизован. Требуется повторный вход. ``` **Решение:** 1. Удалить `sessions/userbot_session.session` 2. Запустить интерактивно: `python userbot_service.py` 3. Следовать инструкциям авторизации ### FloodWait ошибки ``` ⏳ FloodWait на 3600с при парсинге участников ``` **Решение:** - Это нормально - Telegram ограничивает быстрые запросы - Парсер автоматически ждет и продолжает после перерыва - Можно уменьшить `limit` параметр для меньшего нагрузки ### Задача зависает ```python # Проверить статус задачи from celery.result import AsyncResult task_id = "xxx" result = AsyncResult(task_id) print(result.status) # PENDING, PROGRESS, SUCCESS, FAILURE ``` ### Нет доступа к группе ``` ⚠️ Нет доступа к группе -1001234567890 ``` **Решение:** - Добавить UserBot в группу - Дать права администратора если нужен доступ к приватным данным ## Производительность ### Рекомендуемые настройки для разных размеров групп | Размер | Limit | Timeout | Celery workers | |--------|-------|---------|-----------------| | <1K | 1000 | 30s | 1-2 | | 1K-10K | 5000 | 60s | 2-4 | | >10K | 10000 | 120s | 4-8 | ### Оптимизация ```python # Парсить в части если много участников from math import ceil total_members = 50000 batch_size = 5000 for i in range(ceil(total_members / batch_size)): offset = i * batch_size members = await userbot_parser.parse_group_members( chat_id, limit=batch_size, offset=offset ) ``` ## Лимиты Telegram - **Rate limit**: ~33 запроса в секунду на одно соединение - **FloodWait**: автоматически триггерится при превышении - **Размер результата**: до 100K членов в одной группе ## Безопасность ⚠️ **Важно!** - Не делитесь сессионными файлами (`sessions/userbot_session.session`) - API ID и HASH - это не для публичного доступа - Используйте отдельный аккаунт Telegram для UserBot - Хранить в .env.local (не коммитить!) ## Лицензия Внутренний микросервис проекта TG Autoposter