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
11 KiB
11 KiB
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:
- Перейти на https://my.telegram.org/auth
- Войти с номером телефона
- Выбрать "API development tools"
- Скопировать
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
- Откройте http://localhost:5555
- Перейдите на вкладку "Tasks"
- Найдите и запустите нужную задачу:
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 не авторизован. Требуется повторный вход.
Решение:
- Удалить
sessions/userbot_session.session - Запустить интерактивно:
python userbot_service.py - Следовать инструкциям авторизации
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