✅ 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:
@@ -3,6 +3,8 @@ from telegram.ext import ContextTypes
|
||||
from app.database import AsyncSessionLocal
|
||||
from app.database.repository import GroupRepository, MessageRepository, MessageGroupRepository
|
||||
from app.utils.keyboards import get_main_keyboard, get_groups_keyboard, get_messages_keyboard
|
||||
from app.handlers.telethon_client import telethon_manager
|
||||
from app.userbot.parser import userbot_parser
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
@@ -11,6 +13,7 @@ logger = logging.getLogger(__name__)
|
||||
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
"""Обработчик команды /start"""
|
||||
user = update.effective_user
|
||||
logger.info(f"📧 Получена команда /start от пользователя {user.id} (@{user.username})")
|
||||
|
||||
text = f"""👋 Привет, {user.first_name}!
|
||||
|
||||
@@ -32,6 +35,8 @@ async def start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
|
||||
async def help_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
"""Обработчик команды /help"""
|
||||
user = update.effective_user
|
||||
logger.info(f"📧 Получена команда /help от пользователя {user.id}")
|
||||
text = """📖 Справка по использованию:
|
||||
|
||||
<b>Основные команды:</b>
|
||||
@@ -56,3 +61,165 @@ async def help_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> No
|
||||
Нажмите /start для возврата в главное меню."""
|
||||
|
||||
await update.message.reply_text(text, parse_mode='HTML')
|
||||
|
||||
|
||||
async def _sync_groups_with_userbot(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
"""Синхронизировать группы через новый UserBot парсер"""
|
||||
try:
|
||||
status_message = await update.message.reply_text(
|
||||
"⏳ Синхронизирую группы через UserBot парсер..."
|
||||
)
|
||||
|
||||
# Используем userbot для парсинга участников существующих групп
|
||||
async with AsyncSessionLocal() as session:
|
||||
repo = GroupRepository(session)
|
||||
existing_groups = await repo.get_all_active_groups()
|
||||
|
||||
if not existing_groups:
|
||||
await status_message.edit_text(
|
||||
"ℹ️ В БД нет групп для синхронизации участников.\n\n"
|
||||
"Сначала добавьте группы через /start → Группы"
|
||||
)
|
||||
return
|
||||
|
||||
synced_count = 0
|
||||
for group in existing_groups:
|
||||
try:
|
||||
# Синхронизировать информацию о группе и участников
|
||||
success = await userbot_parser.sync_group_to_db(int(group.chat_id))
|
||||
if success:
|
||||
synced_count += 1
|
||||
logger.info(f"✅ Синхронизирована группа: {group.title}")
|
||||
except Exception as e:
|
||||
logger.error(f"❌ Ошибка при синхронизации {group.title}: {e}")
|
||||
|
||||
await session.commit()
|
||||
|
||||
result_text = f"""✅ <b>Синхронизация завершена!</b>
|
||||
|
||||
📊 Результаты:
|
||||
• 🔄 Синхронизировано: {synced_count} групп
|
||||
|
||||
Информация о участниках обновлена и сохранена в БД!"""
|
||||
|
||||
await status_message.edit_text(result_text, parse_mode='HTML')
|
||||
logger.info(f"✅ Синхронизация участников завершена: {synced_count} групп")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"❌ Ошибка при синхронизации через UserBot: {e}", exc_info=True)
|
||||
await update.message.reply_text(
|
||||
f"❌ Ошибка при синхронизации: {str(e)}"
|
||||
)
|
||||
|
||||
|
||||
async def sync_groups_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
"""Синхронизировать группы из Telethon UserBot или UserBot парсера"""
|
||||
user = update.effective_user
|
||||
logger.info(f"🔄 Получена команда /sync_groups от пользователя {user.id}")
|
||||
|
||||
# Попытаться инициализировать userbot если еще не инициализирован
|
||||
if not userbot_parser.is_initialized:
|
||||
logger.info("📱 Инициализация UserBot парсера...")
|
||||
init_success = await userbot_parser.initialize()
|
||||
if not init_success:
|
||||
logger.warning("⚠️ UserBot парсер не инициализирован, используем старый telethon_manager")
|
||||
|
||||
# Попытаться использовать новый userbot сначала
|
||||
if userbot_parser.is_initialized:
|
||||
logger.info("✅ Используем новый UserBot парсер")
|
||||
return await _sync_groups_with_userbot(update, context)
|
||||
else:
|
||||
logger.info("ℹ️ Используем старый Telethon клиент")
|
||||
return await _sync_groups_with_telethon(update, context)
|
||||
|
||||
|
||||
async def _sync_groups_with_telethon(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
"""Синхронизировать группы через telethon_manager"""
|
||||
user = update.effective_user
|
||||
logger.info(f"🔄 Синхронизация через telethon_manager")
|
||||
|
||||
# Проверим, инициализирован ли Telethon клиент
|
||||
if not telethon_manager.is_connected():
|
||||
logger.warning("⚠️ Telethon клиент не инициализирован")
|
||||
await update.message.reply_text(
|
||||
"❌ Telethon UserBot не инициализирован.\n\n"
|
||||
"Убедитесь, что переменные окружения TELETHON_API_ID и TELETHON_API_HASH установлены."
|
||||
)
|
||||
return
|
||||
|
||||
try:
|
||||
# Отправим уведомление о начале синхронизации
|
||||
status_message = await update.message.reply_text(
|
||||
"⏳ Синхронизирую группы через Telethon UserBot..."
|
||||
)
|
||||
|
||||
# Получить все группы от Telethon
|
||||
groups = await telethon_manager.get_user_groups()
|
||||
|
||||
if not groups:
|
||||
await status_message.edit_text(
|
||||
"ℹ️ UserBot не найден ни в одной группе.\n\n"
|
||||
"Чтобы добавить группы:\n"
|
||||
"1. Пригласите UserBot в групп\u044b\n"
|
||||
"2. Повторите /sync_groups"
|
||||
)
|
||||
return
|
||||
|
||||
# Сохранить группы в БД
|
||||
added_count = 0
|
||||
updated_count = 0
|
||||
|
||||
async with AsyncSessionLocal() as session:
|
||||
repo = GroupRepository(session)
|
||||
|
||||
for group in groups:
|
||||
try:
|
||||
# Конвертировать chat_id в string
|
||||
chat_id_str = str(group['chat_id'])
|
||||
|
||||
# Попытаться найти существующую группу
|
||||
existing = await repo.get_group_by_chat_id(chat_id_str)
|
||||
|
||||
if existing:
|
||||
# Обновить информацию
|
||||
await repo.update_group(
|
||||
existing.id,
|
||||
title=group['title'],
|
||||
slow_mode_delay=group['slow_mode_delay']
|
||||
)
|
||||
updated_count += 1
|
||||
logger.info(f"✏️ Обновлена группа: {group['title']} (ID: {chat_id_str})")
|
||||
else:
|
||||
# Добавить новую группу
|
||||
await repo.add_group(
|
||||
chat_id=chat_id_str,
|
||||
title=group['title'],
|
||||
slow_mode_delay=group['slow_mode_delay']
|
||||
)
|
||||
added_count += 1
|
||||
logger.info(f"✅ Добавлена группа: {group['title']} (ID: {chat_id_str})")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"❌ Ошибка при добавлении группы {group['title']}: {e}")
|
||||
continue
|
||||
|
||||
await session.commit()
|
||||
|
||||
# Отправить результаты
|
||||
result_text = f"""✅ <b>Синхронизация завершена!</b>
|
||||
|
||||
📊 Результаты:
|
||||
• ➕ Добавлено: {added_count}
|
||||
• ✏️ Обновлено: {updated_count}
|
||||
• 📈 Всего в БД: {added_count + updated_count}
|
||||
|
||||
Теперь вы можете использовать эти группы для отправки сообщений!"""
|
||||
|
||||
await status_message.edit_text(result_text, parse_mode='HTML')
|
||||
logger.info(f"✅ Синхронизация завершена: добавлено {added_count}, обновлено {updated_count}")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"❌ Ошибка при синхронизации групп: {e}", exc_info=True)
|
||||
await update.message.reply_text(
|
||||
f"❌ Ошибка при синхронизации: {str(e)}"
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user