mirror of
https://github.com/aiogram/aiogram.git
synced 2026-04-08 16:37:47 +00:00
Bot API 5.1 (#519)
* version update * added ChatMemberUpdated class * added ChatInviteLink class * 2.x version update * update types added * added methods createChatInviteLink, editChatInviteLink, revokeChatInviteLink * Voice Chat types added * added Message fields: voice_chat_started, voice_chat_ended, voice_chat_participants_invited * can_manage_voice_chats added * chat links shortcuts added * bowling dice support * reordered ChatMembers params (no changes) * Added can_manage_chat to the class ChatMember and parameter can_manage_chat to the method promoteChatMember * kick_chat_member refactored + docs update * Added the parameter revoke_messages to the method kickChatMember * updated kick_chat_member shortcut for Chat * Added the type MessageAutoDeleteTimerChanged and the field message_auto_delete_timer_changed to the class Message * feat: add methods to register my_chat_member and chat_member handlers * Updated filters for new event types Co-authored-by: Alex Root Junior <jroot.junior@gmail.com>
This commit is contained in:
parent
75222b8af0
commit
24fb07d3fe
18 changed files with 510 additions and 49 deletions
|
|
@ -43,5 +43,5 @@ __all__ = (
|
|||
'utils',
|
||||
)
|
||||
|
||||
__version__ = '2.11.3'
|
||||
__api_version__ = '5.0'
|
||||
__version__ = '2.12'
|
||||
__api_version__ = '5.1'
|
||||
|
|
|
|||
|
|
@ -189,7 +189,7 @@ class Methods(Helper):
|
|||
"""
|
||||
Helper for Telegram API Methods listed on https://core.telegram.org/bots/api
|
||||
|
||||
List is updated to Bot API 5.0
|
||||
List is updated to Bot API 5.1
|
||||
"""
|
||||
mode = HelperMode.lowerCamelCase
|
||||
|
||||
|
|
@ -231,6 +231,9 @@ class Methods(Helper):
|
|||
SET_CHAT_ADMINISTRATOR_CUSTOM_TITLE = Item() # setChatAdministratorCustomTitle
|
||||
SET_CHAT_PERMISSIONS = Item() # setChatPermissions
|
||||
EXPORT_CHAT_INVITE_LINK = Item() # exportChatInviteLink
|
||||
CREATE_CHAT_INVITE_LINK = Item() # createChatInviteLink
|
||||
EDIT_CHAT_INVITE_LINK = Item() # editChatInviteLink
|
||||
REVOKE_CHAT_INVITE_LINK = Item() # revokeChatInviteLink
|
||||
SET_CHAT_PHOTO = Item() # setChatPhoto
|
||||
DELETE_CHAT_PHOTO = Item() # deleteChatPhoto
|
||||
SET_CHAT_TITLE = Item() # setChatTitle
|
||||
|
|
|
|||
|
|
@ -1550,28 +1550,43 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin):
|
|||
result = await self.request(api.Methods.GET_FILE, payload)
|
||||
return types.File(**result)
|
||||
|
||||
async def kick_chat_member(self, chat_id: typing.Union[base.Integer, base.String], user_id: base.Integer,
|
||||
until_date: typing.Union[
|
||||
base.Integer, datetime.datetime, datetime.timedelta, None] = None) -> base.Boolean:
|
||||
async def kick_chat_member(self,
|
||||
chat_id: typing.Union[base.Integer, base.String],
|
||||
user_id: base.Integer,
|
||||
until_date: typing.Union[base.Integer, datetime.datetime,
|
||||
datetime.timedelta, None] = None,
|
||||
revoke_messages: typing.Optional[base.Boolean] = None,
|
||||
) -> base.Boolean:
|
||||
"""
|
||||
Use this method to kick a user from a group, a supergroup or a channel.
|
||||
In the case of supergroups and channels, the user will not be able to return to the group
|
||||
on their own using invite links, etc., unless unbanned first.
|
||||
In the case of supergroups and channels, the user will not be able to return
|
||||
to the chat on their own using invite links, etc., unless unbanned first.
|
||||
|
||||
The bot must be an administrator in the chat for this to work and must have the appropriate admin rights.
|
||||
|
||||
Note: In regular groups (non-supergroups), this method will only work if the ‘All Members Are Admins’ setting
|
||||
is off in the target group.
|
||||
Otherwise members may only be removed by the group's creator or by the member that added them.
|
||||
The bot must be an administrator in the chat for this to work and must have
|
||||
the appropriate admin rights.
|
||||
|
||||
Source: https://core.telegram.org/bots/api#kickchatmember
|
||||
|
||||
:param chat_id: Unique identifier for the target group or username of the target supergroup or channel
|
||||
:param chat_id: Unique identifier for the target group or username of the
|
||||
target supergroup or channel (in the format @channelusername)
|
||||
:type chat_id: :obj:`typing.Union[base.Integer, base.String]`
|
||||
|
||||
:param user_id: Unique identifier of the target user
|
||||
:type user_id: :obj:`base.Integer`
|
||||
:param until_date: Date when the user will be unbanned, unix time
|
||||
:type until_date: :obj:`typing.Optional[base.Integer]`
|
||||
|
||||
:param until_date: Date when the user will be unbanned. If user is banned
|
||||
for more than 366 days or less than 30 seconds from the current time they
|
||||
are considered to be banned forever. Applied for supergroups and channels
|
||||
only.
|
||||
:type until_date: :obj:`typing.Union[base.Integer, datetime.datetime,
|
||||
datetime.timedelta, None`
|
||||
|
||||
:param revoke_messages: Pass True to delete all messages from the chat for
|
||||
the user that is being removed. If False, the user will be able to see
|
||||
messages in the group that were sent before the user was removed. Always
|
||||
True for supergroups and channels.
|
||||
:type revoke_messages: :obj:`typing.Optional[base.Boolean]`
|
||||
|
||||
:return: Returns True on success
|
||||
:rtype: :obj:`base.Boolean`
|
||||
"""
|
||||
|
|
@ -1675,10 +1690,12 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin):
|
|||
chat_id: typing.Union[base.Integer, base.String],
|
||||
user_id: base.Integer,
|
||||
is_anonymous: typing.Optional[base.Boolean] = None,
|
||||
can_manage_chat: typing.Optional[base.Boolean] = None,
|
||||
can_change_info: typing.Optional[base.Boolean] = None,
|
||||
can_post_messages: typing.Optional[base.Boolean] = None,
|
||||
can_edit_messages: typing.Optional[base.Boolean] = None,
|
||||
can_delete_messages: typing.Optional[base.Boolean] = None,
|
||||
can_manage_voice_chats: typing.Optional[base.Boolean] = None,
|
||||
can_invite_users: typing.Optional[base.Boolean] = None,
|
||||
can_restrict_members: typing.Optional[base.Boolean] = None,
|
||||
can_pin_messages: typing.Optional[base.Boolean] = None,
|
||||
|
|
@ -1700,6 +1717,11 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin):
|
|||
:param is_anonymous: Pass True, if the administrator's presence in the chat is hidden
|
||||
:type is_anonymous: :obj:`typing.Optional[base.Boolean]`
|
||||
|
||||
:param can_manage_chat: Pass True, if the administrator can access the chat event log, chat statistics,
|
||||
message statistics in channels, see channel members, see anonymous administrators in supergroups
|
||||
and ignore slow mode. Implied by any other administrator privilege
|
||||
:type can_manage_chat: :obj:`typing.Optional[base.Boolean]`
|
||||
|
||||
:param can_change_info: Pass True, if the administrator can change chat title, photo and other settings
|
||||
:type can_change_info: :obj:`typing.Optional[base.Boolean]`
|
||||
|
||||
|
|
@ -1712,6 +1734,9 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin):
|
|||
:param can_delete_messages: Pass True, if the administrator can delete messages of other users
|
||||
:type can_delete_messages: :obj:`typing.Optional[base.Boolean]`
|
||||
|
||||
:param can_manage_voice_chats: Pass True, if the administrator can manage voice chats, supergroups only
|
||||
:type can_manage_voice_chats: :obj:`typing.Optional[base.Boolean]`
|
||||
|
||||
:param can_invite_users: Pass True, if the administrator can invite new users to the chat
|
||||
:type can_invite_users: :obj:`typing.Optional[base.Boolean]`
|
||||
|
||||
|
|
@ -1789,6 +1814,100 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin):
|
|||
result = await self.request(api.Methods.EXPORT_CHAT_INVITE_LINK, payload)
|
||||
return result
|
||||
|
||||
async def create_chat_invite_link(self,
|
||||
chat_id: typing.Union[base.Integer, base.String],
|
||||
expire_date: typing.Union[base.Integer, datetime.datetime,
|
||||
datetime.timedelta, None],
|
||||
member_limit: typing.Optional[base.Integer],
|
||||
) -> types.ChatInviteLink:
|
||||
"""
|
||||
Use this method to create an additional invite link for a chat.
|
||||
The bot must be an administrator in the chat for this to work and must have
|
||||
the appropriate admin rights. The link can be revoked using the method
|
||||
revokeChatInviteLink.
|
||||
|
||||
Source: https://core.telegram.org/bots/api#createchatinvitelink
|
||||
|
||||
:param chat_id: Unique identifier for the target chat or username of the
|
||||
target channel (in the format @channelusername)
|
||||
:type chat_id: :obj:`typing.Union[base.Integer, base.String]`
|
||||
|
||||
:param expire_date: Point in time when the link will expire
|
||||
:type expire_date: :obj:`typing.Union[base.Integer, datetime.datetime,
|
||||
datetime.timedelta, None]`
|
||||
|
||||
:param member_limit: Maximum number of users that can be members of the chat
|
||||
simultaneously after joining the chat via this invite link; 1-99999
|
||||
:type member_limit: :obj:`typing.Optional[base.Integer]`
|
||||
|
||||
:return: the new invite link as ChatInviteLink object.
|
||||
:rtype: :obj:`types.ChatInviteLink`
|
||||
"""
|
||||
expire_date = prepare_arg(expire_date)
|
||||
payload = generate_payload(**locals())
|
||||
|
||||
result = await self.request(api.Methods.CREATE_CHAT_INVITE_LINK, payload)
|
||||
return result
|
||||
|
||||
async def edit_chat_invite_link(self,
|
||||
chat_id: typing.Union[base.Integer, base.String],
|
||||
invite_link: base.String,
|
||||
expire_date: typing.Union[base.Integer, datetime.datetime,
|
||||
datetime.timedelta, None],
|
||||
member_limit: typing.Optional[base.Integer],
|
||||
) -> types.ChatInviteLink:
|
||||
"""
|
||||
Use this method to edit a non-primary invite link created by the bot.
|
||||
The bot must be an administrator in the chat for this to work and must have
|
||||
the appropriate admin rights.
|
||||
|
||||
Source: https://core.telegram.org/bots/api#editchatinvitelink
|
||||
|
||||
:param chat_id: Unique identifier for the target chat or username of the
|
||||
target channel (in the format @channelusername)
|
||||
:type chat_id: :obj:`typing.Union[base.Integer, base.String]`
|
||||
|
||||
:param invite_link: The invite link to edit
|
||||
:type invite_link: :obj:`base.String`
|
||||
|
||||
:param expire_date: Point in time (Unix timestamp) when the link will expire
|
||||
:type expire_date: :obj:`typing.Union[base.Integer, datetime.datetime,
|
||||
datetime.timedelta, None]`
|
||||
|
||||
:param member_limit: Maximum number of users that can be members of the chat
|
||||
simultaneously after joining the chat via this invite link; 1-99999
|
||||
:type member_limit: :obj:`typing.Optional[base.Integer]`
|
||||
|
||||
:return: edited invite link as a ChatInviteLink object.
|
||||
"""
|
||||
expire_date = prepare_arg(expire_date)
|
||||
payload = generate_payload(**locals())
|
||||
|
||||
result = await self.request(api.Methods.EDIT_CHAT_INVITE_LINK, payload)
|
||||
return result
|
||||
|
||||
async def revoke_chat_invite_link(self,
|
||||
chat_id: typing.Union[base.Integer, base.String],
|
||||
invite_link: base.String,
|
||||
) -> types.ChatInviteLink:
|
||||
"""
|
||||
Use this method to revoke an invite link created by the bot.
|
||||
If the primary link is revoked, a new link is automatically generated.
|
||||
The bot must be an administrator in the chat for this to work and must have
|
||||
the appropriate admin rights.
|
||||
|
||||
Source: https://core.telegram.org/bots/api#revokechatinvitelink
|
||||
|
||||
:param chat_id: Unique identifier for the target chat or username of the
|
||||
target channel (in the format @channelusername)
|
||||
:param invite_link: The invite link to revoke
|
||||
:return: the revoked invite link as ChatInviteLink object
|
||||
"""
|
||||
payload = generate_payload(**locals())
|
||||
|
||||
result = await self.request(api.Methods.REVOKE_CHAT_INVITE_LINK, payload)
|
||||
return result
|
||||
|
||||
async def set_chat_photo(self, chat_id: typing.Union[base.Integer, base.String],
|
||||
photo: base.InputFile) -> base.Boolean:
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -160,6 +160,26 @@ class LoggingMiddleware(BaseMiddleware):
|
|||
self.logger.debug(f"{HANDLED_STR[bool(len(results))]} poll answer [ID:{poll_answer.poll_id}] "
|
||||
f"from user [ID:{poll_answer.user.id}]")
|
||||
|
||||
async def on_pre_process_my_chat_member(self, my_chat_member_update, data):
|
||||
self.logger.info(f"Received chat member update "
|
||||
f"for user [ID:{my_chat_member_update.from_user.id}]. "
|
||||
f"Old state: {my_chat_member_update.old_chat_member.to_python()} "
|
||||
f"New state: {my_chat_member_update.new_chat_member.to_python()} ")
|
||||
|
||||
async def on_post_process_my_chat_member(self, my_chat_member_update, results, data):
|
||||
self.logger.debug(f"{HANDLED_STR[bool(len(results))]} my_chat_member "
|
||||
f"for user [ID:{my_chat_member_update.from_user.id}]")
|
||||
|
||||
async def on_pre_process_chat_member(self, chat_member_update, data):
|
||||
self.logger.info(f"Received chat member update "
|
||||
f"for user [ID:{chat_member_update.from_user.id}]. "
|
||||
f"Old state: {chat_member_update.old_chat_member.to_python()} "
|
||||
f"New state: {chat_member_update.new_chat_member.to_python()} ")
|
||||
|
||||
async def on_post_process_chat_member(self, chat_member_update, results, data):
|
||||
self.logger.debug(f"{HANDLED_STR[bool(len(results))]} chat_member "
|
||||
f"for user [ID:{chat_member_update.from_user.id}]")
|
||||
|
||||
|
||||
class LoggingFilter(logging.Filter):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -78,6 +78,8 @@ class Dispatcher(DataMixin, ContextInstanceMixin):
|
|||
self.pre_checkout_query_handlers = Handler(self, middleware_key='pre_checkout_query')
|
||||
self.poll_handlers = Handler(self, middleware_key='poll')
|
||||
self.poll_answer_handlers = Handler(self, middleware_key='poll_answer')
|
||||
self.my_chat_member_handlers = Handler(self, middleware_key='my_chat_member')
|
||||
self.chat_member_handlers = Handler(self, middleware_key='chat_member')
|
||||
self.errors_handlers = Handler(self, once=False, middleware_key='error')
|
||||
|
||||
self.middleware = MiddlewareManager(self)
|
||||
|
|
@ -163,6 +165,7 @@ class Dispatcher(DataMixin, ContextInstanceMixin):
|
|||
self.edited_channel_post_handlers,
|
||||
self.callback_query_handlers,
|
||||
self.inline_query_handlers,
|
||||
self.chat_member_handlers,
|
||||
])
|
||||
filters_factory.bind(IDFilter, event_handlers=[
|
||||
self.message_handlers,
|
||||
|
|
@ -171,6 +174,8 @@ class Dispatcher(DataMixin, ContextInstanceMixin):
|
|||
self.edited_channel_post_handlers,
|
||||
self.callback_query_handlers,
|
||||
self.inline_query_handlers,
|
||||
self.chat_member_handlers,
|
||||
self.my_chat_member_handlers,
|
||||
])
|
||||
filters_factory.bind(IsReplyFilter, event_handlers=[
|
||||
self.message_handlers,
|
||||
|
|
@ -196,6 +201,8 @@ class Dispatcher(DataMixin, ContextInstanceMixin):
|
|||
self.channel_post_handlers,
|
||||
self.edited_channel_post_handlers,
|
||||
self.callback_query_handlers,
|
||||
self.my_chat_member_handlers,
|
||||
self.chat_member_handlers
|
||||
])
|
||||
|
||||
def __del__(self):
|
||||
|
|
@ -286,6 +293,14 @@ class Dispatcher(DataMixin, ContextInstanceMixin):
|
|||
types.PollAnswer.set_current(update.poll_answer)
|
||||
types.User.set_current(update.poll_answer.user)
|
||||
return await self.poll_answer_handlers.notify(update.poll_answer)
|
||||
if update.my_chat_member:
|
||||
types.ChatMemberUpdated.set_current(update.my_chat_member)
|
||||
types.User.set_current(update.my_chat_member.from_user)
|
||||
return await self.my_chat_member_handlers.notify(update.my_chat_member)
|
||||
if update.chat_member:
|
||||
types.ChatMemberUpdated.set_current(update.chat_member)
|
||||
types.User.set_current(update.chat_member.from_user)
|
||||
return await self.chat_member_handlers.notify(update.chat_member)
|
||||
except Exception as e:
|
||||
err = await self.errors_handlers.notify(update, e)
|
||||
if err:
|
||||
|
|
@ -1005,6 +1020,118 @@ class Dispatcher(DataMixin, ContextInstanceMixin):
|
|||
|
||||
return decorator
|
||||
|
||||
def register_my_chat_member_handler(self,
|
||||
callback: typing.Callable,
|
||||
*custom_filters,
|
||||
run_task: typing.Optional[bool] = None,
|
||||
**kwargs) -> None:
|
||||
"""
|
||||
Register handler for my_chat_member
|
||||
|
||||
Example:
|
||||
|
||||
.. code-block:: python3
|
||||
|
||||
dp.register_my_chat_member_handler(some_my_chat_member_handler)
|
||||
|
||||
:param callback:
|
||||
:param custom_filters:
|
||||
:param run_task: run callback in task (no wait results)
|
||||
:param kwargs:
|
||||
"""
|
||||
filters_set = self.filters_factory.resolve(
|
||||
self.my_chat_member_handlers,
|
||||
*custom_filters,
|
||||
**kwargs,
|
||||
)
|
||||
self.my_chat_member_handlers.register(
|
||||
handler=self._wrap_async_task(callback, run_task),
|
||||
filters=filters_set,
|
||||
)
|
||||
|
||||
def my_chat_member_handler(self, *custom_filters, run_task=None, **kwargs):
|
||||
"""
|
||||
Decorator for my_chat_member handler
|
||||
|
||||
Example:
|
||||
|
||||
.. code-block:: python3
|
||||
|
||||
@dp.my_chat_member_handler()
|
||||
async def some_handler(my_chat_member: types.ChatMemberUpdated)
|
||||
|
||||
:param custom_filters:
|
||||
:param run_task: run callback in task (no wait results)
|
||||
:param kwargs:
|
||||
"""
|
||||
|
||||
def decorator(callback):
|
||||
self.register_my_chat_member_handler(
|
||||
callback,
|
||||
*custom_filters,
|
||||
run_task=run_task,
|
||||
**kwargs,
|
||||
)
|
||||
return callback
|
||||
|
||||
return decorator
|
||||
|
||||
def register_chat_member_handler(self,
|
||||
callback: typing.Callable,
|
||||
*custom_filters,
|
||||
run_task: typing.Optional[bool] = None,
|
||||
**kwargs) -> None:
|
||||
"""
|
||||
Register handler for chat_member
|
||||
|
||||
Example:
|
||||
|
||||
.. code-block:: python3
|
||||
|
||||
dp.register_chat_member_handler(some_chat_member_handler)
|
||||
|
||||
:param callback:
|
||||
:param custom_filters:
|
||||
:param run_task: run callback in task (no wait results)
|
||||
:param kwargs:
|
||||
"""
|
||||
filters_set = self.filters_factory.resolve(
|
||||
self.chat_member_handlers,
|
||||
*custom_filters,
|
||||
**kwargs,
|
||||
)
|
||||
self.chat_member_handlers.register(
|
||||
handler=self._wrap_async_task(callback, run_task),
|
||||
filters=filters_set,
|
||||
)
|
||||
|
||||
def chat_member_handler(self, *custom_filters, run_task=None, **kwargs):
|
||||
"""
|
||||
Decorator for chat_member handler
|
||||
|
||||
Example:
|
||||
|
||||
.. code-block:: python3
|
||||
|
||||
@dp.chat_member_handler()
|
||||
async def some_handler(chat_member: types.ChatMemberUpdated)
|
||||
|
||||
:param custom_filters:
|
||||
:param run_task: run callback in task (no wait results)
|
||||
:param kwargs:
|
||||
"""
|
||||
|
||||
def decorator(callback):
|
||||
self.register_chat_member_handler(
|
||||
callback,
|
||||
*custom_filters,
|
||||
run_task=run_task,
|
||||
**kwargs,
|
||||
)
|
||||
return callback
|
||||
|
||||
return decorator
|
||||
|
||||
def register_errors_handler(self, callback, *custom_filters, exception=None, run_task=None, **kwargs):
|
||||
"""
|
||||
Register handler for errors
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ from babel.support import LazyProxy
|
|||
|
||||
from aiogram import types
|
||||
from aiogram.dispatcher.filters.filters import BoundFilter, Filter
|
||||
from aiogram.types import CallbackQuery, ChatType, InlineQuery, Message, Poll
|
||||
from aiogram.types import CallbackQuery, ChatType, InlineQuery, Message, Poll, ChatMemberUpdated
|
||||
|
||||
ChatIDArgumentType = typing.Union[typing.Iterable[typing.Union[int, str]], str, int]
|
||||
|
||||
|
|
@ -604,7 +604,7 @@ class IDFilter(Filter):
|
|||
|
||||
return result
|
||||
|
||||
async def check(self, obj: Union[Message, CallbackQuery, InlineQuery]):
|
||||
async def check(self, obj: Union[Message, CallbackQuery, InlineQuery, ChatMemberUpdated]):
|
||||
if isinstance(obj, Message):
|
||||
user_id = None
|
||||
if obj.from_user is not None:
|
||||
|
|
@ -619,6 +619,9 @@ class IDFilter(Filter):
|
|||
elif isinstance(obj, InlineQuery):
|
||||
user_id = obj.from_user.id
|
||||
chat_id = None
|
||||
elif isinstance(obj, ChatMemberUpdated):
|
||||
user_id = obj.from_user.id
|
||||
chat_id = obj.chat.id
|
||||
else:
|
||||
return False
|
||||
|
||||
|
|
@ -663,19 +666,21 @@ class AdminFilter(Filter):
|
|||
|
||||
return result
|
||||
|
||||
async def check(self, obj: Union[Message, CallbackQuery, InlineQuery]) -> bool:
|
||||
async def check(self, obj: Union[Message, CallbackQuery, InlineQuery, ChatMemberUpdated]) -> bool:
|
||||
user_id = obj.from_user.id
|
||||
|
||||
if self._check_current:
|
||||
if isinstance(obj, Message):
|
||||
message = obj
|
||||
chat = obj.chat
|
||||
elif isinstance(obj, CallbackQuery) and obj.message:
|
||||
message = obj.message
|
||||
chat = obj.message.chat
|
||||
elif isinstance(obj, ChatMemberUpdated):
|
||||
chat = obj.chat
|
||||
else:
|
||||
return False
|
||||
if message.chat.type == ChatType.PRIVATE: # there is no admin in private chats
|
||||
if chat.type == ChatType.PRIVATE: # there is no admin in private chats
|
||||
return False
|
||||
chat_ids = [message.chat.id]
|
||||
chat_ids = [chat.id]
|
||||
else:
|
||||
chat_ids = self._chat_ids
|
||||
|
||||
|
|
@ -719,11 +724,13 @@ class ChatTypeFilter(BoundFilter):
|
|||
|
||||
self.chat_type: typing.Set[str] = set(chat_type)
|
||||
|
||||
async def check(self, obj: Union[Message, CallbackQuery]):
|
||||
async def check(self, obj: Union[Message, CallbackQuery, ChatMemberUpdated]):
|
||||
if isinstance(obj, Message):
|
||||
obj = obj.chat
|
||||
elif isinstance(obj, CallbackQuery):
|
||||
obj = obj.message.chat
|
||||
elif isinstance(obj, ChatMemberUpdated):
|
||||
obj = obj.chat
|
||||
else:
|
||||
warnings.warn("ChatTypeFilter doesn't support %s as input", type(obj))
|
||||
return False
|
||||
|
|
|
|||
|
|
@ -7,8 +7,10 @@ from .bot_command import BotCommand
|
|||
from .callback_game import CallbackGame
|
||||
from .callback_query import CallbackQuery
|
||||
from .chat import Chat, ChatActions, ChatType
|
||||
from .chat_invite_link import ChatInviteLink
|
||||
from .chat_location import ChatLocation
|
||||
from .chat_member import ChatMember, ChatMemberStatus
|
||||
from .chat_member_updated import ChatMemberUpdated
|
||||
from .chat_permissions import ChatPermissions
|
||||
from .chat_photo import ChatPhoto
|
||||
from .chosen_inline_result import ChosenInlineResult
|
||||
|
|
@ -40,6 +42,7 @@ from .location import Location
|
|||
from .login_url import LoginUrl
|
||||
from .mask_position import MaskPosition
|
||||
from .message import ContentType, ContentTypes, Message, ParseMode
|
||||
from .message_auto_delete_timer_changed import MessageAutoDeleteTimerChanged
|
||||
from .message_entity import MessageEntity, MessageEntityType
|
||||
from .message_id import MessageId
|
||||
from .order_info import OrderInfo
|
||||
|
|
@ -67,6 +70,9 @@ from .venue import Venue
|
|||
from .video import Video
|
||||
from .video_note import VideoNote
|
||||
from .voice import Voice
|
||||
from .voice_chat_ended import VoiceChatEnded
|
||||
from .voice_chat_participants_invited import VoiceChatParticipantsInvited
|
||||
from .voice_chat_started import VoiceChatStarted
|
||||
from .webhook_info import WebhookInfo
|
||||
|
||||
__all__ = (
|
||||
|
|
@ -79,9 +85,11 @@ __all__ = (
|
|||
'CallbackQuery',
|
||||
'Chat',
|
||||
'ChatActions',
|
||||
'ChatInviteLink',
|
||||
'ChatLocation',
|
||||
'ChatMember',
|
||||
'ChatMemberStatus',
|
||||
'ChatMemberUpdated',
|
||||
'ChatPermissions',
|
||||
'ChatPhoto',
|
||||
'ChatType',
|
||||
|
|
@ -143,6 +151,7 @@ __all__ = (
|
|||
'MaskPosition',
|
||||
'MediaGroup',
|
||||
'Message',
|
||||
'MessageAutoDeleteTimerChanged',
|
||||
'MessageEntity',
|
||||
'MessageEntityType',
|
||||
'MessageId',
|
||||
|
|
@ -180,6 +189,9 @@ __all__ = (
|
|||
'Video',
|
||||
'VideoNote',
|
||||
'Voice',
|
||||
'VoiceChatEnded',
|
||||
'VoiceChatParticipantsInvited',
|
||||
'VoiceChatStarted',
|
||||
'WebhookInfo',
|
||||
'base',
|
||||
'fields',
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import datetime
|
|||
import typing
|
||||
|
||||
from . import base, fields
|
||||
from .chat_invite_link import ChatInviteLink
|
||||
from .chat_location import ChatLocation
|
||||
from .chat_member import ChatMember
|
||||
from .chat_permissions import ChatPermissions
|
||||
|
|
@ -185,30 +186,47 @@ class Chat(base.TelegramObject):
|
|||
"""
|
||||
return await self.bot.set_chat_description(self.id, description)
|
||||
|
||||
async def kick(self, user_id: base.Integer,
|
||||
until_date: typing.Union[
|
||||
base.Integer, datetime.datetime, datetime.timedelta, None] = None) -> base.Boolean:
|
||||
async def kick(self,
|
||||
user_id: base.Integer,
|
||||
until_date: typing.Union[base.Integer, datetime.datetime,
|
||||
datetime.timedelta, None] = None,
|
||||
revoke_messages: typing.Optional[base.Boolean] = None,
|
||||
) -> base.Boolean:
|
||||
"""
|
||||
Use this method to kick a user from a group, a supergroup or a channel.
|
||||
In the case of supergroups and channels, the user will not be able to return to the group
|
||||
on their own using invite links, etc., unless unbanned first.
|
||||
In the case of supergroups and channels, the user will not be able to return
|
||||
to the chat on their own using invite links, etc., unless unbanned first.
|
||||
|
||||
The bot must be an administrator in the chat for this to work and must have the appropriate admin rights.
|
||||
|
||||
Note: In regular groups (non-supergroups), this method will only work if the ‘All Members Are Admins’ setting
|
||||
is off in the target group.
|
||||
Otherwise members may only be removed by the group's creator or by the member that added them.
|
||||
The bot must be an administrator in the chat for this to work and must have
|
||||
the appropriate admin rights.
|
||||
|
||||
Source: https://core.telegram.org/bots/api#kickchatmember
|
||||
|
||||
:param user_id: Unique identifier of the target user
|
||||
:type user_id: :obj:`base.Integer`
|
||||
:param until_date: Date when the user will be unbanned, unix time.
|
||||
:type until_date: :obj:`typing.Optional[base.Integer]`
|
||||
:return: Returns True on success.
|
||||
|
||||
:param until_date: Date when the user will be unbanned. If user is banned
|
||||
for more than 366 days or less than 30 seconds from the current time they
|
||||
are considered to be banned forever. Applied for supergroups and channels
|
||||
only.
|
||||
:type until_date: :obj:`typing.Union[base.Integer, datetime.datetime,
|
||||
datetime.timedelta, None`
|
||||
|
||||
:param revoke_messages: Pass True to delete all messages from the chat for
|
||||
the user that is being removed. If False, the user will be able to see
|
||||
messages in the group that were sent before the user was removed. Always
|
||||
True for supergroups and channels.
|
||||
:type revoke_messages: :obj:`typing.Optional[base.Boolean]`
|
||||
|
||||
:return: Returns True on success
|
||||
:rtype: :obj:`base.Boolean`
|
||||
"""
|
||||
return await self.bot.kick_chat_member(self.id, user_id=user_id, until_date=until_date)
|
||||
return await self.bot.kick_chat_member(
|
||||
chat_id=self.id,
|
||||
user_id=user_id,
|
||||
until_date=until_date,
|
||||
revoke_messages=revoke_messages,
|
||||
)
|
||||
|
||||
async def unban(self,
|
||||
user_id: base.Integer,
|
||||
|
|
@ -554,6 +572,41 @@ class Chat(base.TelegramObject):
|
|||
|
||||
return self.invite_link
|
||||
|
||||
async def create_invite_link(self,
|
||||
expire_date: typing.Union[base.Integer, datetime.datetime,
|
||||
datetime.timedelta, None],
|
||||
member_limit: typing.Optional[base.Integer],
|
||||
) -> ChatInviteLink:
|
||||
""" Shortcut for createChatInviteLink method. """
|
||||
return await self.bot.create_chat_invite_link(
|
||||
chat_id=self.id,
|
||||
expire_date=expire_date,
|
||||
member_limit=member_limit,
|
||||
)
|
||||
|
||||
async def edit_invite_link(self,
|
||||
invite_link: base.String,
|
||||
expire_date: typing.Union[base.Integer, datetime.datetime,
|
||||
datetime.timedelta, None],
|
||||
member_limit: typing.Optional[base.Integer],
|
||||
) -> ChatInviteLink:
|
||||
""" Shortcut for editChatInviteLink method. """
|
||||
return await self.bot.edit_chat_invite_link(
|
||||
chat_id=self.id,
|
||||
invite_link=invite_link,
|
||||
expire_date=expire_date,
|
||||
member_limit=member_limit,
|
||||
)
|
||||
|
||||
async def revoke_invite_link(self,
|
||||
invite_link: base.String,
|
||||
) -> ChatInviteLink:
|
||||
""" Shortcut for revokeChatInviteLink method. """
|
||||
return await self.bot.revoke_chat_invite_link(
|
||||
chat_id=self.id,
|
||||
invite_link=invite_link,
|
||||
)
|
||||
|
||||
def __int__(self):
|
||||
return self.id
|
||||
|
||||
|
|
|
|||
20
aiogram/types/chat_invite_link.py
Normal file
20
aiogram/types/chat_invite_link.py
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
from datetime import datetime
|
||||
|
||||
from . import base
|
||||
from . import fields
|
||||
from .user import User
|
||||
|
||||
|
||||
class ChatInviteLink(base.TelegramObject):
|
||||
"""
|
||||
Represents an invite link for a chat.
|
||||
|
||||
https://core.telegram.org/bots/api#chatinvitelink
|
||||
"""
|
||||
|
||||
invite_link: base.String = fields.Field()
|
||||
creator: User = fields.Field(base=User)
|
||||
is_primary: base.Boolean = fields.Field()
|
||||
is_revoked: base.Boolean = fields.Field()
|
||||
expire_date: datetime = fields.DateTimeField()
|
||||
member_limit: base.Integer = fields.Field()
|
||||
|
|
@ -16,22 +16,24 @@ class ChatMember(base.TelegramObject):
|
|||
status: base.String = fields.Field()
|
||||
custom_title: base.String = fields.Field()
|
||||
is_anonymous: base.Boolean = fields.Field()
|
||||
until_date: datetime.datetime = fields.DateTimeField()
|
||||
can_be_edited: base.Boolean = fields.Field()
|
||||
can_change_info: base.Boolean = fields.Field()
|
||||
can_manage_chat: base.Boolean = fields.Field()
|
||||
can_post_messages: base.Boolean = fields.Field()
|
||||
can_edit_messages: base.Boolean = fields.Field()
|
||||
can_delete_messages: base.Boolean = fields.Field()
|
||||
can_invite_users: base.Boolean = fields.Field()
|
||||
can_manage_voice_chats: base.Boolean = fields.Field()
|
||||
can_restrict_members: base.Boolean = fields.Field()
|
||||
can_pin_messages: base.Boolean = fields.Field()
|
||||
can_promote_members: base.Boolean = fields.Field()
|
||||
can_change_info: base.Boolean = fields.Field()
|
||||
can_invite_users: base.Boolean = fields.Field()
|
||||
can_pin_messages: base.Boolean = fields.Field()
|
||||
is_member: base.Boolean = fields.Field()
|
||||
can_send_messages: base.Boolean = fields.Field()
|
||||
can_send_media_messages: base.Boolean = fields.Field()
|
||||
can_send_polls: base.Boolean = fields.Field()
|
||||
can_send_other_messages: base.Boolean = fields.Field()
|
||||
can_add_web_page_previews: base.Boolean = fields.Field()
|
||||
until_date: datetime.datetime = fields.DateTimeField()
|
||||
|
||||
def is_chat_creator(self) -> bool:
|
||||
return ChatMemberStatus.is_chat_creator(self.status)
|
||||
|
|
|
|||
22
aiogram/types/chat_member_updated.py
Normal file
22
aiogram/types/chat_member_updated.py
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
import datetime
|
||||
|
||||
from . import base
|
||||
from . import fields
|
||||
from .chat import Chat
|
||||
from .chat_invite_link import ChatInviteLink
|
||||
from .chat_member import ChatMember
|
||||
from .user import User
|
||||
|
||||
|
||||
class ChatMemberUpdated(base.TelegramObject):
|
||||
"""
|
||||
This object represents changes in the status of a chat member.
|
||||
|
||||
https://core.telegram.org/bots/api#chatmemberupdated
|
||||
"""
|
||||
chat: Chat = fields.Field(base=Chat)
|
||||
from_user: User = fields.Field(base=User)
|
||||
date: datetime.datetime = fields.DateTimeField()
|
||||
old_chat_member: ChatMember = fields.Field(base=ChatMember)
|
||||
new_chat_member: ChatMember = fields.Field(base=ChatMember)
|
||||
invite_link: ChatInviteLink = fields.Field(base=ChatInviteLink)
|
||||
|
|
@ -3,9 +3,7 @@ from . import base, fields
|
|||
|
||||
class Dice(base.TelegramObject):
|
||||
"""
|
||||
This object represents a dice with random value from 1 to 6.
|
||||
(Yes, we're aware of the “proper” singular of die.
|
||||
But it's awkward, and we decided to help it change. One dice at a time!)
|
||||
This object represents an animated emoji that displays a random value.
|
||||
|
||||
https://core.telegram.org/bots/api#dice
|
||||
"""
|
||||
|
|
@ -19,3 +17,4 @@ class DiceEmoji:
|
|||
BASKETBALL = '🏀'
|
||||
FOOTBALL = '⚽'
|
||||
SLOT_MACHINE = '🎰'
|
||||
BOWLING = '🎳'
|
||||
|
|
|
|||
|
|
@ -4,10 +4,6 @@ import datetime
|
|||
import functools
|
||||
import typing
|
||||
|
||||
from ..utils import helper
|
||||
from ..utils import markdown as md
|
||||
from ..utils.deprecated import deprecated
|
||||
from ..utils.text_decorations import html_decoration, markdown_decoration
|
||||
from . import base, fields
|
||||
from .animation import Animation
|
||||
from .audio import Audio
|
||||
|
|
@ -21,6 +17,7 @@ from .inline_keyboard import InlineKeyboardMarkup
|
|||
from .input_media import InputMedia, MediaGroup
|
||||
from .invoice import Invoice
|
||||
from .location import Location
|
||||
from .message_auto_delete_timer_changed import MessageAutoDeleteTimerChanged
|
||||
from .message_entity import MessageEntity
|
||||
from .message_id import MessageId
|
||||
from .passport_data import PassportData
|
||||
|
|
@ -35,6 +32,13 @@ from .venue import Venue
|
|||
from .video import Video
|
||||
from .video_note import VideoNote
|
||||
from .voice import Voice
|
||||
from .voice_chat_ended import VoiceChatEnded
|
||||
from .voice_chat_participants_invited import VoiceChatParticipantsInvited
|
||||
from .voice_chat_started import VoiceChatStarted
|
||||
from ..utils import helper
|
||||
from ..utils import markdown as md
|
||||
from ..utils.deprecated import deprecated
|
||||
from ..utils.text_decorations import html_decoration, markdown_decoration
|
||||
|
||||
|
||||
class Message(base.TelegramObject):
|
||||
|
|
@ -86,6 +90,7 @@ class Message(base.TelegramObject):
|
|||
group_chat_created: base.Boolean = fields.Field()
|
||||
supergroup_chat_created: base.Boolean = fields.Field()
|
||||
channel_chat_created: base.Boolean = fields.Field()
|
||||
message_auto_delete_timer_changed: MessageAutoDeleteTimerChanged = fields.Field(base=MessageAutoDeleteTimerChanged)
|
||||
migrate_to_chat_id: base.Integer = fields.Field()
|
||||
migrate_from_chat_id: base.Integer = fields.Field()
|
||||
pinned_message: Message = fields.Field(base="Message")
|
||||
|
|
@ -94,6 +99,9 @@ class Message(base.TelegramObject):
|
|||
connected_website: base.String = fields.Field()
|
||||
passport_data: PassportData = fields.Field(base=PassportData)
|
||||
proximity_alert_triggered: ProximityAlertTriggered = fields.Field(base=ProximityAlertTriggered)
|
||||
voice_chat_started: VoiceChatStarted = fields.Field(base=VoiceChatStarted)
|
||||
voice_chat_ended: VoiceChatEnded = fields.Field(base=VoiceChatEnded)
|
||||
voice_chat_participants_invited: VoiceChatParticipantsInvited = fields.Field(base=VoiceChatParticipantsInvited)
|
||||
reply_markup: InlineKeyboardMarkup = fields.Field(base=InlineKeyboardMarkup)
|
||||
|
||||
@property
|
||||
|
|
@ -139,6 +147,8 @@ class Message(base.TelegramObject):
|
|||
return ContentType.SUCCESSFUL_PAYMENT
|
||||
if self.connected_website:
|
||||
return ContentType.CONNECTED_WEBSITE
|
||||
if self.message_auto_delete_timer_changed:
|
||||
return ContentType.MESSAGE_AUTO_DELETE_TIMER_CHANGED
|
||||
if self.migrate_from_chat_id:
|
||||
return ContentType.MIGRATE_FROM_CHAT_ID
|
||||
if self.migrate_to_chat_id:
|
||||
|
|
@ -157,6 +167,12 @@ class Message(base.TelegramObject):
|
|||
return ContentType.PASSPORT_DATA
|
||||
if self.proximity_alert_triggered:
|
||||
return ContentType.PROXIMITY_ALERT_TRIGGERED
|
||||
if self.voice_chat_started:
|
||||
return ContentType.VOICE_CHAT_STARTED
|
||||
if self.voice_chat_ended:
|
||||
return ContentType.VOICE_CHAT_ENDED
|
||||
if self.voice_chat_participants_invited:
|
||||
return ContentType.VOICE_CHAT_PARTICIPANTS_INVITED
|
||||
|
||||
return ContentType.UNKNOWN
|
||||
|
||||
|
|
@ -2980,6 +2996,7 @@ class ContentType(helper.Helper):
|
|||
INVOICE = helper.Item() # invoice
|
||||
SUCCESSFUL_PAYMENT = helper.Item() # successful_payment
|
||||
CONNECTED_WEBSITE = helper.Item() # connected_website
|
||||
MESSAGE_AUTO_DELETE_TIMER_CHANGED = helper.Item() # message_auto_delete_timer_changed
|
||||
MIGRATE_TO_CHAT_ID = helper.Item() # migrate_to_chat_id
|
||||
MIGRATE_FROM_CHAT_ID = helper.Item() # migrate_from_chat_id
|
||||
PINNED_MESSAGE = helper.Item() # pinned_message
|
||||
|
|
@ -2989,6 +3006,9 @@ class ContentType(helper.Helper):
|
|||
GROUP_CHAT_CREATED = helper.Item() # group_chat_created
|
||||
PASSPORT_DATA = helper.Item() # passport_data
|
||||
PROXIMITY_ALERT_TRIGGERED = helper.Item() # proximity_alert_triggered
|
||||
VOICE_CHAT_STARTED = helper.Item() # voice_chat_started
|
||||
VOICE_CHAT_ENDED = helper.Item() # voice_chat_ended
|
||||
VOICE_CHAT_PARTICIPANTS_INVITED = helper.Item() # voice_chat_participants_invited
|
||||
|
||||
UNKNOWN = helper.Item() # unknown
|
||||
ANY = helper.Item() # any
|
||||
|
|
|
|||
11
aiogram/types/message_auto_delete_timer_changed.py
Normal file
11
aiogram/types/message_auto_delete_timer_changed.py
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
from . import base
|
||||
from . import fields
|
||||
|
||||
|
||||
class MessageAutoDeleteTimerChanged(base.TelegramObject):
|
||||
"""
|
||||
This object represents a service message about a change in auto-delete timer settings.
|
||||
|
||||
https://core.telegram.org/bots/api#messageautodeletetimerchanged
|
||||
"""
|
||||
message_auto_delete_time: base.Integer = fields.Field()
|
||||
|
|
@ -3,6 +3,7 @@ from __future__ import annotations
|
|||
from . import base
|
||||
from . import fields
|
||||
from .callback_query import CallbackQuery
|
||||
from .chat_member_updated import ChatMemberUpdated
|
||||
from .chosen_inline_result import ChosenInlineResult
|
||||
from .inline_query import InlineQuery
|
||||
from .message import Message
|
||||
|
|
@ -31,6 +32,8 @@ class Update(base.TelegramObject):
|
|||
pre_checkout_query: PreCheckoutQuery = fields.Field(base=PreCheckoutQuery)
|
||||
poll: Poll = fields.Field(base=Poll)
|
||||
poll_answer: PollAnswer = fields.Field(base=PollAnswer)
|
||||
my_chat_member: ChatMemberUpdated = fields.Field(base=ChatMemberUpdated)
|
||||
chat_member: ChatMemberUpdated = fields.Field(base=ChatMemberUpdated)
|
||||
|
||||
def __hash__(self):
|
||||
return self.update_id
|
||||
|
|
@ -61,6 +64,8 @@ class AllowedUpdates(helper.Helper):
|
|||
PRE_CHECKOUT_QUERY = helper.ListItem() # pre_checkout_query
|
||||
POLL = helper.ListItem() # poll
|
||||
POLL_ANSWER = helper.ListItem() # poll_answer
|
||||
MY_CHAT_MEMBER = helper.ListItem() # my_chat_member
|
||||
CHAT_MEMBER = helper.ListItem() # chat_member
|
||||
|
||||
CHOSEN_INLINE_QUERY = deprecated.DeprecatedReadOnlyClassVar(
|
||||
"`CHOSEN_INLINE_QUERY` is a deprecated value for allowed update. "
|
||||
|
|
|
|||
13
aiogram/types/voice_chat_ended.py
Normal file
13
aiogram/types/voice_chat_ended.py
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
from . import base
|
||||
from . import fields
|
||||
from . import mixins
|
||||
|
||||
|
||||
class VoiceChatEnded(base.TelegramObject, mixins.Downloadable):
|
||||
"""
|
||||
This object represents a service message about a voice chat ended in the chat.
|
||||
|
||||
https://core.telegram.org/bots/api#voicechatended
|
||||
"""
|
||||
|
||||
duration: base.Integer = fields.Field()
|
||||
16
aiogram/types/voice_chat_participants_invited.py
Normal file
16
aiogram/types/voice_chat_participants_invited.py
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import typing
|
||||
|
||||
from . import base
|
||||
from . import fields
|
||||
from . import mixins
|
||||
from .user import User
|
||||
|
||||
|
||||
class VoiceChatParticipantsInvited(base.TelegramObject, mixins.Downloadable):
|
||||
"""
|
||||
This object represents a service message about new members invited to a voice chat.
|
||||
|
||||
https://core.telegram.org/bots/api#voicechatparticipantsinvited
|
||||
"""
|
||||
|
||||
users: typing.List[User] = fields.ListField(base=User)
|
||||
12
aiogram/types/voice_chat_started.py
Normal file
12
aiogram/types/voice_chat_started.py
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
from . import base
|
||||
from . import mixins
|
||||
|
||||
|
||||
class VoiceChatStarted(base.TelegramObject, mixins.Downloadable):
|
||||
"""
|
||||
This object represents a service message about a voice chat started in the chat.
|
||||
Currently holds no information.
|
||||
|
||||
https://core.telegram.org/bots/api#voicechatstarted
|
||||
"""
|
||||
pass
|
||||
Loading…
Add table
Add a link
Reference in a new issue