From c39c050abfbd767b57bd2724750489a054a1a315 Mon Sep 17 00:00:00 2001 From: _run Date: Sat, 4 Feb 2023 15:32:55 +0400 Subject: [PATCH 01/13] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7a2bbd8..ffcc909 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@

A simple, but extensible Python implementation for the Telegram Bot API.

Both synchronous and asynchronous.

-##

Supported Bot API version: 6.4! +##

Supported Bot API version: 6.5!

Official documentation

Official ru documentation

From 2e5fb10430f3306089b277d56a860600c5c8dd75 Mon Sep 17 00:00:00 2001 From: coder2020official Date: Sat, 4 Feb 2023 16:02:18 +0400 Subject: [PATCH 02/13] Added the class KeyboardButtonRequestUser and the field request_user to the class KeyboardButton. --- telebot/types.py | 45 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/telebot/types.py b/telebot/types.py index 730a0d4..e8389ab 100644 --- a/telebot/types.py +++ b/telebot/types.py @@ -2245,17 +2245,22 @@ class KeyboardButton(Dictionaryable, JsonSerializable): will be able to send a “web_app_data” service message. Available in private chats only. :type web_app: :class:`telebot.types.WebAppInfo` + :param request_user: Optional. If specified, pressing the button will open a list of suitable users. Tapping on any user + will send their identifier to the bot in a “user_shared” service message. Available in private chats only. + :type request_user: :class:`telebot.types.KeyboardButtonRequestUser` + :return: Instance of the class :rtype: :class:`telebot.types.KeyboardButton` """ def __init__(self, text: str, request_contact: Optional[bool]=None, request_location: Optional[bool]=None, request_poll: Optional[KeyboardButtonPollType]=None, - web_app: WebAppInfo=None): + web_app: Optional[WebAppInfo]=None, request_user: Optional[KeyboardButtonRequestUser]=None): self.text: str = text self.request_contact: bool = request_contact self.request_location: bool = request_location self.request_poll: KeyboardButtonPollType = request_poll self.web_app: WebAppInfo = web_app + self.request_user: KeyboardButtonRequestUser = request_user def to_json(self): return json.dumps(self.to_dict()) @@ -2270,6 +2275,8 @@ class KeyboardButton(Dictionaryable, JsonSerializable): json_dict['request_poll'] = self.request_poll.to_dict() if self.web_app is not None: json_dict['web_app'] = self.web_app.to_dict() + if self.request_user is not None: + json_dict['request_user'] = self.request_user.to_dict() return json_dict @@ -7012,5 +7019,41 @@ class WriteAccessAllowed(JsonDeserializable): pass +class KeyboardButtonRequestUser(Dictionaryable): + """ + This object defines the criteria used to request a suitable user. + The identifier of the selected user will be shared with the bot when the corresponding button is pressed. + + Telegram documentation: https://core.telegram.org/bots/api#keyboardbuttonrequestuser + + :param request_id: Signed 32-bit identifier of the request, which will be received back in the UserShared object. + Must be unique within the message + :type request_id: :obj:`int` + + :param user_is_bot: Optional. Pass True to request a bot, pass False to request a regular user. + If not specified, no additional restrictions are applied. + :type user_is_bot: :obj:`bool` + + :param user_is_premium: Optional. Pass True to request a premium user, pass False to request a non-premium user. + If not specified, no additional restrictions are applied. + :type user_is_premium: :obj:`bool` + + :return: Instance of the class + :rtype: :class:`telebot.types.KeyboardButtonRequestUser` + + """ + + def __init__(self, request_id: int, user_is_bot: Optional[bool]=None, user_is_premium: Optional[bool]=None) -> None: + self.request_id: int = request_id + self.user_is_bot: Optional[bool] = user_is_bot + self.user_is_premium: Optional[bool] = user_is_premium + + def to_dict(self) -> dict: + data = {'request_id': self.request_id} + if self.user_is_bot is not None: + data['user_is_bot'] = self.user_is_bot + if self.user_is_premium is not None: + data['user_is_premium'] = self.user_is_premium + return data From 3e0d69f7f4d8b67253954d1988fe3132141e4176 Mon Sep 17 00:00:00 2001 From: _run Date: Sat, 4 Feb 2023 16:16:34 +0400 Subject: [PATCH 03/13] fixed checks x1 --- telebot/types.py | 77 ++++++++++++++++++++++++------------------------ 1 file changed, 39 insertions(+), 38 deletions(-) diff --git a/telebot/types.py b/telebot/types.py index e8389ab..c788901 100644 --- a/telebot/types.py +++ b/telebot/types.py @@ -2217,6 +2217,45 @@ class KeyboardButtonPollType(Dictionaryable): def to_dict(self): return {'type': self.type} + + + +class KeyboardButtonRequestUser(Dictionaryable): + """ + This object defines the criteria used to request a suitable user. + The identifier of the selected user will be shared with the bot when the corresponding button is pressed. + + Telegram documentation: https://core.telegram.org/bots/api#keyboardbuttonrequestuser + + :param request_id: Signed 32-bit identifier of the request, which will be received back in the UserShared object. + Must be unique within the message + :type request_id: :obj:`int` + + :param user_is_bot: Optional. Pass True to request a bot, pass False to request a regular user. + If not specified, no additional restrictions are applied. + :type user_is_bot: :obj:`bool` + + :param user_is_premium: Optional. Pass True to request a premium user, pass False to request a non-premium user. + If not specified, no additional restrictions are applied. + :type user_is_premium: :obj:`bool` + + :return: Instance of the class + :rtype: :class:`telebot.types.KeyboardButtonRequestUser` + + """ + + def __init__(self, request_id: int, user_is_bot: Optional[bool]=None, user_is_premium: Optional[bool]=None) -> None: + self.request_id: int = request_id + self.user_is_bot: Optional[bool] = user_is_bot + self.user_is_premium: Optional[bool] = user_is_premium + + def to_dict(self) -> dict: + data = {'request_id': self.request_id} + if self.user_is_bot is not None: + data['user_is_bot'] = self.user_is_bot + if self.user_is_premium is not None: + data['user_is_premium'] = self.user_is_premium + return data class KeyboardButton(Dictionaryable, JsonSerializable): @@ -7019,41 +7058,3 @@ class WriteAccessAllowed(JsonDeserializable): pass -class KeyboardButtonRequestUser(Dictionaryable): - """ - This object defines the criteria used to request a suitable user. - The identifier of the selected user will be shared with the bot when the corresponding button is pressed. - - Telegram documentation: https://core.telegram.org/bots/api#keyboardbuttonrequestuser - - :param request_id: Signed 32-bit identifier of the request, which will be received back in the UserShared object. - Must be unique within the message - :type request_id: :obj:`int` - - :param user_is_bot: Optional. Pass True to request a bot, pass False to request a regular user. - If not specified, no additional restrictions are applied. - :type user_is_bot: :obj:`bool` - - :param user_is_premium: Optional. Pass True to request a premium user, pass False to request a non-premium user. - If not specified, no additional restrictions are applied. - :type user_is_premium: :obj:`bool` - - :return: Instance of the class - :rtype: :class:`telebot.types.KeyboardButtonRequestUser` - - """ - - def __init__(self, request_id: int, user_is_bot: Optional[bool]=None, user_is_premium: Optional[bool]=None) -> None: - self.request_id: int = request_id - self.user_is_bot: Optional[bool] = user_is_bot - self.user_is_premium: Optional[bool] = user_is_premium - - def to_dict(self) -> dict: - data = {'request_id': self.request_id} - if self.user_is_bot is not None: - data['user_is_bot'] = self.user_is_bot - if self.user_is_premium is not None: - data['user_is_premium'] = self.user_is_premium - return data - - From 4d7f5310fb7a25d60c47960dd8b34d6cbfca6283 Mon Sep 17 00:00:00 2001 From: coder2020official Date: Sat, 4 Feb 2023 16:24:05 +0400 Subject: [PATCH 04/13] Added the class KeyboardButtonRequestChat and the field request_chat to the class KeyboardButton. --- telebot/types.py | 81 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 80 insertions(+), 1 deletion(-) diff --git a/telebot/types.py b/telebot/types.py index c788901..868413a 100644 --- a/telebot/types.py +++ b/telebot/types.py @@ -2258,6 +2258,78 @@ class KeyboardButtonRequestUser(Dictionaryable): return data +class KeyboardButtonRequestChat(Dictionaryable): + """ + This object defines the criteria used to request a suitable chat. The identifier of the selected chat will + be shared with the bot when the corresponding button is pressed. + + Telegram documentation: https://core.telegram.org/bots/api#keyboardbuttonrequestchat + + :param request_id: Signed 32-bit identifier of the request, which will be received back in the ChatShared object. + Must be unique within the message + :type request_id: :obj:`int` + + :param chat_is_channel: Pass True to request a channel chat, pass False to request a group or a supergroup chat. + :type chat_is_channel: :obj:`bool` + + :param chat_is_forum: Optional. Pass True to request a forum supergroup, pass False to request a non-forum chat. + If not specified, no additional restrictions are applied. + :type chat_is_forum: :obj:`bool` + + :param chat_has_username: Optional. Pass True to request a supergroup or a channel with a username, pass False to request a + chat without a username. If not specified, no additional restrictions are applied. + :type chat_has_username: :obj:`bool` + + :param chat_is_created: Optional. Pass True to request a chat owned by the user. Otherwise, no additional restrictions are applied. + :type chat_is_created: :obj:`bool` + + :param user_administrator_rights: Optional. A JSON-serialized object listing the required administrator rights of the user in the chat. + The rights must be a superset of bot_administrator_rights. If not specified, no additional restrictions are applied. + :type user_administrator_rights: :class:`telebot.types.ChatAdministratorRights` + + :param bot_administrator_rights: Optional. A JSON-serialized object listing the required administrator rights of the bot in the chat. + The rights must be a subset of user_administrator_rights. If not specified, no additional restrictions are applied. + :type bot_administrator_rights: :class:`telebot.types.ChatAdministratorRights` + + :param bot_is_member: Optional. Pass True to request a chat where the bot is a member. Otherwise, no additional restrictions are applied. + :type bot_is_member: :obj:`bool` + + :return: Instance of the class + :rtype: :class:`telebot.types.KeyboardButtonRequestChat` + """ + + def __init__(self, request_id: int, chat_is_channel: bool, chat_is_forum: Optional[bool]=None, + chat_has_username: Optional[bool]=None, chat_is_created: Optional[bool]=None, + user_administrator_rights: Optional[ChatAdministratorRights]=None, + bot_administrator_rights: Optional[ChatAdministratorRights]=None, bot_is_member: Optional[bool]=None) -> None: + self.request_id: int = request_id + self.chat_is_channel: bool = chat_is_channel + self.chat_is_forum: Optional[bool] = chat_is_forum + self.chat_has_username: Optional[bool] = chat_has_username + self.chat_is_created: Optional[bool] = chat_is_created + self.user_administrator_rights: Optional[ChatAdministratorRights] = user_administrator_rights + self.bot_administrator_rights: Optional[ChatAdministratorRights] = bot_administrator_rights + self.bot_is_member: Optional[bool] = bot_is_member + + + def to_dict(self) -> dict: + data = {'request_id': self.request_id, 'chat_is_channel': self.chat_is_channel} + if self.chat_is_forum is not None: + data['chat_is_forum'] = self.chat_is_forum + if self.chat_has_username is not None: + data['chat_has_username'] = self.chat_has_username + if self.chat_is_created is not None: + data['chat_is_created'] = self.chat_is_created + if self.user_administrator_rights is not None: + data['user_administrator_rights'] = self.user_administrator_rights.to_dict() + if self.bot_administrator_rights is not None: + data['bot_administrator_rights'] = self.bot_administrator_rights.to_dict() + if self.bot_is_member is not None: + data['bot_is_member'] = self.bot_is_member + return data + + + class KeyboardButton(Dictionaryable, JsonSerializable): """ This object represents one button of the reply keyboard. For simple text buttons String can be used instead of this object to specify text of the button. Optional fields web_app, request_contact, request_location, and request_poll are mutually exclusive. @@ -2288,18 +2360,25 @@ class KeyboardButton(Dictionaryable, JsonSerializable): will send their identifier to the bot in a “user_shared” service message. Available in private chats only. :type request_user: :class:`telebot.types.KeyboardButtonRequestUser` + :param request_chat: Optional. If specified, pressing the button will open a list of suitable chats. Tapping on a chat will + send its identifier to the bot in a “chat_shared” service message. Available in private chats only. + :type request_chat: :class:`telebot.types.KeyboardButtonRequestChat` + :return: Instance of the class :rtype: :class:`telebot.types.KeyboardButton` """ def __init__(self, text: str, request_contact: Optional[bool]=None, request_location: Optional[bool]=None, request_poll: Optional[KeyboardButtonPollType]=None, - web_app: Optional[WebAppInfo]=None, request_user: Optional[KeyboardButtonRequestUser]=None): + web_app: Optional[WebAppInfo]=None, request_user: Optional[KeyboardButtonRequestUser]=None, + request_chat: Optional[KeyboardButtonRequestChat]=None): self.text: str = text self.request_contact: bool = request_contact self.request_location: bool = request_location self.request_poll: KeyboardButtonPollType = request_poll self.web_app: WebAppInfo = web_app self.request_user: KeyboardButtonRequestUser = request_user + self.request_chat: KeyboardButtonRequestChat = request_chat + def to_json(self): return json.dumps(self.to_dict()) From a3891ff36395e6dff85865beaec4a8325a8405f2 Mon Sep 17 00:00:00 2001 From: coder2020official Date: Sat, 4 Feb 2023 16:29:48 +0400 Subject: [PATCH 05/13] Pep 0563 proposed change https://peps.python.org/pep-0563/ --- telebot/types.py | 1 + 1 file changed, 1 insertion(+) diff --git a/telebot/types.py b/telebot/types.py index 868413a..01c18af 100644 --- a/telebot/types.py +++ b/telebot/types.py @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- +from __future__ import annotations from io import IOBase import logging From ae42d0b1fe6790080990483fc9572fa0b02b78fd Mon Sep 17 00:00:00 2001 From: coder2020official Date: Sat, 4 Feb 2023 16:54:43 +0400 Subject: [PATCH 06/13] Added usershared and user_shared --- telebot/types.py | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/telebot/types.py b/telebot/types.py index 01c18af..96abff4 100644 --- a/telebot/types.py +++ b/telebot/types.py @@ -903,6 +903,9 @@ class Message(JsonDeserializable): the payment. More about payments » :type successful_payment: :class:`telebot.types.SuccessfulPayment` + :param user_shared: Optional. Service message: a user was shared with the bot + :type user_shared: :class:`telebot.types.UserShared` + :param connected_website: Optional. The domain name of the website on which the user has logged in. More about Telegram Login » :type connected_website: :obj:`str` @@ -1152,6 +1155,9 @@ class Message(JsonDeserializable): if 'write_access_allowed' in obj: opts['write_access_allowed'] = WriteAccessAllowed.de_json(obj['write_access_allowed']) content_type = 'write_access_allowed' + if 'user_shared' in obj: + opts['user_shared'] = UserShared.de_json(obj['user_shared']) + content_type = 'user_shared' return cls(message_id, from_user, date, chat, content_type, opts, json_string) @classmethod @@ -1247,6 +1253,7 @@ class Message(JsonDeserializable): self.general_forum_topic_hidden: Optional[GeneralForumTopicHidden] = None self.general_forum_topic_unhidden: Optional[GeneralForumTopicUnhidden] = None self.write_access_allowed: Optional[WriteAccessAllowed] = None + self.user_shared: Optional[UserShared] = None for key in options: setattr(self, key, options[key]) self.json = json_string @@ -7138,3 +7145,34 @@ class WriteAccessAllowed(JsonDeserializable): pass +class UserShared(JsonDeserializable): + """ + This object contains information about the user whose identifier was shared with the bot using a + `telebot.types.KeyboardButtonRequestUser` button. + + Telegram documentation: https://core.telegram.org/bots/api#usershared + + :param request_id: identifier of the request + :type request_id: :obj:`int` + + :param user_id: Identifier of the shared user. This number may have more than 32 significant bits and some programming + languages may have difficulty/silent defects in interpreting it. But it has at most 52 significant bits, so a 64-bit + integer or double-precision float type are safe for storing this identifier. The bot may not have access to the user + and could be unable to use this identifier, unless the user is already known to the bot by some other means. + :type user_id: :obj:`int` + + :return: Instance of the class + :rtype: :class:`telebot.types.UserShared` + """ + + @classmethod + def de_json(cls, json_string): + if json_string is None: return None + obj = cls.check_json(json_string) + return cls(**obj) + + def __init__(self, request_id: int, user_id: int) -> None: + self.request_id: int = request_id + self.user_id: int = user_id + + From 4000c9fb4825567b4c3eeeee77a0b2256ccc3292 Mon Sep 17 00:00:00 2001 From: coder2020official Date: Sat, 4 Feb 2023 16:58:48 +0400 Subject: [PATCH 07/13] Added chat_shared and chatshared --- telebot/types.py | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/telebot/types.py b/telebot/types.py index 96abff4..700436e 100644 --- a/telebot/types.py +++ b/telebot/types.py @@ -906,6 +906,9 @@ class Message(JsonDeserializable): :param user_shared: Optional. Service message: a user was shared with the bot :type user_shared: :class:`telebot.types.UserShared` + :param chat_shared: Optional. Service message: a chat was shared with the bot + :type chat_shared: :class:`telebot.types.ChatShared` + :param connected_website: Optional. The domain name of the website on which the user has logged in. More about Telegram Login » :type connected_website: :obj:`str` @@ -1158,6 +1161,9 @@ class Message(JsonDeserializable): if 'user_shared' in obj: opts['user_shared'] = UserShared.de_json(obj['user_shared']) content_type = 'user_shared' + if 'chat_shared' in obj: + opts['chat_shared'] = ChatShared.de_json(obj['chat_shared']) + content_type = 'chat_shared' return cls(message_id, from_user, date, chat, content_type, opts, json_string) @classmethod @@ -1254,6 +1260,7 @@ class Message(JsonDeserializable): self.general_forum_topic_unhidden: Optional[GeneralForumTopicUnhidden] = None self.write_access_allowed: Optional[WriteAccessAllowed] = None self.user_shared: Optional[UserShared] = None + self.chat_shared: Optional[ChatShared] = None for key in options: setattr(self, key, options[key]) self.json = json_string @@ -7175,4 +7182,36 @@ class UserShared(JsonDeserializable): self.request_id: int = request_id self.user_id: int = user_id + +class ChatShared(JsonDeserializable): + """ + This object contains information about the chat whose identifier was shared with the bot using a + `telebot.types.KeyboardButtonRequestChat` button. + + Telegram documentation: https://core.telegram.org/bots/api#Chatshared + + :param request_id: identifier of the request + :type request_id: :obj:`int` + + :param chat_id: Identifier of the shared chat. This number may have more than 32 significant bits and some programming + languages may have difficulty/silent defects in interpreting it. But it has at most 52 significant bits, so a 64-bit + integer or double-precision float type are safe for storing this identifier. The bot may not have access to the chat + and could be unable to use this identifier, unless the chat is already known to the bot by some other means. + :type chat_id: :obj:`int` + + :return: Instance of the class + :rtype: :class:`telebot.types.ChatShared` + """ + + @classmethod + def de_json(cls, json_string): + if json_string is None: return None + obj = cls.check_json(json_string) + return cls(**obj) + + def __init__(self, request_id: int, chat_id: int) -> None: + self.request_id: int = request_id + self.chat_id: int = chat_id + + \ No newline at end of file From 9e68f76f5d5f31646444655784a2e42bc3c1525d Mon Sep 17 00:00:00 2001 From: coder2020official Date: Sat, 4 Feb 2023 18:57:06 +0400 Subject: [PATCH 08/13] Replaced the fields can_send_media_messages in the classes ChatMemberRestricted and ChatPermissions with separate fields can_send_audios, can_send_documents, can_send_photos, can_send_videos, can_send_video_notes, and can_send_voice_notes for different media types. --- telebot/types.py | 98 ++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 78 insertions(+), 20 deletions(-) diff --git a/telebot/types.py b/telebot/types.py index 700436e..d454536 100644 --- a/telebot/types.py +++ b/telebot/types.py @@ -2806,10 +2806,14 @@ class ChatMember(JsonDeserializable): can_post_messages=None, can_edit_messages=None, can_delete_messages=None, can_restrict_members=None, can_promote_members=None, can_change_info=None, can_invite_users=None, can_pin_messages=None, is_member=None, - can_send_messages=None, can_send_media_messages=None, can_send_polls=None, + can_send_messages=None, can_send_audios=None, can_send_documents=None, + can_send_photos=None, can_send_videos=None, can_send_video_notes=None, + can_send_voice_notes=None, + can_send_polls=None, can_send_other_messages=None, can_add_web_page_previews=None, can_manage_chat=None, can_manage_video_chats=None, - until_date=None, can_manage_topics=None, **kwargs): + until_date=None, can_manage_topics=None, + **kwargs): self.user: User = user self.status: str = status self.custom_title: str = custom_title @@ -2825,7 +2829,7 @@ class ChatMember(JsonDeserializable): self.can_pin_messages: bool = can_pin_messages self.is_member: bool = is_member self.can_send_messages: bool = can_send_messages - self.can_send_media_messages: bool = can_send_media_messages + #self.can_send_media_messages: bool = can_send_media_messages self.can_send_polls: bool = can_send_polls self.can_send_other_messages: bool = can_send_other_messages self.can_add_web_page_previews: bool = can_add_web_page_previews @@ -2834,6 +2838,13 @@ class ChatMember(JsonDeserializable): self.can_manage_voice_chats: bool = self.can_manage_video_chats # deprecated, for backward compatibility self.until_date: int = until_date self.can_manage_topics: bool = can_manage_topics + self.can_send_audios: bool = can_send_audios + self.can_send_documents: bool = can_send_documents + self.can_send_photos: bool = can_send_photos + self.can_send_videos: bool = can_send_videos + self.can_send_video_notes: bool = can_send_video_notes + self.can_send_voice_notes: bool = can_send_voice_notes + class ChatMemberOwner(ChatMember): @@ -2974,9 +2985,23 @@ class ChatMemberRestricted(ChatMember): :param can_send_messages: True, if the user is allowed to send text messages, contacts, locations and venues :type can_send_messages: :obj:`bool` - :param can_send_media_messages: True, if the user is allowed to send audios, documents, photos, videos, video - notes and voice notes - :type can_send_media_messages: :obj:`bool` + :param can_send_audios: True, if the user is allowed to send audios + :type can_send_audios: :obj:`bool` + + :param can_send_documents: True, if the user is allowed to send documents + :type can_send_documents: :obj:`bool` + + :param can_send_photos: True, if the user is allowed to send photos + :type can_send_photos: :obj:`bool` + + :param can_send_videos: True, if the user is allowed to send videos + :type can_send_videos: :obj:`bool` + + :param can_send_video_notes: True, if the user is allowed to send video notes + :type can_send_video_notes: :obj:`bool` + + :param can_send_voice_notes: True, if the user is allowed to send voice notes + :type can_send_voice_notes: :obj:`bool` :param can_send_polls: True, if the user is allowed to send polls :type can_send_polls: :obj:`bool` @@ -3048,19 +3073,33 @@ class ChatPermissions(JsonDeserializable, JsonSerializable, Dictionaryable): venues :type can_send_messages: :obj:`bool` - :param can_send_media_messages: Optional. True, if the user is allowed to send audios, documents, photos, videos, - video notes and voice notes, implies can_send_messages - :type can_send_media_messages: :obj:`bool` + :param can_send_audios: Optional. True, if the user is allowed to send audios + :type can_send_audios: :obj:`bool` + + :param can_send_documents: Optional. True, if the user is allowed to send documents + :type can_send_documents: :obj:`bool` + + :param can_send_photos: Optional. True, if the user is allowed to send photos + :type can_send_photos: :obj:`bool` + + :param can_send_videos: Optional. True, if the user is allowed to send videos + :type can_send_videos: :obj:`bool` + + :param can_send_video_notes: Optional. True, if the user is allowed to send video notes + :type can_send_video_notes: :obj:`bool` + + :param can_send_voice_notes: Optional. True, if the user is allowed to send voice notes + :type can_send_voice_notes: :obj:`bool` :param can_send_polls: Optional. True, if the user is allowed to send polls, implies can_send_messages :type can_send_polls: :obj:`bool` :param can_send_other_messages: Optional. True, if the user is allowed to send animations, games, stickers and use - inline bots, implies can_send_media_messages + inline bots :type can_send_other_messages: :obj:`bool` :param can_add_web_page_previews: Optional. True, if the user is allowed to add web page previews to their - messages, implies can_send_media_messages + messages :type can_add_web_page_previews: :obj:`bool` :param can_change_info: Optional. True, if the user is allowed to change the chat title, photo and other settings. @@ -3086,13 +3125,15 @@ class ChatPermissions(JsonDeserializable, JsonSerializable, Dictionaryable): obj = cls.check_json(json_string, dict_copy=False) return cls(**obj) - def __init__(self, can_send_messages=None, can_send_media_messages=None, - can_send_polls=None, can_send_other_messages=None, - can_add_web_page_previews=None, can_change_info=None, - can_invite_users=None, can_pin_messages=None, - can_manage_topics=None, **kwargs): + def __init__(self, can_send_messages=None, can_send_audios=None, + can_send_documents=None, can_send_photos=None, + can_send_videos=None, can_send_video_notes=None, + can_send_voice_notes=None, can_send_polls=None, can_send_other_messages=None, + can_add_web_page_previews=None, can_change_info=None, + can_invite_users=None, can_pin_messages=None, + can_manage_topics=None, **kwargs): self.can_send_messages: bool = can_send_messages - self.can_send_media_messages: bool = can_send_media_messages + #self.can_send_media_messages: bool = can_send_media_messages self.can_send_polls: bool = can_send_polls self.can_send_other_messages: bool = can_send_other_messages self.can_add_web_page_previews: bool = can_add_web_page_previews @@ -3100,6 +3141,13 @@ class ChatPermissions(JsonDeserializable, JsonSerializable, Dictionaryable): self.can_invite_users: bool = can_invite_users self.can_pin_messages: bool = can_pin_messages self.can_manage_topics: bool = can_manage_topics + self.can_send_audios: bool = can_send_audios + self.can_send_documents: bool = can_send_documents + self.can_send_photos: bool = can_send_photos + self.can_send_videos: bool = can_send_videos + self.can_send_video_notes: bool = can_send_video_notes + self.can_send_voice_notes: bool = can_send_voice_notes + def to_json(self): return json.dumps(self.to_dict()) @@ -3108,8 +3156,19 @@ class ChatPermissions(JsonDeserializable, JsonSerializable, Dictionaryable): json_dict = dict() if self.can_send_messages is not None: json_dict['can_send_messages'] = self.can_send_messages - if self.can_send_media_messages is not None: - json_dict['can_send_media_messages'] = self.can_send_media_messages + if self.can_send_audios is not None: + json_dict['can_send_audios'] = self.can_send_audios + + if self.can_send_documents is not None: + json_dict['can_send_documents'] = self.can_send_documents + if self.can_send_photos is not None: + json_dict['can_send_photos'] = self.can_send_photos + if self.can_send_videos is not None: + json_dict['can_send_videos'] = self.can_send_videos + if self.can_send_video_notes is not None: + json_dict['can_send_video_notes'] = self.can_send_video_notes + if self.can_send_voice_notes is not None: + json_dict['can_send_voice_notes'] = self.can_send_voice_notes if self.can_send_polls is not None: json_dict['can_send_polls'] = self.can_send_polls if self.can_send_other_messages is not None: @@ -7214,4 +7273,3 @@ class ChatShared(JsonDeserializable): self.request_id: int = request_id self.chat_id: int = chat_id - \ No newline at end of file From d0d03d0c097e1973e506db5d64d1cc895e22479c Mon Sep 17 00:00:00 2001 From: coder2020official Date: Sat, 4 Feb 2023 19:59:49 +0400 Subject: [PATCH 09/13] Added use_independent_chat_permissions for restrictchatmember --- telebot/__init__.py | 11 +++++++++-- telebot/apihelper.py | 5 ++++- telebot/async_telebot.py | 11 +++++++++-- telebot/asyncio_helper.py | 5 ++++- 4 files changed, 26 insertions(+), 6 deletions(-) diff --git a/telebot/__init__.py b/telebot/__init__.py index 6f6b452..095b12e 100644 --- a/telebot/__init__.py +++ b/telebot/__init__.py @@ -2917,7 +2917,8 @@ class TeleBot: can_add_web_page_previews: Optional[bool]=None, can_change_info: Optional[bool]=None, can_invite_users: Optional[bool]=None, - can_pin_messages: Optional[bool]=None) -> bool: + can_pin_messages: Optional[bool]=None, + use_independent_chat_permissions: Optional[bool]=None) -> bool: """ Use this method to restrict a user in a supergroup. The bot must be an administrator in the supergroup for this to work and must have @@ -2965,6 +2966,12 @@ class TeleBot: :param can_pin_messages: Pass True, if the user is allowed to pin messages. Ignored in public supergroups :type can_pin_messages: :obj:`bool` + :param use_independent_chat_permissions: Pass True if chat permissions are set independently. Otherwise, + the can_send_other_messages and can_add_web_page_previews permissions will imply the can_send_messages, + can_send_audios, can_send_documents, can_send_photos, can_send_videos, can_send_video_notes, and + can_send_voice_notes permissions; the can_send_polls permission will imply the can_send_messages permission. + :type use_independent_chat_permissions: :obj:`bool` + :return: True on success :rtype: :obj:`bool` """ @@ -2973,7 +2980,7 @@ class TeleBot: can_send_messages, can_send_media_messages, can_send_polls, can_send_other_messages, can_add_web_page_previews, can_change_info, - can_invite_users, can_pin_messages) + can_invite_users, can_pin_messages, use_independent_chat_permissions) def promote_chat_member( self, chat_id: Union[int, str], user_id: int, diff --git a/telebot/apihelper.py b/telebot/apihelper.py index 1086f54..aa9e337 100644 --- a/telebot/apihelper.py +++ b/telebot/apihelper.py @@ -972,7 +972,7 @@ def restrict_chat_member( can_send_messages=None, can_send_media_messages=None, can_send_polls=None, can_send_other_messages=None, can_add_web_page_previews=None, can_change_info=None, - can_invite_users=None, can_pin_messages=None): + can_invite_users=None, can_pin_messages=None, use_independent_chat_permissions=None): method_url = 'restrictChatMember' permissions = {} if can_send_messages is not None: @@ -991,6 +991,9 @@ def restrict_chat_member( permissions['can_invite_users'] = can_invite_users if can_pin_messages is not None: permissions['can_pin_messages'] = can_pin_messages + if use_independent_chat_permissions is not None: + permissions['use_independent_chat_permissions'] = use_independent_chat_permissions + permissions_json = json.dumps(permissions) payload = {'chat_id': chat_id, 'user_id': user_id, 'permissions': permissions_json} if until_date is not None: diff --git a/telebot/async_telebot.py b/telebot/async_telebot.py index 8dbf55a..d976c78 100644 --- a/telebot/async_telebot.py +++ b/telebot/async_telebot.py @@ -3775,7 +3775,8 @@ class AsyncTeleBot: can_add_web_page_previews: Optional[bool]=None, can_change_info: Optional[bool]=None, can_invite_users: Optional[bool]=None, - can_pin_messages: Optional[bool]=None) -> bool: + can_pin_messages: Optional[bool]=None, + use_independent_chat_permissions: Optional[bool]=None) -> bool: """ Use this method to restrict a user in a supergroup. The bot must be an administrator in the supergroup for this to work and must have @@ -3823,6 +3824,12 @@ class AsyncTeleBot: :param can_pin_messages: Pass True, if the user is allowed to pin messages. Ignored in public supergroups :type can_pin_messages: :obj:`bool` + :param use_independent_chat_permissions: Pass True if chat permissions are set independently. Otherwise, + the can_send_other_messages and can_add_web_page_previews permissions will imply the can_send_messages, + can_send_audios, can_send_documents, can_send_photos, can_send_videos, can_send_video_notes, and + can_send_voice_notes permissions; the can_send_polls permission will imply the can_send_messages permission. + :type use_independent_chat_permissions: :obj:`bool` + :return: True on success :rtype: :obj:`bool` """ @@ -3831,7 +3838,7 @@ class AsyncTeleBot: can_send_messages, can_send_media_messages, can_send_polls, can_send_other_messages, can_add_web_page_previews, can_change_info, - can_invite_users, can_pin_messages) + can_invite_users, can_pin_messages, use_independent_chat_permissions) async def promote_chat_member( self, chat_id: Union[int, str], user_id: int, diff --git a/telebot/asyncio_helper.py b/telebot/asyncio_helper.py index 219cc1d..df4b17c 100644 --- a/telebot/asyncio_helper.py +++ b/telebot/asyncio_helper.py @@ -964,7 +964,7 @@ async def restrict_chat_member( can_send_messages=None, can_send_media_messages=None, can_send_polls=None, can_send_other_messages=None, can_add_web_page_previews=None, can_change_info=None, - can_invite_users=None, can_pin_messages=None): + can_invite_users=None, can_pin_messages=None, use_independent_chat_permissions=None): method_url = 'restrictChatMember' permissions = {} if can_send_messages is not None: @@ -983,6 +983,9 @@ async def restrict_chat_member( permissions['can_invite_users'] = can_invite_users if can_pin_messages is not None: permissions['can_pin_messages'] = can_pin_messages + if use_independent_chat_permissions is not None: + permissions['use_independent_chat_permissions'] = use_independent_chat_permissions + permissions_json = json.dumps(permissions) payload = {'chat_id': chat_id, 'user_id': user_id, 'permissions': permissions_json} if until_date is not None: From d1348606e33b005b47adf757f44a0cd9f6e48dd3 Mon Sep 17 00:00:00 2001 From: coder2020official Date: Sat, 4 Feb 2023 20:04:07 +0400 Subject: [PATCH 10/13] Added use_independent_chat_permissions to setchatpermissions --- telebot/__init__.py | 11 +++++++++-- telebot/apihelper.py | 6 ++++-- telebot/async_telebot.py | 11 +++++++++-- telebot/asyncio_helper.py | 4 +++- 4 files changed, 25 insertions(+), 7 deletions(-) diff --git a/telebot/__init__.py b/telebot/__init__.py index 095b12e..0d6e37b 100644 --- a/telebot/__init__.py +++ b/telebot/__init__.py @@ -3138,7 +3138,8 @@ class TeleBot: return apihelper.unban_chat_sender_chat(self.token, chat_id, sender_chat_id) def set_chat_permissions( - self, chat_id: Union[int, str], permissions: types.ChatPermissions) -> bool: + self, chat_id: Union[int, str], permissions: types.ChatPermissions, + use_independent_chat_permissions: Optional[bool]=None) -> bool: """ Use this method to set default chat permissions for all members. The bot must be an administrator in the group or a supergroup for this to work @@ -3153,10 +3154,16 @@ class TeleBot: :param permissions: New default chat permissions :type permissions: :class:`telebot.types..ChatPermissions` + :param use_independent_chat_permissions: Pass True if chat permissions are set independently. Otherwise, + the can_send_other_messages and can_add_web_page_previews permissions will imply the can_send_messages, + can_send_audios, can_send_documents, can_send_photos, can_send_videos, can_send_video_notes, and + can_send_voice_notes permissions; the can_send_polls permission will imply the can_send_messages permission. + :type use_independent_chat_permissions: :obj:`bool` + :return: True on success :rtype: :obj:`bool` """ - return apihelper.set_chat_permissions(self.token, chat_id, permissions) + return apihelper.set_chat_permissions(self.token, chat_id, permissions, use_independent_chat_permissions) def create_chat_invite_link( self, chat_id: Union[int, str], diff --git a/telebot/apihelper.py b/telebot/apihelper.py index aa9e337..82e1269 100644 --- a/telebot/apihelper.py +++ b/telebot/apihelper.py @@ -993,7 +993,7 @@ def restrict_chat_member( permissions['can_pin_messages'] = can_pin_messages if use_independent_chat_permissions is not None: permissions['use_independent_chat_permissions'] = use_independent_chat_permissions - + permissions_json = json.dumps(permissions) payload = {'chat_id': chat_id, 'user_id': user_id, 'permissions': permissions_json} if until_date is not None: @@ -1059,12 +1059,14 @@ def unban_chat_sender_chat(token, chat_id, sender_chat_id): return _make_request(token, method_url, params=payload, method='post') -def set_chat_permissions(token, chat_id, permissions): +def set_chat_permissions(token, chat_id, permissions, use_independent_chat_permissions=None): method_url = 'setChatPermissions' payload = { 'chat_id': chat_id, 'permissions': permissions.to_json() } + if use_independent_chat_permissions is not None: + payload['use_independent_chat_permissions'] = use_independent_chat_permissions return _make_request(token, method_url, params=payload, method='post') diff --git a/telebot/async_telebot.py b/telebot/async_telebot.py index d976c78..67d7529 100644 --- a/telebot/async_telebot.py +++ b/telebot/async_telebot.py @@ -3998,7 +3998,8 @@ class AsyncTeleBot: return await asyncio_helper.unban_chat_sender_chat(self.token, chat_id, sender_chat_id) async def set_chat_permissions( - self, chat_id: Union[int, str], permissions: types.ChatPermissions) -> bool: + self, chat_id: Union[int, str], permissions: types.ChatPermissions, + use_independent_chat_permissions: Optional[bool]=None) -> bool: """ Use this method to set default chat permissions for all members. The bot must be an administrator in the group or a supergroup for this to work @@ -4013,10 +4014,16 @@ class AsyncTeleBot: :param permissions: New default chat permissions :type permissions: :class:`telebot.types..ChatPermissions` + :param use_independent_chat_permissions: Pass True if chat permissions are set independently. Otherwise, + the can_send_other_messages and can_add_web_page_previews permissions will imply the can_send_messages, + can_send_audios, can_send_documents, can_send_photos, can_send_videos, can_send_video_notes, and + can_send_voice_notes permissions; the can_send_polls permission will imply the can_send_messages permission. + :type use_independent_chat_permissions: :obj:`bool` + :return: True on success :rtype: :obj:`bool` """ - return await asyncio_helper.set_chat_permissions(self.token, chat_id, permissions) + return await asyncio_helper.set_chat_permissions(self.token, chat_id, permissions, use_independent_chat_permissions) async def create_chat_invite_link( self, chat_id: Union[int, str], diff --git a/telebot/asyncio_helper.py b/telebot/asyncio_helper.py index df4b17c..ddad140 100644 --- a/telebot/asyncio_helper.py +++ b/telebot/asyncio_helper.py @@ -1049,12 +1049,14 @@ async def unban_chat_sender_chat(token, chat_id, sender_chat_id): payload = {'chat_id': chat_id, 'sender_chat_id': sender_chat_id} return await _process_request(token, method_url, params=payload, method='post') -async def set_chat_permissions(token, chat_id, permissions): +async def set_chat_permissions(token, chat_id, permissions, use_independent_chat_permissions=None): method_url = 'setChatPermissions' payload = { 'chat_id': chat_id, 'permissions': permissions.to_json() } + if use_independent_chat_permissions is not None: + payload['use_independent_chat_permissions'] = use_independent_chat_permissions return await _process_request(token, method_url, params=payload, method='post') From 2094120ec78ddce8fa9c54f0b97bd4df7fc07ff8 Mon Sep 17 00:00:00 2001 From: coder2020official Date: Sat, 4 Feb 2023 20:07:01 +0400 Subject: [PATCH 11/13] Added user_chat_id to ChatJoinRequest; And, i corrected typehints --- telebot/types.py | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/telebot/types.py b/telebot/types.py index d454536..082acf1 100644 --- a/telebot/types.py +++ b/telebot/types.py @@ -289,9 +289,16 @@ class ChatJoinRequest(JsonDeserializable): :param chat: Chat to which the request was sent :type chat: :class:`telebot.types.Chat` - :param from: User that sent the join request + :param from_user: User that sent the join request :type from_user: :class:`telebot.types.User` + :param user_chat_id: Optional. Identifier of a private chat with the user who sent the join request. + This number may have more than 32 significant bits and some programming languages may have difficulty/silent + defects in interpreting it. But it has at most 52 significant bits, so a 64-bit integer or double-precision + float type are safe for storing this identifier. The bot can use this identifier for 24 hours to send messages + until the join request is processed, assuming no other administrator contacted the user. + :type user_chat_id: :obj:`int` + :param date: Date the request was sent in Unix time :type date: :obj:`int` @@ -313,12 +320,13 @@ class ChatJoinRequest(JsonDeserializable): obj['invite_link'] = ChatInviteLink.de_json(obj.get('invite_link')) return cls(**obj) - def __init__(self, chat, from_user, date, bio=None, invite_link=None, **kwargs): - self.chat = chat - self.from_user = from_user - self.date = date - self.bio = bio - self.invite_link = invite_link + def __init__(self, chat, from_user, user_chat_id, date, bio=None, invite_link=None, **kwargs): + self.chat: Chat = chat + self.from_user: User = from_user + self.date: str = date + self.bio: str = bio + self.invite_link: ChatInviteLink = invite_link + self.user_chat_id: int = user_chat_id class WebhookInfo(JsonDeserializable): """ From a9b878107cef661ec7acca5abdfc79a5ef94c39d Mon Sep 17 00:00:00 2001 From: coder2020official Date: Sat, 4 Feb 2023 22:24:26 +0400 Subject: [PATCH 12/13] Fix can_send_media_messages param, added warnings --- telebot/__init__.py | 31 ++++++++++++++++++++++++++----- telebot/apihelper.py | 30 +++++------------------------- telebot/async_telebot.py | 30 +++++++++++++++++++++++++----- telebot/asyncio_helper.py | 29 ++++------------------------- telebot/types.py | 16 +++++++++++++++- 5 files changed, 75 insertions(+), 61 deletions(-) diff --git a/telebot/__init__.py b/telebot/__init__.py index 0d6e37b..70daddc 100644 --- a/telebot/__init__.py +++ b/telebot/__init__.py @@ -2918,6 +2918,7 @@ class TeleBot: can_change_info: Optional[bool]=None, can_invite_users: Optional[bool]=None, can_pin_messages: Optional[bool]=None, + permissions: Optional[types.ChatPermissions]=None, use_independent_chat_permissions: Optional[bool]=None) -> bool: """ Use this method to restrict a user in a supergroup. @@ -2926,6 +2927,10 @@ class TeleBot: Telegram documentation: https://core.telegram.org/bots/api#restrictchatmember + .. warning:: + Please pass `telebot.types.ChatPermissions` object to `permissions` parameter instead of + passing all boolean parameters. Those boolean parameters won't be supported soon, so please take it into consideration. + :param chat_id: Unique identifier for the target group or username of the target supergroup or channel (in the format @channelusername) :type chat_id: :obj:`int` or :obj:`str` @@ -2972,15 +2977,31 @@ class TeleBot: can_send_voice_notes permissions; the can_send_polls permission will imply the can_send_messages permission. :type use_independent_chat_permissions: :obj:`bool` + :param permissions: Pass ChatPermissions object to set all permissions at once. Use this param instead of + passing all boolean parameters. + :type permissions: :class:`telebot.types.ChatPermissions` + :return: True on success :rtype: :obj:`bool` """ + + if permissions is None: + permissions = types.ChatPermissions( + can_send_messages=can_send_messages, + can_send_media_messages=can_send_media_messages, + can_send_polls=can_send_polls, + can_send_other_messages=can_send_other_messages, + can_add_web_page_previews=can_add_web_page_previews, + can_change_info=can_change_info, + can_invite_users=can_invite_users, + can_pin_messages=can_pin_messages + ) + logger.warning( + 'Please pass `telebot.types.ChatPermissions` object to `permissions` parameter instead of ' + 'passing all boolean parameters. Those boolean parameters won\'t be supported soon, so please take it into consideration.' + ) return apihelper.restrict_chat_member( - self.token, chat_id, user_id, until_date, - can_send_messages, can_send_media_messages, - can_send_polls, can_send_other_messages, - can_add_web_page_previews, can_change_info, - can_invite_users, can_pin_messages, use_independent_chat_permissions) + self.token, chat_id, user_id, permissions, until_date, use_independent_chat_permissions) def promote_chat_member( self, chat_id: Union[int, str], user_id: int, diff --git a/telebot/apihelper.py b/telebot/apihelper.py index 82e1269..2a95eb0 100644 --- a/telebot/apihelper.py +++ b/telebot/apihelper.py @@ -968,39 +968,19 @@ def unban_chat_member(token, chat_id, user_id, only_if_banned): def restrict_chat_member( - token, chat_id, user_id, until_date=None, - can_send_messages=None, can_send_media_messages=None, - can_send_polls=None, can_send_other_messages=None, - can_add_web_page_previews=None, can_change_info=None, - can_invite_users=None, can_pin_messages=None, use_independent_chat_permissions=None): + token, chat_id, user_id, permissions, until_date=None, + use_independent_chat_permissions=None): method_url = 'restrictChatMember' - permissions = {} - if can_send_messages is not None: - permissions['can_send_messages'] = can_send_messages - if can_send_media_messages is not None: - permissions['can_send_media_messages'] = can_send_media_messages - if can_send_polls is not None: - permissions['can_send_polls'] = can_send_polls - if can_send_other_messages is not None: - permissions['can_send_other_messages'] = can_send_other_messages - if can_add_web_page_previews is not None: - permissions['can_add_web_page_previews'] = can_add_web_page_previews - if can_change_info is not None: - permissions['can_change_info'] = can_change_info - if can_invite_users is not None: - permissions['can_invite_users'] = can_invite_users - if can_pin_messages is not None: - permissions['can_pin_messages'] = can_pin_messages + payload = {'chat_id': chat_id, 'user_id': user_id, 'permissions': permissions.to_json()} + if use_independent_chat_permissions is not None: permissions['use_independent_chat_permissions'] = use_independent_chat_permissions - - permissions_json = json.dumps(permissions) - payload = {'chat_id': chat_id, 'user_id': user_id, 'permissions': permissions_json} if until_date is not None: if isinstance(until_date, datetime): payload['until_date'] = until_date.timestamp() else: payload['until_date'] = until_date + return _make_request(token, method_url, params=payload, method='post') diff --git a/telebot/async_telebot.py b/telebot/async_telebot.py index 67d7529..ebfaca5 100644 --- a/telebot/async_telebot.py +++ b/telebot/async_telebot.py @@ -3776,6 +3776,7 @@ class AsyncTeleBot: can_change_info: Optional[bool]=None, can_invite_users: Optional[bool]=None, can_pin_messages: Optional[bool]=None, + permissions: Optional[types.ChatPermissions]=None, use_independent_chat_permissions: Optional[bool]=None) -> bool: """ Use this method to restrict a user in a supergroup. @@ -3784,6 +3785,10 @@ class AsyncTeleBot: Telegram documentation: https://core.telegram.org/bots/api#restrictchatmember + .. warning:: + Please pass `telebot.types.ChatPermissions` object to `permissions` parameter instead of + passing all boolean parameters. Those boolean parameters won't be supported soon, so please take it into consideration. + :param chat_id: Unique identifier for the target group or username of the target supergroup or channel (in the format @channelusername) :type chat_id: :obj:`int` or :obj:`str` @@ -3830,15 +3835,30 @@ class AsyncTeleBot: can_send_voice_notes permissions; the can_send_polls permission will imply the can_send_messages permission. :type use_independent_chat_permissions: :obj:`bool` + :param permissions: Pass ChatPermissions object to set all permissions at once. Use this parameter instead of + passing all boolean parameters to avoid backward compatibility problems in future. + :type permissions: :obj:`types.ChatPermissions` + :return: True on success :rtype: :obj:`bool` """ + if permissions is None: + permissions = types.ChatPermissions( + can_send_messages=can_send_messages, + can_send_media_messages=can_send_media_messages, + can_send_polls=can_send_polls, + can_send_other_messages=can_send_other_messages, + can_add_web_page_previews=can_add_web_page_previews, + can_change_info=can_change_info, + can_invite_users=can_invite_users, + can_pin_messages=can_pin_messages + ) + logger.warning( + 'Please pass `telebot.types.ChatPermissions` object to `permissions` parameter instead of ' + 'passing all boolean parameters. Those boolean parameters won\'t be supported soon, so please take it into consideration.' + ) return await asyncio_helper.restrict_chat_member( - self.token, chat_id, user_id, until_date, - can_send_messages, can_send_media_messages, - can_send_polls, can_send_other_messages, - can_add_web_page_previews, can_change_info, - can_invite_users, can_pin_messages, use_independent_chat_permissions) + self.token, chat_id, user_id, permissions, until_date, use_independent_chat_permissions) async def promote_chat_member( self, chat_id: Union[int, str], user_id: int, diff --git a/telebot/asyncio_helper.py b/telebot/asyncio_helper.py index ddad140..9fa7345 100644 --- a/telebot/asyncio_helper.py +++ b/telebot/asyncio_helper.py @@ -960,34 +960,13 @@ async def unban_chat_member(token, chat_id, user_id, only_if_banned): async def restrict_chat_member( - token, chat_id, user_id, until_date=None, - can_send_messages=None, can_send_media_messages=None, - can_send_polls=None, can_send_other_messages=None, - can_add_web_page_previews=None, can_change_info=None, - can_invite_users=None, can_pin_messages=None, use_independent_chat_permissions=None): + token, chat_id, user_id, permissions, until_date=None, + use_independent_chat_permissions=None): method_url = 'restrictChatMember' - permissions = {} - if can_send_messages is not None: - permissions['can_send_messages'] = can_send_messages - if can_send_media_messages is not None: - permissions['can_send_media_messages'] = can_send_media_messages - if can_send_polls is not None: - permissions['can_send_polls'] = can_send_polls - if can_send_other_messages is not None: - permissions['can_send_other_messages'] = can_send_other_messages - if can_add_web_page_previews is not None: - permissions['can_add_web_page_previews'] = can_add_web_page_previews - if can_change_info is not None: - permissions['can_change_info'] = can_change_info - if can_invite_users is not None: - permissions['can_invite_users'] = can_invite_users - if can_pin_messages is not None: - permissions['can_pin_messages'] = can_pin_messages + payload = {'chat_id': chat_id, 'user_id': user_id, 'permissions': permissions.to_json()} + if use_independent_chat_permissions is not None: permissions['use_independent_chat_permissions'] = use_independent_chat_permissions - - permissions_json = json.dumps(permissions) - payload = {'chat_id': chat_id, 'user_id': user_id, 'permissions': permissions_json} if until_date is not None: if isinstance(until_date, datetime): payload['until_date'] = until_date.timestamp() diff --git a/telebot/types.py b/telebot/types.py index 082acf1..b53706e 100644 --- a/telebot/types.py +++ b/telebot/types.py @@ -2418,6 +2418,8 @@ class KeyboardButton(Dictionaryable, JsonSerializable): json_dict['web_app'] = self.web_app.to_dict() if self.request_user is not None: json_dict['request_user'] = self.request_user.to_dict() + if self.request_chat is not None: + json_dict['request_chat'] = self.request_chat.to_dict() return json_dict @@ -3124,6 +3126,10 @@ class ChatPermissions(JsonDeserializable, JsonSerializable, Dictionaryable): value of can_pin_messages :type can_manage_topics: :obj:`bool` + :param can_send_media_messages: deprecated. True, if the user is allowed to send audios, documents, photos, videos, + video notes and voice notes + :type can_send_media_messages: :obj:`bool` + :return: Instance of the class :rtype: :class:`telebot.types.ChatPermissions` """ @@ -3133,7 +3139,7 @@ class ChatPermissions(JsonDeserializable, JsonSerializable, Dictionaryable): obj = cls.check_json(json_string, dict_copy=False) return cls(**obj) - def __init__(self, can_send_messages=None, can_send_audios=None, + def __init__(self, can_send_messages=None, can_send_media_messages=None,can_send_audios=None, can_send_documents=None, can_send_photos=None, can_send_videos=None, can_send_video_notes=None, can_send_voice_notes=None, can_send_polls=None, can_send_other_messages=None, @@ -3156,6 +3162,14 @@ class ChatPermissions(JsonDeserializable, JsonSerializable, Dictionaryable): self.can_send_video_notes: bool = can_send_video_notes self.can_send_voice_notes: bool = can_send_voice_notes + if can_send_media_messages is not None: + self.can_send_audios = can_send_media_messages + self.can_send_documents = can_send_media_messages + self.can_send_photos = can_send_media_messages + self.can_send_videos = can_send_media_messages + self.can_send_video_notes = can_send_media_messages + self.can_send_voice_notes = can_send_media_messages + def to_json(self): return json.dumps(self.to_dict()) From 4179e502c38eaf4069d1638c79e03d1014a458b4 Mon Sep 17 00:00:00 2001 From: coder2020official Date: Sun, 5 Feb 2023 11:13:31 +0400 Subject: [PATCH 13/13] Fix description --- telebot/__init__.py | 6 ++---- telebot/async_telebot.py | 6 ++---- telebot/types.py | 1 + 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/telebot/__init__.py b/telebot/__init__.py index 70daddc..46669a6 100644 --- a/telebot/__init__.py +++ b/telebot/__init__.py @@ -2928,8 +2928,7 @@ class TeleBot: Telegram documentation: https://core.telegram.org/bots/api#restrictchatmember .. warning:: - Please pass `telebot.types.ChatPermissions` object to `permissions` parameter instead of - passing all boolean parameters. Those boolean parameters won't be supported soon, so please take it into consideration. + Individual parameters are deprecated and will be removed, use 'permissions' instead. :param chat_id: Unique identifier for the target group or username of the target supergroup or channel (in the format @channelusername) @@ -2997,8 +2996,7 @@ class TeleBot: can_pin_messages=can_pin_messages ) logger.warning( - 'Please pass `telebot.types.ChatPermissions` object to `permissions` parameter instead of ' - 'passing all boolean parameters. Those boolean parameters won\'t be supported soon, so please take it into consideration.' + "Individual parameters are deprecated and will be removed, use 'permissions' instead." ) return apihelper.restrict_chat_member( self.token, chat_id, user_id, permissions, until_date, use_independent_chat_permissions) diff --git a/telebot/async_telebot.py b/telebot/async_telebot.py index ebfaca5..d1fa77b 100644 --- a/telebot/async_telebot.py +++ b/telebot/async_telebot.py @@ -3786,8 +3786,7 @@ class AsyncTeleBot: Telegram documentation: https://core.telegram.org/bots/api#restrictchatmember .. warning:: - Please pass `telebot.types.ChatPermissions` object to `permissions` parameter instead of - passing all boolean parameters. Those boolean parameters won't be supported soon, so please take it into consideration. + Individual parameters are deprecated and will be removed, use 'permissions' instead :param chat_id: Unique identifier for the target group or username of the target supergroup or channel (in the format @channelusername) @@ -3854,8 +3853,7 @@ class AsyncTeleBot: can_pin_messages=can_pin_messages ) logger.warning( - 'Please pass `telebot.types.ChatPermissions` object to `permissions` parameter instead of ' - 'passing all boolean parameters. Those boolean parameters won\'t be supported soon, so please take it into consideration.' + "Individual parameters are deprecated and will be removed, use 'permissions' instead." ) return await asyncio_helper.restrict_chat_member( self.token, chat_id, user_id, permissions, until_date, use_independent_chat_permissions) diff --git a/telebot/types.py b/telebot/types.py index b53706e..cb4facb 100644 --- a/telebot/types.py +++ b/telebot/types.py @@ -3163,6 +3163,7 @@ class ChatPermissions(JsonDeserializable, JsonSerializable, Dictionaryable): self.can_send_voice_notes: bool = can_send_voice_notes if can_send_media_messages is not None: + logger.warning("can_send_media_messages is deprecated. Use individual parameters like can_send_audios, can_send_documents, etc.") self.can_send_audios = can_send_media_messages self.can_send_documents = can_send_media_messages self.can_send_photos = can_send_media_messages