83 lines
4.2 KiB
Python
83 lines
4.2 KiB
Python
from aiogram import Router, F, Bot
|
||
from aiogram.types import CallbackQuery, Message
|
||
from repos.user_repo import UsersRepo, UserStatus
|
||
from keyboards import get_admin_decision_kb
|
||
|
||
router = Router()
|
||
|
||
|
||
# Чтобы IDE не ругалась, переменные инициализируются в main,
|
||
# но здесь мы ожидаем, что они будут переданы или доступны через DI (workflow_data)
|
||
# В этом примере я буду доставать их из data, переданной диспетчером, или глобально (для простоты примера - глобально в рамках архитектуры aiogram лучше через middleware DI).
|
||
# Для простоты доступа предположим, что repo и admin_id прокинуты.
|
||
|
||
|
||
|
||
@router.callback_query(F.data == "req_access")
|
||
async def user_request_access(callback: CallbackQuery, repo: UsersRepo, bot: Bot, admin_id: int):
|
||
"""Пользователь нажал 'Запросить доступ'"""
|
||
user = callback.from_user
|
||
|
||
# Двойная проверка на 24 часа (на случай если пользователь не обновлял сообщение)
|
||
if not await repo.can_request_access(user.id):
|
||
await callback.answer("⏳ Вы уже отправляли запрос недавно. Повторите через сутки.", show_alert=True)
|
||
return
|
||
|
||
# 1. Записываем в БД статус PENDING
|
||
await repo.create_or_update_request(user)
|
||
|
||
# 2. Уведомляем пользователя
|
||
await callback.message.edit_text("✅ Заявка отправлена администратору. Ожидайте решения.")
|
||
|
||
# 3. Отправляем уведомление Админу
|
||
# Формируем красивый текст
|
||
info = (
|
||
f"🔔 <b>Новый запрос доступа!</b>\n"
|
||
f"👤 Имя: {user.full_name}\n"
|
||
f"🆔 ID: <code>{user.id}</code>\n"
|
||
f"🔗 Username: @{user.username if user.username else 'нет'}"
|
||
)
|
||
|
||
await bot.send_message(
|
||
chat_id=admin_id,
|
||
text=info,
|
||
reply_markup=get_admin_decision_kb(user.id)
|
||
)
|
||
await callback.answer()
|
||
|
||
|
||
@router.callback_query(F.data.startswith("access_"))
|
||
async def admin_decision(callback: CallbackQuery, repo: UsersRepo, bot: Bot):
|
||
"""Админ нажал Разрешить или Запретить"""
|
||
action, user_id_str = callback.data.split("_")[1], callback.data.split("_")[2]
|
||
target_user_id = int(user_id_str)
|
||
|
||
if action == "allow":
|
||
# Обновляем БД
|
||
await repo.set_status(target_user_id, UserStatus.ALLOWED)
|
||
|
||
# Ответ админу
|
||
await callback.message.edit_text(f"✅ Доступ для {target_user_id} <b>РАЗРЕШЕН</b>.")
|
||
|
||
# Уведомление пользователю
|
||
try:
|
||
await bot.send_message(target_user_id, "🎉 <b>Вам предоставлен доступ к боту!</b>\nНажмите /start")
|
||
except:
|
||
await callback.message.answer(
|
||
f"⚠️ Не удалось уведомить пользователя {target_user_id} (он заблокировал бота?)")
|
||
|
||
elif action == "deny":
|
||
# Обновляем БД (статус DENIED, дата запроса остается старой - то есть через сутки он сможет снова попросить)
|
||
# Если хотите, чтобы при отказе таймер 24ч сбрасывался на "сейчас", нужно обновить last_request_date.
|
||
# В текущей реализации repo, мы просто меняем статус. Таймер тикает от момента подачи заявки пользователем.
|
||
|
||
await repo.set_status(target_user_id, UserStatus.DENIED)
|
||
|
||
await callback.message.edit_text(f"🚫 Доступ для {target_user_id} <b>ЗАПРЕЩЕН</b>.")
|
||
|
||
try:
|
||
await bot.send_message(target_user_id, "🚫 Администратор отклонил ваш запрос доступа.")
|
||
except:
|
||
pass
|
||
|
||
await callback.answer() |