типо да

This commit is contained in:
admin
2025-09-08 00:40:18 +07:00
commit 0f05fc8455
83 changed files with 5775 additions and 0 deletions

5
bot/filters/__init__.py Normal file
View 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
View 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))

View 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
View 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"}

View 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
View 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