from uuid import uuid4 from aiogram import Bot, F, Router from aiogram.types import CallbackQuery, Message from aiogram.utils.deep_linking import create_start_link from bot.factories import SettingsAction, SettingsCallback from bot.filters import ChannelOwnerFilter from bot.keyboards import channel_settings_kb, invite_mode_kb, members_kb from utils.db.models import Channel, Invite router = Router() def settings_text(channel: Channel) -> str: return f"⚙️ {channel.title}" def members_text(channel: Channel) -> str: return f"👥 {channel.title}" async def refresh_channel(channel: Channel) -> Channel: return await Channel.get_by_id(channel.id) or channel @router.callback_query( SettingsCallback.filter(F.action == SettingsAction.MAIN), ChannelOwnerFilter() ) async def show_settings(callback: CallbackQuery, channel: Channel): if not isinstance(callback.message, Message): return await callback.message.edit_text( settings_text(channel), reply_markup=channel_settings_kb(channel) ) await callback.answer() @router.callback_query( SettingsCallback.filter(F.action == SettingsAction.MEMBERS), ChannelOwnerFilter() ) @router.callback_query( SettingsCallback.filter(F.action == SettingsAction.PAGE), ChannelOwnerFilter() ) async def show_members( callback: CallbackQuery, callback_data: SettingsCallback, channel: Channel ): if not isinstance(callback.message, Message): return if not channel.members: await callback.answer("Нет участников.", show_alert=True) return await callback.message.edit_text( members_text(channel), reply_markup=members_kb(channel, callback_data.page) ) await callback.answer() @router.callback_query( SettingsCallback.filter(F.action == SettingsAction.MODE_TOGGLE), ChannelOwnerFilter(), ) async def toggle_member_mode( callback: CallbackQuery, callback_data: SettingsCallback, channel: Channel ): if not isinstance(callback.message, Message): return member = channel.get_member(callback_data.user_id) if member is None: await callback.answer("Участник не найден.", show_alert=True) return next_mode = "approval" if member.mode == "instant" else "instant" await channel.set_member_mode(callback_data.user_id, next_mode) refreshed = await refresh_channel(channel) await callback.message.edit_reply_markup( reply_markup=members_kb(refreshed, callback_data.page) ) await callback.answer() @router.callback_query( SettingsCallback.filter(F.action == SettingsAction.KICK), ChannelOwnerFilter() ) async def kick_member( callback: CallbackQuery, callback_data: SettingsCallback, channel: Channel ): if not isinstance(callback.message, Message): return await channel.remove_member(callback_data.user_id) refreshed = await refresh_channel(channel) if refreshed.members: await callback.message.edit_reply_markup( reply_markup=members_kb(refreshed, callback_data.page) ) else: await callback.message.edit_text( settings_text(refreshed), reply_markup=channel_settings_kb(refreshed) ) await callback.answer() @router.callback_query( SettingsCallback.filter(F.action == SettingsAction.INVITE_MODE), ChannelOwnerFilter(), ) async def show_invite_modes(callback: CallbackQuery, channel: Channel): if not isinstance(callback.message, Message): return await callback.message.edit_text( f"🔗 Режим для нового участника {channel.title}:", reply_markup=invite_mode_kb(channel.id), ) await callback.answer() @router.callback_query( SettingsCallback.filter(F.action == SettingsAction.INVITE_CREATE), ChannelOwnerFilter(), ) async def create_invite( callback: CallbackQuery, callback_data: SettingsCallback, channel: Channel, bot: Bot ): if not isinstance(callback.message, Message): return if callback_data.mode == "approval": mode = "approval" elif callback_data.mode == "instant": mode = "instant" else: await callback.answer("Неверный режим.", show_alert=True) return invite = Invite(code=uuid4().hex[:12], channel_id=channel.id, mode=mode) await invite.insert() link = await create_start_link(bot, f"inv_{invite.code}", encode=True) mode_label = "сразу" if mode == "instant" else "после проверки" await callback.message.edit_text( f"🔗 Инвайт для {channel.title} (режим: {mode_label}):\n\n" f"{link}", reply_markup=channel_settings_kb(channel), ) await callback.answer()