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

360 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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