diff --git a/telebot/__init__.py b/telebot/__init__.py index c4c9eab67..fb12ea686 100644 --- a/telebot/__init__.py +++ b/telebot/__init__.py @@ -1827,7 +1827,8 @@ def forward_message( message_thread_id: Optional[int]=None, video_start_timestamp: Optional[int]=None, direct_messages_topic_id: Optional[int]=None, - suggested_post_parameters: Optional[types.SuggestedPostParameters]=None) -> types.Message: + suggested_post_parameters: Optional[types.SuggestedPostParameters]=None, + message_effect_id: Optional[str]=None) -> types.Message: """ Use this method to forward messages of any kind. @@ -1866,6 +1867,9 @@ def forward_message( is automatically declined. :type suggested_post_parameters: :class:`telebot.types.SuggestedPostParameters` + :param message_effect_id: Unique identifier of the message effect to be added to the message; only available when forwarding to private chats + :type message_effect_id: :obj:`str` + :return: On success, the sent Message is returned. :rtype: :class:`telebot.types.Message` """ @@ -1877,7 +1881,7 @@ def forward_message( self.token, chat_id, from_chat_id, message_id, disable_notification=disable_notification, timeout=timeout, protect_content=protect_content, message_thread_id=message_thread_id, video_start_timestamp=video_start_timestamp, direct_messages_topic_id=direct_messages_topic_id, - suggested_post_parameters=suggested_post_parameters + suggested_post_parameters=suggested_post_parameters, message_effect_id=message_effect_id ) ) @@ -1901,7 +1905,8 @@ def copy_message( allow_paid_broadcast: Optional[bool]=None, video_start_timestamp: Optional[int]=None, direct_messages_topic_id: Optional[int]=None, - suggested_post_parameters: Optional[types.SuggestedPostParameters]=None) -> types.MessageID: + suggested_post_parameters: Optional[types.SuggestedPostParameters]=None, + message_effect_id: Optional[str]=None) -> types.MessageID: """ Use this method to copy messages of any kind. Service messages, paid media messages, giveaway messages, giveaway winners messages, and invoice messages can't be copied. @@ -1973,6 +1978,9 @@ def copy_message( is automatically declined. :type suggested_post_parameters: :class:`telebot.types.SuggestedPostParameters` + :param message_effect_id: Unique identifier of the message effect to be added to the message; only available when copying to private chats + :type message_effect_id: :obj:`str` + :return: On success, the MessageId of the sent message is returned. :rtype: :class:`telebot.types.MessageID` """ @@ -2006,7 +2014,7 @@ def copy_message( message_thread_id=message_thread_id, reply_parameters=reply_parameters, show_caption_above_media=show_caption_above_media, allow_paid_broadcast=allow_paid_broadcast, video_start_timestamp=video_start_timestamp, direct_messages_topic_id=direct_messages_topic_id, - suggested_post_parameters=suggested_post_parameters + suggested_post_parameters=suggested_post_parameters, message_effect_id=message_effect_id )) @@ -4195,6 +4203,45 @@ def send_contact( business_connection_id=business_connection_id, message_effect_id=message_effect_id, allow_paid_broadcast=allow_paid_broadcast, direct_messages_topic_id=direct_messages_topic_id, suggested_post_parameters=suggested_post_parameters) ) + + + def send_message_draft( + self, chat_id: int, + draft_id: int, + text: str, + message_thread_id: Optional[int]=None, + parse_mode: Optional[str]=None, + entities: Optional[List[types.MessageEntity]]=None): + """ + Use this method to stream a partial message to a user while the message is being generated; + supported only for bots with forum topic mode enabled. Returns True on success. + + Telegram documentation: https://core.telegram.org/bots/api#sendmessagedraft + + :param chat_id: Unique identifier for the target private chat + :type chat_id: :obj:`int` + + :param message_thread_id: Unique identifier for the target message thread + :type message_thread_id: :obj:`int` + + :param draft_id: Unique identifier of the message draft; must be non-zero. Changes of drafts with the same identifier are animated + :type draft_id: :obj:`int` + + :param text: Text of the message to be sent, 1-4096 characters after entities parsing + :type text: :obj:`str` + + :param parse_mode: Mode for parsing entities in the message text. See formatting options for more details. + :type parse_mode: :obj:`str` + + :param entities: A JSON-serialized list of special entities that appear in message text, which can be specified instead of parse_mode + :type entities: :obj:`list` of :class:`telebot.types.MessageEntity + + :return: Returns True on success. + :rtype: :obj:`bool` + """ + return apihelper.send_message_draft( + self.token, chat_id, draft_id, text, parse_mode=parse_mode, entities=entities, message_thread_id=message_thread_id) + def send_chat_action( @@ -4222,7 +4269,7 @@ def send_chat_action( :param timeout: Timeout in seconds for the request. :type timeout: :obj:`int` - :param message_thread_id: The thread identifier of a message from which the reply will be sent(supergroups only) + :param message_thread_id: The thread identifier of a message from which the reply will be sent(for supergroups and private chats) :type message_thread_id: :obj:`int` :param business_connection_id: Identifier of a business connection @@ -6909,7 +6956,10 @@ def get_business_account_gifts( exclude_unique: Optional[bool]=None, sort_by_price: Optional[bool]=None, offset: Optional[str]=None, - limit: Optional[int]=None) -> types.OwnedGifts: + limit: Optional[int]=None, + exclude_limited_upgradable: Optional[bool]=None, + exclude_limited_non_upgradable: Optional[bool]=None, + exclude_from_blockchain: Optional[bool]=None,) -> types.OwnedGifts: """ Returns the gifts received and owned by a managed business account. Requires the can_view_gifts_and_stars business bot right. Returns OwnedGifts on success. @@ -6933,6 +6983,9 @@ def get_business_account_gifts( :param exclude_unique: Pass True to exclude unique gifts :type exclude_unique: :obj:`bool` + :param exclude_from_blockchain: Pass True to exclude gifts that were assigned from the TON blockchain and can't be resold or transferred in Telegram + :type exclude_from_blockchain: :obj:`bool` + :param sort_by_price: Pass True to sort results by gift price instead of send date. Sorting is applied before pagination. :type sort_by_price: :obj:`bool` @@ -6942,16 +6995,157 @@ def get_business_account_gifts( :param limit: The maximum number of gifts to be returned; 1-100. Defaults to 100 :type limit: :obj:`int` + :param exclude_limited_upgradable: Pass True to exclude gifts that can be purchased a limited number of times and can be upgraded to unique + :type exclude_limited_upgradable: :obj:`bool` + + :param exclude_limited_non_upgradable: Pass True to exclude gifts that can be purchased a limited number of times and can't be upgraded to unique + :type exclude_limited_non_upgradable: :obj:`bool` + :return: On success, a OwnedGifts object is returned. :rtype: :class:`telebot.types.OwnedGifts` """ + if exclude_limited is not None and exclude_limited_upgradable is None and exclude_limited_non_upgradable is None: + exclude_limited_upgradable = exclude_limited + exclude_limited_non_upgradable = exclude_limited + + return types.OwnedGifts.de_json( apihelper.get_business_account_gifts( self.token, business_connection_id, exclude_unsaved=exclude_unsaved, exclude_saved=exclude_saved, exclude_unlimited=exclude_unlimited, - exclude_limited=exclude_limited, + exclude_unique=exclude_unique, + sort_by_price=sort_by_price, + offset=offset, + limit=limit, + exclude_limited_upgradable=exclude_limited_upgradable, + exclude_limited_non_upgradable=exclude_limited_non_upgradable, + exclude_from_blockchain=exclude_from_blockchain + ) + ) + + def get_user_gifts( + self, user_id: int, + exclude_unlimited: Optional[bool]=None, + exclude_limited_upgradable: Optional[bool]=None, + exclude_limited_non_upgradable: Optional[bool]=None, + exclude_from_blockchain: Optional[bool]=None, + exclude_unique: Optional[bool]=None, + sort_by_price: Optional[bool]=None, + offset: Optional[str]=None, + limit: Optional[int]=None) -> types.OwnedGifts: + """ + Returns the gifts owned and hosted by a user. Returns OwnedGifts on success. + + Telegram documentation: https://core.telegram.org/bots/api#getusergifts + + :param user_id: Unique identifier of the user + :type user_id: :obj:`int` + + :param exclude_unlimited: Pass True to exclude gifts that can be purchased an unlimited number of times + :type exclude_unlimited: :obj:`bool` + + :param exclude_limited_upgradable: Pass True to exclude gifts that can be purchased a limited number of times and can be upgraded to unique + :type exclude_limited_upgradable: :obj:`bool` + + :param exclude_limited_non_upgradable: Pass True to exclude gifts that can be purchased a limited number of times and can't be upgraded to unique + :type exclude_limited_non_upgradable: :obj:`bool` + + :param exclude_from_blockchain: Pass True to exclude gifts that were assigned from the TON blockchain and can't be resold or transferred in Telegram + :type exclude_from_blockchain: :obj:`bool` + + :param exclude_unique: Pass True to exclude unique gifts + :type exclude_unique: :obj:`bool` + + :param sort_by_price: Pass True to sort results by gift price instead of send date. Sorting is applied before pagination. + :type sort_by_price: :obj:`bool` + + :param offset: Offset of the first entry to return as received from the previous request; use an empty string to get the first chunk of results + :type offset: :obj:`str` + + :param limit: The maximum number of gifts to be returned; 1-100. Defaults to 100 + :type limit: :obj:`int` + + :return: On success, a OwnedGifts object is returned. + :rtype: :class:`telebot.types.OwnedGifts` + """ + return types.OwnedGifts.de_json( + apihelper.get_user_gifts( + self.token, user_id, + exclude_unlimited=exclude_unlimited, + exclude_limited_upgradable=exclude_limited_upgradable, + exclude_limited_non_upgradable=exclude_limited_non_upgradable, + exclude_from_blockchain=exclude_from_blockchain, + exclude_unique=exclude_unique, + sort_by_price=sort_by_price, + offset=offset, + limit=limit + ) + ) + + def get_chat_gifts( + self, chat_id: Union[int, str], + exclude_unsaved: Optional[bool]=None, + exclude_saved: Optional[bool]=None, + exclude_unlimited: Optional[bool]=None, + exclude_limited_upgradable: Optional[bool]=None, + exclude_limited_non_upgradable: Optional[bool]=None, + exclude_from_blockchain: Optional[bool]=None, + exclude_unique: Optional[bool]=None, + sort_by_price: Optional[bool]=None, + offset: Optional[str]=None, + limit: Optional[int]=None) -> types.OwnedGifts: + """ + Returns the gifts owned by a chat. Returns OwnedGifts on success. + + Telegram documentation: https://core.telegram.org/bots/api#getchatgifts + + :param chat_id: Unique identifier for the target chat or username of the target channel (in the format @channelusername) + :type chat_id: :obj:`int` | :obj:`str` + + :param exclude_unsaved: Pass True to exclude gifts that aren't saved to the chat's profile page. Always True, unless the bot has the can_post_messages administrator right in the channel. + :type exclude_unsaved: :obj:`bool` + + :param exclude_saved: Pass True to exclude gifts that are saved to the chat's profile page. Always False, unless the bot has the can_post_messages administrator right in the channel. + :type exclude_saved: :obj:`bool` + + :param exclude_unlimited: Pass True to exclude gifts that can be purchased an unlimited number of times + :type exclude_unlimited: :obj:`bool` + + :param exclude_limited_upgradable: Pass True to exclude gifts that can be purchased a limited number of times and can be upgraded to unique + :type exclude_limited_upgradable: :obj:`bool` + + :param exclude_limited_non_upgradable: Pass True to exclude gifts that can be purchased a limited number of times and can't be upgraded to unique + :type exclude_limited_non_upgradable: :obj:`bool` + + :param exclude_from_blockchain: Pass True to exclude gifts that were assigned from the TON blockchain and can't be resold or transferred in Telegram + :type exclude_from_blockchain: :obj:`bool` + + :param exclude_unique: Pass True to exclude unique gifts + :type exclude_unique: :obj:`bool` + + :param sort_by_price: Pass True to sort results by gift price instead of send date. Sorting is applied before pagination. + :type sort_by_price: :obj:`bool` + + :param offset: Offset of the first entry to return as received from the previous request; use an empty string to get the first chunk of results + :type offset: :obj:`str` + + :param limit: The maximum number of gifts to be returned; 1-100. Defaults to 100 + :type limit: :obj:`int` + + :return: On success, a OwnedGifts object is returned. + :rtype: :class:`telebot.types.OwnedGifts` + """ + return types.OwnedGifts.de_json( + apihelper.get_chat_gifts( + self.token, chat_id, + exclude_unsaved=exclude_unsaved, + exclude_saved=exclude_saved, + exclude_unlimited=exclude_unlimited, + exclude_limited_upgradable=exclude_limited_upgradable, + exclude_limited_non_upgradable=exclude_limited_non_upgradable, + exclude_from_blockchain=exclude_from_blockchain, exclude_unique=exclude_unique, sort_by_price=sort_by_price, offset=offset, @@ -6959,6 +7153,7 @@ def get_business_account_gifts( ) ) + def convert_gift_to_stars(self, business_connection_id: str, owned_gift_id: str) -> bool: """ Converts a given regular gift to Telegram Stars. Requires the can_convert_gifts_to_stars business bot right. Returns True on success. @@ -7096,6 +7291,50 @@ def post_story( ) ) + def repost_story( + self, business_connection_id: str, + from_chat_id: int, from_story_id: int, + active_period: int, + post_to_chat_page: Optional[bool]=None, + protect_content: Optional[bool]=None) -> types.Story: + """ + Reposts a story on behalf of a business account from another business account. Both business accounts + must be managed by the same bot, and the story on the source account must have been posted (or reposted) + by the bot. Requires the can_manage_stories business bot right for both business accounts. Returns Story on success. + + Telegram documentation: https://core.telegram.org/bots/api#repoststory + + :param business_connection_id: Unique identifier of the business connection + :type business_connection_id: :obj:`str` + + :param from_chat_id: Unique identifier of the chat which posted the story that should be reposted + :type from_chat_id: :obj:`int` + + :param from_story_id: Unique identifier of the story that should be reposted + :type from_story_id: :obj:`int` + + :param active_period: Period after which the story is moved to the archive, in seconds; must be one of 6 * 3600, 12 * 3600, 86400, or 2 * 86400 + :type active_period: :obj:`int` + + :param post_to_chat_page: Pass True to keep the story accessible after it expires + :type post_to_chat_page: :obj:`bool` + + :param protect_content: Pass True if the content of the story must be protected from forwarding and screenshotting + :type protect_content: :obj:`bool` + + :return: On success, a Story object is returned. + :rtype: :class:`telebot.types.Story` + """ + return types.Story.de_json( + apihelper.repost_story( + self.token, business_connection_id, + from_chat_id, from_story_id, + active_period, + post_to_chat_page=post_to_chat_page, + protect_content=protect_content + ) + ) + def edit_story( self, business_connection_id: str, story_id: int, content: types.InputStoryContent, diff --git a/telebot/apihelper.py b/telebot/apihelper.py index 68f2418da..01137b7ca 100644 --- a/telebot/apihelper.py +++ b/telebot/apihelper.py @@ -432,7 +432,8 @@ def get_chat_member(token, chat_id, user_id): def forward_message( token, chat_id, from_chat_id, message_id, disable_notification=None, timeout=None, protect_content=None, message_thread_id=None, - video_start_timestamp=None, direct_messages_topic_id=None, suggested_post_parameters=None): + video_start_timestamp=None, direct_messages_topic_id=None, suggested_post_parameters=None, + message_effect_id=None): method_url = r'forwardMessage' payload = {'chat_id': chat_id, 'from_chat_id': from_chat_id, 'message_id': message_id} if disable_notification is not None: @@ -449,13 +450,16 @@ def forward_message( payload['direct_messages_topic_id'] = direct_messages_topic_id if suggested_post_parameters is not None: payload['suggested_post_parameters'] = suggested_post_parameters.to_json() + if message_effect_id: + payload['message_effect_id'] = message_effect_id return _make_request(token, method_url, params=payload) def copy_message(token, chat_id, from_chat_id, message_id, caption=None, parse_mode=None, caption_entities=None, disable_notification=None, reply_markup=None, timeout=None, protect_content=None, message_thread_id=None, reply_parameters=None, show_caption_above_media=None, allow_paid_broadcast=None, - video_start_timestamp=None, direct_messages_topic_id=None, suggested_post_parameters=None): + video_start_timestamp=None, direct_messages_topic_id=None, suggested_post_parameters=None, + message_effect_id=None): method_url = r'copyMessage' payload = {'chat_id': chat_id, 'from_chat_id': from_chat_id, 'message_id': message_id} if caption is not None: @@ -486,6 +490,8 @@ def copy_message(token, chat_id, from_chat_id, message_id, caption=None, parse_m payload['direct_messages_topic_id'] = direct_messages_topic_id if suggested_post_parameters is not None: payload['suggested_post_parameters'] = suggested_post_parameters.to_json() + if message_effect_id: + payload['message_effect_id'] = message_effect_id return _make_request(token, method_url, params=payload) def send_checklist( @@ -848,6 +854,20 @@ def send_contact( return _make_request(token, method_url, params=payload) +def send_message_draft( + token, chat_id, draft_id, text, + message_thread_id=None, parse_mode=None, entities=None): + method_url = r'sendMessageDraft' + payload = {'chat_id': chat_id, 'draft_id': draft_id, 'text': text} + if message_thread_id is not None: + payload['message_thread_id'] = message_thread_id + if parse_mode: + payload['parse_mode'] = parse_mode + if entities: + payload['entities'] = json.dumps(types.MessageEntity.to_list_of_dicts(entities)) + return _make_request(token, method_url, params=payload) + + def send_chat_action(token, chat_id, action, timeout=None, message_thread_id=None, business_connection_id=None): method_url = r'sendChatAction' payload = {'chat_id': chat_id, 'action': action} @@ -2176,27 +2196,85 @@ def transfer_business_account_stars(token, business_connection_id, star_count): return _make_request(token, method_url, params=payload, method='post') def get_business_account_gifts(token, business_connection_id, exclude_unsaved=None, exclude_saved=None, - exclude_unlimited=None, exclude_limited=None, exclude_unique=None, - sort_by_price=None, offset=None, limit=None): - method_url = 'getBusinessAccountGifts' - payload = {'business_connection_id': business_connection_id} - if exclude_unsaved is not None: - payload['exclude_unsaved'] = exclude_unsaved - if exclude_saved is not None: - payload['exclude_saved'] = exclude_saved - if exclude_unlimited is not None: - payload['exclude_unlimited'] = exclude_unlimited - if exclude_limited is not None: - payload['exclude_limited'] = exclude_limited - if exclude_unique is not None: - payload['exclude_unique'] = exclude_unique - if sort_by_price is not None: - payload['sort_by_price'] = sort_by_price - if offset is not None: - payload['offset'] = offset - if limit is not None: - payload['limit'] = limit - return _make_request(token, method_url, params=payload) + exclude_unlimited=None, exclude_unique=None, + sort_by_price=None, offset=None, limit=None, exclude_limited_upgradable=None, + exclude_limited_non_upgradable=None, exclude_from_blockchain=None): + method_url = 'getBusinessAccountGifts' + payload = {'business_connection_id': business_connection_id} + if exclude_unsaved is not None: + payload['exclude_unsaved'] = exclude_unsaved + if exclude_saved is not None: + payload['exclude_saved'] = exclude_saved + if exclude_unlimited is not None: + payload['exclude_unlimited'] = exclude_unlimited + if exclude_unique is not None: + payload['exclude_unique'] = exclude_unique + if sort_by_price is not None: + payload['sort_by_price'] = sort_by_price + if offset is not None: + payload['offset'] = offset + if limit is not None: + payload['limit'] = limit + if exclude_limited_upgradable is not None: + payload['exclude_limited_upgradable'] = exclude_limited_upgradable + if exclude_limited_non_upgradable is not None: + payload['exclude_limited_non_upgradable'] = exclude_limited_non_upgradable + if exclude_from_blockchain is not None: + payload['exclude_from_blockchain'] = exclude_from_blockchain + + return _make_request(token, method_url, params=payload) + + +def get_user_gifts(token, user_id, exclude_unlimited=None, exclude_limited_upgradable=None, + exclude_limited_non_upgradable=None, exclude_from_blockchain=None, exclude_unique=None, + sort_by_price=None, offset=None, limit=None): + method_url = 'getUserGifts' + payload = {'user_id': user_id} + if exclude_unlimited is not None: + payload['exclude_unlimited'] = exclude_unlimited + if exclude_limited_upgradable is not None: + payload['exclude_limited_upgradable'] = exclude_limited_upgradable + if exclude_limited_non_upgradable is not None: + payload['exclude_limited_non_upgradable'] = exclude_limited_non_upgradable + if exclude_from_blockchain is not None: + payload['exclude_from_blockchain'] = exclude_from_blockchain + if exclude_unique is not None: + payload['exclude_unique'] = exclude_unique + if sort_by_price is not None: + payload['sort_by_price'] = sort_by_price + if offset is not None: + payload['offset'] = offset + if limit is not None: + payload['limit'] = limit + return _make_request(token, method_url, params=payload) + +def get_chat_gifts(token, chat_id, exclude_unsaved=None, exclude_saved=None, + exclude_unlimited=None, exclude_limited_upgradable=None, + exclude_limited_non_upgradable=None, exclude_from_blockchain=None, + exclude_unique=None, sort_by_price=None, offset=None, limit=None): + method_url = 'getChatGifts' + payload = {'chat_id': chat_id} + if exclude_unsaved is not None: + payload['exclude_unsaved'] = exclude_unsaved + if exclude_saved is not None: + payload['exclude_saved'] = exclude_saved + if exclude_unlimited is not None: + payload['exclude_unlimited'] = exclude_unlimited + if exclude_limited_upgradable is not None: + payload['exclude_limited_upgradable'] = exclude_limited_upgradable + if exclude_limited_non_upgradable is not None: + payload['exclude_limited_non_upgradable'] = exclude_limited_non_upgradable + if exclude_from_blockchain is not None: + payload['exclude_from_blockchain'] = exclude_from_blockchain + if exclude_unique is not None: + payload['exclude_unique'] = exclude_unique + if sort_by_price is not None: + payload['sort_by_price'] = sort_by_price + if offset is not None: + payload['offset'] = offset + if limit is not None: + payload['limit'] = limit + return _make_request(token, method_url, params=payload) def convert_gift_to_stars(token, business_connection_id, owned_gift_id): @@ -2242,6 +2320,20 @@ def post_story(token, business_connection_id, content, active_period, caption=No payload['protect_content'] = protect_content return _make_request(token, method_url, params=payload, files=files, method='post') + +def repost_story(token, business_connection_id, from_chat_id, from_story_id, active_period, + post_to_chat_page=None, protect_content=None): + method_url = 'repostStory' + payload = {'business_connection_id': business_connection_id, 'from_chat_id': from_chat_id, + 'from_story_id': from_story_id, 'active_period': active_period} + + if post_to_chat_page is not None: + payload['post_to_chat_page'] = post_to_chat_page + if protect_content is not None: + payload['protect_content'] = protect_content + return _make_request(token, method_url, params=payload, method='post') + + def edit_story(token, business_connection_id, story_id, content, caption=None, parse_mode=None, caption_entities=None, areas=None): method_url = 'editStory' diff --git a/telebot/async_telebot.py b/telebot/async_telebot.py index 192d9d369..d8a70742b 100644 --- a/telebot/async_telebot.py +++ b/telebot/async_telebot.py @@ -3355,7 +3355,8 @@ async def forward_message( message_thread_id: Optional[int]=None, video_start_timestamp: Optional[int]=None, direct_messages_topic_id: Optional[int]=None, - suggested_post_parameters: Optional[types.SuggestedPostParameters]=None) -> types.Message: + suggested_post_parameters: Optional[types.SuggestedPostParameters]=None, + message_effect_id: Optional[str]=None) -> types.Message: """ Use this method to forward messages of any kind. @@ -3394,6 +3395,9 @@ async def forward_message( is automatically declined. :type suggested_post_parameters: :class:`telebot.types.SuggestedPostParameters` + :param message_effect_id: Unique identifier of the message effect to be added to the message; only available when forwarding to private chats + :type message_effect_id: :obj:`str` + :return: On success, the sent Message is returned. :rtype: :class:`telebot.types.Message` """ @@ -3404,7 +3408,8 @@ async def forward_message( await asyncio_helper.forward_message(self.token, chat_id=chat_id, from_chat_id=from_chat_id, message_id=message_id, disable_notification=disable_notification, protect_content=protect_content, timeout=timeout, message_thread_id=message_thread_id, video_start_timestamp=video_start_timestamp, - direct_messages_topic_id=direct_messages_topic_id, suggested_post_parameters=suggested_post_parameters) + direct_messages_topic_id=direct_messages_topic_id, suggested_post_parameters=suggested_post_parameters, + message_effect_id=message_effect_id) ) async def copy_message( @@ -3426,7 +3431,8 @@ async def copy_message( allow_paid_broadcast: Optional[bool]=None, video_start_timestamp: Optional[bool]=None, direct_messages_topic_id: Optional[int]=None, - suggested_post_parameters: Optional[types.SuggestedPostParameters]=None) -> types.MessageID: + suggested_post_parameters: Optional[types.SuggestedPostParameters]=None, + message_effect_id: Optional[str]=None) -> types.MessageID: """ Use this method to copy messages of any kind. If some of the specified messages can't be found or copied, they are skipped. Service messages, paid media messages, giveaway messages, giveaway winners messages, @@ -3499,6 +3505,9 @@ async def copy_message( is automatically declined. :type suggested_post_parameters: :class:`telebot.types.SuggestedPostParameters` + :param message_effect_id: Unique identifier of the message effect to be added to the message; only available when forwarding to private chats + :type message_effect_id: :obj:`str` + :return: On success, the MessageId of the sent message is returned. :rtype: :class:`telebot.types.MessageID` """ @@ -3533,7 +3542,8 @@ async def copy_message( reply_parameters=reply_parameters, reply_markup=reply_markup, timeout=timeout, message_thread_id=message_thread_id, show_caption_above_media=show_caption_above_media, allow_paid_broadcast=allow_paid_broadcast, video_start_timestamp=video_start_timestamp, - direct_messages_topic_id=direct_messages_topic_id, suggested_post_parameters=suggested_post_parameters + direct_messages_topic_id=direct_messages_topic_id, suggested_post_parameters=suggested_post_parameters, + message_effect_id=message_effect_id ) ) @@ -5716,9 +5726,44 @@ async def send_contact( await asyncio_helper.send_contact( self.token, chat_id, phone_number, first_name, last_name, vcard, disable_notification, reply_markup, timeout, - protect_content, message_thread_id, reply_parameters, business_connection_id, message_effect_id=message_effect_id, allow_paid_broadcast=allow_paid_broadcast, - direct_messages_topic_id=direct_messages_topic_id, suggested_post_parameters=suggested_post_parameters) - ) + protect_content, message_thread_id, reply_parameters, business_connection_id, message_effect_id=message_effect_id, allow_paid_broadcast=allow_paid_broadcast)) + + async def send_message_draft( + self, chat_id: int, + draft_id: int, + text: str, + message_thread_id: Optional[int]=None, + parse_mode: Optional[str]=None, + entities: Optional[List[types.MessageEntity]]=None): + """ + Use this method to stream a partial message to a user while the message is being generated; + supported only for bots with forum topic mode enabled. Returns True on success. + + Telegram documentation: https://core.telegram.org/bots/api#sendmessagedraft + + :param chat_id: Unique identifier for the target private chat + :type chat_id: :obj:`int` + + :param message_thread_id: Unique identifier for the target message thread + :type message_thread_id: :obj:`int` + + :param draft_id: Unique identifier of the message draft; must be non-zero. Changes of drafts with the same identifier are animated + :type draft_id: :obj:`int` + + :param text: Text of the message to be sent, 1-4096 characters after entities parsing + :type text: :obj:`str` + + :param parse_mode: Mode for parsing entities in the message text. See formatting options for more details. + :type parse_mode: :obj:`str` + + :param entities: A JSON-serialized list of special entities that appear in message text, which can be specified instead of parse_mode + :type entities: :obj:`list` of :class:`telebot.types.MessageEntity + + :return: Returns True on success. + :rtype: :obj:`bool` + """ + return await asyncio_helper.send_message_draft( + self.token, chat_id, draft_id, text, parse_mode=parse_mode, entities=entities, message_thread_id=message_thread_id) async def send_chat_action( self, chat_id: Union[int, str], action: str, timeout: Optional[int]=None, message_thread_id: Optional[int]=None, @@ -5745,7 +5790,7 @@ async def send_chat_action( :param timeout: Timeout in seconds for the request. :type timeout: :obj:`int` - :param message_thread_id: The thread to which the message will be sent(supergroups only) + :param message_thread_id: The thread to which the message will be sent(supergroups and private chats only) :type message_thread_id: :obj:`int` :param business_connection_id: Identifier of a business connection, in which the message will be sent @@ -8372,7 +8417,11 @@ async def get_business_account_gifts( exclude_unique: Optional[bool]=None, sort_by_price: Optional[bool]=None, offset: Optional[str]=None, - limit: Optional[int]=None) -> types.OwnedGifts: + limit: Optional[int]=None, + exclude_limited_upgradable: Optional[bool]=None, + exclude_limited_non_upgradable: Optional[bool]=None, + exclude_from_blockchain: Optional[bool]=None + ) -> types.OwnedGifts: """ Returns the gifts received and owned by a managed business account. Requires the can_view_gifts_and_stars business bot right. Returns OwnedGifts on success. @@ -8396,6 +8445,9 @@ async def get_business_account_gifts( :param exclude_unique: Pass True to exclude unique gifts :type exclude_unique: :obj:`bool` + :param exclude_from_blockchain: Pass True to exclude gifts that were assigned from the TON blockchain and can't be resold or transferred in Telegram + :type exclude_from_blockchain: :obj:`bool` + :param sort_by_price: Pass True to sort results by gift price instead of send date. Sorting is applied before pagination. :type sort_by_price: :obj:`bool` @@ -8405,16 +8457,157 @@ async def get_business_account_gifts( :param limit: The maximum number of gifts to be returned; 1-100. Defaults to 100 :type limit: :obj:`int` + :param exclude_limited_upgradable: Pass True to exclude gifts that can be purchased a limited number of times and can be upgraded to unique + :type exclude_limited_upgradable: :obj:`bool` + + :param exclude_limited_non_upgradable: Pass True to exclude gifts that can be purchased a limited number of times and can't be upgraded to unique + :type exclude_limited_non_upgradable: :obj:`bool` + :return: On success, a OwnedGifts object is returned. :rtype: :class:`telebot.types.OwnedGifts` """ + if exclude_limited is not None and exclude_limited_upgradable is None and exclude_limited_non_upgradable is None: + exclude_limited_upgradable = exclude_limited + exclude_limited_non_upgradable = exclude_limited + return types.OwnedGifts.de_json( await asyncio_helper.get_business_account_gifts( self.token, business_connection_id, exclude_unsaved=exclude_unsaved, exclude_saved=exclude_saved, exclude_unlimited=exclude_unlimited, - exclude_limited=exclude_limited, + exclude_unique=exclude_unique, + sort_by_price=sort_by_price, + offset=offset, + limit=limit, + exclude_limited_upgradable=exclude_limited_upgradable, + exclude_limited_non_upgradable=exclude_limited_non_upgradable, + exclude_from_blockchain=exclude_from_blockchain + ) + ) + + async def get_user_gifts( + self, user_id: int, + exclude_unlimited: Optional[bool]=None, + exclude_limited_upgradable: Optional[bool]=None, + exclude_limited_non_upgradable: Optional[bool]=None, + exclude_from_blockchain: Optional[bool]=None, + exclude_unique: Optional[bool]=None, + sort_by_price: Optional[bool]=None, + offset: Optional[str]=None, + limit: Optional[int]=None) -> types.OwnedGifts: + """ + Returns the gifts owned and hosted by a user. Returns OwnedGifts on success. + + Telegram documentation: https://core.telegram.org/bots/api#getusergifts + + :param user_id: Unique identifier of the user + :type user_id: :obj:`int` + + :param exclude_unlimited: Pass True to exclude gifts that can be purchased an unlimited number of times + :type exclude_unlimited: :obj:`bool` + + :param exclude_limited_upgradable: Pass True to exclude gifts that can be purchased a limited number of times and can be upgraded to unique + :type exclude_limited_upgradable: :obj:`bool` + + :param exclude_limited_non_upgradable: Pass True to exclude gifts that can be purchased a limited number of times and can't be upgraded to unique + :type exclude_limited_non_upgradable: :obj:`bool` + + :param exclude_from_blockchain: Pass True to exclude gifts that were assigned from the TON blockchain and can't be resold or transferred in Telegram + :type exclude_from_blockchain: :obj:`bool` + + :param exclude_unique: Pass True to exclude unique gifts + :type exclude_unique: :obj:`bool` + + :param sort_by_price: Pass True to sort results by gift price instead of send date. Sorting is applied before pagination. + :type sort_by_price: :obj:`bool` + + :param offset: Offset of the first entry to return as received from the previous request; use an empty string to get the first chunk of results + :type offset: :obj:`str` + + :param limit: The maximum number of gifts to be returned; 1-100. Defaults to 100 + :type limit: :obj:`int` + + :return: On success, a OwnedGifts object is returned. + :rtype: :class:`telebot.types.OwnedGifts` + """ + return types.OwnedGifts.de_json( + await asyncio_helper.get_user_gifts( + self.token, user_id, + exclude_unlimited=exclude_unlimited, + exclude_limited_upgradable=exclude_limited_upgradable, + exclude_limited_non_upgradable=exclude_limited_non_upgradable, + exclude_from_blockchain=exclude_from_blockchain, + exclude_unique=exclude_unique, + sort_by_price=sort_by_price, + offset=offset, + limit=limit + ) + ) + + + async def get_chat_gifts( + self, chat_id: Union[int, str], + exclude_unsaved: Optional[bool]=None, + exclude_saved: Optional[bool]=None, + exclude_unlimited: Optional[bool]=None, + exclude_limited_upgradable: Optional[bool]=None, + exclude_limited_non_upgradable: Optional[bool]=None, + exclude_from_blockchain: Optional[bool]=None, + exclude_unique: Optional[bool]=None, + sort_by_price: Optional[bool]=None, + offset: Optional[str]=None, + limit: Optional[int]=None) -> types.OwnedGifts: + """ + Returns the gifts owned by a chat. Returns OwnedGifts on success. + + Telegram documentation: https://core.telegram.org/bots/api#getchatgifts + + :param chat_id: Unique identifier for the target chat or username of the target channel (in the format @channelusername) + :type chat_id: :obj:`int` | :obj:`str` + + :param exclude_unsaved: Pass True to exclude gifts that aren't saved to the chat's profile page. Always True, unless the bot has the can_post_messages administrator right in the channel. + :type exclude_unsaved: :obj:`bool` + + :param exclude_saved: Pass True to exclude gifts that are saved to the chat's profile page. Always False, unless the bot has the can_post_messages administrator right in the channel. + :type exclude_saved: :obj:`bool` + + :param exclude_unlimited: Pass True to exclude gifts that can be purchased an unlimited number of times + :type exclude_unlimited: :obj:`bool` + + :param exclude_limited_upgradable: Pass True to exclude gifts that can be purchased a limited number of times and can be upgraded to unique + :type exclude_limited_upgradable: :obj:`bool` + + :param exclude_limited_non_upgradable: Pass True to exclude gifts that can be purchased a limited number of times and can't be upgraded to unique + :type exclude_limited_non_upgradable: :obj:`bool` + + :param exclude_from_blockchain: Pass True to exclude gifts that were assigned from the TON blockchain and can't be resold or transferred in Telegram + :type exclude_from_blockchain: :obj:`bool` + + :param exclude_unique: Pass True to exclude unique gifts + :type exclude_unique: :obj:`bool` + + :param sort_by_price: Pass True to sort results by gift price instead of send date. Sorting is applied before pagination. + :type sort_by_price: :obj:`bool` + + :param offset: Offset of the first entry to return as received from the previous request; use an empty string to get the first chunk of results + :type offset: :obj:`str` + + :param limit: The maximum number of gifts to be returned; 1-100. Defaults to 100 + :type limit: :obj:`int` + + :return: On success, a OwnedGifts object is returned. + :rtype: :class:`telebot.types.OwnedGifts` + """ + return types.OwnedGifts.de_json( + await asyncio_helper.get_chat_gifts( + self.token, chat_id, + exclude_unsaved=exclude_unsaved, + exclude_saved=exclude_saved, + exclude_unlimited=exclude_unlimited, + exclude_limited_upgradable=exclude_limited_upgradable, + exclude_limited_non_upgradable=exclude_limited_non_upgradable, + exclude_from_blockchain=exclude_from_blockchain, exclude_unique=exclude_unique, sort_by_price=sort_by_price, offset=offset, @@ -8559,6 +8752,50 @@ async def post_story( ) ) + async def repost_story( + self, business_connection_id: str, + from_chat_id: int, from_story_id: int, + active_period: int, + post_to_chat_page: Optional[bool]=None, + protect_content: Optional[bool]=None) -> types.Story: + """ + Reposts a story on behalf of a business account from another business account. Both business accounts + must be managed by the same bot, and the story on the source account must have been posted (or reposted) + by the bot. Requires the can_manage_stories business bot right for both business accounts. Returns Story on success. + + Telegram documentation: https://core.telegram.org/bots/api#repoststory + + :param business_connection_id: Unique identifier of the business connection + :type business_connection_id: :obj:`str` + + :param from_chat_id: Unique identifier of the chat which posted the story that should be reposted + :type from_chat_id: :obj:`int` + + :param from_story_id: Unique identifier of the story that should be reposted + :type from_story_id: :obj:`int` + + :param active_period: Period after which the story is moved to the archive, in seconds; must be one of 6 * 3600, 12 * 3600, 86400, or 2 * 86400 + :type active_period: :obj:`int` + + :param post_to_chat_page: Pass True to keep the story accessible after it expires + :type post_to_chat_page: :obj:`bool` + + :param protect_content: Pass True if the content of the story must be protected from forwarding and screenshotting + :type protect_content: :obj:`bool` + + :return: On success, a Story object is returned. + :rtype: :class:`telebot.types.Story` + """ + return types.Story.de_json( + await asyncio_helper.repost_story( + self.token, business_connection_id, + from_chat_id, from_story_id, + active_period, + post_to_chat_page=post_to_chat_page, + protect_content=protect_content + ) + ) + async def edit_story( self, business_connection_id: str, story_id: int, content: types.InputStoryContent, diff --git a/telebot/asyncio_helper.py b/telebot/asyncio_helper.py index f127f316f..5e95e365c 100644 --- a/telebot/asyncio_helper.py +++ b/telebot/asyncio_helper.py @@ -434,7 +434,7 @@ async def forward_message( token, chat_id, from_chat_id, message_id, disable_notification=None, timeout=None, protect_content=None, message_thread_id=None, video_start_timestamp=None, direct_messages_topic_id=None, - suggested_post_parameters=None): + suggested_post_parameters=None, message_effect_id=None): method_url = r'forwardMessage' payload = {'chat_id': chat_id, 'from_chat_id': from_chat_id, 'message_id': message_id} if disable_notification is not None: @@ -451,13 +451,16 @@ async def forward_message( payload['direct_messages_topic_id'] = direct_messages_topic_id if suggested_post_parameters is not None: payload['suggested_post_parameters'] = suggested_post_parameters.to_json() + if message_effect_id: + payload['message_effect_id'] = message_effect_id return await _process_request(token, method_url, params=payload) async def copy_message(token, chat_id, from_chat_id, message_id, caption=None, parse_mode=None, caption_entities=None, disable_notification=None, reply_markup=None, timeout=None, protect_content=None, message_thread_id=None, reply_parameters=None, show_caption_above_media=None, - allow_paid_broadcast=None, video_start_timestamp=None, direct_messages_topic_id=None, suggested_post_parameters=None): + allow_paid_broadcast=None, video_start_timestamp=None, direct_messages_topic_id=None, suggested_post_parameters=None, + message_effect_id=None): method_url = r'copyMessage' payload = {'chat_id': chat_id, 'from_chat_id': from_chat_id, 'message_id': message_id} if caption is not None: @@ -488,6 +491,8 @@ async def copy_message(token, chat_id, from_chat_id, message_id, caption=None, p payload['direct_messages_topic_id'] = direct_messages_topic_id if suggested_post_parameters is not None: payload['suggested_post_parameters'] = suggested_post_parameters.to_json() + if message_effect_id: + payload['message_effect_id'] = message_effect_id return await _process_request(token, method_url, params=payload) async def send_checklist( @@ -847,6 +852,18 @@ async def send_contact( payload['suggested_post_parameters'] = suggested_post_parameters.to_json() return await _process_request(token, method_url, params=payload) +async def send_message_draft( + token, chat_id, draft_id, text, + message_thread_id=None, parse_mode=None, entities=None): + method_url = r'sendMessageDraft' + payload = {'chat_id': chat_id, 'draft_id': draft_id, 'text': text} + if message_thread_id is not None: + payload['message_thread_id'] = message_thread_id + if parse_mode: + payload['parse_mode'] = parse_mode + if entities: + payload['entities'] = json.dumps(types.MessageEntity.to_list_of_dicts(entities)) + return await _process_request(token, method_url, params=payload) async def send_chat_action(token, chat_id, action, timeout=None, message_thread_id=None, business_connection_id=None): method_url = r'sendChatAction' @@ -2149,18 +2166,46 @@ async def transfer_business_account_stars(token, business_connection_id, star_co return await _process_request(token, method_url, params=payload, method='post') async def get_business_account_gifts(token, business_connection_id, exclude_unsaved=None, exclude_saved=None, - exclude_unlimited=None, exclude_limited=None, exclude_unique=None, - sort_by_price=None, offset=None, limit=None): - method_url = 'getBusinessAccountGifts' - payload = {'business_connection_id': business_connection_id} - if exclude_unsaved is not None: - payload['exclude_unsaved'] = exclude_unsaved - if exclude_saved is not None: - payload['exclude_saved'] = exclude_saved + exclude_unlimited=None, exclude_unique=None, + sort_by_price=None, offset=None, limit=None, exclude_limited_upgradable=None, + exclude_limited_non_upgradable=None, exclude_from_blockchain=None): + method_url = 'getBusinessAccountGifts' + payload = {'business_connection_id': business_connection_id} + if exclude_unsaved is not None: + payload['exclude_unsaved'] = exclude_unsaved + if exclude_saved is not None: + payload['exclude_saved'] = exclude_saved + if exclude_unlimited is not None: + payload['exclude_unlimited'] = exclude_unlimited + if exclude_unique is not None: + payload['exclude_unique'] = exclude_unique + if sort_by_price is not None: + payload['sort_by_price'] = sort_by_price + if offset is not None: + payload['offset'] = offset + if limit is not None: + payload['limit'] = limit + if exclude_limited_upgradable is not None: + payload['exclude_limited_upgradable'] = exclude_limited_upgradable + if exclude_limited_non_upgradable is not None: + payload['exclude_limited_non_upgradable'] = exclude_limited_non_upgradable + if exclude_from_blockchain is not None: + payload['exclude_from_blockchain'] = exclude_from_blockchain + return await _process_request(token, method_url, params=payload) + +async def get_user_gifts(token, user_id, exclude_unlimited=None, exclude_limited_upgradable=None, + exclude_limited_non_upgradable=None, exclude_from_blockchain=None, exclude_unique=None, + sort_by_price=None, offset=None, limit=None): + method_url = 'getUserGifts' + payload = {'user_id': user_id} if exclude_unlimited is not None: payload['exclude_unlimited'] = exclude_unlimited - if exclude_limited is not None: - payload['exclude_limited'] = exclude_limited + if exclude_limited_upgradable is not None: + payload['exclude_limited_upgradable'] = exclude_limited_upgradable + if exclude_limited_non_upgradable is not None: + payload['exclude_limited_non_upgradable'] = exclude_limited_non_upgradable + if exclude_from_blockchain is not None: + payload['exclude_from_blockchain'] = exclude_from_blockchain if exclude_unique is not None: payload['exclude_unique'] = exclude_unique if sort_by_price is not None: @@ -2171,6 +2216,34 @@ async def get_business_account_gifts(token, business_connection_id, exclude_unsa payload['limit'] = limit return await _process_request(token, method_url, params=payload) +async def get_chat_gifts(token, chat_id, exclude_unsaved=None, exclude_saved=None, + exclude_unlimited=None, exclude_limited_upgradable=None, + exclude_limited_non_upgradable=None, exclude_from_blockchain=None, + exclude_unique=None, sort_by_price=None, offset=None, limit=None): + method_url = 'getChatGifts' + payload = {'chat_id': chat_id} + if exclude_unsaved is not None: + payload['exclude_unsaved'] = exclude_unsaved + if exclude_saved is not None: + payload['exclude_saved'] = exclude_saved + if exclude_unlimited is not None: + payload['exclude_unlimited'] = exclude_unlimited + if exclude_limited_upgradable is not None: + payload['exclude_limited_upgradable'] = exclude_limited_upgradable + if exclude_limited_non_upgradable is not None: + payload['exclude_limited_non_upgradable'] = exclude_limited_non_upgradable + if exclude_from_blockchain is not None: + payload['exclude_from_blockchain'] = exclude_from_blockchain + if exclude_unique is not None: + payload['exclude_unique'] = exclude_unique + if sort_by_price is not None: + payload['sort_by_price'] = sort_by_price + if offset is not None: + payload['offset'] = offset + if limit is not None: + payload['limit'] = limit + return await _process_request(token, method_url, params=payload) + async def convert_gift_to_stars(token, business_connection_id, owned_gift_id): method_url = 'convertGiftToStars' payload = {'business_connection_id': business_connection_id, 'owned_gift_id': owned_gift_id} @@ -2214,6 +2287,18 @@ async def post_story(token, business_connection_id, content, active_period, capt payload['protect_content'] = protect_content return await _process_request(token, method_url, params=payload, files=files, method='post') +async def repost_story(token, business_connection_id, from_chat_id, from_story_id, active_period, + post_to_chat_page=None, protect_content=None): + method_url = 'repostStory' + payload = {'business_connection_id': business_connection_id, 'from_chat_id': from_chat_id, + 'from_story_id': from_story_id, 'active_period': active_period} + + if post_to_chat_page is not None: + payload['post_to_chat_page'] = post_to_chat_page + if protect_content is not None: + payload['protect_content'] = protect_content + return await _process_request(token, method_url, params=payload, method='post') + async def edit_story(token, business_connection_id, story_id, content, caption=None, parse_mode=None, caption_entities=None, areas=None): method_url = 'editStory' diff --git a/telebot/types.py b/telebot/types.py index 41f55f5f7..f2a845b25 100644 --- a/telebot/types.py +++ b/telebot/types.py @@ -512,6 +512,9 @@ class User(JsonDeserializable, Dictionaryable, JsonSerializable): :param has_main_web_app: Optional. True, if the bot has a main Web App. Returned only in getMe. :type has_main_web_app: :obj:`bool` + :param has_topics_enabled: Optional. True, if the bot has forum topic mode enabled in private chats. Returned only in getMe. + :type has_topics_enabled: :obj:`bool` + :return: Instance of the class :rtype: :class:`telebot.types.User` """ @@ -523,9 +526,9 @@ def de_json(cls, json_string): # noinspection PyShadowingBuiltins def __init__(self, id, is_bot, first_name, last_name=None, username=None, language_code=None, - can_join_groups=None, can_read_all_group_messages=None, supports_inline_queries=None, - is_premium=None, added_to_attachment_menu=None, can_connect_to_business=None, - has_main_web_app=None, **kwargs): + can_join_groups=None, can_read_all_group_messages=None, supports_inline_queries=None, + is_premium=None, added_to_attachment_menu=None, can_connect_to_business=None, + has_main_web_app=None, has_topics_enabled=None, **kwargs): self.id: int = id self.is_bot: bool = is_bot self.first_name: str = first_name @@ -539,6 +542,7 @@ def __init__(self, id, is_bot, first_name, last_name=None, username=None, langua self.added_to_attachment_menu: Optional[bool] = added_to_attachment_menu self.can_connect_to_business: Optional[bool] = can_connect_to_business self.has_main_web_app: Optional[bool] = has_main_web_app + self.has_topics_enabled: Optional[bool] = has_topics_enabled @property def full_name(self) -> str: @@ -744,6 +748,15 @@ class ChatFullInfo(JsonDeserializable): :param location: Optional. For supergroups, the location to which the supergroup is connected. Returned only in getChat. :type location: :class:`telebot.types.ChatLocation` + :param rating: Optional. For private chats, the rating of the user if any + :type rating: :class:`telebot.types.UserRating` + + :param paid_message_star_count: Optional. The number of Telegram Stars a general user have to pay to send a message to the chat + :type paid_message_star_count: :obj:`int` + + :param unique_gift_colors: Optional. The color scheme based on a unique gift that must be used for the chat's name, message replies and link previews + :type unique_gift_colors: :class:`telebot.types.UniqueGiftColors` + :return: Instance of the class :rtype: :class:`telebot.types.ChatFullInfo` """ @@ -775,23 +788,28 @@ def de_json(cls, json_string): obj['accepted_gift_types'] = AcceptedGiftTypes.de_json(obj['accepted_gift_types']) if 'parent_chat' in obj: obj['parent_chat'] = Chat.de_json(obj['parent_chat']) + if 'rating' in obj: + obj['rating'] = UserRating.de_json(obj['rating']) + if 'unique_gift_colors' in obj: + obj['unique_gift_colors'] = UniqueGiftColors.de_json(obj['unique_gift_colors']) return cls(**obj) def __init__(self, id, type, title=None, username=None, first_name=None, - last_name=None, photo=None, bio=None, has_private_forwards=None, - description=None, invite_link=None, pinned_message=None, - permissions=None, slow_mode_delay=None, - message_auto_delete_time=None, has_protected_content=None, sticker_set_name=None, - can_set_sticker_set=None, linked_chat_id=None, location=None, - join_to_send_messages=None, join_by_request=None, has_restricted_voice_and_video_messages=None, - is_forum=None, max_reaction_count=None, active_usernames=None, emoji_status_custom_emoji_id=None, - has_hidden_members=None, has_aggressive_anti_spam_enabled=None, emoji_status_expiration_date=None, - available_reactions=None, accent_color_id=None, background_custom_emoji_id=None, profile_accent_color_id=None, - profile_background_custom_emoji_id=None, has_visible_history=None, - unrestrict_boost_count=None, custom_emoji_sticker_set_name=None, business_intro=None, business_location=None, - business_opening_hours=None, personal_chat=None, birthdate=None, - can_send_paid_media=None, - accepted_gift_types=None, is_direct_messages=None, parent_chat=None, **kwargs): + last_name=None, photo=None, bio=None, has_private_forwards=None, + description=None, invite_link=None, pinned_message=None, + permissions=None, slow_mode_delay=None, + message_auto_delete_time=None, has_protected_content=None, sticker_set_name=None, + can_set_sticker_set=None, linked_chat_id=None, location=None, + join_to_send_messages=None, join_by_request=None, has_restricted_voice_and_video_messages=None, + is_forum=None, max_reaction_count=None, active_usernames=None, emoji_status_custom_emoji_id=None, + has_hidden_members=None, has_aggressive_anti_spam_enabled=None, emoji_status_expiration_date=None, + available_reactions=None, accent_color_id=None, background_custom_emoji_id=None, profile_accent_color_id=None, + profile_background_custom_emoji_id=None, has_visible_history=None, + unrestrict_boost_count=None, custom_emoji_sticker_set_name=None, business_intro=None, business_location=None, + business_opening_hours=None, personal_chat=None, birthdate=None, + can_send_paid_media=None, + accepted_gift_types=None, is_direct_messages=None, parent_chat=None, rating=None, paid_message_star_count=None, + unique_gift_colors=None, **kwargs): self.id: int = id self.type: str = type self.title: Optional[str] = title @@ -839,6 +857,11 @@ def __init__(self, id, type, title=None, username=None, first_name=None, self.accepted_gift_types: AcceptedGiftTypes = accepted_gift_types self.is_direct_messages: Optional[bool] = is_direct_messages self.parent_chat: Optional[Chat] = parent_chat + self.rating: Optional[UserRating] = rating + self.paid_message_star_count: Optional[int] = paid_message_star_count + self.unique_gift_colors: Optional[UniqueGiftColors] = unique_gift_colors + + @property def can_send_gift(self) -> bool: """ @@ -926,7 +949,7 @@ class Message(JsonDeserializable): :param message_id: Unique message identifier inside this chat :type message_id: :obj:`int` - :param message_thread_id: Optional. Unique identifier of a message thread to which the message belongs; for supergroups only + :param message_thread_id: Optional. Unique identifier of a message thread to which the message belongs; for supergroups and private chats only :type message_thread_id: :obj:`int` :param direct_messages_topic: Optional. Information about the direct messages chat topic that contains the message @@ -961,7 +984,7 @@ class Message(JsonDeserializable): :forward_origin: Optional. For forwarded messages, information about the original message; :type forward_origin: :class:`telebot.types.MessageOrigin` - :param is_topic_message: Optional. True, if the message is sent to a forum topic + :param is_topic_message: Optional. True, if the message is sent to a topic in a forum supergroup or a private chat with the bot :type is_topic_message: :obj:`bool` :param is_automatic_forward: Optional. :obj:`bool`, if the message is a channel post that was automatically @@ -1167,6 +1190,9 @@ class Message(JsonDeserializable): :param unique_gift: Optional. Service message: a unique gift was sent or received :type unique_gift: :class:`telebot.types.UniqueGiftInfo` + :param gift_upgrade_sent: Optional. Service message: upgrade of a gift was purchased after the gift was sent + :type gift_upgrade_sent: :class:`telebot.types.GiftInfo` + :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` @@ -1523,6 +1549,10 @@ def de_json(cls, json_string): if 'direct_message_price_changed' in obj: opts['direct_message_price_changed'] = DirectMessagePriceChanged.de_json(obj['direct_message_price_changed']) content_type = 'direct_message_price_changed' + if 'gift_upgrade_sent' in obj: + opts['gift_upgrade_sent'] = GiftInfo.de_json(obj['gift_upgrade_sent']) + content_type = 'gift_upgrade_sent' + if 'reply_to_checklist_task_id' in obj: opts['reply_to_checklist_task_id'] = obj['reply_to_checklist_task_id'] if 'direct_messages_topic' in obj: @@ -1673,6 +1703,7 @@ def __init__(self, message_id, from_user, date, chat, content_type, options, jso self.checklist_tasks_done: Optional[ChecklistTasksDone] = None self.checklist_tasks_added: Optional[List[ChecklistTasksAdded]] = None self.direct_message_price_changed: Optional[DirectMessagePriceChanged] = None + self.gift_upgrade_sent: Optional[GiftInfo] = None self.reply_to_checklist_task_id: Optional[int] = None self.direct_messages_topic: Optional[DirectMessagesTopic] = None self.is_paid_post: Optional[bool] = None @@ -8117,6 +8148,9 @@ class ForumTopicCreated(JsonDeserializable): :param icon_custom_emoji_id: Optional. Unique identifier of the custom emoji shown as the topic icon :type icon_custom_emoji_id: :obj:`str` + :param is_name_implicit: Optional. True, if the name of the topic wasn't specified explicitly by its creator and likely needs to be changed by the bot + :type is_name_implicit: :obj:`bool` + :return: Instance of the class :rtype: :class:`telebot.types.ForumTopicCreated` """ @@ -8126,11 +8160,12 @@ def de_json(cls, json_string): obj = cls.check_json(json_string) return cls(**obj) - def __init__(self, name: str, icon_color: int, icon_custom_emoji_id: Optional[str]=None, **kwargs) -> None: + def __init__(self, name: str, icon_color: int, icon_custom_emoji_id: Optional[str]=None, + is_name_implicit: Optional[bool]=None, **kwargs) -> None: self.name: str = name self.icon_color: int = icon_color self.icon_custom_emoji_id: Optional[str] = icon_custom_emoji_id - + self.is_name_implicit: Optional[bool] = is_name_implicit class ForumTopicClosed(JsonDeserializable): """ @@ -8235,6 +8270,9 @@ class ForumTopic(JsonDeserializable): :param icon_custom_emoji_id: Optional. Unique identifier of the custom emoji shown as the topic icon :type icon_custom_emoji_id: :obj:`str` + :param is_name_implicit: Optional. True, if the name of the topic wasn't specified explicitly by its creator and likely needs to be changed by the bot + :type is_name_implicit: :obj:`bool` + :return: Instance of the class :rtype: :class:`telebot.types.ForumTopic` """ @@ -8246,11 +8284,12 @@ def de_json(cls, json_string): return cls(**obj) def __init__(self, message_thread_id: int, name: str, icon_color: int, icon_custom_emoji_id: Optional[str]=None, - **kwargs) -> None: + is_name_implicit: Optional[bool]=None, **kwargs) -> None: self.message_thread_id: int = message_thread_id self.name: str = name self.icon_color: int = icon_color self.icon_custom_emoji_id: Optional[str] = icon_custom_emoji_id + self.is_name_implicit: Optional[bool] = is_name_implicit class WriteAccessAllowed(JsonDeserializable): @@ -11342,12 +11381,30 @@ class Gift(JsonDeserializable): :param upgrade_star_count: Optional. The number of Telegram Stars that must be paid to upgrade the gift to a unique one :type upgrade_star_count: :obj:`int` + :param is_premium: Optional. True, if the gift can only be purchased by Telegram Premium subscribers + :type is_premium: :obj:`bool` + + :param has_colors: Optional. True, if the gift can be used (after being upgraded) to customize a user's appearance + :type has_colors: :obj:`bool` + :param total_count: Optional. The total number of the gifts of this type that can be sent; for limited gifts only :type total_count: :obj:`int` :param remaining_count: Optional. The number of remaining gifts of this type that can be sent; for limited gifts only :type remaining_count: :obj:`int` + :param personal_total_count: Optional. The total number of gifts of this type that can be sent by the bot; for limited gifts only + :type personal_total_count: :obj:`int` + + :param personal_remaining_count: Optional. The number of remaining gifts of this type that can be sent by the bot; for limited gifts only + :type personal_remaining_count: :obj:`int` + + :param background: Optional. Background of the gift + :type background: :class:`GiftBackground` + + :param unique_gift_variant_count: Optional. The total number of different unique gifts that can be obtained by upgrading the gift + :type unique_gift_variant_count: :obj:`int` + :param publisher_chat: Optional. Information about the chat that published the gift :type publisher_chat: :class:`Chat` @@ -11355,21 +11412,30 @@ class Gift(JsonDeserializable): :rtype: :class:`Gift` """ - def __init__(self, id, sticker, star_count, total_count=None, remaining_count=None, upgrade_star_count=None, - publisher_chat=None, **kwargs): + def __init__(self, id, sticker, star_count, total_count=None, remaining_count=None, upgrade_star_count=None, + personal_total_count=None, personal_remaining_count=None, is_premium=None, has_colors=None, + background=None, publisher_chat=None, unique_gift_variant_count=None, **kwargs): self.id: str = id self.sticker: Sticker = sticker self.star_count: int = star_count self.total_count: Optional[int] = total_count self.remaining_count: Optional[int] = remaining_count self.upgrade_star_count: Optional[int] = upgrade_star_count + self.personal_total_count: Optional[int] = personal_total_count + self.personal_remaining_count: Optional[int] = personal_remaining_count + self.is_premium: Optional[bool] = is_premium + self.has_colors: Optional[bool] = has_colors + self.background: Optional[GiftBackground] = background self.publisher_chat: Optional[Chat] = publisher_chat + self.unique_gift_variant_count: Optional[int] = unique_gift_variant_count @classmethod def de_json(cls, json_string): if json_string is None: return None obj = cls.check_json(json_string) obj['sticker'] = Sticker.de_json(obj['sticker']) + if 'background' in obj: + obj['background'] = GiftBackground.de_json(obj['background']) if 'publisher_chat' in obj: obj['publisher_chat'] = Chat.de_json(obj['publisher_chat']) return cls(**obj) @@ -11607,26 +11673,35 @@ class AcceptedGiftTypes(JsonDeserializable, JsonSerializable): :param premium_subscription: True, if a Telegram Premium subscription is accepted :type premium_subscription: :obj:`bool` + :param gifts_from_channels: True, if transfers of unique gifts from channels are accepted + :type gifts_from_channels: :obj:`bool` + :return: Instance of the class :rtype: :class:`AcceptedGiftTypes` """ - def __init__(self, unlimited_gifts: bool, limited_gifts: bool, - unique_gifts: bool, premium_subscription: bool, **kwargs): - self.unlimited_gifts: bool = unlimited_gifts - self.limited_gifts: bool = limited_gifts - self.unique_gifts: bool = unique_gifts - self.premium_subscription: bool = premium_subscription + def __init__(self, unlimited_gifts: Optional[bool]=None, limited_gifts: Optional[bool]=None, + unique_gifts: Optional[bool]=None, premium_subscription: Optional[bool]=None, gifts_from_channels: Optional[bool]=None, **kwargs): + self.unlimited_gifts: Optional[bool] = unlimited_gifts + self.limited_gifts: Optional[bool] = limited_gifts + self.unique_gifts: Optional[bool] = unique_gifts + self.premium_subscription: Optional[bool] = premium_subscription + self.gifts_from_channels: Optional[bool] = gifts_from_channels def to_json(self): return json.dumps(self.to_dict()) def to_dict(self): - data = { - 'unlimited_gifts': self.unlimited_gifts, - 'limited_gifts': self.limited_gifts, - 'unique_gifts': self.unique_gifts, - 'premium_subscription': self.premium_subscription - } + data = {} + if self.unlimited_gifts is not None: + data['unlimited_gifts'] = self.unlimited_gifts + if self.limited_gifts is not None: + data['limited_gifts'] = self.limited_gifts + if self.unique_gifts is not None: + data['unique_gifts'] = self.unique_gifts + if self.premium_subscription is not None: + data['premium_subscription'] = self.premium_subscription + if self.gifts_from_channels is not None: + data['gifts_from_channels'] = self.gifts_from_channels return data @classmethod @@ -11734,12 +11809,18 @@ class OwnedGiftRegular(OwnedGift): :param prepaid_upgrade_star_count: Optional. Number of Telegram Stars that were paid by the sender for the ability to upgrade the gift :type prepaid_upgrade_star_count: :obj:`int` + :param is_upgrade_separate: Optional. True, if the gift's upgrade was purchased after the gift was sent; for gifts received on behalf of business accounts only + :type is_upgrade_separate: :obj:`bool` + + :param unique_gift_number: Optional. Unique number reserved for this gift when upgraded. See the number field in UniqueGift + :type unique_gift_number: :obj:`int` + :return: Instance of the class :rtype: :class:`OwnedGiftRegular` """ def __init__(self, type, gift, owned_gift_id=None, sender_user=None, send_date=None, text=None, entities=None, is_private=None, is_saved=None, can_be_upgraded=None, was_refunded=None, convert_star_count=None, - prepaid_upgrade_star_count=None, **kwargs): + prepaid_upgrade_star_count=None, is_upgrade_separate=None, unique_gift_number=None, **kwargs): super().__init__(type=type) self.gift: Gift = gift self.owned_gift_id: Optional[str] = owned_gift_id @@ -11753,6 +11834,8 @@ def __init__(self, type, gift, owned_gift_id=None, sender_user=None, send_date=N self.was_refunded: Optional[bool] = was_refunded self.convert_star_count: Optional[int] = convert_star_count self.prepaid_upgrade_star_count: Optional[int] = prepaid_upgrade_star_count + self.is_upgrade_separate: Optional[bool] = is_upgrade_separate + self.unique_gift_number: Optional[int] = unique_gift_number @classmethod def de_json(cls, json_string): @@ -11863,6 +11946,9 @@ class UniqueGift(JsonDeserializable): Telegram documentation: https://core.telegram.org/bots/api#uniquegift + :param gift_id: Identifier of the regular gift from which the gift was upgraded + :type gift_id: :obj:`str` + :param base_name: Human-readable name of the regular gift from which this unique gift was upgraded :type base_name: :obj:`str` @@ -11881,19 +11967,31 @@ class UniqueGift(JsonDeserializable): :param backdrop: Backdrop of the gift :type backdrop: :class:`UniqueGiftBackdrop` + :param is_from_blockchain: Optional. True, if the gift is assigned from the TON blockchain and can't be resold or transferred in Telegram + :type is_from_blockchain: :obj:`bool` + + :param is_premium: Optional. True, if the gift can only be purchased by Telegram Premium subscribers + :type is_premium: :obj:`bool` + + :param colors: Optional. The color scheme that can be used by the gift's owner for the chat's name, replies to messages and link previews; for business account gifts and gifts that are currently on sale only + :type colors: :class:`UniqueGiftColors` :param publisher_chat: Optional. Information about the chat that published the gift :type publisher_chat: :class:`Chat` :return: Instance of the class :rtype: :class:`UniqueGift` """ - def __init__(self, base_name, name, number, model, symbol, backdrop, publisher_chat=None, **kwargs): + def __init__(self, base_name, name, number, model, symbol, backdrop, gift_id, publisher_chat=None, is_from_blockchain=None, is_premium=None, colors=None, **kwargs): self.base_name: str = base_name self.name: str = name self.number: int = number self.model: UniqueGiftModel = model self.symbol: UniqueGiftSymbol = symbol self.backdrop: UniqueGiftBackdrop = backdrop + self.gift_id: str = gift_id + self.is_from_blockchain: Optional[bool] = is_from_blockchain + self.is_premium: Optional[bool] = is_premium + self.colors: Optional[UniqueGiftColors] = colors self.publisher_chat: Optional[Chat] = publisher_chat @classmethod @@ -11903,6 +12001,8 @@ def de_json(cls, json_string): obj['model'] = UniqueGiftModel.de_json(obj['model']) obj['symbol'] = UniqueGiftSymbol.de_json(obj['symbol']) obj['backdrop'] = UniqueGiftBackdrop.de_json(obj['backdrop']) + if 'colors' in obj: + obj['colors'] = UniqueGiftColors.de_json(obj['colors']) if 'publisher_chat' in obj: obj['publisher_chat'] = Chat.de_json(obj['publisher_chat']) return cls(**obj) @@ -12480,6 +12580,9 @@ class GiftInfo(JsonDeserializable): :param prepaid_upgrade_star_count: Optional. Number of Telegram Stars that were prepaid by the sender for the ability to upgrade the gift :type prepaid_upgrade_star_count: :obj:`int` + :param is_upgrade_separate: Optional. True, if the gift's upgrade was purchased after the gift was sent + :type is_upgrade_separate: :obj:`bool` + :param can_be_upgraded: Optional. True, if the gift can be upgraded to a unique gift :type can_be_upgraded: :obj:`bool` @@ -12492,13 +12595,17 @@ class GiftInfo(JsonDeserializable): :param is_private: Optional. True, if the sender and gift text are shown only to the gift receiver; otherwise, everyone will be able to see them :type is_private: :obj:`bool` + :param unique_gift_number: Optional. Unique number reserved for this gift when upgraded. See the number field in UniqueGift + :type unique_gift_number: :obj:`int` + :return: Instance of the class :rtype: :class:`GiftInfo` """ def __init__(self, gift: Gift, owned_gift_id: Optional[str] = None, convert_star_count: Optional[int] = None, prepaid_upgrade_star_count: Optional[int] = None, can_be_upgraded: Optional[bool] = None, text: Optional[str] = None, entities: Optional[List[MessageEntity]] = None, - is_private: Optional[bool] = None, **kwargs): + is_private: Optional[bool] = None, is_upgrade_separate: Optional[bool] = None, + unique_gift_number: Optional[int] = None, **kwargs): self.gift: Gift = gift self.owned_gift_id: Optional[str] = owned_gift_id self.convert_star_count: Optional[int] = convert_star_count @@ -12507,6 +12614,8 @@ def __init__(self, gift: Gift, owned_gift_id: Optional[str] = None, convert_star self.text: Optional[str] = text self.entities: Optional[List[MessageEntity]] = entities self.is_private: Optional[bool] = is_private + self.is_upgrade_separate: Optional[bool] = is_upgrade_separate + self.unique_gift_number: Optional[int] = unique_gift_number @classmethod def de_json(cls, json_string): @@ -12527,13 +12636,20 @@ class UniqueGiftInfo(JsonDeserializable): :param gift: Information about the gift :type gift: :class:`UniqueGift` - :param origin: Origin of the gift. Currently, either “upgrade” for gifts upgraded from regular gifts, “transfer” for gifts transferred from other users or channels, - or “resale” for gifts bought from other users + :param origin: Origin of the gift. Currently, either “upgrade” for gifts upgraded from regular gifts, “transfer” for gifts + transferred from other users or channels, “resale” for gifts bought from other users, “gifted_upgrade” for upgrades purchased + after the gift was sent, or “offer” for gifts bought or sold through gift purchase offers :type origin: :obj:`str` :param last_resale_star_count: Optional. For gifts bought from other users, the price paid for the gift :type last_resale_star_count: :obj:`int` + :param last_resale_currency: Optional. For gifts bought from other users, the currency in which the payment for the gift was done. Currently, one of “XTR” for Telegram Stars or “TON” for toncoins. + :type last_resale_currency: :obj:`str` + + :param last_resale_amount: Optional. For gifts bought from other users, the price paid for the gift in either Telegram Stars or nanotoncoins + :type last_resale_amount: :obj:`int` + :param owned_gift_id: Optional. Unique identifier of the received gift for the bot; only present for gifts received on behalf of business accounts :type owned_gift_id: :obj:`str` @@ -12548,14 +12664,18 @@ class UniqueGiftInfo(JsonDeserializable): """ def __init__(self, gift: UniqueGift, origin: str, owned_gift_id: Optional[str] = None, transfer_star_count: Optional[int] = None, next_transfer_date: Optional[int] = None, - last_resale_star_count: Optional[int] = None, **kwargs): + last_resale_star_count: Optional[int] = None, last_resale_currency: Optional[str] = None, + last_resale_amount: Optional[int] = None, **kwargs): self.gift: UniqueGift = gift self.origin: str = origin self.last_resale_star_count: Optional[int] = last_resale_star_count + self.last_resale_currency: Optional[str] = last_resale_currency + self.last_resale_amount: Optional[int] = last_resale_amount self.owned_gift_id: Optional[str] = owned_gift_id self.transfer_star_count: Optional[int] = transfer_star_count self.next_transfer_date: Optional[int] = next_transfer_date + @classmethod def de_json(cls, json_string): if json_string is None: return None @@ -12696,6 +12816,9 @@ class ChecklistTask(JsonDeserializable): :param completed_by_user: Optional. User that completed the task; omitted if the task wasn't completed :type completed_by_user: :class:`User` + :param completed_by_chat: Optional. Chat that completed the task; omitted if the task wasn't completed by a chat + :type completed_by_chat: :class:`Chat` + :param completion_date: Optional. Point in time (Unix timestamp) when the task was completed; 0 if the task wasn't completed :type completion_date: :obj:`int` @@ -12704,11 +12827,13 @@ class ChecklistTask(JsonDeserializable): """ def __init__(self, id: int, text: str, text_entities: Optional[List[MessageEntity]] = None, completed_by_user: Optional[User] = None, + completed_by_chat: Optional[Chat] = None, completion_date: Optional[int] = None, **kwargs): self.id: int = id self.text: str = text self.text_entities: Optional[List[MessageEntity]] = text_entities self.completed_by_user: Optional[User] = completed_by_user + self.completed_by_chat: Optional[Chat] = completed_by_chat self.completion_date: Optional[int] = completion_date @classmethod @@ -12719,6 +12844,8 @@ def de_json(cls, json_string): obj['text_entities'] = Message.parse_entities(obj['text_entities']) if 'completed_by_user' in obj: obj['completed_by_user'] = User.de_json(obj['completed_by_user']) + if 'completed_by_chat' in obj: + obj['completed_by_chat'] = Chat.de_json(obj['completed_by_chat']) return cls(**obj) @@ -12956,6 +13083,43 @@ def de_json(cls, json_string): return cls(**obj) +class UniqueGiftColors(JsonDeserializable): + """ + This object contains information about the color scheme for a user's name, message replies and link previews + based on a unique gift. + + Telegram documentation: https://core.telegram.org/bots/api#uniquegiftcolors + + :param model_custom_emoji_id: Custom emoji identifier of the unique gift's model + :type model_custom_emoji_id: :obj:`str` + + :param symbol_custom_emoji_id: Custom emoji identifier of the unique gift's symbol + :type symbol_custom_emoji_id: :obj:`str` + + :param light_theme_main_color: Main color used in light themes; RGB format + :type light_theme_main_color: :obj:`int` + + :param light_theme_other_colors: List of 1-3 additional colors used in light themes; RGB format + :type light_theme_other_colors: :obj:`list` of :obj:`int` + + :param dark_theme_main_color: Main color used in dark themes; RGB format + :type dark_theme_main_color: :obj:`int` + + :param dark_theme_other_colors: List of 1-3 additional colors used in dark themes; RGB format + :type dark_theme_other_colors: :obj:`list` of :obj:`int` + + :return: Instance of the class + :rtype: :class:`UniqueGiftColors` + """ + def __init__(self, model_custom_emoji_id: str, symbol_custom_emoji_id: str, + light_theme_main_color: int, light_theme_other_colors: List[int], + dark_theme_main_color: int, dark_theme_other_colors: List[int], **kwargs): + self.model_custom_emoji_id: str = model_custom_emoji_id + self.symbol_custom_emoji_id: str = symbol_custom_emoji_id + self.light_theme_main_color: int = light_theme_main_color + self.light_theme_other_colors: List[int] = light_theme_other_colors + self.dark_theme_main_color: int = dark_theme_main_color + self.dark_theme_other_colors: List[int] = dark_theme_other_colors class DirectMessagesTopic(JsonDeserializable): """ Describes a topic of a direct messages chat. @@ -13119,6 +13283,30 @@ def de_json(cls, json_string): if 'price' in obj: obj['price'] = SuggestedPostPrice.de_json(obj['price']) return cls(**obj) + + +class GiftBackground(JsonDeserializable): + """ + This object describes the background of a gift. + + Telegram documentation: https://core.telegram.org/bots/api#giftbackground + + :param center_color: Center color of the background in RGB format + :type center_color: :obj:`int` + + :param edge_color: Edge color of the background in RGB format + :type edge_color: :obj:`int` + + :param text_color: Text color of the background in RGB format + :type text_color: :obj:`int` + + :return: Instance of the class + :rtype: :class:`GiftBackground` + """ + def __init__(self, center_color: int, edge_color: int, text_color: int, **kwargs): + self.center_color: int = center_color + self.edge_color: int = edge_color + self.text_color: int = text_color class SuggestedPostApprovalFailed(JsonDeserializable): """ @@ -13243,4 +13431,38 @@ def de_json(cls, json_string): return cls(**obj) +class UserRating(JsonDeserializable): + """ + This object describes the rating of a user based on their Telegram Star spendings. + + Telegram documentation: https://core.telegram.org/bots/api#userrating + + :param level: Current level of the user, indicating their reliability when purchasing digital goods and services. A higher level suggests a more trustworthy customer; a negative level is likely reason for concern. + :type level: :obj:`int` + + :param rating: Numerical value of the user's rating; the higher the rating, the better + :type rating: :obj:`int` + + :param current_level_rating: The rating value required to get the current level + :type current_level_rating: :obj:`int` + + :param next_level_rating: Optional. The rating value required to get to the next level; omitted if the maximum level was reached + :type next_level_rating: :obj:`int` + + :return: Instance of the class + :rtype: :class:`UserRating` + """ + def __init__(self, level: int, rating: int, current_level_rating: int, + next_level_rating: Optional[int] = None, **kwargs): + self.level: int = level + self.rating: int = rating + self.current_level_rating: int = current_level_rating + self.next_level_rating: Optional[int] = next_level_rating + + @classmethod + def de_json(cls, json_string): + if json_string is None: return None + obj = cls.check_json(json_string) + return cls(**obj) + \ No newline at end of file