diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index e0556d54..59410e25 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -4,7 +4,7 @@ about: Create a bug report affecting the library labels: "bug" --- - + ## Checklist - [ ] I am sure the error is coming from Pyrogram's code and not elsewhere. @@ -15,7 +15,7 @@ labels: "bug" A clear and concise description of the problem. ## Steps to Reproduce -[A minimal, complete and verifiable example](https://stackoverflow.com/help/mcve). +[A minimal, reproducible example](https://stackoverflow.com/help/minimal-reproducible-example). ## Traceback The full traceback (if applicable). \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index 70a39192..4d2f447c 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -4,7 +4,7 @@ about: Suggest ideas, new features or enhancements labels: "enhancement" --- - + ## Checklist - [ ] I believe the idea is awesome and would benefit the library. diff --git a/.github/ISSUE_TEMPLATE/question.md b/.github/ISSUE_TEMPLATE/question.md index 737304d9..88d91ecd 100644 --- a/.github/ISSUE_TEMPLATE/question.md +++ b/.github/ISSUE_TEMPLATE/question.md @@ -5,11 +5,11 @@ title: For Q&A purposes, please read this template body labels: "question" --- - + # Important This place is for issues about Pyrogram, it's **not a forum**. -If you'd like to post a question, please move to https://stackoverflow.com or join the Telegram community by following the description in https://t.me/pyrogram. +If you'd like to post a question, please move to https://stackoverflow.com or join the Telegram community at https://t.me/pyrogram. Thanks. \ No newline at end of file diff --git a/compiler/error/source/400_BAD_REQUEST.tsv b/compiler/error/source/400_BAD_REQUEST.tsv index fa6ff67e..8e82c9f6 100644 --- a/compiler/error/source/400_BAD_REQUEST.tsv +++ b/compiler/error/source/400_BAD_REQUEST.tsv @@ -99,4 +99,10 @@ RESULT_ID_DUPLICATE The result contains items with duplicated identifiers ACCESS_TOKEN_INVALID The bot access token is invalid INVITE_HASH_EXPIRED The chat invite link is no longer valid USER_BANNED_IN_CHANNEL You are limited, check @SpamBot for details -MESSAGE_EDIT_TIME_EXPIRED You can no longer edit this message \ No newline at end of file +MESSAGE_EDIT_TIME_EXPIRED You can no longer edit this message +FOLDER_ID_INVALID The folder id is invalid +MEGAGROUP_PREHISTORY_HIDDEN The action failed because the supergroup has the pre-history hidden +CHAT_LINK_EXISTS The action failed because the supergroup is linked to a channel +LINK_NOT_MODIFIED The chat link was not modified because you tried to link to the same target +BROADCAST_ID_INVALID The channel is invalid +MEGAGROUP_ID_INVALID The supergroup is invalid \ No newline at end of file diff --git a/docs/robots.txt b/docs/robots.txt index 0ecbac7b..1b9e8da6 100644 --- a/docs/robots.txt +++ b/docs/robots.txt @@ -1,3 +1,8 @@ User-agent: * + Allow: / + +Disallow: /dev/* +Disallow: /old/* + Sitemap: https://docs.pyrogram.org/sitemap.xml \ No newline at end of file diff --git a/docs/source/api/bound-methods.rst b/docs/source/api/bound-methods.rst index 0622e6b8..d01a4383 100644 --- a/docs/source/api/bound-methods.rst +++ b/docs/source/api/bound-methods.rst @@ -59,6 +59,24 @@ Message - :meth:`~Message.reply_video_note` - :meth:`~Message.reply_voice` +Chat +^^^^ + +.. hlist:: + :columns: 2 + + - :meth:`~Chat.archive` + - :meth:`~Chat.unarchive` + +User +^^^^ + +.. hlist:: + :columns: 2 + + - :meth:`~User.archive` + - :meth:`~User.unarchive` + CallbackQuery ^^^^^^^^^^^^^ @@ -109,6 +127,14 @@ Details .. automethod:: Message.reply_video_note() .. automethod:: Message.reply_voice() +.. Chat +.. automethod:: Chat.archive() +.. automethod:: Chat.unarchive() + +.. User +.. automethod:: User.archive() +.. automethod:: User.unarchive() + .. CallbackQuery .. automethod:: CallbackQuery.answer() diff --git a/docs/source/api/client.rst b/docs/source/api/client.rst index 9527ca73..d1b8c4b0 100644 --- a/docs/source/api/client.rst +++ b/docs/source/api/client.rst @@ -13,4 +13,7 @@ This is the Client class. It exposes high-level methods for an easy access to th with app: app.send_message("me", "Hi!") +Details +------- + .. autoclass:: pyrogram.Client() diff --git a/docs/source/api/filters.rst b/docs/source/api/filters.rst index 87faa801..6cb01cda 100644 --- a/docs/source/api/filters.rst +++ b/docs/source/api/filters.rst @@ -1,5 +1,8 @@ Update Filters ============== +Details +------- + .. autoclass:: pyrogram.Filters :members: diff --git a/docs/source/api/methods.rst b/docs/source/api/methods.rst index ed150e4c..e688903f 100644 --- a/docs/source/api/methods.rst +++ b/docs/source/api/methods.rst @@ -104,6 +104,8 @@ Chats - :meth:`~Client.get_dialogs_count` - :meth:`~Client.restrict_chat` - :meth:`~Client.update_chat_username` + - :meth:`~Client.archive_chats` + - :meth:`~Client.unarchive_chats` Users ^^^^^ @@ -233,6 +235,8 @@ Details .. automethod:: Client.get_dialogs_count() .. automethod:: Client.restrict_chat() .. automethod:: Client.update_chat_username() +.. automethod:: Client.archive_chats() +.. automethod:: Client.unarchive_chats() .. Users .. automethod:: Client.get_me() diff --git a/docs/source/license.rst b/docs/source/license.rst index 43f59d73..38302bdc 100644 --- a/docs/source/license.rst +++ b/docs/source/license.rst @@ -2,7 +2,7 @@ About the License ================= .. image:: https://www.gnu.org/graphics/lgplv3-with-text-154x68.png - :align: left + :align: right Pyrogram is free software and is currently licensed under the terms of the `GNU Lesser General Public License v3 or later (LGPLv3+)`_. In short: you may use, redistribute and/or modify it diff --git a/pyrogram/client/methods/chats/__init__.py b/pyrogram/client/methods/chats/__init__.py index c0176939..969628ee 100644 --- a/pyrogram/client/methods/chats/__init__.py +++ b/pyrogram/client/methods/chats/__init__.py @@ -16,6 +16,7 @@ # You should have received a copy of the GNU Lesser General Public License # along with Pyrogram. If not, see . +from .archive_chats import ArchiveChats from .delete_chat_photo import DeleteChatPhoto from .export_chat_invite_link import ExportChatInviteLink from .get_chat import GetChat @@ -36,6 +37,7 @@ from .restrict_chat_member import RestrictChatMember from .set_chat_description import SetChatDescription from .set_chat_photo import SetChatPhoto from .set_chat_title import SetChatTitle +from .unarchive_chats import UnarchiveChats from .unban_chat_member import UnbanChatMember from .unpin_chat_message import UnpinChatMessage from .update_chat_username import UpdateChatUsername @@ -64,6 +66,8 @@ class Chats( IterChatMembers, UpdateChatUsername, RestrictChat, - GetDialogsCount + GetDialogsCount, + ArchiveChats, + UnarchiveChats ): pass diff --git a/pyrogram/client/methods/chats/archive_chats.py b/pyrogram/client/methods/chats/archive_chats.py new file mode 100644 index 00000000..3c929983 --- /dev/null +++ b/pyrogram/client/methods/chats/archive_chats.py @@ -0,0 +1,58 @@ +# Pyrogram - Telegram MTProto API Client Library for Python +# Copyright (C) 2017-2019 Dan Tès +# +# 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, List + +from pyrogram.api import functions, types +from ...ext import BaseClient + + +class ArchiveChats(BaseClient): + def archive_chats( + self, + chat_ids: Union[int, str, List[Union[int, str]]], + ) -> bool: + """Archive one or more chats. + + Parameters: + chat_ids (``int`` | ``str`` | List[``int``, ``str``]): + Unique identifier (int) or username (str) of the target chat. + You can also pass a list of ids (int) or usernames (str). + + Returns: + ``bool``: On success, True is returned. + + Raises: + RPCError: In case of a Telegram RPC error. + """ + + if not isinstance(chat_ids, list): + chat_ids = [chat_ids] + + self.send( + functions.folders.EditPeerFolders( + folder_peers=[ + types.InputFolderPeer( + peer=self.resolve_peer(chat), + folder_id=1 + ) for chat in chat_ids + ] + ) + ) + + return True diff --git a/pyrogram/client/methods/chats/unarchive_chats.py b/pyrogram/client/methods/chats/unarchive_chats.py new file mode 100644 index 00000000..56bcc6f8 --- /dev/null +++ b/pyrogram/client/methods/chats/unarchive_chats.py @@ -0,0 +1,58 @@ +# Pyrogram - Telegram MTProto API Client Library for Python +# Copyright (C) 2017-2019 Dan Tès +# +# 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, List + +from pyrogram.api import functions, types +from ...ext import BaseClient + + +class UnarchiveChats(BaseClient): + def unarchive_chats( + self, + chat_ids: Union[int, str, List[Union[int, str]]], + ) -> bool: + """Unarchive one or more chats. + + Parameters: + chat_ids (``int`` | ``str`` | List[``int``, ``str``]): + Unique identifier (int) or username (str) of the target chat. + You can also pass a list of ids (int) or usernames (str). + + Returns: + ``bool``: On success, True is returned. + + Raises: + RPCError: In case of a Telegram RPC error. + """ + + if not isinstance(chat_ids, list): + chat_ids = [chat_ids] + + self.send( + functions.folders.EditPeerFolders( + folder_peers=[ + types.InputFolderPeer( + peer=self.resolve_peer(chat), + folder_id=0 + ) for chat in chat_ids + ] + ) + ) + + return True diff --git a/pyrogram/client/methods/users/get_profile_photos.py b/pyrogram/client/methods/users/get_profile_photos.py index eaf632e2..e2845c8d 100644 --- a/pyrogram/client/methods/users/get_profile_photos.py +++ b/pyrogram/client/methods/users/get_profile_photos.py @@ -55,7 +55,7 @@ class GetProfilePhotos(BaseClient): """ peer_id = self.resolve_peer(chat_id) - if isinstance(peer_id, types.InputPeerUser): + if isinstance(peer_id, (types.InputPeerUser, types.InputPeerSelf)): r = self.send( functions.photos.GetUserPhotos( user_id=peer_id, diff --git a/pyrogram/client/types/messages_and_media/message.py b/pyrogram/client/types/messages_and_media/message.py index f7e99d0a..c6f3cc77 100644 --- a/pyrogram/client/types/messages_and_media/message.py +++ b/pyrogram/client/types/messages_and_media/message.py @@ -661,7 +661,7 @@ class Message(Object, Update): reply_to_message_id: int = None, reply_markup=None ) -> "Message": - """Bound method *reply* :obj:`Message `. + """Bound method *reply* of :obj:`Message`. Use as a shortcut for: @@ -748,7 +748,7 @@ class Message(Object, Update): progress: callable = None, progress_args: tuple = () ) -> "Message": - """Bound method *reply_animation* :obj:`Message `. + """Bound method *reply_animation* :obj:`Message`. Use as a shortcut for: @@ -882,7 +882,7 @@ class Message(Object, Update): progress: callable = None, progress_args: tuple = () ) -> "Message": - """Bound method *reply_audio* :obj:`Message `. + """Bound method *reply_audio* of :obj:`Message`. Use as a shortcut for: @@ -1010,7 +1010,7 @@ class Message(Object, Update): "pyrogram.ForceReply" ] = None ) -> "Message": - """Bound method *reply_cached_media* :obj:`Message `. + """Bound method *reply_cached_media* of :obj:`Message`. Use as a shortcut for: @@ -1077,7 +1077,7 @@ class Message(Object, Update): ) def reply_chat_action(self, action: str) -> bool: - """Bound method *reply_chat_action* :obj:`Message `. + """Bound method *reply_chat_action* of :obj:`Message`. Use as a shortcut for: @@ -1130,7 +1130,7 @@ class Message(Object, Update): "pyrogram.ForceReply" ] = None ) -> "Message": - """Bound method *reply_contact* :obj:`Message `. + """Bound method *reply_contact* of :obj:`Message`. Use as a shortcut for: @@ -1217,7 +1217,7 @@ class Message(Object, Update): progress: callable = None, progress_args: tuple = () ) -> "Message": - """Bound method *reply_document* :obj:`Message `. + """Bound method *reply_document* of :obj:`Message`. Use as a shortcut for: @@ -1331,7 +1331,7 @@ class Message(Object, Update): "pyrogram.ForceReply" ] = None ) -> "Message": - """Bound method *reply_game* :obj:`Message `. + """Bound method *reply_game* of :obj:`Message`. Use as a shortcut for: @@ -1396,7 +1396,7 @@ class Message(Object, Update): reply_to_message_id: int = None, hide_via: bool = None ) -> "Message": - """Bound method *reply_inline_bot_result* :obj:`Message `. + """Bound method *reply_inline_bot_result* of :obj:`Message`. Use as a shortcut for: @@ -1470,7 +1470,7 @@ class Message(Object, Update): "pyrogram.ForceReply" ] = None ) -> "Message": - """Bound method *reply_location* :obj:`Message `. + """Bound method *reply_location* of :obj:`Message`. Use as a shortcut for: @@ -1538,7 +1538,7 @@ class Message(Object, Update): disable_notification: bool = None, reply_to_message_id: int = None ) -> "Message": - """Bound method *reply_media_group* :obj:`Message `. + """Bound method *reply_media_group* of :obj:`Message`. Use as a shortcut for: @@ -1610,7 +1610,7 @@ class Message(Object, Update): progress: callable = None, progress_args: tuple = () ) -> "Message": - """Bound method *reply_photo* :obj:`Message `. + """Bound method *reply_photo* of :obj:`Message`. Use as a shortcut for: @@ -1724,7 +1724,7 @@ class Message(Object, Update): "pyrogram.ForceReply" ] = None ) -> "Message": - """Bound method *reply_poll* :obj:`Message `. + """Bound method *reply_poll* of :obj:`Message`. Use as a shortcut for: @@ -1800,7 +1800,7 @@ class Message(Object, Update): progress: callable = None, progress_args: tuple = () ) -> "Message": - """Bound method *reply_sticker* :obj:`Message `. + """Bound method *reply_sticker* of :obj:`Message`. Use as a shortcut for: @@ -1903,7 +1903,7 @@ class Message(Object, Update): "pyrogram.ForceReply" ] = None ) -> "Message": - """Bound method *reply_venue* :obj:`Message `. + """Bound method *reply_venue* of :obj:`Message`. Use as a shortcut for: @@ -2005,7 +2005,7 @@ class Message(Object, Update): progress: callable = None, progress_args: tuple = () ) -> "Message": - """Bound method *reply_video* :obj:`Message `. + """Bound method *reply_video* of :obj:`Message`. Use as a shortcut for: @@ -2140,7 +2140,7 @@ class Message(Object, Update): progress: callable = None, progress_args: tuple = () ) -> "Message": - """Bound method *reply_video_note* :obj:`Message `. + """Bound method *reply_video_note* of :obj:`Message`. Use as a shortcut for: @@ -2258,7 +2258,7 @@ class Message(Object, Update): progress: callable = None, progress_args: tuple = () ) -> "Message": - """Bound method *reply_voice* :obj:`Message `. + """Bound method *reply_voice* of :obj:`Message`. Use as a shortcut for: @@ -2368,7 +2368,7 @@ class Message(Object, Update): "pyrogram.ForceReply" ] = None ) -> "Message": - """Bound method *edit* :obj:`Message `. + """Bound method *edit* of :obj:`Message`. Use as a shortcut for: @@ -2425,7 +2425,7 @@ class Message(Object, Update): "pyrogram.ForceReply" ] = None ) -> "Message": - """Bound method *edit_caption* :obj:`Message `. + """Bound method *edit_caption* of :obj:`Message`. Use as a shortcut for: @@ -2468,7 +2468,7 @@ class Message(Object, Update): ) def edit_media(self, media: InputMedia, reply_markup: "pyrogram.InlineKeyboardMarkup" = None) -> "Message": - """Bound method *edit_media* :obj:`Message `. + """Bound method *edit_media* of :obj:`Message`. Use as a shortcut for: @@ -2506,7 +2506,7 @@ class Message(Object, Update): ) def edit_reply_markup(self, reply_markup: "pyrogram.InlineKeyboardMarkup" = None) -> "Message": - """Bound method *edit_reply_markup* :obj:`Message `. + """Bound method *edit_reply_markup* of :obj:`Message`. Use as a shortcut for: @@ -2547,7 +2547,7 @@ class Message(Object, Update): as_copy: bool = False, remove_caption: bool = False ) -> "Message": - """Bound method *forward* :obj:`Message `. + """Bound method *forward* of :obj:`Message`. Use as a shortcut for: @@ -2690,7 +2690,7 @@ class Message(Object, Update): ) def delete(self, revoke: bool = True): - """Bound method *delete* :obj:`Message `. + """Bound method *delete* of :obj:`Message`. Use as a shortcut for: @@ -2726,7 +2726,7 @@ class Message(Object, Update): ) def click(self, x: int or str, y: int = 0, quote: bool = None, timeout: int = 10): - """Bound method *click* :obj:`Message `. + """Bound method *click* of :obj:`Message`. Use as a shortcut for clicking a button attached to the message instead of: @@ -2853,7 +2853,7 @@ class Message(Object, Update): progress: callable = None, progress_args: tuple = () ) -> str: - """Bound method *download* :obj:`Message `. + """Bound method *download* of :obj:`Message`. Use as a shortcut for: @@ -2902,7 +2902,7 @@ class Message(Object, Update): ) def pin(self, disable_notification: bool = None) -> "Message": - """Bound method *pin* :obj:`Message `. + """Bound method *pin* of :obj:`Message`. Use as a shortcut for: diff --git a/pyrogram/client/types/user_and_chats/chat.py b/pyrogram/client/types/user_and_chats/chat.py index ca9acd65..2d88d3ed 100644 --- a/pyrogram/client/types/user_and_chats/chat.py +++ b/pyrogram/client/types/user_and_chats/chat.py @@ -36,14 +36,17 @@ class Chat(Object): Type of chat, can be either "private", "bot", "group", "supergroup" or "channel". is_verified (``bool``, *optional*): - True, if this chat has been verified by Telegram. Supergroups and channels only. + True, if this chat has been verified by Telegram. Supergroups, channels and bots only. is_restricted (``bool``, *optional*): - True, if this chat has been restricted. Supergroups and channels only. + True, if this chat has been restricted. Supergroups, channels and bots only. See *restriction_reason* for details. is_scam (``bool``, *optional*): - True, if this chat has been flagged for scam. Supergroups and channels only. + True, if this chat has been flagged for scam. Supergroups, channels and bots only. + + is_support (``bool``): + True, if this chat is part of the Telegram support team. Users and bots only. title (``str``, *optional*): Title, for supergroups, channels and basic group chats. @@ -92,8 +95,8 @@ class Chat(Object): """ __slots__ = [ - "id", "type", "is_verified", "is_restricted", "is_scam", "title", "username", "first_name", "last_name", - "photo", "description", "invite_link", "pinned_message", "sticker_set_name", "can_set_sticker_set", + "id", "type", "is_verified", "is_restricted", "is_scam", "is_support", "title", "username", "first_name", + "last_name", "photo", "description", "invite_link", "pinned_message", "sticker_set_name", "can_set_sticker_set", "members_count", "restriction_reason", "permissions" ] @@ -106,6 +109,7 @@ class Chat(Object): is_verified: bool = None, is_restricted: bool = None, is_scam: bool = None, + is_support: bool = None, title: str = None, username: str = None, first_name: str = None, @@ -127,6 +131,7 @@ class Chat(Object): self.is_verified = is_verified self.is_restricted = is_restricted self.is_scam = is_scam + self.is_support = is_support self.title = title self.username = username self.first_name = first_name @@ -148,6 +153,10 @@ class Chat(Object): return Chat( id=peer_id, type="bot" if user.bot else "private", + is_verified=getattr(user, "verified", None), + is_restricted=getattr(user, "restricted", None), + is_scam=getattr(user, "scam", None), + is_support=getattr(user, "support", None), username=user.username, first_name=user.first_name, last_name=user.last_name, @@ -257,3 +266,49 @@ class Chat(Object): return Chat._parse_user_chat(client, chat) else: return Chat._parse_channel_chat(client, chat) + + def archive(self): + """Bound method *archive* of :obj:`Chat`. + + Use as a shortcut for: + + .. code-block:: python + + client.archive_chats(-100123456789) + + Example: + .. code-block:: python + + chat.archive() + + Returns: + True on success. + + Raises: + RPCError: In case of a Telegram RPC error. + """ + + return self._client.archive_chats(self.id) + + def unarchive(self): + """Bound method *unarchive* of :obj:`Chat`. + + Use as a shortcut for: + + .. code-block:: python + + client.unarchive_chats(-100123456789) + + Example: + .. code-block:: python + + chat.unarchive() + + Returns: + True on success. + + Raises: + RPCError: In case of a Telegram RPC error. + """ + + return self._client.unarchive_chats(self.id) diff --git a/pyrogram/client/types/user_and_chats/user.py b/pyrogram/client/types/user_and_chats/user.py index 50dd8361..f47e8c42 100644 --- a/pyrogram/client/types/user_and_chats/user.py +++ b/pyrogram/client/types/user_and_chats/user.py @@ -52,12 +52,12 @@ class User(Object): True, if this user has been restricted. Bots only. See *restriction_reason* for details. - is_support (``bool``): - True, if this user is part of the Telegram support team. - is_scam (``bool``): True, if this user has been flagged for scam. + is_support (``bool``): + True, if this user is part of the Telegram support team. + first_name (``str``): User's or bot's first name. @@ -86,7 +86,7 @@ class User(Object): __slots__ = [ "id", "is_self", "is_contact", "is_mutual_contact", "is_deleted", "is_bot", "is_verified", "is_restricted", - "is_support", "is_scam", "first_name", "last_name", "status", "username", "language_code", "phone_number", + "is_scam", "is_support", "first_name", "last_name", "status", "username", "language_code", "phone_number", "photo", "restriction_reason" ] @@ -102,8 +102,8 @@ class User(Object): is_bot: bool, is_verified: bool, is_restricted: bool, - is_support: bool, is_scam: bool, + is_support: bool, first_name: str, last_name: str = None, status: UserStatus = None, @@ -123,8 +123,8 @@ class User(Object): self.is_bot = is_bot self.is_verified = is_verified self.is_restricted = is_restricted - self.is_support = is_support self.is_scam = is_scam + self.is_support = is_support self.first_name = first_name self.last_name = last_name self.status = status @@ -148,8 +148,8 @@ class User(Object): is_bot=user.bot, is_verified=user.verified, is_restricted=user.restricted, - is_support=user.support, is_scam=user.scam, + is_support=user.support, first_name=user.first_name, last_name=user.last_name, status=UserStatus._parse(client, user.status, user.id, user.bot), @@ -160,3 +160,49 @@ class User(Object): restriction_reason=user.restriction_reason, client=client ) + + def archive(self): + """Bound method *archive* of :obj:`User`. + + Use as a shortcut for: + + .. code-block:: python + + client.archive_chats(123456789) + + Example: + .. code-block:: python + + user.archive() + + Returns: + True on success. + + Raises: + RPCError: In case of a Telegram RPC error. + """ + + return self._client.archive_chats(self.id) + + def unarchive(self): + """Bound method *unarchive* of :obj:`User`. + + Use as a shortcut for: + + .. code-block:: python + + client.unarchive_chats(123456789) + + Example: + .. code-block:: python + + user.unarchive() + + Returns: + True on success. + + Raises: + RPCError: In case of a Telegram RPC error. + """ + + return self._client.unarchive_chats(self.id)