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

203
examples_userbot.py Normal file
View File

@@ -0,0 +1,203 @@
#!/usr/bin/env python3
"""
Примеры использования Telethon UserBot Microservice
"""
import asyncio
from app.userbot.parser import userbot_parser
from app.database import AsyncSessionLocal
from app.database.repository import GroupRepository
from app.database.member_repository import GroupMemberRepository
async def example_1_parse_single_group():
"""Пример 1: Парсить одну группу"""
print("\n" + "="*60)
print("📊 Пример 1: Парсить одну группу")
print("="*60)
# Инициализировать
success = await userbot_parser.initialize()
if not success:
print("❌ Ошибка инициализации")
return
# Парсить группу
chat_id = -1001234567890 # Замените на реальный ID
print(f"\n🔍 Парсинг информации о группе {chat_id}...")
group_info = await userbot_parser.parse_group_info(chat_id)
if group_info:
print(f"\n✅ Информация о группе:")
print(f" Название: {group_info['title']}")
print(f" Членов: {group_info['members_count']}")
print(f" Канал: {group_info['is_channel']}")
else:
print("Не удалось получить информацию")
await userbot_parser.shutdown()
async def example_2_parse_members():
"""Пример 2: Получить участников группы"""
print("\n" + "="*60)
print("👥 Пример 2: Получить участников группы")
print("="*60)
success = await userbot_parser.initialize()
if not success:
print("❌ Ошибка инициализации")
return
chat_id = -1001234567890 # Замените на реальный ID
print(f"\n📊 Парсинг участников группы {chat_id}...")
members = await userbot_parser.parse_group_members(chat_id, limit=100)
if members:
print(f"\n✅ Получено {len(members)} участников:")
for member in members[:5]: # Показать первых 5
print(f" - {member['first_name']} {member['last_name']} (@{member['username']})")
if len(members) > 5:
print(f" ... и еще {len(members) - 5}")
else:
print("Не удалось получить участников")
await userbot_parser.shutdown()
async def example_3_sync_to_db():
"""Пример 3: Синхронизировать группу в БД"""
print("\n" + "="*60)
print("💾 Пример 3: Синхронизировать группу в БД")
print("="*60)
success = await userbot_parser.initialize()
if not success:
print("❌ Ошибка инициализации")
return
chat_id = -1001234567890 # Замените на реальный ID
print(f"\n🔄 Синхронизация группы {chat_id}...")
success = await userbot_parser.sync_group_to_db(chat_id)
if success:
print("✅ Группа синхронизирована в БД")
# Показать сохраненные данные
async with AsyncSessionLocal() as session:
repo = GroupRepository(session)
group = await repo.get_group_by_chat_id(str(chat_id))
if group:
print(f"\n📋 Информация в БД:")
print(f" ID: {group.id}")
print(f" Название: {group.title}")
print(f" Членов: {group.members_count}")
else:
print("❌ Ошибка синхронизации")
await userbot_parser.shutdown()
async def example_4_query_members():
"""Пример 4: Получить участников из БД"""
print("\n" + "="*60)
print("🔍 Пример 4: Получить участников из БД")
print("="*60)
async with AsyncSessionLocal() as session:
repo = GroupMemberRepository(session)
# Получить участников группы
group_id = 1 # Замените на реальный ID из БД
members = await repo.get_members_by_group(group_id)
if members:
print(f"\n✅ Получено {len(members)} участников из БД:")
# Статистика
admin_count = sum(1 for m in members if m.is_admin)
bot_count = sum(1 for m in members if m.is_bot)
print(f"\n📊 Статистика:")
print(f" Всего: {len(members)}")
print(f" Администраторов: {admin_count}")
print(f" Ботов: {bot_count}")
print(f"\n👤 Первые 5 участников:")
for member in members[:5]:
status = "🤖" if member.is_bot else "👤"
admin = "👑" if member.is_admin else ""
print(f" {status} {member.first_name} (@{member.username}) {admin}")
else:
print(" В БД нет участников")
async def example_5_search_members():
"""Пример 5: Поиск участников"""
print("\n" + "="*60)
print("🔎 Пример 5: Поиск участников")
print("="*60)
async with AsyncSessionLocal() as session:
repo = GroupMemberRepository(session)
group_id = 1
keyword = "john"
print(f"\n🔍 Поиск участников по имени '{keyword}' в группе {group_id}...")
members = await repo.search_members_by_name(group_id, keyword)
if members:
print(f"\n✅ Найдено {len(members)} участников:")
for member in members:
print(f" - {member.first_name} {member.last_name} (@{member.username})")
else:
print(f"❌ Участников с '{keyword}' не найдено")
def print_menu():
"""Показать меню примеров"""
print("\n" + "="*60)
print("🎯 Примеры использования UserBot Microservice")
print("="*60)
print("\n1. Парсить одну группу (информация)")
print("2. Получить участников группы")
print("3. Синхронизировать группу в БД")
print("4. Получить участников из БД")
print("5. Поиск участников")
print("0. Выход")
print("\n" + "-"*60)
async def main():
"""Главная функция"""
while True:
print_menu()
choice = input("Выберите пример (0-5): ").strip()
if choice == "1":
await example_1_parse_single_group()
elif choice == "2":
await example_2_parse_members()
elif choice == "3":
await example_3_sync_to_db()
elif choice == "4":
await example_4_query_members()
elif choice == "5":
await example_5_search_members()
elif choice == "0":
print("\n✅ До свидания!")
break
else:
print("❌ Неверный выбор")
input("\n📌 Нажмите Enter для продолжения...")
if __name__ == "__main__":
asyncio.run(main())