diff --git a/compiler/docs/compiler.py b/compiler/docs/compiler.py index 9b9aa49d..78328459 100644 --- a/compiler/docs/compiler.py +++ b/compiler/docs/compiler.py @@ -191,7 +191,6 @@ def pyrogram_api(): restrict_chat_member promote_chat_member set_administrator_title - export_chat_invite_link set_chat_photo delete_chat_photo set_chat_title @@ -238,6 +237,20 @@ def pyrogram_api(): unblock_user get_common_chats """, + invite_links=""" + Invite Links + export_chat_invite_link + create_chat_invite_link + edit_chat_invite_link + revoke_chat_invite_link + delete_chat_invite_link + delete_all_chat_invite_links + get_chat_invite_links + get_chat_invite_links_count + get_chat_invite_link_members + get_chat_invite_link_members_count + get_chat_admins_with_invite_links + """, contacts=""" Contacts add_contacts @@ -332,6 +345,8 @@ def pyrogram_api(): ChatPhoto ChatMember ChatPermissions + ChatInviteLink + ChatAdminWithInviteLinks ChatEvent ChatEventFilter Dialog diff --git a/compiler/docs/template/methods.rst b/compiler/docs/template/methods.rst index f99605ca..dc2950dc 100644 --- a/compiler/docs/template/methods.rst +++ b/compiler/docs/template/methods.rst @@ -88,6 +88,19 @@ Users {users} +Invite Links +------------ + +.. autosummary:: + :nosignatures: + + {invite_links} + +.. toctree:: + :hidden: + + {invite_links} + Contacts -------- diff --git a/pyrogram/methods/__init__.py b/pyrogram/methods/__init__.py index 728af9a2..ee453ce3 100644 --- a/pyrogram/methods/__init__.py +++ b/pyrogram/methods/__init__.py @@ -22,6 +22,7 @@ from .bots import Bots from .chats import Chats from .contacts import Contacts from .decorators import Decorators +from .invite_links import InviteLinks from .messages import Messages from .password import Password from .users import Users @@ -38,6 +39,7 @@ class Methods( Users, Messages, Decorators, - Utilities + Utilities, + InviteLinks, ): pass diff --git a/pyrogram/methods/chats/__init__.py b/pyrogram/methods/chats/__init__.py index 62dfd5bd..8aeb5fe4 100644 --- a/pyrogram/methods/chats/__init__.py +++ b/pyrogram/methods/chats/__init__.py @@ -25,7 +25,6 @@ from .delete_channel import DeleteChannel from .delete_chat_photo import DeleteChatPhoto from .delete_supergroup import DeleteSupergroup from .delete_user_history import DeleteUserHistory -from .export_chat_invite_link import ExportChatInviteLink from .get_chat import GetChat from .get_chat_event_log import GetChatEventLog from .get_chat_member import GetChatMember @@ -58,7 +57,6 @@ from .update_chat_username import UpdateChatUsername class Chats( GetChat, - ExportChatInviteLink, LeaveChat, JoinChat, KickChatMember, diff --git a/pyrogram/methods/chats/set_chat_photo.py b/pyrogram/methods/chats/set_chat_photo.py index 81260989..e1114490 100644 --- a/pyrogram/methods/chats/set_chat_photo.py +++ b/pyrogram/methods/chats/set_chat_photo.py @@ -21,8 +21,8 @@ from typing import Union, BinaryIO from pyrogram import raw from pyrogram import utils -from pyrogram.scaffold import Scaffold from pyrogram.file_id import FileType +from pyrogram.scaffold import Scaffold class SetChatPhoto(Scaffold): diff --git a/pyrogram/methods/invite_links/__init__.py b/pyrogram/methods/invite_links/__init__.py new file mode 100644 index 00000000..17b1abbe --- /dev/null +++ b/pyrogram/methods/invite_links/__init__.py @@ -0,0 +1,46 @@ +# Pyrogram - Telegram MTProto API Client Library for Python +# Copyright (C) 2017-2021 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 .create_chat_invite_link import CreateChatInviteLink +from .delete_all_chat_invite_links import DeleteAllChatInviteLinks +from .delete_chat_invite_link import DeleteChatInviteLink +from .edit_chat_invite_link import EditChatInviteLink +from .export_chat_invite_link import ExportChatInviteLink +from .get_chat_admins_with_invite_links import GetChatAdminsWithInviteLinks +from .get_chat_invite_link_members import GetChatInviteLinkMembers +from .get_chat_invite_link_members_count import GetChatInviteLinkMembersCount +from .get_chat_invite_links import GetChatInviteLinks +from .get_chat_invite_links_count import GetChatInviteLinksCount +from .revoke_chat_invite_link import RevokeChatInviteLink + + +class InviteLinks( + RevokeChatInviteLink, + DeleteChatInviteLink, + EditChatInviteLink, + CreateChatInviteLink, + GetChatInviteLinkMembers, + GetChatInviteLinkMembersCount, + GetChatInviteLinks, + ExportChatInviteLink, + DeleteAllChatInviteLinks, + GetChatInviteLinksCount, + GetChatAdminsWithInviteLinks +): + pass diff --git a/pyrogram/methods/invite_links/create_chat_invite_link.py b/pyrogram/methods/invite_links/create_chat_invite_link.py new file mode 100644 index 00000000..006e7e14 --- /dev/null +++ b/pyrogram/methods/invite_links/create_chat_invite_link.py @@ -0,0 +1,73 @@ +# Pyrogram - Telegram MTProto API Client Library for Python +# Copyright (C) 2017-2021 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 typing import Union + +from pyrogram import raw +from pyrogram import types +from pyrogram.scaffold import Scaffold + + +class CreateChatInviteLink(Scaffold): + async def create_chat_invite_link( + self, + chat_id: Union[int, str], + expire_date: int = None, + member_limit: int = None, + ) -> "types.ChatInviteLink": + """Create an additional invite link for a chat. + + You 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 :meth:`~pyrogram.Client.revoke_chat_invite_link`. + + Parameters: + chat_id (``int`` | ``str``): + Unique identifier for the target chat or username of the target channel/supergroup + (in the format @username). + + expire_date (``int``, *optional*): + Point in time (Unix timestamp) when the link will expire. + Defaults to None (no expiration date). + + member_limit (``int``, *optional*): + Maximum number of users that can be members of the chat simultaneously after joining the chat via + this invite link; 1-99999. + Defaults to None (no member limit). + + Returns: + :obj:`~pyrogram.types.ChatInviteLink`: On success, the new invite link is returned. + + Example: + .. code-block:: python + + # Create a new link without limits + link = app.create_chat_invite_link(chat_id) + + # Create a new link for up to 7 new users + link = app.create_chat_invite_link(chat_id, member_limit=7) + """ + r = await self.send( + raw.functions.messages.ExportChatInvite( + peer=await self.resolve_peer(chat_id), + expire_date=expire_date, + usage_limit=member_limit, + ) + ) + + return types.ChatInviteLink._parse(self, r) diff --git a/pyrogram/methods/invite_links/delete_all_chat_invite_links.py b/pyrogram/methods/invite_links/delete_all_chat_invite_links.py new file mode 100644 index 00000000..ea1738b9 --- /dev/null +++ b/pyrogram/methods/invite_links/delete_all_chat_invite_links.py @@ -0,0 +1,52 @@ +# Pyrogram - Telegram MTProto API Client Library for Python +# Copyright (C) 2017-2021 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 typing import Union + +from pyrogram import raw +from pyrogram.scaffold import Scaffold + + +class DeleteAllChatInviteLinks(Scaffold): + async def delete_all_chat_invite_links( + self, + chat_id: Union[int, str], + admin_id: Union[int, str], + ) -> bool: + """Delete all revoked invite links of an administrator. + + Parameters: + chat_id (``int`` | ``str``): + Unique identifier for the target chat or username of the target channel/supergroup + (in the format @username). + + admin_id (``int`` | ``str``): + Unique identifier (int) or username (str) of the target user. + For you yourself you can simply use "me" or "self". + For a contact that exists in your Telegram address book you can use his phone number (str). + + Returns: + ``bool``: On success ``True`` is returned. + """ + + return await self.send( + raw.functions.messages.DeleteRevokedExportedChatInvites( + peer=await self.resolve_peer(chat_id), + admin_id=await self.resolve_peer(admin_id), + ) + ) diff --git a/pyrogram/methods/invite_links/delete_chat_invite_link.py b/pyrogram/methods/invite_links/delete_chat_invite_link.py new file mode 100644 index 00000000..987cc781 --- /dev/null +++ b/pyrogram/methods/invite_links/delete_chat_invite_link.py @@ -0,0 +1,50 @@ +# Pyrogram - Telegram MTProto API Client Library for Python +# Copyright (C) 2017-2021 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 typing import Union + +from pyrogram import raw +from pyrogram.scaffold import Scaffold + + +class DeleteChatInviteLink(Scaffold): + async def delete_chat_invite_link( + self, + chat_id: Union[int, str], + invite_link: str, + ) -> bool: + """Delete an already revoked invite link. + + Parameters: + chat_id (``int`` | ``str``): + Unique identifier for the target chat or username of the target channel/supergroup + (in the format @username). + + invite_link (``str``): + The revoked invite link to delete. + + Returns: + ``bool``: On success ``True`` is returned. + """ + + return await self.send( + raw.functions.messages.DeleteExportedChatInvite( + peer=await self.resolve_peer(chat_id), + link=invite_link, + ) + ) diff --git a/pyrogram/methods/invite_links/edit_chat_invite_link.py b/pyrogram/methods/invite_links/edit_chat_invite_link.py new file mode 100644 index 00000000..07c84d3c --- /dev/null +++ b/pyrogram/methods/invite_links/edit_chat_invite_link.py @@ -0,0 +1,78 @@ +# Pyrogram - Telegram MTProto API Client Library for Python +# Copyright (C) 2017-2021 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 typing import Union + +from pyrogram import raw +from pyrogram import types +from pyrogram.scaffold import Scaffold + + +class EditChatInviteLink(Scaffold): + async def edit_chat_invite_link( + self, + chat_id: Union[int, str], + invite_link: str, + expire_date: int = None, + member_limit: int = None, + ) -> "types.ChatInviteLink": + """Edit a non-primary invite link. + + You must be an administrator in the chat for this to work and must have the appropriate admin rights. + + Parameters: + chat_id (``int`` | ``str``): + Unique identifier for the target chat or username of the target channel/supergroup + (in the format @username). + + invite_link (``str``): + The invite link to edit + + expire_date (``int``, *optional*): + Point in time (Unix timestamp) when the link will expire. + Defaults to None (no change), pass 0 to set no expiration date. + + member_limit (``int``, *optional*): + Maximum number of users that can be members of the chat simultaneously after joining the chat via this + invite link; 1-99999. + Defaults to None (no change), pass 0 to set no member limit. + + Returns: + :obj:`~pyrogram.types.ChatInviteLink`: On success, the new invite link is returned + + Example: + .. code-block:: python + + # Edit the member limit of a link + link = app.edit_chat_invite_link(chat_id, invite_link, member_limit=9) + + # Set no expiration date of a link + link = app.edit_chat_invite_link(chat_id, invite_link, expire_date=0) + """ + r = await self.send( + raw.functions.messages.EditExportedChatInvite( + peer=await self.resolve_peer(chat_id), + link=invite_link, + expire_date=expire_date, + usage_limit=member_limit, + ) + ) + + users = {i.id: i for i in r.users} + + return types.ChatInviteLink._parse(self, r.invite, users) diff --git a/pyrogram/methods/chats/export_chat_invite_link.py b/pyrogram/methods/invite_links/export_chat_invite_link.py similarity index 72% rename from pyrogram/methods/chats/export_chat_invite_link.py rename to pyrogram/methods/invite_links/export_chat_invite_link.py index 9fbaf8b6..ee59750c 100644 --- a/pyrogram/methods/chats/export_chat_invite_link.py +++ b/pyrogram/methods/invite_links/export_chat_invite_link.py @@ -19,20 +19,20 @@ from typing import Union from pyrogram import raw +from pyrogram import types from pyrogram.scaffold import Scaffold class ExportChatInviteLink(Scaffold): async def export_chat_invite_link( self, - chat_id: Union[int, str] - ) -> str: - """Generate a new invite link for a chat; any previously generated link is revoked. + chat_id: Union[int, str], + ) -> "types.ChatInviteLink": + """Generate a new primary invite link for a chat; any previously generated primary link is revoked. - You must be an administrator in the chat for this to work and have the appropriate admin rights. + You must be an administrator in the chat for this to work and must have the appropriate admin rights. .. note :: - Each administrator in a chat generates their own invite links. Bots can't use invite links generated by other administrators. If you want your bot to work with invite links, it will need to generate its own link using this method – after this the link will become available to the bot via the @@ -45,24 +45,19 @@ class ExportChatInviteLink(Scaffold): (in the format @username). Returns: - ``str``: On success, the exported invite link is returned. - - Raises: - ValueError: In case the chat_id belongs to a user. + ``str``: On success, the new invite link as string is returned. Example: .. code-block:: python + # Generate a new primary link link = app.export_chat_invite_link(chat_id) - print(link) """ - peer = await self.resolve_peer(chat_id) + r = await self.send( + raw.functions.messages.ExportChatInvite( + peer=await self.resolve_peer(chat_id), + legacy_revoke_permanent=True + ) + ) - if isinstance(peer, (raw.types.InputPeerChat, raw.types.InputPeerChannel)): - return (await self.send( - raw.functions.messages.ExportChatInvite( - peer=peer - ) - )).link - else: - raise ValueError(f'The chat_id "{chat_id}" belongs to a user') + return r.link diff --git a/pyrogram/methods/invite_links/get_chat_admins_with_invite_links.py b/pyrogram/methods/invite_links/get_chat_admins_with_invite_links.py new file mode 100644 index 00000000..1f2cc1c1 --- /dev/null +++ b/pyrogram/methods/invite_links/get_chat_admins_with_invite_links.py @@ -0,0 +1,54 @@ +# Pyrogram - Telegram MTProto API Client Library for Python +# Copyright (C) 2017-2021 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 typing import Union + +from pyrogram import raw, types +from pyrogram.scaffold import Scaffold + + +class GetChatAdminsWithInviteLinks(Scaffold): + async def get_chat_admins_with_invite_links( + self, + chat_id: Union[int, str], + ): + """Get the list of the administrators that have exported invite links in a chat. + + You must be the owner of a chat for this to work. + + Args: + chat_id (``int`` | ``str``): + Unique identifier for the target chat or username of the target channel/supergroup + (in the format @username). + + Returns: + List of :obj:`~pyrogram.types.ChatAdminWithInviteLink`: On success, the list of admins that have exported + invite links is returned. + """ + r = await self.send( + raw.functions.messages.GetAdminsWithInvites( + peer=await self.resolve_peer(chat_id) + ) + ) + + users = {i.id: i for i in r.users} + + return types.List( + types.ChatAdminWithInviteLinks._parse(self, admin, users) + for admin in r.admins + ) diff --git a/pyrogram/methods/invite_links/get_chat_invite_link_members.py b/pyrogram/methods/invite_links/get_chat_invite_link_members.py new file mode 100644 index 00000000..e48422ea --- /dev/null +++ b/pyrogram/methods/invite_links/get_chat_invite_link_members.py @@ -0,0 +1,91 @@ +# Pyrogram - Telegram MTProto API Client Library for Python +# Copyright (C) 2017-2021 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 typing import Union, Optional, AsyncGenerator + +from pyrogram import raw +from pyrogram import types +from pyrogram.scaffold import Scaffold + + +class GetChatInviteLinkMembers(Scaffold): + async def get_chat_invite_link_members( + self, + chat_id: Union[int, str], + invite_link: str, + limit: int = 0 + ) -> Optional[AsyncGenerator["types.ChatMember", None]]: + """Get the members who joined the chat with the invite link. + + Parameters: + chat_id (``int`` | ``str``): + Unique identifier for the target chat or username of the target channel/supergroup + (in the format @username). + + invite_link (str): + The invite link. + + limit (``int``, *optional*): + Limits the number of invite links to be retrieved. + By default, no limit is applied and all invite links are returned. + + Returns: + ``Generator``: A generator yielding :obj:`~pyrogram.types.ChatMember` objects. + + Yields: + :obj:`~pyrogram.types.ChatMember` objects. + """ + current = 0 + total = abs(limit) or (1 << 31) - 1 + limit = min(100, total) + + offset_date = 0 + offset_user = raw.types.InputUserEmpty() + + while True: + r = await self.send( + raw.functions.messages.GetChatInviteImporters( + peer=await self.resolve_peer(chat_id), + link=invite_link, + limit=limit, + offset_date=offset_date, + offset_user=offset_user + ) + ) + + if not r.importers: + break + + users = {i.id: i for i in r.users} + + offset_date = r.importers[-1].date + offset_user = await self.resolve_peer(r.importers[-1].user_id) + + for i in r.importers: + user = types.User._parse(self, users[i.user_id]) + + yield types.ChatMember( + user=user, + status="member", + joined_date=i.date + ) + + current += 1 + + if current >= total: + return diff --git a/pyrogram/methods/invite_links/get_chat_invite_link_members_count.py b/pyrogram/methods/invite_links/get_chat_invite_link_members_count.py new file mode 100644 index 00000000..bd6a2fcc --- /dev/null +++ b/pyrogram/methods/invite_links/get_chat_invite_link_members_count.py @@ -0,0 +1,54 @@ +# Pyrogram - Telegram MTProto API Client Library for Python +# Copyright (C) 2017-2021 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 typing import Union + +from pyrogram import raw +from pyrogram.scaffold import Scaffold + + +class GetChatInviteLinkMembersCount(Scaffold): + async def get_chat_invite_link_members_count( + self, + chat_id: Union[int, str], + invite_link: str + ) -> int: + """Get the count of the members who joined the chat with the invite link. + + Parameters: + chat_id (``int`` | ``str``): + Unique identifier for the target chat or username of the target channel/supergroup + (in the format @username). + + invite_link (str): + The invite link. + + Returns: + ``int``: On success, the joined chat members count is returned. + """ + r = await self.send( + raw.functions.messages.GetChatInviteImporters( + peer=await self.resolve_peer(chat_id), + link=invite_link, + limit=1, + offset_date=0, + offset_user=raw.types.InputUserEmpty() + ) + ) + + return r.count diff --git a/pyrogram/methods/invite_links/get_chat_invite_links.py b/pyrogram/methods/invite_links/get_chat_invite_links.py new file mode 100644 index 00000000..17d28a0c --- /dev/null +++ b/pyrogram/methods/invite_links/get_chat_invite_links.py @@ -0,0 +1,98 @@ +# Pyrogram - Telegram MTProto API Client Library for Python +# Copyright (C) 2017-2021 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 typing import Union, Optional, AsyncGenerator + +from pyrogram import raw +from pyrogram import types +from pyrogram.scaffold import Scaffold + + +class GetChatInviteLinks(Scaffold): + async def get_chat_invite_links( + self, + chat_id: Union[int, str], + admin_id: Union[int, str], + revoked: bool = False, + limit: int = 0, + ) -> Optional[AsyncGenerator["types.ChatInviteLink", None]]: + """Get the invite links created by an administrator in a chat. + + .. note:: + + As an administrator you can only get your own links you have exported. + As the chat or channel owner you can get everyones links. + + Parameters: + chat_id (``int`` | ``str``): + Unique identifier for the target chat or username of the target channel/supergroup + (in the format @username). + + admin_id (``int`` | ``str``): + Unique identifier (int) or username (str) of the target user. + For you yourself you can simply use "me" or "self". + For a contact that exists in your Telegram address book you can use his phone number (str). + + revoked (``bool``, *optional*): + True, if you want to get revoked links instead. + Defaults to False (get active links only). + + limit (``int``, *optional*): + Limits the number of invite links to be retrieved. + By default, no limit is applied and all invite links are returned. + + Returns: + ``Generator``: A generator yielding :obj:`~pyrogram.types.ChatInviteLink` objects. + + Yields: + :obj:`~pyrogram.types.ChatInviteLink` objects. + """ + current = 0 + total = abs(limit) or (1 << 31) - 1 + limit = min(100, total) + + offset_date = None + offset_link = None + + while True: + r = await self.send( + raw.functions.messages.GetExportedChatInvites( + peer=await self.resolve_peer(chat_id), + admin_id=await self.resolve_peer(admin_id), + limit=limit, + revoked=revoked, + offset_date=offset_date, + offset_link=offset_link + ) + ) + + if not r.invites: + break + + users = {i.id: i for i in r.users} + + offset_date = r.invites[-1].date + offset_link = r.invites[-1].link + + for i in r.invites: + yield types.ChatInviteLink._parse(self, i, users) + + current += 1 + + if current >= total: + return diff --git a/pyrogram/methods/invite_links/get_chat_invite_links_count.py b/pyrogram/methods/invite_links/get_chat_invite_links_count.py new file mode 100644 index 00000000..52d3528b --- /dev/null +++ b/pyrogram/methods/invite_links/get_chat_invite_links_count.py @@ -0,0 +1,60 @@ +# Pyrogram - Telegram MTProto API Client Library for Python +# Copyright (C) 2017-2021 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 typing import Union + +from pyrogram import raw +from pyrogram.scaffold import Scaffold + + +class GetChatInviteLinksCount(Scaffold): + async def get_chat_invite_links_count( + self, + chat_id: Union[int, str], + admin_id: Union[int, str], + revoked: bool = False, + ) -> int: + """Get the count of the invite links created by an administrator in a chat. + + Parameters: + chat_id (``int`` | ``str``): + Unique identifier for the target chat or username of the target channel/supergroup + (in the format @username). + + admin_id (``int`` | ``str``): + Unique identifier (int) or username (str) of the target user. + For you yourself you can simply use "me" or "self". + For a contact that exists in your Telegram address book you can use his phone number (str). + + revoked (``bool``, *optional*): + True, if you want to get revoked links instead. + Defaults to False (get active links only). + + Returns: + ``int``: On success, the invite links count is returned. + """ + r = await self.send( + raw.functions.messages.GetExportedChatInvites( + peer=await self.resolve_peer(chat_id), + admin_id=await self.resolve_peer(admin_id), + limit=1, + revoked=revoked + ) + ) + + return r.count diff --git a/pyrogram/methods/invite_links/revoke_chat_invite_link.py b/pyrogram/methods/invite_links/revoke_chat_invite_link.py new file mode 100644 index 00000000..b49a51dd --- /dev/null +++ b/pyrogram/methods/invite_links/revoke_chat_invite_link.py @@ -0,0 +1,66 @@ +# Pyrogram - Telegram MTProto API Client Library for Python +# Copyright (C) 2017-2021 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 typing import Union + +from pyrogram import raw +from pyrogram import types +from pyrogram.scaffold import Scaffold + + +class RevokeChatInviteLink(Scaffold): + async def revoke_chat_invite_link( + self, + chat_id: Union[int, str], + invite_link: str, + ) -> "types.ChatInviteLink": + """Revoke a previously created invite link. + + If the primary link is revoked, a new link is automatically generated. + + You must be an administrator in the chat for this to work and must have the appropriate admin rights. + + Parameters: + chat_id (``int`` | ``str``): + Unique identifier for the target chat or username of the target channel/supergroup + (in the format @username). + + invite_link (``str``): + The invite link to revoke. + + Returns: + :obj:`~pyrogram.types.ChatInviteLink`: On success, the invite link object is returned. + """ + + r = await self.send( + raw.functions.messages.EditExportedChatInvite( + peer=await self.resolve_peer(chat_id), + link=invite_link, + revoked=True + ) + ) + + users = {i.id: i for i in r.users} + + chat_invite = ( + r.new_invite + if isinstance(r, raw.types.messages.ExportedChatInviteReplaced) + else r.invite + ) + + return types.ChatInviteLink._parse(self, chat_invite, users) diff --git a/pyrogram/methods/messages/edit_inline_media.py b/pyrogram/methods/messages/edit_inline_media.py index 1d32eec3..e941c131 100644 --- a/pyrogram/methods/messages/edit_inline_media.py +++ b/pyrogram/methods/messages/edit_inline_media.py @@ -21,9 +21,9 @@ import re from pyrogram import raw from pyrogram import types from pyrogram import utils +from pyrogram.file_id import FileType from pyrogram.scaffold import Scaffold from .inline_session import get_session -from pyrogram.file_id import FileType class EditInlineMedia(Scaffold): diff --git a/pyrogram/methods/messages/get_media_group.py b/pyrogram/methods/messages/get_media_group.py index cf01a8ed..7c5249e9 100644 --- a/pyrogram/methods/messages/get_media_group.py +++ b/pyrogram/methods/messages/get_media_group.py @@ -19,8 +19,8 @@ import logging from typing import Union, List -from pyrogram.scaffold import Scaffold from pyrogram import types +from pyrogram.scaffold import Scaffold log = logging.getLogger(__name__) @@ -49,7 +49,8 @@ class GetMediaGroup(Scaffold): ValueError: In case the passed message id doesn't belong to a media group. """ # There can be maximum 10 items in a media group. - messages = await self.get_messages(chat_id, [msg_id for msg_id in range(message_id - 9, message_id + 10)], replies=0) + messages = await self.get_messages(chat_id, [msg_id for msg_id in range(message_id - 9, message_id + 10)], + replies=0) media_group_id = messages[9].media_group_id diff --git a/pyrogram/methods/utilities/restart.py b/pyrogram/methods/utilities/restart.py index 9d5b7d3a..afd22bb4 100644 --- a/pyrogram/methods/utilities/restart.py +++ b/pyrogram/methods/utilities/restart.py @@ -16,8 +16,6 @@ # You should have received a copy of the GNU Lesser General Public License # along with Pyrogram. If not, see . -import asyncio - from pyrogram.scaffold import Scaffold diff --git a/pyrogram/methods/utilities/stop.py b/pyrogram/methods/utilities/stop.py index acf28f28..38f0d4c4 100644 --- a/pyrogram/methods/utilities/stop.py +++ b/pyrogram/methods/utilities/stop.py @@ -16,8 +16,6 @@ # You should have received a copy of the GNU Lesser General Public License # along with Pyrogram. If not, see . -import asyncio - from pyrogram.scaffold import Scaffold diff --git a/pyrogram/scaffold.py b/pyrogram/scaffold.py index a0033599..434c5bb4 100644 --- a/pyrogram/scaffold.py +++ b/pyrogram/scaffold.py @@ -41,7 +41,8 @@ class Scaffold: PARENT_DIR = Path(sys.argv[0]).parent - INVITE_LINK_RE = re.compile(r"^(?:https?://)?(?:www\.)?(?:t(?:elegram)?\.(?:org|me|dog)/joinchat/)([\w-]+)$") + # https://regex101.com/r/pme5ZE/2 Matches both the entire link and the hash itself + INVITE_LINK_RE = re.compile(r"^(?:(?:https?://)?(?:www\.)?(?:t(?:elegram)?\.(?:org|me|dog)/joinchat/))?(?P[\w-]+)$") WORKERS = min(32, os.cpu_count() + 4) WORKDIR = PARENT_DIR CONFIG_FILE = PARENT_DIR / "config.ini" diff --git a/pyrogram/types/user_and_chats/__init__.py b/pyrogram/types/user_and_chats/__init__.py index 0c776c99..7c4a65da 100644 --- a/pyrogram/types/user_and_chats/__init__.py +++ b/pyrogram/types/user_and_chats/__init__.py @@ -17,17 +17,31 @@ # along with Pyrogram. If not, see . from .chat import Chat +from .chat_admin_with_invite_links import ChatAdminWithInviteLinks from .chat_event import ChatEvent +from .chat_event_filter import ChatEventFilter +from .chat_invite_link import ChatInviteLink from .chat_member import ChatMember from .chat_permissions import ChatPermissions from .chat_photo import ChatPhoto from .chat_preview import ChatPreview from .dialog import Dialog +from .invite_link_importer import InviteLinkImporter from .restriction import Restriction from .user import User -from .chat_event_filter import ChatEventFilter __all__ = [ - "Chat", "ChatMember", "ChatPermissions", "ChatPhoto", "ChatPreview", "Dialog", "User", "Restriction", "ChatEvent", - "ChatEventFilter" + "Chat", + "ChatMember", + "ChatPermissions", + "ChatPhoto", + "ChatPreview", + "Dialog", + "User", + "Restriction", + "ChatEvent", + "ChatEventFilter", + "ChatInviteLink", + "InviteLinkImporter", + "ChatAdminWithInviteLinks" ] diff --git a/pyrogram/types/user_and_chats/chat_admin_with_invite_links.py b/pyrogram/types/user_and_chats/chat_admin_with_invite_links.py new file mode 100644 index 00000000..c7e617e9 --- /dev/null +++ b/pyrogram/types/user_and_chats/chat_admin_with_invite_links.py @@ -0,0 +1,63 @@ +# Pyrogram - Telegram MTProto API Client Library for Python +# Copyright (C) 2017-2021 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 typing import Dict + +import pyrogram +from pyrogram import raw +from pyrogram import types +from ..object import Object + + +class ChatAdminWithInviteLinks(Object): + """Represents a chat administrator that has created invite links in a chat. + + Parameters: + admin (:obj:`~pyrogram.types.User`): + The administrator. + + chat_invite_links_count (``int``): + The number of valid chat invite links created by this administrator. + + revoked_chat_invite_links_count (``int``): + The number of revoked chat invite links created by this administrator. + """ + + def __init__( + self, *, + admin: "types.User", + chat_invite_links_count: int, + revoked_chat_invite_links_count: int = None + ): + super().__init__() + + self.admin = admin + self.chat_invite_links_count = chat_invite_links_count + self.revoked_chat_invite_links_count = revoked_chat_invite_links_count + + @staticmethod + def _parse( + client: "pyrogram.Client", + admin: "raw.types.ChatAdminWithInvites", + users: Dict[int, "raw.types.User"] = None + ) -> "ChatAdminWithInviteLinks": + return ChatAdminWithInviteLinks( + admin=types.User._parse(client, users[admin.admin_id]), + chat_invite_links_count=admin.invites_count, + revoked_chat_invite_links_count=admin.revoked_invites_count + ) diff --git a/pyrogram/types/user_and_chats/chat_invite_link.py b/pyrogram/types/user_and_chats/chat_invite_link.py new file mode 100644 index 00000000..cee80dd4 --- /dev/null +++ b/pyrogram/types/user_and_chats/chat_invite_link.py @@ -0,0 +1,102 @@ +# Pyrogram - Telegram MTProto API Client Library for Python +# Copyright (C) 2017-2021 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 typing import Dict + +import pyrogram +from pyrogram import raw +from pyrogram import types +from ..object import Object + + +class ChatInviteLink(Object): + """An invite link for a chat. + + Parameters: + invite_link (``str``): + The invite link. + + date (``int``): + The date in Unix timestamp when the link was created. + + is_primary (``bool``): + True, if the link is primary. + + is_revoked (``bool``): + True, if the link is revoked. + + creator (:obj:`~pyrogram.types.User`, *optional*): + Creator of the link. + + expire_date (``int``, *optional*): + Point in time (Unix timestamp) when the link will expire or has been expired. + + member_limit (``int``, *optional*): + Maximum number of users that can be members of the chat simultaneously after joining the chat via this + invite link; 1-99999. + + member_count (``int``, *optional*): + Number of users that joined via this link and are currently member of the chat. + """ + + def __init__( + self, *, + invite_link: str, + creator: "types.User", + date: int, + is_primary: bool = None, + is_revoked: bool = None, + start_date: int = None, + expire_date: int = None, + member_limit: int = None, + member_count: int = None + ): + super().__init__() + + self.invite_link = invite_link + self.creator = creator + self.date = date + self.is_primary = is_primary + self.is_revoked = is_revoked + self.start_date = start_date + self.expire_date = expire_date + self.member_limit = member_limit + self.member_count = member_count + + @staticmethod + def _parse( + client: "pyrogram.Client", + invite: "raw.types.ChatInviteExported", + users: Dict[int, "raw.types.User"] = None + ) -> "ChatInviteLink": + creator = ( + types.User._parse(client, users[invite.admin_id]) + if users is not None + else None + ) + + return ChatInviteLink( + invite_link=invite.link, + creator=creator, + date=invite.date, + is_primary=invite.permanent, + is_revoked=invite.revoked, + expire_date=invite.expire_date, + member_limit=invite.usage_limit, + member_count=invite.usage + ) diff --git a/pyrogram/types/user_and_chats/invite_link_importer.py b/pyrogram/types/user_and_chats/invite_link_importer.py new file mode 100644 index 00000000..4517ae3c --- /dev/null +++ b/pyrogram/types/user_and_chats/invite_link_importer.py @@ -0,0 +1,55 @@ +# Pyrogram - Telegram MTProto API Client Library for Python +# Copyright (C) 2017-2021 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 pyrogram import types +from ..object import Object + + +class InviteLinkImporter(Object): + """The date and user of when someone has joined with an invite link. + + Parameters: + date (``int``): + The unix time of when this user used the given link + + user (:obj:`~pyrogram.types.User`): + The user that has used the given invite link + """ + + def __init__(self, *, date, user): + super().__init__(None) + + self.date = date + self.user = user + + @staticmethod + def _parse(client, invite_importers: "raw.types.ChatInviteImporters"): + importers = types.List() + + d = {i.id: i for i in invite_importers.users} + + for j in invite_importers.importers: + importers.append( + InviteLinkImporter( + date=j.date, + user=types.User._parse(client=None, user=d[j.user_id]) + ) + ) + + return importers