from telegram import Update
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__)
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}!
Я бот для автоматической рассылки сообщений в группы.
Что я умею:
• 📨 Создавать и управлять сообщениями
• 👥 Добавлять группы и управлять ими
• 📤 Отправлять сообщения со скоростью группы (slow mode)
• 📊 Отслеживать статус отправки
Выберите действие:"""
await update.message.reply_text(
text,
reply_markup=get_main_keyboard()
)
async def help_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
"""Обработчик команды /help"""
user = update.effective_user
logger.info(f"📧 Получена команда /help от пользователя {user.id}")
text = """📖 Справка по использованию:
Основные команды:
/start - Главное меню
/help - Эта справка
Как работать с сообщениями:
1. Перейдите в раздел "Сообщения"
2. Создайте новое сообщение
3. Введите текст сообщения
4. Выберите группы для отправки
Как работать с группами:
1. Бот автоматически обнаружит группы при добавлении
2. Для каждой группы можно настроить slow mode
3. Вы сможете отправлять разные сообщения в разные группы
Slow mode:
Это ограничение на скорость отправки сообщений в группу.
Бот автоматически учитывает это при отправке.
Нажмите /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"""✅ Синхронизация завершена!
📊 Результаты:
• 🔄 Синхронизировано: {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"""✅ Синхронизация завершена!
📊 Результаты:
• ➕ Добавлено: {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)}"
)