Первый коммит
This commit is contained in:
5
bot/filters/__init__.py
Normal file
5
bot/filters/__init__.py
Normal file
@@ -0,0 +1,5 @@
|
||||
from .callback import *
|
||||
from .chat_rights import *
|
||||
from .chat_type import *
|
||||
from .message_content import *
|
||||
from .subscrided import *
|
||||
21
bot/filters/callback.py
Normal file
21
bot/filters/callback.py
Normal file
@@ -0,0 +1,21 @@
|
||||
from aiogram.filters import BaseFilter
|
||||
from aiogram.types import CallbackQuery
|
||||
|
||||
# Настройка экспорта
|
||||
__all__ = ("CallbackDataStartsWith",)
|
||||
|
||||
|
||||
class CallbackDataStartsWith(BaseFilter):
|
||||
"""
|
||||
Фильтр для callback_data, начинающихся с префикса.
|
||||
|
||||
Example:
|
||||
@router.callback_query(CallbackDataStartsWith("menu:"))
|
||||
async def handler(cb: CallbackQuery):
|
||||
await cb.answer("Это callback из меню ✅")
|
||||
"""
|
||||
def __init__(self, prefix: str) -> None:
|
||||
self.prefix = prefix
|
||||
|
||||
async def __call__(self, callback: CallbackQuery) -> bool:
|
||||
return bool(callback.data and callback.data.startswith(self.prefix))
|
||||
73
bot/filters/chat_rights.py
Normal file
73
bot/filters/chat_rights.py
Normal file
@@ -0,0 +1,73 @@
|
||||
from aiogram import Bot
|
||||
from aiogram.filters import BaseFilter
|
||||
from aiogram.types import Message, ResultChatMemberUnion
|
||||
from aiogram.exceptions import TelegramBadRequest, TelegramForbiddenError
|
||||
|
||||
# Настройка экспорта
|
||||
__all__ = ("IsChatCreator", "IsAdmin", "IsModerator",)
|
||||
|
||||
|
||||
class IsChatCreator(BaseFilter):
|
||||
"""
|
||||
Пользователь является создателем чата.
|
||||
|
||||
Example:
|
||||
@router.message(IsChatCreator())
|
||||
async def handler(msg: Message):
|
||||
await msg.answer("Ты создатель этого чата 👑")
|
||||
"""
|
||||
async def __call__(self, message: Message, bot: Bot) -> bool:
|
||||
try:
|
||||
member: ResultChatMemberUnion = await bot.get_chat_member(message.chat.id, message.from_user.id)
|
||||
return member.status == "creator"
|
||||
except (TelegramBadRequest, TelegramForbiddenError):
|
||||
return False
|
||||
|
||||
|
||||
class IsAdmin(BaseFilter):
|
||||
"""
|
||||
Пользователь является администратором (или создателем).
|
||||
|
||||
Example:
|
||||
@router.message(IsAdmin())
|
||||
async def handler(msg: Message):
|
||||
await msg.answer("Ты админ ✅")
|
||||
"""
|
||||
async def __call__(self, message: Message, bot: Bot) -> bool:
|
||||
try:
|
||||
member: ResultChatMemberUnion = await bot.get_chat_member(message.chat.id, message.from_user.id)
|
||||
return member.status in {"administrator", "creator"}
|
||||
except (TelegramBadRequest, TelegramForbiddenError):
|
||||
return False
|
||||
|
||||
|
||||
class IsModerator(BaseFilter):
|
||||
"""
|
||||
Администратор с модераторскими правами:
|
||||
- удаление сообщений
|
||||
- ограничение пользователей
|
||||
- закрепление сообщений
|
||||
|
||||
Example:
|
||||
@router.message(IsModerator())
|
||||
async def handler(msg: Message):
|
||||
await msg.answer("Ты модератор ✅")
|
||||
"""
|
||||
async def __call__(self, message: Message, bot: Bot) -> bool:
|
||||
try:
|
||||
member: ResultChatMemberUnion = await bot.get_chat_member(message.chat.id, message.from_user.id)
|
||||
|
||||
if member.status == "creator":
|
||||
return True
|
||||
if member.status != "administrator":
|
||||
return False
|
||||
|
||||
required_rights: list[bool] = [
|
||||
getattr(member, "can_delete_messages", False),
|
||||
getattr(member, "can_restrict_members", False),
|
||||
getattr(member, "can_pin_messages", False),
|
||||
]
|
||||
return all(required_rights)
|
||||
|
||||
except (TelegramBadRequest, TelegramForbiddenError):
|
||||
return False
|
||||
31
bot/filters/chat_type.py
Normal file
31
bot/filters/chat_type.py
Normal file
@@ -0,0 +1,31 @@
|
||||
from aiogram.filters import BaseFilter
|
||||
from aiogram.types import Message
|
||||
|
||||
# Настройка экспорта
|
||||
__all__ = ("IsPrivate", "IsGroup",)
|
||||
|
||||
|
||||
class IsPrivate(BaseFilter):
|
||||
"""
|
||||
Сообщение в личке с ботом.
|
||||
|
||||
Example:
|
||||
@router.message(IsPrivate())
|
||||
async def handler(msg: Message):
|
||||
await msg.answer("Это ЛС ✅")
|
||||
"""
|
||||
async def __call__(self, message: Message) -> bool:
|
||||
return message.chat.type == "private"
|
||||
|
||||
|
||||
class IsGroup(BaseFilter):
|
||||
"""
|
||||
Сообщение в группе или супергруппе.
|
||||
|
||||
Example:
|
||||
@router.message(IsGroup())
|
||||
async def handler(msg: Message):
|
||||
await msg.answer("Это сообщение в группе ✅")
|
||||
"""
|
||||
async def __call__(self, message: Message) -> bool:
|
||||
return message.chat.type in {"group", "supergroup"}
|
||||
67
bot/filters/message_content.py
Normal file
67
bot/filters/message_content.py
Normal file
@@ -0,0 +1,67 @@
|
||||
from aiogram.filters import BaseFilter
|
||||
from aiogram.types import Message
|
||||
|
||||
# Настройка экспорта
|
||||
__all__ = ("IsReply", "IsForwarded", "HasMedia", "ContainsURL",)
|
||||
|
||||
|
||||
class IsReply(BaseFilter):
|
||||
"""
|
||||
Сообщение является ответом.
|
||||
|
||||
Example:
|
||||
@router.message(IsReply())
|
||||
async def handler(msg: Message):
|
||||
await msg.answer("Это реплай ✅")
|
||||
"""
|
||||
async def __call__(self, message: Message) -> bool:
|
||||
return message.reply_to_message is not None
|
||||
|
||||
|
||||
class IsForwarded(BaseFilter):
|
||||
"""
|
||||
Сообщение переслано из другого чата/от пользователя.
|
||||
|
||||
Example:
|
||||
@router.message(IsForwarded())
|
||||
async def handler(msg: Message):
|
||||
await msg.answer("Это пересланное сообщение 🔄")
|
||||
"""
|
||||
async def __call__(self, message: Message) -> bool:
|
||||
return (message.forward_from is not None) or (message.forward_from_chat is not None)
|
||||
|
||||
|
||||
class HasMedia(BaseFilter):
|
||||
"""
|
||||
Сообщение содержит медиа (фото, видео, документ и т.д.).
|
||||
|
||||
Example:
|
||||
@router.message(HasMedia())
|
||||
async def handler(msg: Message):
|
||||
await msg.answer("Это медиа ✅")
|
||||
"""
|
||||
async def __call__(self, message: Message) -> bool:
|
||||
return any([
|
||||
message.photo,
|
||||
message.video,
|
||||
message.document,
|
||||
message.audio,
|
||||
message.voice,
|
||||
message.video_note,
|
||||
message.sticker,
|
||||
])
|
||||
|
||||
|
||||
class ContainsURL(BaseFilter):
|
||||
"""
|
||||
Сообщение содержит ссылку (http/https).
|
||||
|
||||
Example:
|
||||
@router.message(ContainsURL())
|
||||
async def handler(msg: Message):
|
||||
await msg.answer("Это сообщение с ссылкой 🔗")
|
||||
"""
|
||||
async def __call__(self, message: Message) -> bool:
|
||||
if not message.text:
|
||||
return False
|
||||
return "http://" in message.text or "https://" in message.text
|
||||
39
bot/filters/subscrided.py
Normal file
39
bot/filters/subscrided.py
Normal file
@@ -0,0 +1,39 @@
|
||||
from aiogram.types import Message, ResultChatMemberUnion
|
||||
from aiogram.filters import BaseFilter
|
||||
from aiogram import Bot
|
||||
from aiogram.exceptions import TelegramBadRequest, TelegramForbiddenError
|
||||
from typing import Union
|
||||
|
||||
# Настройки экспорта
|
||||
__all__ = ("FilterSubscribed",)
|
||||
|
||||
|
||||
class FilterSubscribed(BaseFilter):
|
||||
"""
|
||||
Фильтр для проверки подписки пользователя на один или несколько каналов.
|
||||
Поддерживает как публичные каналы (username), так и приватные (ID).
|
||||
|
||||
Пример:
|
||||
# Проверка сразу двух каналов: публичный по username и приватный по ID
|
||||
@router.message(FilterSubscribed(["@public_channel", -1001234567890]))
|
||||
async def only_subscribed(message: Message):
|
||||
await message.answer("Ты подписан и на публичный, и на приватный канал ✅")
|
||||
"""
|
||||
def __init__(self, channels: list[Union[str, int]]) -> None:
|
||||
self.channels = channels
|
||||
|
||||
async def __call__(self, message: Message, bot: Bot) -> bool:
|
||||
for channel in self.channels:
|
||||
try:
|
||||
member: ResultChatMemberUnion = await bot.get_chat_member(
|
||||
chat_id=channel,
|
||||
user_id=message.from_user.id
|
||||
)
|
||||
if member.status in ("left", "kicked"):
|
||||
return False
|
||||
|
||||
except (TelegramBadRequest, TelegramForbiddenError):
|
||||
# Канал недоступен, либо у бота нет прав
|
||||
return False
|
||||
|
||||
return True
|
||||
Reference in New Issue
Block a user