First commit
This commit is contained in:
108
bot/middlewares/ban_user_mdw.py
Normal file
108
bot/middlewares/ban_user_mdw.py
Normal file
@@ -0,0 +1,108 @@
|
||||
from typing import Callable, Awaitable, Any, Dict
|
||||
|
||||
from aiogram import BaseMiddleware
|
||||
from aiogram.types import Message, CallbackQuery, TelegramObject
|
||||
|
||||
from database import db
|
||||
|
||||
__all__ = ("BanCheckMiddleware",)
|
||||
|
||||
class BanCheckMiddleware(BaseMiddleware):
|
||||
"""
|
||||
Middleware для проверки забанен ли пользователь.
|
||||
Если пользователь забанен в боте - блокирует все его действия.
|
||||
"""
|
||||
|
||||
async def __call__(
|
||||
self,
|
||||
handler: Callable[[TelegramObject, Dict[str, Any]], Awaitable[Any]],
|
||||
event: TelegramObject,
|
||||
data: Dict[str, Any]
|
||||
) -> Any:
|
||||
"""
|
||||
Проверяет каждый входящий запрос на наличие пользователя в черном списке.
|
||||
|
||||
Args:
|
||||
handler: Следующий обработчик
|
||||
event: Событие (сообщение, callback и т.д.)
|
||||
data: Данные контекста
|
||||
|
||||
Returns:
|
||||
Результат обработчика или None если пользователь забанен
|
||||
"""
|
||||
# Извлекаем информацию о пользователе из события
|
||||
user = await self._extract_user(event)
|
||||
|
||||
if user is None:
|
||||
# Не смогли определить пользователя - пропускаем
|
||||
return await handler(event, data)
|
||||
|
||||
# Проверяем в базе данных статус пользователя
|
||||
user_db = await db.get_user(user.id)
|
||||
|
||||
if user_db and user_db.status == "banned":
|
||||
# Пользователь забанен - блокируем запрос
|
||||
await self._send_ban_message(event, data)
|
||||
return None
|
||||
|
||||
# Пользователь не забанен - пропускаем запрос дальше
|
||||
return await handler(event, data)
|
||||
|
||||
@staticmethod
|
||||
async def _extract_user(event: TelegramObject) -> Any:
|
||||
"""
|
||||
Извлекает пользователя из разных типов событий.
|
||||
|
||||
Args:
|
||||
event: Событие Telegram
|
||||
|
||||
Returns:
|
||||
Объект пользователя или None
|
||||
"""
|
||||
if isinstance(event, Message):
|
||||
return event.from_user
|
||||
elif isinstance(event, CallbackQuery):
|
||||
return event.from_user
|
||||
# Можно добавить другие типы событий при необходимости
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
async def _send_ban_message(event: TelegramObject, data: Dict[str, Any]) -> None:
|
||||
"""
|
||||
Отправляет сообщение о бане пользователю.
|
||||
|
||||
Args:
|
||||
event: Событие которое triggered проверку
|
||||
data: Данные контекста с ботом
|
||||
"""
|
||||
bot = data.get('bot')
|
||||
|
||||
if not bot:
|
||||
return
|
||||
|
||||
chat_id = None
|
||||
message_id = None
|
||||
|
||||
# Определяем куда отправлять сообщение в зависимости от типа события
|
||||
if isinstance(event, Message):
|
||||
chat_id = event.chat.id
|
||||
message_id = event.message_id
|
||||
elif isinstance(event, CallbackQuery) and event.message:
|
||||
chat_id = event.message.chat.id
|
||||
message_id = event.message.message_id
|
||||
|
||||
if chat_id:
|
||||
try:
|
||||
if isinstance(event, CallbackQuery):
|
||||
# Для callback запросов отвечаем уведомлением
|
||||
await event.answer("🚫 Вы заблокированы в боте!", show_alert=True)
|
||||
else:
|
||||
# Для сообщений отправляем новое сообщение
|
||||
await bot.send_message(
|
||||
chat_id=chat_id,
|
||||
text="🚫 Вы заблокированы в боте!",
|
||||
reply_to_message_id=message_id
|
||||
)
|
||||
except Exception:
|
||||
# Игнорируем ошибки отправки (пользователь мог заблокировать бота)
|
||||
pass
|
||||
Reference in New Issue
Block a user