Skip to content

Commit dff3d99

Browse files
committed
Add support for updates about chat member status changes
1 parent 86cc183 commit dff3d99

10 files changed

Lines changed: 219 additions & 5 deletions

File tree

compiler/docs/compiler.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,7 @@ def get_title_list(s: str) -> list:
349349
ChatAdminWithInviteLinks
350350
ChatEvent
351351
ChatEventFilter
352+
ChatMemberUpdated
352353
Dialog
353354
Restriction
354355
""",
@@ -373,6 +374,9 @@ def get_title_list(s: str) -> list:
373374
Poll
374375
PollOption
375376
Dice
377+
VoiceChatStarted
378+
VoiceChatEnded
379+
VoiceChatMembersInvited
376380
""",
377381
bots_keyboard="""
378382
Bots & Keyboards

docs/source/api/decorators.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ Index
4343
- :meth:`~Client.on_callback_query`
4444
- :meth:`~Client.on_inline_query`
4545
- :meth:`~Client.on_chosen_inline_result`
46+
- :meth:`~Client.on_chat_member_updated`
4647
- :meth:`~Client.on_deleted_messages`
4748
- :meth:`~Client.on_user_status`
4849
- :meth:`~Client.on_poll`
@@ -59,6 +60,7 @@ Details
5960
.. autodecorator:: pyrogram.Client.on_callback_query()
6061
.. autodecorator:: pyrogram.Client.on_inline_query()
6162
.. autodecorator:: pyrogram.Client.on_chosen_inline_result()
63+
.. autodecorator:: pyrogram.Client.on_chat_member_updated()
6264
.. autodecorator:: pyrogram.Client.on_deleted_messages()
6365
.. autodecorator:: pyrogram.Client.on_user_status()
6466
.. autodecorator:: pyrogram.Client.on_poll()

docs/source/api/handlers.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ Index
4141
- :class:`CallbackQueryHandler`
4242
- :class:`InlineQueryHandler`
4343
- :class:`ChosenInlineResultHandler`
44+
- :class:`ChatMemberUpdated`
4445
- :class:`UserStatusHandler`
4546
- :class:`PollHandler`
4647
- :class:`DisconnectHandler`
@@ -57,6 +58,7 @@ Details
5758
.. autoclass:: CallbackQueryHandler()
5859
.. autoclass:: InlineQueryHandler()
5960
.. autoclass:: ChosenInlineResultHandler()
61+
.. autoclass:: ChatMemberUpdated()
6062
.. autoclass:: UserStatusHandler()
6163
.. autoclass:: PollHandler()
6264
.. autoclass:: DisconnectHandler()

pyrogram/dispatcher.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,15 @@
2626
from pyrogram.handlers import (
2727
CallbackQueryHandler, MessageHandler, DeletedMessagesHandler,
2828
UserStatusHandler, RawUpdateHandler, InlineQueryHandler, PollHandler,
29-
ChosenInlineResultHandler
29+
ChosenInlineResultHandler, ChatMemberUpdatedHandler
3030
)
3131
from pyrogram.raw.types import (
3232
UpdateNewMessage, UpdateNewChannelMessage, UpdateNewScheduledMessage,
3333
UpdateEditMessage, UpdateEditChannelMessage,
3434
UpdateDeleteMessages, UpdateDeleteChannelMessages,
3535
UpdateBotCallbackQuery, UpdateInlineBotCallbackQuery,
3636
UpdateUserStatus, UpdateBotInlineQuery, UpdateMessagePoll,
37-
UpdateBotInlineSend
37+
UpdateBotInlineSend, UpdateChatParticipant, UpdateChannelParticipant
3838
)
3939

4040
log = logging.getLogger(__name__)
@@ -62,6 +62,11 @@ class Dispatcher:
6262
UpdateInlineBotCallbackQuery
6363
)
6464

65+
CHAT_MEMBER_UPDATES = (
66+
UpdateChatParticipant,
67+
UpdateChannelParticipant
68+
)
69+
6570
MESSAGE_UPDATES = NEW_MESSAGE_UPDATES + EDIT_MESSAGE_UPDATES
6671

6772
def __init__(self, client: "pyrogram.Client"):
@@ -98,14 +103,18 @@ async def poll_parser(update, users, chats):
98103
async def chosen_inline_result_parser(update, users, chats):
99104
return pyrogram.types.ChosenInlineResult._parse(self.client, update, users), ChosenInlineResultHandler
100105

106+
async def chat_member_updated_parser(update, users, chats):
107+
return pyrogram.types.ChatMemberUpdated._parse(self.client, update, users, chats), ChatMemberUpdatedHandler
108+
101109
self.update_parsers = {
102110
Dispatcher.MESSAGE_UPDATES: message_parser,
103111
Dispatcher.DELETE_MESSAGES_UPDATES: deleted_messages_parser,
104112
Dispatcher.CALLBACK_QUERY_UPDATES: callback_query_parser,
105113
(UpdateUserStatus,): user_status_parser,
106114
(UpdateBotInlineQuery,): inline_query_parser,
107115
(UpdateMessagePoll,): poll_parser,
108-
(UpdateBotInlineSend,): chosen_inline_result_parser
116+
(UpdateBotInlineSend,): chosen_inline_result_parser,
117+
Dispatcher.CHAT_MEMBER_UPDATES: chat_member_updated_parser
109118
}
110119

111120
self.update_parsers = {key: value for key_tuple, value in self.update_parsers.items() for key in key_tuple}

pyrogram/handlers/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
1818

1919
from .callback_query_handler import CallbackQueryHandler
20+
from .chat_member_updated_handler import ChatMemberUpdatedHandler
2021
from .chosen_inline_result_handler import ChosenInlineResultHandler
2122
from .deleted_messages_handler import DeletedMessagesHandler
2223
from .disconnect_handler import DisconnectHandler
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# Pyrogram - Telegram MTProto API Client Library for Python
2+
# Copyright (C) 2017-2021 Dan <https://github.com/delivrance>
3+
#
4+
# This file is part of Pyrogram.
5+
#
6+
# Pyrogram is free software: you can redistribute it and/or modify
7+
# it under the terms of the GNU Lesser General Public License as published
8+
# by the Free Software Foundation, either version 3 of the License, or
9+
# (at your option) any later version.
10+
#
11+
# Pyrogram is distributed in the hope that it will be useful,
12+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
# GNU Lesser General Public License for more details.
15+
#
16+
# You should have received a copy of the GNU Lesser General Public License
17+
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
18+
19+
from .handler import Handler
20+
21+
22+
class ChatMemberUpdatedHandler(Handler):
23+
"""The ChatMemberUpdated handler class. Used to handle changes in the status of a chat member.
24+
It is intended to be used with :meth:`~pyrogram.Client.add_handler`.
25+
26+
For a nicer way to register this handler, have a look at the
27+
:meth:`~pyrogram.Client.on_chat_member_updated` decorator.
28+
29+
Parameters:
30+
callback (``callable``):
31+
Pass a function that will be called when a new ChatMemberUpdated event arrives. It takes
32+
*(client, chat_member_updated)* as positional arguments (look at the section below for a detailed
33+
description).
34+
35+
filters (:obj:`Filters`):
36+
Pass one or more filters to allow only a subset of updates to be passed in your callback function.
37+
38+
Other parameters:
39+
client (:obj:`~pyrogram.Client`):
40+
The Client itself, useful when you want to call other API methods inside the handler.
41+
42+
chat_member_updated (:obj:`~pyrogram.types.ChatMemberUpdated`):
43+
The received chat member update.
44+
"""
45+
46+
def __init__(self, callback: callable, filters=None):
47+
super().__init__(callback, filters)

pyrogram/methods/decorators/__init__.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
1818

1919
from .on_callback_query import OnCallbackQuery
20+
from .on_chat_member_updated import OnChatMemberUpdated
2021
from .on_chosen_inline_result import OnChosenInlineResult
2122
from .on_deleted_messages import OnDeletedMessages
2223
from .on_disconnect import OnDisconnect
@@ -36,6 +37,7 @@ class Decorators(
3637
OnUserStatus,
3738
OnInlineQuery,
3839
OnPoll,
39-
OnChosenInlineResult
40+
OnChosenInlineResult,
41+
OnChatMemberUpdated
4042
):
4143
pass
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# Pyrogram - Telegram MTProto API Client Library for Python
2+
# Copyright (C) 2017-2021 Dan <https://github.com/delivrance>
3+
#
4+
# This file is part of Pyrogram.
5+
#
6+
# Pyrogram is free software: you can redistribute it and/or modify
7+
# it under the terms of the GNU Lesser General Public License as published
8+
# by the Free Software Foundation, either version 3 of the License, or
9+
# (at your option) any later version.
10+
#
11+
# Pyrogram is distributed in the hope that it will be useful,
12+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
# GNU Lesser General Public License for more details.
15+
#
16+
# You should have received a copy of the GNU Lesser General Public License
17+
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
18+
19+
from typing import Callable
20+
21+
import pyrogram
22+
from pyrogram.filters import Filter
23+
from pyrogram.scaffold import Scaffold
24+
25+
26+
class OnChatMemberUpdated(Scaffold):
27+
def on_chat_member_updated(
28+
self=None,
29+
filters=None,
30+
group: int = 0
31+
) -> callable:
32+
"""Decorator for handling event changes on chat members.
33+
34+
This does the same thing as :meth:`~pyrogram.Client.add_handler` using the
35+
:obj:`~pyrogram.handlers.ChatMemberUpdated`.
36+
37+
Parameters:
38+
filters (:obj:`~pyrogram.filters`, *optional*):
39+
Pass one or more filters to allow only a subset of updates to be passed in your function.
40+
41+
group (``int``, *optional*):
42+
The group identifier, defaults to 0.
43+
"""
44+
45+
def decorator(func: Callable) -> Callable:
46+
if isinstance(self, pyrogram.Client):
47+
self.add_handler(pyrogram.handlers.ChatMemberUpdatedHandler(func, filters), group)
48+
elif isinstance(self, Filter) or self is None:
49+
func.handler = (
50+
pyrogram.handlers.ChatMemberUpdatedHandler(func, self),
51+
group if filters is None else filters
52+
)
53+
54+
return func
55+
56+
return decorator

pyrogram/types/user_and_chats/__init__.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
from .chat_event_filter import ChatEventFilter
2323
from .chat_invite_link import ChatInviteLink
2424
from .chat_member import ChatMember
25+
from .chat_member_updated import ChatMemberUpdated
2526
from .chat_permissions import ChatPermissions
2627
from .chat_photo import ChatPhoto
2728
from .chat_preview import ChatPreview
@@ -49,5 +50,6 @@
4950
"ChatAdminWithInviteLinks",
5051
"VoiceChatStarted",
5152
"VoiceChatEnded",
52-
"VoiceChatMembersInvited"
53+
"VoiceChatMembersInvited",
54+
"ChatMemberUpdated"
5355
]
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# Pyrogram - Telegram MTProto API Client Library for Python
2+
# Copyright (C) 2017-2021 Dan <https://github.com/delivrance>
3+
#
4+
# This file is part of Pyrogram.
5+
#
6+
# Pyrogram is free software: you can redistribute it and/or modify
7+
# it under the terms of the GNU Lesser General Public License as published
8+
# by the Free Software Foundation, either version 3 of the License, or
9+
# (at your option) any later version.
10+
#
11+
# Pyrogram is distributed in the hope that it will be useful,
12+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
# GNU Lesser General Public License for more details.
15+
#
16+
# You should have received a copy of the GNU Lesser General Public License
17+
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
18+
19+
from typing import Dict, Union
20+
21+
import pyrogram
22+
from pyrogram import raw
23+
from pyrogram import types
24+
from ..object import Object
25+
from ..update import Update
26+
27+
28+
class ChatMemberUpdated(Object, Update):
29+
"""Represents changes in the status of a chat member.
30+
31+
Parameters:
32+
chat (:obj:`~pyrogram.types.Chat`):
33+
Chat the user belongs to.
34+
35+
from_user (:obj:`~pyrogram.types.User`):
36+
Performer of the action, which resulted in the change.
37+
38+
date (``int``):
39+
Date the change was done in Unix time.
40+
41+
old_chat_member (:obj:`~pyrogram.types.ChatMember`):
42+
Previous information about the chat member.
43+
44+
new_chat_member (:obj:`~pyrogram.types.ChatMember`):
45+
New information about the chat member.
46+
47+
invite_link (:obj:`~pyrogram.types.ChatInviteLink`, *optional*):
48+
Chat invite link, which was used by the user to join the chat; for joining by invite link events only.
49+
"""
50+
51+
def __init__(
52+
self,
53+
*,
54+
client: "pyrogram.Client" = None,
55+
chat: "types.Chat",
56+
from_user: "types.User",
57+
date: int,
58+
old_chat_member: "types.ChatMember",
59+
new_chat_member: "types.ChatMember",
60+
invite_link: "types.ChatInviteLink" = None,
61+
):
62+
super().__init__(client)
63+
64+
self.chat = chat
65+
self.from_user = from_user
66+
self.date = date
67+
self.old_chat_member = old_chat_member
68+
self.new_chat_member = new_chat_member
69+
self.invite_link = invite_link
70+
71+
@staticmethod
72+
def _parse(
73+
client: "pyrogram.Client",
74+
update: Union["raw.types.UpdateChatParticipant", "raw.types.UpdateChannelParticipant"],
75+
users: Dict[int, "raw.types.User"],
76+
chats: Dict[int, "raw.types.Chat"]
77+
) -> "ChatMemberUpdated":
78+
chat_id = getattr(update, "chat_id", None) or getattr(update, "channel_id")
79+
invite_link = types.ChatInviteLink._parse(client, update.invite, users) if update.invite else None
80+
81+
return ChatMemberUpdated(
82+
chat=types.Chat._parse_chat(client, chats[chat_id]),
83+
from_user=types.User._parse(client, users[update.actor_id]),
84+
date=update.date,
85+
old_chat_member=types.ChatMember._parse(client, update.prev_participant, users),
86+
new_chat_member=types.ChatMember._parse(client, update.new_participant, users),
87+
invite_link=invite_link,
88+
client=client
89+
)

0 commit comments

Comments
 (0)