from typing import Dict, Tuple from aiogram import Router, F from aiogram.filters import Command from aiogram.types import Message, CallbackQuery, InlineKeyboardButton, InlineKeyboardMarkup from aiogram.fsm.context import FSMContext from bot.utils import status_clear # ------------------- # Router # ------------------- router: Router = Router(name="anon_router") # ------------------- # Конфигурация # ------------------- # CHAT_ID в формате "-100000_29" -> chat_id + thread_id CHAT_ID: str = "-1003098225669_724" def parse_chat_id(chat_id_str: str) -> Tuple[int, int]: chat_str, thread_str = chat_id_str.split("_") return int(chat_str), int(thread_str) ADMIN_CHAT_ID, ADMIN_THREAD_ID = parse_chat_id(CHAT_ID) # ------------------- # FSM состояния # ------------------- class AnonStates: USER_WAITING_TEXT = "user_waiting_text" ADMIN_WAITING_REPLY = "admin_waiting_reply" # ------------------- # Словари для отслеживания сообщений # ------------------- # user_id -> message_id в админском топике user_to_admin_map: Dict[int, int] = {} # admin_message_id -> user_id admin_to_user_map: Dict[int, int] = {} # ------------------- # Команда /anon или callback # ------------------- @router.callback_query(F.data.casefold() == "anon") @router.message(Command("anon")) async def anon_start(message: Message | CallbackQuery, state: FSMContext) -> None: """Начало анонимного сообщения. Ждём текст пользователя.""" await status_clear(message=message, state=state) await state.clear() await state.set_state(AnonStates.USER_WAITING_TEXT) text = "Напишите сообщение, которое вы хотите отправить анонимно администраторам." if isinstance(message, Message): await message.reply(text) else: await message.message.answer(text) # ------------------- # Получение текста от пользователя # ------------------- @router.message(F.text, F.state == AnonStates.USER_WAITING_TEXT) async def anon_send_text(message: Message, state: FSMContext) -> None: """Пересылает текст пользователя в админский топик анонимно.""" anon_text = message.text.strip() if not anon_text: await message.reply("Сообщение не может быть пустым. Попробуйте снова.") return forwarded_text = f"Сообщение от [пользователя](tg://user?id={message.from_user.id}):\n{anon_text}" keyboard = InlineKeyboardMarkup( inline_keyboard=[ [InlineKeyboardButton(text="Ответить", callback_data=f"anon_reply:{message.from_user.id}")] ] ) sent_msg = await message.bot.send_message( chat_id=ADMIN_CHAT_ID, message_thread_id=ADMIN_THREAD_ID, text=forwarded_text, parse_mode="Markdown", reply_markup=keyboard ) user_to_admin_map[message.from_user.id] = sent_msg.message_id admin_to_user_map[sent_msg.message_id] = message.from_user.id await message.reply("Ваше сообщение отправлено анонимно администраторам.") await state.clear() # ------------------- # Кнопка "Ответить" админа # ------------------- @router.callback_query(F.data.startswith("anon_reply:")) async def anon_admin_reply(callback: CallbackQuery, state: FSMContext) -> None: """Начинаем сессию ответа админа пользователю.""" user_id = int(callback.data.split(":")[1]) await state.set_state(AnonStates.ADMIN_WAITING_REPLY) await state.update_data(reply_to_user=user_id) await callback.message.answer(f"Введите ответ для пользователя [id={user_id}]:") await callback.answer() # ------------------- # Текст ответа админа # ------------------- @router.message(F.text, F.state == AnonStates.ADMIN_WAITING_REPLY) async def anon_send_admin_text(message: Message, state: FSMContext) -> None: """Пересылает текст админа пользователю.""" data = await state.get_data() reply_to_user = data.get("reply_to_user") if reply_to_user: await message.bot.send_message( chat_id=reply_to_user, text=f"Ответ администратора:\n{message.text}" ) await message.reply("Сообщение отправлено пользователю.") await state.clear()