127 lines
4.5 KiB
Python
127 lines
4.5 KiB
Python
from aiogram import Dispatcher, F
|
|
from aiogram.enums import ChatType
|
|
from aiogram.filters import Command, CommandObject
|
|
from aiogram.types import Message
|
|
|
|
from pymax.types.domain.enums import ChatType as MaxChatType
|
|
|
|
from app.config import Settings
|
|
from app.max_layer.client_holder import MaxClientHolder
|
|
from app.max_layer.formatter import resolve_sender_name
|
|
from app.storage.protocols import StoragePort
|
|
|
|
|
|
def register_admin_handlers(
|
|
dp: Dispatcher,
|
|
settings: Settings,
|
|
storage: StoragePort,
|
|
max_holder: MaxClientHolder,
|
|
) -> None:
|
|
fallback = (
|
|
F.chat.type == ChatType.PRIVATE,
|
|
F.from_user.id == settings.fallback_user_id,
|
|
)
|
|
|
|
@dp.message(Command("start"), *fallback)
|
|
async def cmd_start(message: Message) -> None:
|
|
connected = max_holder.ready.is_set()
|
|
status = "подключён" if connected else "ожидание подключения"
|
|
await message.answer(
|
|
"max2telegram bridge\n\n"
|
|
f"Статус MAX: {status}\n\n"
|
|
"Команды: /help, /list, /join, /leave, /last_messages"
|
|
)
|
|
|
|
@dp.message(Command("help"), *fallback)
|
|
async def cmd_help(message: Message) -> None:
|
|
await message.answer(
|
|
"/start — статус\n"
|
|
"/help — справка\n"
|
|
"/list — активные маппинги\n"
|
|
"/join <ссылка> — вступить в MAX-группу\n"
|
|
"/leave <id или название> — выйти из MAX-чата\n"
|
|
"/last_messages <id или название> — последние 10 сообщений"
|
|
)
|
|
|
|
@dp.message(Command("list"), *fallback)
|
|
async def cmd_list(message: Message) -> None:
|
|
mappings = await storage.list_mappings()
|
|
if not mappings:
|
|
await message.answer("Маппинги не найдены.")
|
|
return
|
|
lines = [
|
|
f"• {m.display_name}\n MAX: {m.max_chat_id} → TG thread: {m.tg_thread_id}"
|
|
for m in mappings
|
|
]
|
|
await message.answer("Активные маппинги:\n\n" + "\n".join(lines))
|
|
|
|
@dp.message(Command("join"), *fallback)
|
|
async def cmd_join(message: Message, command: CommandObject) -> None:
|
|
if not command.args:
|
|
await message.answer("Использование: /join <ссылка>")
|
|
return
|
|
client = await max_holder.wait_client()
|
|
try:
|
|
chat = await client.join_group(command.args.strip())
|
|
await message.answer(f"Вступили в «{chat.title}» (id={chat.id})")
|
|
except Exception as exc:
|
|
await message.answer(f"Ошибка: {exc}")
|
|
|
|
@dp.message(Command("leave"), *fallback)
|
|
async def cmd_leave(message: Message, command: CommandObject) -> None:
|
|
if not command.args:
|
|
await message.answer("Использование: /leave <id или название>")
|
|
return
|
|
client = await max_holder.wait_client()
|
|
target = command.args.strip()
|
|
chat = await _resolve_chat(client, target)
|
|
if chat is None:
|
|
await message.answer("Чат не найден.")
|
|
return
|
|
if chat.type == MaxChatType.CHANNEL:
|
|
await client.leave_channel(chat.id)
|
|
else:
|
|
await client.leave_group(chat.id)
|
|
await message.answer(f"Вышли из «{chat.title}» (id={chat.id})")
|
|
|
|
@dp.message(Command("last_messages"), *fallback)
|
|
async def cmd_last_messages(message: Message, command: CommandObject) -> None:
|
|
if not command.args:
|
|
await message.answer("Использование: /last_messages <id или название>")
|
|
return
|
|
client = await max_holder.wait_client()
|
|
target = command.args.strip()
|
|
chat = await _resolve_chat(client, target)
|
|
if chat is None:
|
|
await message.answer("Чат не найден.")
|
|
return
|
|
history = await client.fetch_history(chat_id=chat.id, backward=10)
|
|
if not history:
|
|
await message.answer("Сообщений нет.")
|
|
return
|
|
lines = []
|
|
for msg in reversed(history):
|
|
sender = f"User {msg.sender}" if msg.sender else "?"
|
|
if msg.sender:
|
|
try:
|
|
user = await client.get_user(msg.sender)
|
|
sender = resolve_sender_name(user)
|
|
except Exception:
|
|
pass
|
|
text = (msg.text or "")[:200]
|
|
lines.append(f"[{msg.id}] {sender}: {text}")
|
|
await message.answer("\n".join(lines) or "Пусто.")
|
|
|
|
|
|
async def _resolve_chat(client, target: str):
|
|
if target.isdigit():
|
|
try:
|
|
return await client.get_chat(int(target))
|
|
except Exception:
|
|
return None
|
|
if client.chats:
|
|
for chat in client.chats:
|
|
if chat.title and target.lower() in chat.title.lower():
|
|
return chat
|
|
return None
|