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
This commit is contained in:
2025-12-21 12:09:11 +09:00
parent b8136138dc
commit 48f8c6f0eb
48 changed files with 6593 additions and 113 deletions

View File

@@ -2,7 +2,8 @@ import logging
import os
from typing import List, Optional, Dict
from telethon import TelegramClient, events
from telethon.tl.types import ChatMember, User
from telethon.tl.types import User
from telethon.tl.types.auth import Authorization
from telethon.errors import (
FloodWaitError, UserDeactivatedError, ChatAdminRequiredError,
PeerIdInvalidError, ChannelInvalidError, UserNotParticipantError
@@ -272,6 +273,50 @@ class TelethonClientManager:
logger.error(f"❌ Ошибка при поиске сообщений: {e}")
return []
async def get_user_groups(self) -> List[Dict]:
"""
Получить все группы и супергруппы пользователя
Returns:
List[Dict]: Список групп с информацией {id, title, slow_mode_delay, members_count}
"""
if not self.is_initialized:
logger.error("Telethon клиент не инициализирован")
return []
try:
groups = []
from telethon.tl.types import Chat, Channel
# Получить все диалоги (чаты/группы)
async for dialog in self.client.iter_dialogs():
entity = dialog.entity
# Пропустить личные чаты и каналы (только группы и супергруппы)
if not isinstance(entity, (Chat, Channel)):
continue
# Пропустить каналы (broadcast)
if isinstance(entity, Channel) and entity.broadcast:
continue
group_info = {
'chat_id': entity.id,
'title': entity.title if hasattr(entity, 'title') else str(entity.id),
'slow_mode_delay': entity.slowmode_seconds if hasattr(entity, 'slowmode_seconds') else 0,
'members_count': entity.participants_count if hasattr(entity, 'participants_count') else 0,
'is_supergroup': isinstance(entity, Channel), # Channel = supergroup/megagroup
}
groups.append(group_info)
logger.debug(f"📍 Найдена группа: {group_info['title']} (ID: {group_info['chat_id']})")
logger.info(f"✅ Получено {len(groups)} групп от Telethon")
return groups
except Exception as e:
logger.error(f"❌ Ошибка при получении групп: {e}")
return []
def is_connected(self) -> bool:
"""Проверить, подключен ли клиент"""
return self.is_initialized and self.client is not None