diff --git a/compiler/docs/compiler.py b/compiler/docs/compiler.py
index 7ce7bc96..53ceb91c 100644
--- a/compiler/docs/compiler.py
+++ b/compiler/docs/compiler.py
@@ -361,6 +361,7 @@ def pyrogram_api():
ChatPhoto
ChatMember
ChatPermissions
+ ChatPrivileges
ChatInviteLink
ChatAdminWithInviteLinks
ChatEvent
diff --git a/pyrogram/methods/chats/iter_chat_members.py b/pyrogram/methods/chats/iter_chat_members.py
index e9fa5b82..3661d506 100644
--- a/pyrogram/methods/chats/iter_chat_members.py
+++ b/pyrogram/methods/chats/iter_chat_members.py
@@ -112,14 +112,14 @@ class IterChatMembers(Scaffold):
offset += len(chat_members)
for chat_member in chat_members:
- user_id = chat_member.user.id
+ peer_id = chat_member.user.id if chat_member.user else chat_member.chat.id
- if user_id in yielded:
+ if peer_id in yielded:
continue
yield chat_member
- yielded.add(chat_member.user.id)
+ yielded.add(peer_id)
current += 1
diff --git a/pyrogram/methods/chats/promote_chat_member.py b/pyrogram/methods/chats/promote_chat_member.py
index 8ab5fe29..b1d43867 100644
--- a/pyrogram/methods/chats/promote_chat_member.py
+++ b/pyrogram/methods/chats/promote_chat_member.py
@@ -18,7 +18,7 @@
from typing import Union
-from pyrogram import raw
+from pyrogram import raw, types
from pyrogram.scaffold import Scaffold
@@ -27,17 +27,7 @@ class PromoteChatMember(Scaffold):
self,
chat_id: Union[int, str],
user_id: Union[int, str],
- is_anonymous: bool = False,
- can_manage_chat: bool = True,
- can_change_info: bool = False,
- can_post_messages: bool = False,
- can_edit_messages: bool = False,
- can_delete_messages: bool = False,
- can_restrict_members: bool = False,
- can_invite_users: bool = False,
- can_pin_messages: bool = False,
- can_promote_members: bool = False,
- can_manage_voice_chats: bool = False
+ privileges: "types.ChatPrivileges" = types.ChatPrivileges(),
) -> bool:
"""Promote or demote a user in a supergroup or a channel.
@@ -52,42 +42,8 @@ class PromoteChatMember(Scaffold):
Unique identifier (int) or username (str) of the target user.
For a contact that exists in your Telegram address book you can use his phone number (str).
- is_anonymous (``bool``, *optional*):
- Pass True, if the administrator's presence in the chat is hidden.
-
- can_manage_chat (``bool``, *optional*):
- 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.
-
- can_change_info (``bool``, *optional*):
- Pass True, if the administrator can change chat title, photo and other settings.
-
- can_post_messages (``bool``, *optional*):
- Pass True, if the administrator can create channel posts, channels only.
-
- can_edit_messages (``bool``, *optional*):
- Pass True, if the administrator can edit messages of other users and can pin messages, channels only.
-
- can_delete_messages (``bool``, *optional*):
- Pass True, if the administrator can delete messages of other users.
-
- can_restrict_members (``bool``, *optional*):
- Pass True, if the administrator can restrict, ban or unban chat members.
-
- can_invite_users (``bool``, *optional*):
- Pass True, if the administrator can invite new users to the chat.
-
- can_pin_messages (``bool``, *optional*):
- Pass True, if the administrator can pin messages, supergroups only.
-
- can_promote_members (``bool``, *optional*):
- Pass True, if the administrator can add new administrators with a subset of his own privileges or
- demote administrators that he has promoted, directly or indirectly (promoted by administrators that
- were appointed by him).
-
- can_manage_voice_chats (``bool``, *optional*):
- Pass True, if the administration can manage voice chats (also called group calls).
+ privileges (:obj:`~pyrogram.types.ChatPrivileges`, *optional*):
+ New user privileges.
Returns:
``bool``: True on success.
@@ -95,27 +51,41 @@ class PromoteChatMember(Scaffold):
Example:
.. code-block:: python
- # Promote chat member to supergroup admin
+ # Promote chat member to admin
app.promote_chat_member(chat_id, user_id)
"""
+ chat_id = await self.resolve_peer(chat_id)
+ user_id = await self.resolve_peer(user_id)
+
+ raw_chat_member = (await self.send(
+ raw.functions.channels.GetParticipant(
+ channel=chat_id,
+ participant=user_id
+ )
+ )).participant
+
+ rank = None
+ if isinstance(raw_chat_member, raw.types.ChannelParticipantAdmin):
+ rank = raw_chat_member.rank
+
await self.send(
raw.functions.channels.EditAdmin(
- channel=await self.resolve_peer(chat_id),
- user_id=await self.resolve_peer(user_id),
+ channel=chat_id,
+ user_id=user_id,
admin_rights=raw.types.ChatAdminRights(
- anonymous=is_anonymous or None,
- change_info=can_change_info or None,
- post_messages=can_post_messages or None,
- edit_messages=can_edit_messages or None,
- delete_messages=can_delete_messages or None,
- ban_users=can_restrict_members or None,
- invite_users=can_invite_users or None,
- pin_messages=can_pin_messages or None,
- add_admins=can_promote_members or None,
- manage_call=can_manage_voice_chats or None,
- other=can_manage_chat or None
+ anonymous=privileges.is_anonymous,
+ change_info=privileges.can_change_info,
+ post_messages=privileges.can_post_messages,
+ edit_messages=privileges.can_edit_messages,
+ delete_messages=privileges.can_delete_messages,
+ ban_users=privileges.can_restrict_members,
+ invite_users=privileges.can_invite_users,
+ pin_messages=privileges.can_pin_messages,
+ add_admins=privileges.can_promote_members,
+ manage_call=privileges.can_manage_voice_chats,
+ other=privileges.can_manage_chat
),
- rank=""
+ rank=rank or ""
)
)
diff --git a/pyrogram/methods/chats/restrict_chat_member.py b/pyrogram/methods/chats/restrict_chat_member.py
index 7c74d685..7a759185 100644
--- a/pyrogram/methods/chats/restrict_chat_member.py
+++ b/pyrogram/methods/chats/restrict_chat_member.py
@@ -77,17 +77,17 @@ class RestrictChatMember(Scaffold):
participant=await self.resolve_peer(user_id),
banned_rights=raw.types.ChatBannedRights(
until_date=until_date,
- send_messages=True if not permissions.can_send_messages else None,
- send_media=True if not permissions.can_send_media_messages else None,
- send_stickers=True if not permissions.can_send_other_messages else None,
- send_gifs=True if not permissions.can_send_other_messages else None,
- send_games=True if not permissions.can_send_other_messages else None,
- send_inline=True if not permissions.can_send_other_messages else None,
- embed_links=True if not permissions.can_add_web_page_previews else None,
- send_polls=True if not permissions.can_send_polls else None,
- change_info=True if not permissions.can_change_info else None,
- invite_users=True if not permissions.can_invite_users else None,
- pin_messages=True if not permissions.can_pin_messages else None,
+ send_messages=not permissions.can_send_messages,
+ send_media=not permissions.can_send_media_messages,
+ send_stickers=not permissions.can_send_other_messages,
+ send_gifs=not permissions.can_send_other_messages,
+ send_games=not permissions.can_send_other_messages,
+ send_inline=not permissions.can_send_other_messages,
+ embed_links=not permissions.can_add_web_page_previews,
+ send_polls=not permissions.can_send_polls,
+ change_info=not permissions.can_change_info,
+ invite_users=not permissions.can_invite_users,
+ pin_messages=not permissions.can_pin_messages,
)
)
)
diff --git a/pyrogram/methods/chats/set_administrator_title.py b/pyrogram/methods/chats/set_administrator_title.py
index 382d1fac..f59cf28a 100644
--- a/pyrogram/methods/chats/set_administrator_title.py
+++ b/pyrogram/methods/chats/set_administrator_title.py
@@ -65,45 +65,12 @@ class SetAdministratorTitle(Scaffold):
)).participant
if isinstance(r, raw.types.ChannelParticipantCreator):
- admin_rights = raw.types.ChatAdminRights(
- change_info=True,
- post_messages=True,
- edit_messages=True,
- delete_messages=True,
- ban_users=True,
- invite_users=True,
- pin_messages=True,
- add_admins=True,
- )
+ admin_rights = raw.types.ChatAdminRights()
elif isinstance(r, raw.types.ChannelParticipantAdmin):
admin_rights = r.admin_rights
else:
raise ValueError("Custom titles can only be applied to owners or administrators of supergroups")
- if not admin_rights.change_info:
- admin_rights.change_info = None
-
- if not admin_rights.post_messages:
- admin_rights.post_messages = None
-
- if not admin_rights.edit_messages:
- admin_rights.edit_messages = None
-
- if not admin_rights.delete_messages:
- admin_rights.delete_messages = None
-
- if not admin_rights.ban_users:
- admin_rights.ban_users = None
-
- if not admin_rights.invite_users:
- admin_rights.invite_users = None
-
- if not admin_rights.pin_messages:
- admin_rights.pin_messages = None
-
- if not admin_rights.add_admins:
- admin_rights.add_admins = None
-
await self.send(
raw.functions.channels.EditAdmin(
channel=chat_id,
diff --git a/pyrogram/types/user_and_chats/__init__.py b/pyrogram/types/user_and_chats/__init__.py
index 4667628a..15ddf8c9 100644
--- a/pyrogram/types/user_and_chats/__init__.py
+++ b/pyrogram/types/user_and_chats/__init__.py
@@ -27,6 +27,7 @@ from .chat_member_updated import ChatMemberUpdated
from .chat_permissions import ChatPermissions
from .chat_photo import ChatPhoto
from .chat_preview import ChatPreview
+from .chat_privileges import ChatPrivileges
from .dialog import Dialog
from .invite_link_importer import InviteLinkImporter
from .restriction import Restriction
@@ -55,5 +56,6 @@ __all__ = [
"VoiceChatMembersInvited",
"ChatMemberUpdated",
"VoiceChatScheduled",
- "ChatJoinRequest"
+ "ChatJoinRequest",
+ "ChatPrivileges"
]
diff --git a/pyrogram/types/user_and_chats/chat_member.py b/pyrogram/types/user_and_chats/chat_member.py
index ff550815..65324dbd 100644
--- a/pyrogram/types/user_and_chats/chat_member.py
+++ b/pyrogram/types/user_and_chats/chat_member.py
@@ -16,9 +16,10 @@
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see .
+from typing import Union, Dict
+
import pyrogram
-from pyrogram import raw
-from pyrogram import types
+from pyrogram import raw, types, utils
from ..object import Object
@@ -26,14 +27,21 @@ class ChatMember(Object):
"""Contains information about one member of a chat.
Parameters:
- user (:obj:`~pyrogram.types.User`):
- Information about the user.
-
status (``str``):
The member's status in the chat.
Can be "creator", "administrator", "member", "restricted", "left" or "banned".
- title (``str``, *optional*):
+ user (:obj:`~pyrogram.types.User`, *optional*):
+ Information about the user.
+
+ chat (:obj:`~pyrogram.types.Chat`, *optional*):
+ Information about the chat (useful in case of banned channel senders).
+
+ joined_date (``int``, *optional*):
+ Date when the user joined, unix time.
+ Not available for the owner.
+
+ custom_title (``str``, *optional*):
A custom title that will be shown to all members instead of "Owner" or "Admin".
Creator (owner) and administrators only. Can be None in case there's no custom title set.
@@ -41,10 +49,6 @@ class ChatMember(Object):
Restricted and banned only.
Date when restrictions will be lifted for this user; unix time.
- joined_date (``int``, *optional*):
- Date when the user joined, unix time.
- Not available for creator.
-
invited_by (:obj:`~pyrogram.types.User`, *optional*):
Administrators and self member only. Information about the user who invited this member.
In case the user joined by himself this will be the same as "user".
@@ -58,268 +62,159 @@ class ChatMember(Object):
is_member (``bool``, *optional*):
Restricted only. True, if the user is a member of the chat at the moment of the request.
- is_anonymous (``bool``, *optional*):
- True, if the user's presence in the chat is hidden.
- Owner and administrators only.
-
can_be_edited (``bool``, *optional*):
- Administrators only.
- True, if you are allowed to edit administrator privileges of the user.
+ True, if the you are allowed to edit administrator privileges of the user.
- can_manage_chat (``bool``, *optional*):
- Administrators only.
- 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.
+ permissions (:obj:`~pyrogram.types.ChatPermissions`, *optional*):
+ Restricted only. Restricted actions that a non-administrator user is allowed to take.
- can_post_messages (``bool``, *optional*):
- Administrators only. Channels only.
- True, if the administrator can post messages in the channel.
-
- can_edit_messages (``bool``, *optional*):
- Administrators only. Channels only.
- True, if the administrator can edit messages of other users and can pin messages.
-
- can_delete_messages (``bool``, *optional*):
- Administrators only.
- True, if the administrator can delete messages of other users.
-
- can_restrict_members (``bool``, *optional*):
- Administrators only.
- True, if the administrator can restrict, ban or unban chat members.
-
- can_promote_members (``bool``, *optional*):
- Administrators only.
- True, if the administrator can add new administrators with a subset of his own privileges or demote
- administrators that he has promoted, directly or indirectly (promoted by administrators that were appointed
- by the user).
-
- can_change_info (``bool``, *optional*):
- Administrators and restricted only.
- True, if the user is allowed to change the chat title, photo and other settings.
-
- can_invite_users (``bool``, *optional*):
- Administrators and restricted only.
- True, if the user is allowed to invite new users to the chat.
-
- can_pin_messages (``bool``, *optional*):
- Administrators and restricted only. Groups and supergroups only.
- True, if the user is allowed to pin messages.
-
- can_manage_voice_chats (``bool``, *optional*):
- Administrators only. Groups and supergroups only.
- True, if the administrator can manage voice chats (also called group calls).
-
- can_send_messages (``bool``, *optional*):
- Restricted only.
- True, if the user is allowed to send text messages, contacts, locations and venues.
-
- can_send_media_messages (``bool``, *optional*):
- Restricted only.
- True, if the user is allowed to send audios, documents, photos, videos, video notes and voice notes.
-
- can_send_stickers (``bool``, *optional*):
- True, if the user is allowed to send stickers, implies can_send_media_messages.
-
- can_send_animations (``bool``, *optional*):
- True, if the user is allowed to send animations (GIFs), implies can_send_media_messages.
-
- can_send_games (``bool``, *optional*):
- True, if the user is allowed to send games, implies can_send_media_messages.
-
- can_use_inline_bots (``bool``, *optional*):
- True, if the user is allowed to use inline bots, implies can_send_media_messages.
-
- can_add_web_page_previews (``bool``, *optional*):
- Restricted only.
- True, if the user is allowed to add web page previews to their messages.
-
- can_send_polls (``bool``, *optional*):
- Restricted only.
- True, if the user is allowed to send polls.
+ privileges (:obj:`~pyrogram.types.ChatPrivileges`, *optional*):
+ Administrators only. Privileged actions that an administrator is able to take.
"""
def __init__(
self,
*,
client: "pyrogram.Client" = None,
- user: "types.User",
status: str,
- title: str = None,
+ user: "types.User" = None,
+ chat: "types.Chat" = None,
+ custom_title: str = None,
until_date: int = None,
joined_date: int = None,
invited_by: "types.User" = None,
promoted_by: "types.User" = None,
restricted_by: "types.User" = None,
is_member: bool = None,
- is_anonymous: bool = None,
-
- # Admin permissions
can_be_edited: bool = None,
- can_manage_chat: bool = None,
- can_post_messages: bool = None, # Channels only
- can_edit_messages: bool = None, # Channels only
- can_delete_messages: bool = None,
- can_restrict_members: bool = None,
- can_promote_members: bool = None,
- can_change_info: bool = None,
- can_invite_users: bool = None,
- can_pin_messages: bool = None, # Groups and supergroups only
- can_manage_voice_chats: bool = None,
-
- # Restricted user permissions
- can_send_messages: bool = None, # Text, contacts, locations and venues
- can_send_media_messages: bool = None, # Audios, documents, photos, videos, video notes and voice notes
- can_send_stickers: bool = None,
- can_send_animations: bool = None,
- can_send_games: bool = None,
- can_use_inline_bots: bool = None,
- can_add_web_page_previews: bool = None,
- can_send_polls: bool = None
+ permissions: "types.ChatPermissions" = None,
+ privileges: "types.ChatPrivileges" = None
):
super().__init__(client)
- self.user = user
self.status = status
- self.title = title
+ self.user = user
+ self.chat = chat
+ self.custom_title = custom_title
self.until_date = until_date
self.joined_date = joined_date
self.invited_by = invited_by
self.promoted_by = promoted_by
self.restricted_by = restricted_by
self.is_member = is_member
- self.is_anonymous = is_anonymous
-
self.can_be_edited = can_be_edited
- self.can_manage_chat = can_manage_chat
- self.can_post_messages = can_post_messages
- self.can_edit_messages = can_edit_messages
- self.can_delete_messages = can_delete_messages
- self.can_restrict_members = can_restrict_members
- self.can_promote_members = can_promote_members
- self.can_change_info = can_change_info
- self.can_invite_users = can_invite_users
- self.can_pin_messages = can_pin_messages
- self.can_manage_voice_chats = can_manage_voice_chats
-
- self.can_send_messages = can_send_messages
- self.can_send_media_messages = can_send_media_messages
- self.can_send_stickers = can_send_stickers
- self.can_send_animations = can_send_animations
- self.can_send_games = can_send_games
- self.can_use_inline_bots = can_use_inline_bots
- self.can_add_web_page_previews = can_add_web_page_previews
- self.can_send_polls = can_send_polls
+ self.permissions = permissions
+ self.privileges = privileges
@staticmethod
- def _parse(client, member, users, chats) -> "ChatMember":
- if not isinstance(member, (raw.types.ChannelParticipantBanned, raw.types.ChannelParticipantLeft)):
- user = types.User._parse(client, users[member.user_id])
- else:
- if isinstance(member.peer, raw.types.PeerUser):
- user = types.User._parse(client, users[member.peer.user_id])
- else:
- user = None
-
- invited_by = (
- types.User._parse(client, users[member.inviter_id])
- if getattr(member, "inviter_id", None) else None
- )
-
- if isinstance(member, (raw.types.ChannelParticipant,
- raw.types.ChannelParticipantSelf,
- raw.types.ChatParticipant)):
+ def _parse(
+ client: "pyrogram.Client",
+ member: Union["raw.base.ChatParticipant", "raw.base.ChannelParticipant"],
+ users: Dict[int, "raw.base.User"],
+ chats: Dict[int, "raw.base.Chat"]
+ ) -> "ChatMember":
+ # Chat participants
+ if isinstance(member, raw.types.ChatParticipant):
return ChatMember(
- user=user,
status="member",
+ user=types.User._parse(client, users[member.user_id]),
joined_date=member.date,
- invited_by=invited_by,
+ invited_by=types.User._parse(client, users[member.inviter_id]),
client=client
)
-
- if isinstance(member, raw.types.ChatParticipantCreator):
+ elif isinstance(member, raw.types.ChatParticipantAdmin):
return ChatMember(
- user=user,
- status="creator",
- client=client
- )
-
- if isinstance(member, raw.types.ChatParticipantAdmin):
- return ChatMember(
- user=user,
status="administrator",
+ user=types.User._parse(client, users[member.user_id]),
joined_date=member.date,
- invited_by=invited_by,
+ invited_by=types.User._parse(client, users[member.inviter_id]),
+ client=client
+ )
+ elif isinstance(member, raw.types.ChatParticipantCreator):
+ return ChatMember(
+ status="owner",
+ user=types.User._parse(client, users[member.user_id]),
client=client
)
- if isinstance(member, raw.types.ChannelParticipantCreator):
- permissions = member.admin_rights
-
+ # Channel participants
+ if isinstance(member, raw.types.ChannelParticipant):
return ChatMember(
- user=user,
- status="creator",
- title=member.rank,
- invited_by=invited_by,
- can_change_info=permissions.change_info,
- can_manage_chat=permissions.other,
- can_post_messages=permissions.post_messages,
- can_edit_messages=permissions.edit_messages,
- can_delete_messages=permissions.delete_messages,
- can_restrict_members=permissions.ban_users,
- can_invite_users=permissions.invite_users,
- can_pin_messages=permissions.pin_messages,
- can_promote_members=permissions.add_admins,
- can_manage_voice_chats=permissions.manage_call,
- is_anonymous=permissions.anonymous,
+ status="member",
+ user=types.User._parse(client, users[member.user_id]),
+ joined_date=member.date,
client=client
)
-
- if isinstance(member, raw.types.ChannelParticipantAdmin):
- permissions = member.admin_rights
-
+ elif isinstance(member, raw.types.ChannelParticipantAdmin):
return ChatMember(
- user=user,
status="administrator",
- title=member.rank,
+ user=types.User._parse(client, users[member.user_id]),
joined_date=member.date,
- invited_by=invited_by,
promoted_by=types.User._parse(client, users[member.promoted_by]),
+ invited_by=types.User._parse(client, users[member.inviter_id]),
+ custom_title=member.rank,
can_be_edited=member.can_edit,
- can_manage_chat=permissions.other,
- can_change_info=permissions.change_info,
- can_post_messages=permissions.post_messages,
- can_edit_messages=permissions.edit_messages,
- can_delete_messages=permissions.delete_messages,
- can_restrict_members=permissions.ban_users,
- can_invite_users=permissions.invite_users,
- can_pin_messages=permissions.pin_messages,
- can_promote_members=permissions.add_admins,
- can_manage_voice_chats=permissions.manage_call,
- is_anonymous=permissions.anonymous,
+ privileges=types.ChatPrivileges._parse(member.admin_rights),
client=client
)
+ elif isinstance(member, raw.types.ChannelParticipantBanned):
+ peer = member.peer
+ peer_id = utils.get_raw_peer_id(peer)
- if isinstance(member, raw.types.ChannelParticipantBanned):
- denied_permissions = member.banned_rights
+ user = (
+ types.User._parse(client, users[peer_id])
+ if isinstance(peer, raw.types.PeerUser) else None
+ )
+
+ chat = (
+ types.Chat._parse_chat(client, chats[peer_id])
+ if not isinstance(peer, raw.types.PeerUser) else None
+ )
return ChatMember(
- user=user,
status="banned" if member.banned_rights.view_messages else "restricted",
- until_date=denied_permissions.until_date,
+ user=user,
+ chat=chat,
+ until_date=member.banned_rights.until_date,
joined_date=member.date,
is_member=not member.left,
restricted_by=types.User._parse(client, users[member.kicked_by]),
- can_send_messages=not denied_permissions.send_messages,
- can_send_media_messages=not denied_permissions.send_media,
- can_send_stickers=not denied_permissions.send_stickers,
- can_send_animations=not denied_permissions.send_gifs,
- can_send_games=not denied_permissions.send_games,
- can_use_inline_bots=not denied_permissions.send_inline,
- can_add_web_page_previews=not denied_permissions.embed_links,
- can_send_polls=not denied_permissions.send_polls,
- can_change_info=not denied_permissions.change_info,
- can_invite_users=not denied_permissions.invite_users,
- can_pin_messages=not denied_permissions.pin_messages,
+ permissions=types.ChatPermissions._parse(member.banned_rights),
+ client=client
+ )
+ elif isinstance(member, raw.types.ChannelParticipantCreator):
+ return ChatMember(
+ status="owner",
+ user=types.User._parse(client, users[member.user_id]),
+ custom_title=member.rank,
+ privileges=types.ChatPrivileges._parse(member.admin_rights),
+ client=client
+ )
+ elif isinstance(member, raw.types.ChannelParticipantLeft):
+ peer = member.peer
+ peer_id = utils.get_raw_peer_id(peer)
+
+ user = (
+ types.User._parse(client, users[peer_id])
+ if isinstance(peer, raw.types.PeerUser) else None
+ )
+
+ chat = (
+ types.Chat._parse_chat(client, chats[peer_id])
+ if not isinstance(peer, raw.types.PeerUser) else None
+ )
+
+ return ChatMember(
+ status="left",
+ user=user,
+ chat=chat,
+ client=client
+ )
+ elif isinstance(member, raw.types.ChannelParticipantSelf):
+ return ChatMember(
+ status="member",
+ user=types.User._parse(client, users[member.user_id]),
+ joined_date=member.date,
+ invited_by=types.User._parse(client, users[member.inviter_id]),
client=client
)
diff --git a/pyrogram/types/user_and_chats/chat_permissions.py b/pyrogram/types/user_and_chats/chat_permissions.py
index e209625a..d920394c 100644
--- a/pyrogram/types/user_and_chats/chat_permissions.py
+++ b/pyrogram/types/user_and_chats/chat_permissions.py
@@ -79,7 +79,7 @@ class ChatPermissions(Object):
self.can_pin_messages = can_pin_messages
@staticmethod
- def _parse(denied_permissions: "raw.types.ChatBannedRights") -> "ChatPermissions":
+ def _parse(denied_permissions: "raw.base.ChatBannedRights") -> "ChatPermissions":
if isinstance(denied_permissions, raw.types.ChatBannedRights):
return ChatPermissions(
can_send_messages=not denied_permissions.send_messages,
diff --git a/pyrogram/types/user_and_chats/chat_privileges.py b/pyrogram/types/user_and_chats/chat_privileges.py
new file mode 100644
index 00000000..403bb957
--- /dev/null
+++ b/pyrogram/types/user_and_chats/chat_privileges.py
@@ -0,0 +1,112 @@
+# Pyrogram - Telegram MTProto API Client Library for Python
+# Copyright (C) 2017-present Dan
+#
+# 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 .
+
+from pyrogram import raw
+from ..object import Object
+
+
+class ChatPrivileges(Object):
+ """Describes privileged actions an administrator is able to take in a chat.
+
+ Parameters:
+ can_manage_chat (``bool``, *optional*):
+ 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.
+
+ can_delete_messages (``bool``, *optional*):
+ True, if the administrator can delete messages of other users.
+
+ can_manage_voice_chats (``bool``, *optional*):
+ Groups and supergroups only.
+ True, if the administrator can manage voice chats (also called group calls).
+
+ can_restrict_members (``bool``, *optional*):
+ True, if the administrator can restrict, ban or unban chat members.
+
+ can_promote_members (``bool``, *optional*):
+ True, if the administrator can add new administrators with a subset of his own privileges or demote
+ administrators that he has promoted, directly or indirectly (promoted by administrators that were appointed
+ by the user).
+
+ can_change_info (``bool``, *optional*):
+ True, if the user is allowed to change the chat title, photo and other settings.
+
+ can_post_messages (``bool``, *optional*):
+ Channels only.
+ True, if the administrator can post messages in the channel.
+
+ can_edit_messages (``bool``, *optional*):
+ Channels only.
+ True, if the administrator can edit messages of other users and can pin messages.
+
+ can_invite_users (``bool``, *optional*):
+ True, if the user is allowed to invite new users to the chat.
+
+ can_pin_messages (``bool``, *optional*):
+ Groups and supergroups only.
+ True, if the user is allowed to pin messages.
+
+ is_anonymous (``bool``, *optional*):
+ True, if the user's presence in the chat is hidden.
+ """
+
+ def __init__(
+ self,
+ *,
+ can_manage_chat: bool = True,
+ can_delete_messages: bool = False,
+ can_manage_voice_chats: bool = False, # Groups and supergroups only
+ can_restrict_members: bool = False,
+ can_promote_members: bool = False,
+ can_change_info: bool = False,
+ can_post_messages: bool = False, # Channels only
+ can_edit_messages: bool = False, # Channels only
+ can_invite_users: bool = False,
+ can_pin_messages: bool = False, # Groups and supergroups only
+ is_anonymous: bool = False
+ ):
+ super().__init__(None)
+
+ self.can_manage_chat: bool = can_manage_chat
+ self.can_delete_messages: bool = can_delete_messages
+ self.can_manage_voice_chats: bool = can_manage_voice_chats
+ self.can_restrict_members: bool = can_restrict_members
+ self.can_promote_members: bool = can_promote_members
+ self.can_change_info: bool = can_change_info
+ self.can_post_messages: bool = can_post_messages
+ self.can_edit_messages: bool = can_edit_messages
+ self.can_invite_users: bool = can_invite_users
+ self.can_pin_messages: bool = can_pin_messages
+ self.is_anonymous: bool = is_anonymous
+
+ @staticmethod
+ def _parse(admin_rights: "raw.base.ChatAdminRights") -> "ChatPrivileges":
+ return ChatPrivileges(
+ can_manage_chat=admin_rights.other,
+ can_delete_messages=admin_rights.delete_messages,
+ can_manage_voice_chats=admin_rights.manage_call,
+ can_restrict_members=admin_rights.ban_users,
+ can_promote_members=admin_rights.add_admins,
+ can_change_info=admin_rights.change_info,
+ can_post_messages=admin_rights.post_messages,
+ can_edit_messages=admin_rights.edit_messages,
+ can_invite_users=admin_rights.invite_users,
+ can_pin_messages=admin_rights.pin_messages,
+ is_anonymous=admin_rights.anonymous
+ )
diff --git a/pyrogram/types/user_and_chats/user.py b/pyrogram/types/user_and_chats/user.py
index 8579ba15..ac141033 100644
--- a/pyrogram/types/user_and_chats/user.py
+++ b/pyrogram/types/user_and_chats/user.py
@@ -206,8 +206,8 @@ class User(Object, Update):
return Link(f"tg://user?id={self.id}", self.first_name, self._client.parse_mode)
@staticmethod
- def _parse(client, user: "raw.types.User") -> Optional["User"]:
- if user is None:
+ def _parse(client, user: "raw.base.User") -> Optional["User"]:
+ if user is None or isinstance(user, raw.types.UserEmpty):
return None
return User(