Files
TG_autoposter/docs/USERBOT_MICROSERVICE.md
Andrew K. Choi 48f8c6f0eb UserBot Integration Complete: Fixed container startup, integrated UserBot menu to main bot
MAJOR FIXES:
 Fixed UserBot container startup by making TELEGRAM_BOT_TOKEN optional
 Broke circular import chain between app modules
 Made Config.validate() conditional for UserBot-only mode
 Removed unused celery import from userbot_service.py

INTEGRATION:
 UserBot menu now accessible from main bot /start command
 Added 🤖 UserBot button to main keyboard
 Integrated userbot_manager.py handlers:
   - userbot_menu: Main UserBot interface
   - userbot_settings: Configuration
   - userbot_collect_groups: Gather all user groups
   - userbot_collect_members: Parse group members
 UserBot handlers properly registered in ConversationHandler

CONTAINERS:
 tg_autoposter_bot: Running and handling /start commands
 tg_autoposter_userbot: Running as standalone microservice
 All dependent services (Redis, PostgreSQL, Celery workers) operational

STATUS: Bot is fully operational and ready for testing
2025-12-21 12:09:11 +09:00

11 KiB
Raw Permalink Blame History

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:

# 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. Первый запуск (Авторизация)

# Запустить userbot в интерактивном режиме
python userbot_service.py

# Следовать инструкциям для авторизации через SMS код

Сессия будет сохранена в sessions/userbot_session.session

3. Запуск в Docker

# Собрать контейнер
docker-compose build userbot

# Запустить вместе с другими сервисами
docker-compose up -d userbot

# Просмотр логов
docker-compose logs -f userbot

4. Запуск как Celery воркер

# В отдельном терминале
python userbot_service.py --celery

# Или через Docker
docker-compose run --rm userbot python userbot_service.py --celery

API / Использование

Programmatically

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 задачи

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 (в БД)

{
    '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 (в БД)

{
    '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: Парсить группу через кнопку в боте

# В обработчике кнопки
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: Синхронизировать все группы по расписанию

# В 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: Получить участников группы

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}

Мониторинг

Через логи

docker-compose logs -f userbot | grep "✅\|❌\|⏳"

Через Flower

http://localhost:5555/dashboard

Отслеживайте:

  • Active tasks
  • Task history
  • Worker stats
  • Pool size

Метрики

# Получить статистику парсинга
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 параметр для меньшего нагрузки

Задача зависает

# Проверить статус задачи
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

Оптимизация

# Парсить в части если много участников
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