Files
TG_autoposter/app/userbot/tasks.py
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

140 lines
5.4 KiB
Python
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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.

"""
Celery задачи для UserBot микросервиса
Запускает парсинг групп в фоновом режиме
"""
import asyncio
import logging
from celery import shared_task
from app.userbot.parser import userbot_parser
from app.database import AsyncSessionLocal
from app.database.repository import GroupRepository
logger = logging.getLogger(__name__)
def run_async(coro):
"""Вспомогательная функция для запуска async функций в Celery"""
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
try:
return loop.run_until_complete(coro)
finally:
loop.close()
@shared_task(name='app.userbot.tasks.initialize_userbot')
def initialize_userbot_task():
"""Инициализировать UserBot при запуске"""
logger.info("🚀 Инициализация UserBot...")
result = run_async(userbot_parser.initialize())
if result:
logger.info("✅ UserBot успешно инициализирован")
return {'status': 'success', 'message': 'UserBot initialized'}
else:
logger.error("❌ Ошибка инициализации UserBot")
return {'status': 'error', 'message': 'UserBot initialization failed'}
@shared_task(name='app.userbot.tasks.parse_group')
def parse_group_task(chat_id: int):
"""
Парсить группу и сохранить в БД
Args:
chat_id: ID группы для парсинга
"""
logger.info(f"📊 Парсинг группы {chat_id}...")
result = run_async(userbot_parser.sync_group_to_db(chat_id))
if result:
logger.info(f"✅ Группа {chat_id} успешно спарсена")
return {'status': 'success', 'chat_id': chat_id, 'message': 'Group parsed successfully'}
else:
logger.error(f"❌ Ошибка парсинга группы {chat_id}")
return {'status': 'error', 'chat_id': chat_id, 'message': 'Group parsing failed'}
@shared_task(name='app.userbot.tasks.sync_all_groups')
def sync_all_groups_task():
"""Синхронизировать все активные группы из БД"""
logger.info("🔄 Начало синхронизации всех групп...")
async def _sync_all():
try:
async with AsyncSessionLocal() as session:
repo = GroupRepository(session)
groups = await repo.get_all_active_groups()
if not groups:
logger.info(" Нет активных групп для синхронизации")
return {'status': 'success', 'groups_synced': 0}
synced = 0
failed = 0
for group in groups:
success = await userbot_parser.sync_group_to_db(group.chat_id)
if success:
synced += 1
else:
failed += 1
logger.info(f"✅ Синхронизировано {synced} групп (ошибок: {failed})")
return {'status': 'success', 'groups_synced': synced, 'groups_failed': failed}
except Exception as e:
logger.error(f"❌ Ошибка при синхронизации групп: {e}")
return {'status': 'error', 'message': str(e)}
return run_async(_sync_all())
@shared_task(name='app.userbot.tasks.parse_group_members')
def parse_group_members_task(chat_id: int, limit: int = 10000):
"""
Парсить участников группы
Args:
chat_id: ID группы
limit: максимум участников
"""
logger.info(f"👥 Парсинг участников группы {chat_id} (лимит: {limit})...")
async def _parse_members():
try:
members = await userbot_parser.parse_group_members(chat_id, limit)
if not members:
return {'status': 'error', 'chat_id': chat_id, 'members_count': 0}
# Сохранить в БД
async with AsyncSessionLocal() as session:
from app.database.repository import GroupMemberRepository
member_repo = GroupMemberRepository(session)
for member in members:
member_data = {
'group_id': chat_id,
'user_id': int(member['user_id']),
'username': member['username'],
'first_name': member['first_name'],
'last_name': member['last_name'],
'is_bot': member['is_bot'],
}
await member_repo.add_or_update_member(member_data)
await session.commit()
logger.info(f"{len(members)} участников группы {chat_id} сохранено в БД")
return {'status': 'success', 'chat_id': chat_id, 'members_count': len(members)}
except Exception as e:
logger.error(f"❌ Ошибка при парсинге участников {chat_id}: {e}")
return {'status': 'error', 'chat_id': chat_id, 'message': str(e)}
return run_async(_parse_members())