Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add ChatType builtin filter #356

Merged
merged 14 commits into from
Jul 2, 2020
10 changes: 8 additions & 2 deletions aiogram/dispatcher/dispatcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@
from aiogram.utils.deprecated import renamed_argument
from .filters import Command, ContentTypeFilter, ExceptionsFilter, FiltersFactory, HashTag, Regexp, \
RegexpCommandsFilter, StateFilter, Text, IDFilter, AdminFilter, IsReplyFilter, ForwardedMessageFilter, \
AbstractFilter
from .filters.builtin import IsSenderContact
IsSenderContact, ChatTypeFilter, AbstractFilter
from .handler import Handler
from .middlewares import MiddlewareManager
from .storage import BaseStorage, DELTA, DisabledStorage, EXCEEDED_COUNT, FSMContext, \
Expand Down Expand Up @@ -167,6 +166,13 @@ def _setup_filters(self):
self.channel_post_handlers,
self.edited_channel_post_handlers
])
filters_factory.bind(ChatTypeFilter, event_handlers=[
self.message_handlers,
self.edited_message_handlers,
self.channel_post_handlers,
self.edited_channel_post_handlers,
self.callback_query_handlers,
])

def __del__(self):
self.stop_polling()
Expand Down
4 changes: 3 additions & 1 deletion aiogram/dispatcher/filters/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from .builtin import Command, CommandHelp, CommandPrivacy, CommandSettings, CommandStart, ContentTypeFilter, \
ExceptionsFilter, HashTag, Regexp, RegexpCommandsFilter, StateFilter, \
Text, IDFilter, AdminFilter, IsReplyFilter, IsSenderContact, ForwardedMessageFilter
Text, IDFilter, AdminFilter, IsReplyFilter, IsSenderContact, ForwardedMessageFilter, \
ChatTypeFilter
from .factory import FiltersFactory
from .filters import AbstractFilter, BoundFilter, Filter, FilterNotPassed, FilterRecord, execute_filter, \
check_filters, get_filter_spec, get_filters_spec
Expand Down Expand Up @@ -33,4 +34,5 @@
'execute_filter',
'check_filters',
'ForwardedMessageFilter',
'ChatTypeFilter',
]
25 changes: 23 additions & 2 deletions aiogram/dispatcher/filters/builtin.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import inspect
import re
import typing
import warnings
from contextvars import ContextVar
from dataclasses import dataclass, field
from typing import Any, Dict, Iterable, Optional, Union
Expand All @@ -9,8 +10,7 @@

from aiogram import types
from aiogram.dispatcher.filters.filters import BoundFilter, Filter
from aiogram.types import CallbackQuery, Message, InlineQuery, Poll, ChatType

from aiogram.types import CallbackQuery, ChatType, InlineQuery, Message, Poll

ChatIDArgumentType = typing.Union[typing.Iterable[typing.Union[int, str]], str, int]

Expand Down Expand Up @@ -691,3 +691,24 @@ def __init__(self, is_forwarded: bool):

async def check(self, message: Message):
return bool(getattr(message, "forward_date")) is self.is_forwarded


class ChatTypeFilter(BoundFilter):
key = 'chat_type'

def __init__(self, chat_type: typing.Container[ChatType]):
if isinstance(chat_type, str):
chat_type = {chat_type}

self.chat_type: typing.Set[str] = set(chat_type)

async def check(self, obj: Union[Message, CallbackQuery]):
if isinstance(obj, Message):
obj = obj.chat
elif isinstance(obj, CallbackQuery):
obj = obj.message.chat
else:
warnings.warn("ChatTypeFilter doesn't support %s as input", type(obj))
return False

return obj.type in self.chat_type
6 changes: 6 additions & 0 deletions aiogram/types/chat.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from .chat_permissions import ChatPermissions
from .chat_photo import ChatPhoto
from .input_file import InputFile
from ..utils.deprecated import deprecated


class Chat(base.TelegramObject):
Expand Down Expand Up @@ -512,6 +513,7 @@ def _check(obj, chat_types) -> bool:
return obj.type in chat_types

@classmethod
@deprecated("This filter was moved to ChatTypeFilter, and will be removed in aiogram v3.0")
Birdi7 marked this conversation as resolved.
Show resolved Hide resolved
def is_private(cls, obj) -> bool:
"""
Check chat is private
Expand All @@ -522,6 +524,7 @@ def is_private(cls, obj) -> bool:
return cls._check(obj, [cls.PRIVATE])

@classmethod
@deprecated("This filter was moved to ChatTypeFilter, and will be removed in aiogram v3.0")
def is_group(cls, obj) -> bool:
"""
Check chat is group
Expand All @@ -532,6 +535,7 @@ def is_group(cls, obj) -> bool:
return cls._check(obj, [cls.GROUP])

@classmethod
@deprecated("This filter was moved to ChatTypeFilter, and will be removed in aiogram v3.0")
def is_super_group(cls, obj) -> bool:
"""
Check chat is super-group
Expand All @@ -542,6 +546,7 @@ def is_super_group(cls, obj) -> bool:
return cls._check(obj, [cls.SUPER_GROUP])

@classmethod
@deprecated("This filter was moved to ChatTypeFilter, and will be removed in aiogram v3.0")
def is_group_or_super_group(cls, obj) -> bool:
"""
Check chat is group or super-group
Expand All @@ -552,6 +557,7 @@ def is_group_or_super_group(cls, obj) -> bool:
return cls._check(obj, [cls.GROUP, cls.SUPER_GROUP])

@classmethod
@deprecated("This filter was moved to ChatTypeFilter, and will be removed in aiogram v3.0")
def is_channel(cls, obj) -> bool:
"""
Check chat is channel
Expand Down
8 changes: 8 additions & 0 deletions docs/source/dispatcher/filters.rst
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,14 @@ ForwardedMessageFilter
:show-inheritance:


ChatTypeFilter
-------------

.. autoclass:: aiogram.dispatcher.filters.filters.ChatTypeFilter
:members:
:show-inheritance:


Making own filters (Custom filters)
===================================

Expand Down
42 changes: 42 additions & 0 deletions examples/chat_type_filter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
"""
This is an example with usage of ChatTypeFilter
It filters incoming object based on type of its chat type
"""

import logging

from aiogram import Bot, Dispatcher, executor, types
from aiogram.dispatcher.handler import SkipHandler
from aiogram.types import ChatType

API_TOKEN = 'BOT TOKEN HERE'

# Configure logging
logging.basicConfig(level=logging.INFO)

# Initialize bot and dispatcher
bot = Bot(token=API_TOKEN)
dp = Dispatcher(bot)


@dp.message_handler(chat_type=[ChatType.PRIVATE, ChatType.CHANNEL])
async def send_welcome(message: types.Message):
"""
This handler will be called when user sends `/start` or `/help` command
"""
await message.reply("Hi!\nI'm hearing your messages in private chats and channels")

# propagate message to the next handler
raise SkipHandler


@dp.message_handler(chat_type=ChatType.PRIVATE)
async def send_welcome(message: types.Message):
"""
This handler will be called when user sends `/start` or `/help` command
"""
await message.reply("Hi!\nI'm hearing your messages only in private chats")


if __name__ == '__main__':
executor.start_polling(dp, skip_updates=True)