Add support for updates about chat member status changes

This commit is contained in:
Dan 2021-03-17 15:11:23 +01:00
parent 86cc1837b6
commit dff3d993e1
10 changed files with 219 additions and 5 deletions

View File

@ -349,6 +349,7 @@ def pyrogram_api():
ChatAdminWithInviteLinks
ChatEvent
ChatEventFilter
ChatMemberUpdated
Dialog
Restriction
""",
@ -373,6 +374,9 @@ def pyrogram_api():
Poll
PollOption
Dice
VoiceChatStarted
VoiceChatEnded
VoiceChatMembersInvited
""",
bots_keyboard="""
Bots & Keyboards

View File

@ -43,6 +43,7 @@ Index
- :meth:`~Client.on_callback_query`
- :meth:`~Client.on_inline_query`
- :meth:`~Client.on_chosen_inline_result`
- :meth:`~Client.on_chat_member_updated`
- :meth:`~Client.on_deleted_messages`
- :meth:`~Client.on_user_status`
- :meth:`~Client.on_poll`
@ -59,6 +60,7 @@ Details
.. autodecorator:: pyrogram.Client.on_callback_query()
.. autodecorator:: pyrogram.Client.on_inline_query()
.. autodecorator:: pyrogram.Client.on_chosen_inline_result()
.. autodecorator:: pyrogram.Client.on_chat_member_updated()
.. autodecorator:: pyrogram.Client.on_deleted_messages()
.. autodecorator:: pyrogram.Client.on_user_status()
.. autodecorator:: pyrogram.Client.on_poll()

View File

@ -41,6 +41,7 @@ Index
- :class:`CallbackQueryHandler`
- :class:`InlineQueryHandler`
- :class:`ChosenInlineResultHandler`
- :class:`ChatMemberUpdated`
- :class:`UserStatusHandler`
- :class:`PollHandler`
- :class:`DisconnectHandler`
@ -57,6 +58,7 @@ Details
.. autoclass:: CallbackQueryHandler()
.. autoclass:: InlineQueryHandler()
.. autoclass:: ChosenInlineResultHandler()
.. autoclass:: ChatMemberUpdated()
.. autoclass:: UserStatusHandler()
.. autoclass:: PollHandler()
.. autoclass:: DisconnectHandler()

View File

@ -26,7 +26,7 @@ from pyrogram import utils
from pyrogram.handlers import (
CallbackQueryHandler, MessageHandler, DeletedMessagesHandler,
UserStatusHandler, RawUpdateHandler, InlineQueryHandler, PollHandler,
ChosenInlineResultHandler
ChosenInlineResultHandler, ChatMemberUpdatedHandler
)
from pyrogram.raw.types import (
UpdateNewMessage, UpdateNewChannelMessage, UpdateNewScheduledMessage,
@ -34,7 +34,7 @@ from pyrogram.raw.types import (
UpdateDeleteMessages, UpdateDeleteChannelMessages,
UpdateBotCallbackQuery, UpdateInlineBotCallbackQuery,
UpdateUserStatus, UpdateBotInlineQuery, UpdateMessagePoll,
UpdateBotInlineSend
UpdateBotInlineSend, UpdateChatParticipant, UpdateChannelParticipant
)
log = logging.getLogger(__name__)
@ -62,6 +62,11 @@ class Dispatcher:
UpdateInlineBotCallbackQuery
)
CHAT_MEMBER_UPDATES = (
UpdateChatParticipant,
UpdateChannelParticipant
)
MESSAGE_UPDATES = NEW_MESSAGE_UPDATES + EDIT_MESSAGE_UPDATES
def __init__(self, client: "pyrogram.Client"):
@ -98,6 +103,9 @@ class Dispatcher:
async def chosen_inline_result_parser(update, users, chats):
return pyrogram.types.ChosenInlineResult._parse(self.client, update, users), ChosenInlineResultHandler
async def chat_member_updated_parser(update, users, chats):
return pyrogram.types.ChatMemberUpdated._parse(self.client, update, users, chats), ChatMemberUpdatedHandler
self.update_parsers = {
Dispatcher.MESSAGE_UPDATES: message_parser,
Dispatcher.DELETE_MESSAGES_UPDATES: deleted_messages_parser,
@ -105,7 +113,8 @@ class Dispatcher:
(UpdateUserStatus,): user_status_parser,
(UpdateBotInlineQuery,): inline_query_parser,
(UpdateMessagePoll,): poll_parser,
(UpdateBotInlineSend,): chosen_inline_result_parser
(UpdateBotInlineSend,): chosen_inline_result_parser,
Dispatcher.CHAT_MEMBER_UPDATES: chat_member_updated_parser
}
self.update_parsers = {key: value for key_tuple, value in self.update_parsers.items() for key in key_tuple}

View File

@ -17,6 +17,7 @@
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from .callback_query_handler import CallbackQueryHandler
from .chat_member_updated_handler import ChatMemberUpdatedHandler
from .chosen_inline_result_handler import ChosenInlineResultHandler
from .deleted_messages_handler import DeletedMessagesHandler
from .disconnect_handler import DisconnectHandler

View File

@ -0,0 +1,47 @@
# Pyrogram - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-2021 Dan <https://github.com/delivrance>
#
# This file is part of Pyrogram.
#
# Pyrogram is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Pyrogram is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from .handler import Handler
class ChatMemberUpdatedHandler(Handler):
"""The ChatMemberUpdated handler class. Used to handle changes in the status of a chat member.
It is intended to be used with :meth:`~pyrogram.Client.add_handler`.
For a nicer way to register this handler, have a look at the
:meth:`~pyrogram.Client.on_chat_member_updated` decorator.
Parameters:
callback (``callable``):
Pass a function that will be called when a new ChatMemberUpdated event arrives. It takes
*(client, chat_member_updated)* as positional arguments (look at the section below for a detailed
description).
filters (:obj:`Filters`):
Pass one or more filters to allow only a subset of updates to be passed in your callback function.
Other parameters:
client (:obj:`~pyrogram.Client`):
The Client itself, useful when you want to call other API methods inside the handler.
chat_member_updated (:obj:`~pyrogram.types.ChatMemberUpdated`):
The received chat member update.
"""
def __init__(self, callback: callable, filters=None):
super().__init__(callback, filters)

View File

@ -17,6 +17,7 @@
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from .on_callback_query import OnCallbackQuery
from .on_chat_member_updated import OnChatMemberUpdated
from .on_chosen_inline_result import OnChosenInlineResult
from .on_deleted_messages import OnDeletedMessages
from .on_disconnect import OnDisconnect
@ -36,6 +37,7 @@ class Decorators(
OnUserStatus,
OnInlineQuery,
OnPoll,
OnChosenInlineResult
OnChosenInlineResult,
OnChatMemberUpdated
):
pass

View File

@ -0,0 +1,56 @@
# Pyrogram - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-2021 Dan <https://github.com/delivrance>
#
# This file is part of Pyrogram.
#
# Pyrogram is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Pyrogram is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from typing import Callable
import pyrogram
from pyrogram.filters import Filter
from pyrogram.scaffold import Scaffold
class OnChatMemberUpdated(Scaffold):
def on_chat_member_updated(
self=None,
filters=None,
group: int = 0
) -> callable:
"""Decorator for handling event changes on chat members.
This does the same thing as :meth:`~pyrogram.Client.add_handler` using the
:obj:`~pyrogram.handlers.ChatMemberUpdated`.
Parameters:
filters (:obj:`~pyrogram.filters`, *optional*):
Pass one or more filters to allow only a subset of updates to be passed in your function.
group (``int``, *optional*):
The group identifier, defaults to 0.
"""
def decorator(func: Callable) -> Callable:
if isinstance(self, pyrogram.Client):
self.add_handler(pyrogram.handlers.ChatMemberUpdatedHandler(func, filters), group)
elif isinstance(self, Filter) or self is None:
func.handler = (
pyrogram.handlers.ChatMemberUpdatedHandler(func, self),
group if filters is None else filters
)
return func
return decorator

View File

@ -22,6 +22,7 @@ from .chat_event import ChatEvent
from .chat_event_filter import ChatEventFilter
from .chat_invite_link import ChatInviteLink
from .chat_member import ChatMember
from .chat_member_updated import ChatMemberUpdated
from .chat_permissions import ChatPermissions
from .chat_photo import ChatPhoto
from .chat_preview import ChatPreview
@ -49,5 +50,6 @@ __all__ = [
"ChatAdminWithInviteLinks",
"VoiceChatStarted",
"VoiceChatEnded",
"VoiceChatMembersInvited"
"VoiceChatMembersInvited",
"ChatMemberUpdated"
]

View File

@ -0,0 +1,89 @@
# Pyrogram - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-2021 Dan <https://github.com/delivrance>
#
# This file is part of Pyrogram.
#
# Pyrogram is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Pyrogram is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from typing import Dict, Union
import pyrogram
from pyrogram import raw
from pyrogram import types
from ..object import Object
from ..update import Update
class ChatMemberUpdated(Object, Update):
"""Represents changes in the status of a chat member.
Parameters:
chat (:obj:`~pyrogram.types.Chat`):
Chat the user belongs to.
from_user (:obj:`~pyrogram.types.User`):
Performer of the action, which resulted in the change.
date (``int``):
Date the change was done in Unix time.
old_chat_member (:obj:`~pyrogram.types.ChatMember`):
Previous information about the chat member.
new_chat_member (:obj:`~pyrogram.types.ChatMember`):
New information about the chat member.
invite_link (:obj:`~pyrogram.types.ChatInviteLink`, *optional*):
Chat invite link, which was used by the user to join the chat; for joining by invite link events only.
"""
def __init__(
self,
*,
client: "pyrogram.Client" = None,
chat: "types.Chat",
from_user: "types.User",
date: int,
old_chat_member: "types.ChatMember",
new_chat_member: "types.ChatMember",
invite_link: "types.ChatInviteLink" = None,
):
super().__init__(client)
self.chat = chat
self.from_user = from_user
self.date = date
self.old_chat_member = old_chat_member
self.new_chat_member = new_chat_member
self.invite_link = invite_link
@staticmethod
def _parse(
client: "pyrogram.Client",
update: Union["raw.types.UpdateChatParticipant", "raw.types.UpdateChannelParticipant"],
users: Dict[int, "raw.types.User"],
chats: Dict[int, "raw.types.Chat"]
) -> "ChatMemberUpdated":
chat_id = getattr(update, "chat_id", None) or getattr(update, "channel_id")
invite_link = types.ChatInviteLink._parse(client, update.invite, users) if update.invite else None
return ChatMemberUpdated(
chat=types.Chat._parse_chat(client, chats[chat_id]),
from_user=types.User._parse(client, users[update.actor_id]),
date=update.date,
old_chat_member=types.ChatMember._parse(client, update.prev_participant, users),
new_chat_member=types.ChatMember._parse(client, update.new_participant, users),
invite_link=invite_link,
client=client
)