from telegram import Update, InlineKeyboardMarkup, InlineKeyboardButton from telegram.ext import ContextTypes, ConversationHandler from app.database import AsyncSessionLocal from app.database.repository import ( GroupRepository, MessageRepository, MessageGroupRepository ) from app.utils.keyboards import ( get_back_keyboard, get_main_keyboard, CallbackType ) import logging logger = logging.getLogger(__name__) # Состояния для ConversationHandler CREATE_MSG_TITLE = 1 CREATE_MSG_TEXT = 2 SELECT_GROUPS = 3 WAITING_GROUP_INPUT = 4 async def create_message_start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: """Начало создания нового сообщения""" query = update.callback_query await query.answer() text = "📝 Введите название сообщения (короткое описание):" await query.edit_message_text(text) return CREATE_MSG_TITLE async def create_message_title(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: """Получаем название и просим текст""" message = update.message title = message.text.strip() if len(title) > 100: await message.reply_text("❌ Название слишком длинное (макс 100 символов)") return CREATE_MSG_TITLE context.user_data['message_title'] = title text = """✏️ Теперь введите текст сообщения. Вы можете использовать HTML форматирование: жирный курсив подчеркивание код Введите /cancel для отмены""" await message.reply_text(text, parse_mode='HTML') return CREATE_MSG_TEXT async def create_message_text(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: """Получаем текст и показываем выбор групп""" message = update.message if message.text == '/cancel': await message.reply_text("❌ Отменено", reply_markup=get_main_keyboard()) return ConversationHandler.END text = message.text.strip() if len(text) > 4096: await message.reply_text("❌ Текст слишком длинный (макс 4096 символов)") return CREATE_MSG_TEXT context.user_data['message_text'] = text # Сохраняем сообщение в БД async with AsyncSessionLocal() as session: msg_repo = MessageRepository(session) msg = await msg_repo.add_message( text=text, title=context.user_data['message_title'] ) context.user_data['message_id'] = msg.id # Теперь показываем список групп для выбора async with AsyncSessionLocal() as session: group_repo = GroupRepository(session) groups = await group_repo.get_all_active_groups() if not groups: await message.reply_text( "❌ Нет активных групп. Сначала добавьте бота в группы.", reply_markup=get_main_keyboard() ) return ConversationHandler.END # Создаем клавиатуру с группами keyboard = [] for group in groups: callback = f"select_group_{group.id}" keyboard.append([InlineKeyboardButton( f"✅ {group.title} (delay: {group.slow_mode_delay}s)", callback_data=callback )]) keyboard.append([InlineKeyboardButton("✔️ Готово", callback_data="done_groups")]) keyboard.append([InlineKeyboardButton("❌ Отмена", callback_data=f"{CallbackType.MAIN_MENU}")]) text = f"""✅ Сообщение создано: {context.user_data['message_title']} Выберите группы для отправки (нажмите на каждую):""" await message.reply_text( text, parse_mode='HTML', reply_markup=InlineKeyboardMarkup(keyboard) ) context.user_data['selected_groups'] = [] return SELECT_GROUPS async def select_groups(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: """Выбор групп для отправки""" query = update.callback_query callback_data = query.data if callback_data == "done_groups": # Подтверждаем выбор selected = context.user_data.get('selected_groups', []) if not selected: await query.answer("❌ Выберите хотя бы одну группу", show_alert=True) return SELECT_GROUPS # Добавляем сообщение в выбранные группы message_id = context.user_data['message_id'] async with AsyncSessionLocal() as session: mg_repo = MessageGroupRepository(session) for group_id in selected: await mg_repo.add_message_to_group(message_id, group_id) text = f"""✅ Сообщение готово! Название: {context.user_data['message_title']} Групп выбрано: {len(selected)} Теперь вы можете отправить сообщение нажав кнопку "Отправить" в списке сообщений.""" await query.edit_message_text(text, parse_mode='HTML', reply_markup=get_main_keyboard()) return ConversationHandler.END elif callback_data.startswith("select_group_"): group_id = int(callback_data.split("_")[2]) selected = context.user_data.get('selected_groups', []) if group_id in selected: selected.remove(group_id) else: selected.append(group_id) context.user_data['selected_groups'] = selected # Обновляем клавиатуру async with AsyncSessionLocal() as session: group_repo = GroupRepository(session) groups = await group_repo.get_all_active_groups() keyboard = [] for group in groups: callback = f"select_group_{group.id}" is_selected = group.id in selected prefix = "✅" if is_selected else "☐" keyboard.append([InlineKeyboardButton( f"{prefix} {group.title} (delay: {group.slow_mode_delay}s)", callback_data=callback )]) keyboard.append([InlineKeyboardButton("✔️ Готово", callback_data="done_groups")]) keyboard.append([InlineKeyboardButton("❌ Отмена", callback_data=f"{CallbackType.MAIN_MENU}")]) await query.edit_message_text( f"Выбрано групп: {len(selected)}", reply_markup=InlineKeyboardMarkup(keyboard) ) await query.answer() return SELECT_GROUPS elif callback_data == CallbackType.MAIN_MENU: # Отмена await query.answer() await query.edit_message_text( "❌ Создание сообщения отменено", reply_markup=get_main_keyboard() ) return ConversationHandler.END await query.answer() return SELECT_GROUPS