diff --git a/README.md b/README.md index 97d55930d..119545779 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@

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

Both synchronous and asynchronous.

-##

Supported Bot API version: Supported Bot API version +##

Supported Bot API version: Supported Bot API version

Official documentation

Official ru documentation

diff --git a/telebot/__init__.py b/telebot/__init__.py index 62cae3f96..bb33f55b5 100644 --- a/telebot/__init__.py +++ b/telebot/__init__.py @@ -1512,6 +1512,26 @@ def get_user_profile_photos(self, user_id: int, offset: Optional[int]=None, apihelper.get_user_profile_photos(self.token, user_id, offset=offset, limit=limit) ) + def set_user_emoji_status(self, user_id: int, emoji_status_custom_emoji_id: Optional[str]=None, emoji_status_expiration_date: Optional[int]=None) -> bool: + """ + Changes the emoji status for a given user that previously allowed the bot to manage their emoji status via the Mini App method requestEmojiStatusAccess. Returns True on success. + + Telegram documentation: https://core.telegram.org/bots/api#setuseremojistatus + + :param user_id: Unique identifier of the target user + :type user_id: :obj:`int` + + :param emoji_status_custom_emoji_id: Custom emoji identifier of the emoji status to set. Pass an empty string to remove the status. + :type emoji_status_custom_emoji_id: :obj:`str` + + :param emoji_status_expiration_date: Expiration date of the emoji status, if any + :type emoji_status_expiration_date: :obj:`int` + + :return: :obj:`bool` + """ + return apihelper.set_user_emoji_status( + self.token, user_id, emoji_status_custom_emoji_id=emoji_status_custom_emoji_id, emoji_status_expiration_date=emoji_status_expiration_date) + def get_chat(self, chat_id: Union[int, str]) -> types.ChatFullInfo: """ @@ -5418,7 +5438,9 @@ def create_invoice_link(self, need_shipping_address: Optional[bool]=None, send_phone_number_to_provider: Optional[bool]=None, send_email_to_provider: Optional[bool]=None, - is_flexible: Optional[bool]=None) -> str: + is_flexible: Optional[bool]=None, + subscription_period: Optional[int]=None, + business_connection_id: Optional[str]=None) -> str: """ Use this method to create a link for an invoice. @@ -5427,6 +5449,9 @@ def create_invoice_link(self, Telegram documentation: https://core.telegram.org/bots/api#createinvoicelink + :param business_connection_id: Unique identifier of the business connection on behalf of which the link will be created + :type business_connection_id: :obj:`str` + :param title: Product name, 1-32 characters :type title: :obj:`str` @@ -5449,6 +5474,11 @@ def create_invoice_link(self, (e.g. product price, tax, discount, delivery cost, delivery tax, bonus, etc.) :type prices: :obj:`list` of :obj:`types.LabeledPrice` + :subscription_period: The number of seconds the subscription will be active for before the next payment. + The currency must be set to “XTR” (Telegram Stars) if the parameter is used. Currently, it must always + be 2592000 (30 days) if specified. + :type subscription_period: :obj:`int` + :param max_tip_amount: The maximum accepted amount for tips in the smallest units of the currency :type max_tip_amount: :obj:`int` @@ -5505,7 +5535,8 @@ def create_invoice_link(self, photo_width=photo_width, photo_height=photo_height, need_name=need_name, need_phone_number=need_phone_number, need_email=need_email, need_shipping_address=need_shipping_address, send_phone_number_to_provider=send_phone_number_to_provider, - send_email_to_provider=send_email_to_provider, is_flexible=is_flexible) + send_email_to_provider=send_email_to_provider, is_flexible=is_flexible ,subscription_period=subscription_period, + business_connection_id=business_connection_id) # noinspection PyShadowingBuiltins @@ -5803,6 +5834,26 @@ def refund_star_payment(self, user_id: int, telegram_payment_charge_id: str) -> """ return apihelper.refund_star_payment(self.token, user_id, telegram_payment_charge_id) + def edit_user_star_subscription(self, user_id: int, telegram_payment_charge_id: str, is_canceled: bool) -> bool: + """ + Allows the bot to cancel or re-enable extension of a subscription paid in Telegram Stars. Returns True on success. + + Telegram documentation: https://core.telegram.org/bots/api#edituserstarsubscription + + :param user_id: Identifier of the user whose subscription will be edited + :type user_id: :obj:`int` + + :param telegram_payment_charge_id: Telegram payment identifier for the subscription + :type telegram_payment_charge_id: :obj:`str` + + :param is_canceled: Pass True to cancel extension of the user subscription; the subscription must be active up to the end of the current subscription period. Pass False to allow the user to re-enable a subscription that was previously canceled by the bot. + :type is_canceled: :obj:`bool` + + :return: On success, True is returned. + :rtype: :obj:`bool` + """ + return apihelper.edit_user_star_subscription(self.token, user_id, telegram_payment_charge_id, is_canceled) + def edit_message_caption( self, caption: str, chat_id: Optional[Union[int, str]]=None, message_id: Optional[int]=None, @@ -6199,6 +6250,44 @@ def delete_sticker_set(self, name:str) -> bool: """ return apihelper.delete_sticker_set(self.token, name) + def send_gift(self, user_id: int, gift_id: str, text: Optional[str]=None, text_parse_mode: Optional[str]=None, text_entities: Optional[List[types.MessageEntity]]=None) -> bool: + """ + Sends a gift to the given user. The gift can't be converted to Telegram Stars by the user. Returns True on success. + + Telegram documentation: https://core.telegram.org/bots/api#sendgift + + :param user_id: Unique identifier of the target user that will receive the gift + :type user_id: :obj:`int` + + :param gift_id: Identifier of the gift + :type gift_id: :obj:`str` + + :param text: Text that will be shown along with the gift; 0-255 characters + :type text: :obj:`str` + + :param text_parse_mode: Mode for parsing entities in the text. See formatting options for more details. Entities other than “bold”, “italic”, “underline”, “strikethrough”, “spoiler”, and “custom_emoji” are ignored. + :type text_parse_mode: :obj:`str` + + :param text_entities: A JSON-serialized list of special entities that appear in the gift text. It can be specified instead of text_parse_mode. Entities other than “bold”, “italic”, “underline”, “strikethrough”, “spoiler”, and “custom_emoji” are ignored. + :type text_entities: :obj:`list` of :obj:`types.MessageEntity` + + :return: Returns True on success. + :rtype: :obj:`bool` + """ + return apihelper.send_gift(self.token, user_id, gift_id, text=text, text_parse_mode=text_parse_mode, text_entities=text_entities) + + def get_available_gifts(self) -> types.Gifts: + """ + Returns the list of gifts that can be sent by the bot to users. Requires no parameters. Returns a Gifts object. + + Telegram documentation: https://core.telegram.org/bots/api#getavailablegifts + + :return: On success, a Gifts object is returned. + :rtype: :class:`telebot.types.Gifts` + """ + return types.Gifts.de_json( + apihelper.get_available_gifts(self.token) + ) def replace_sticker_in_set(self, user_id: int, name: str, old_sticker: str, sticker: types.InputSticker) -> bool: """ @@ -6718,6 +6807,42 @@ def answer_web_app_query(self, web_app_query_id: str, result: types.InlineQueryR """ return apihelper.answer_web_app_query(self.token, web_app_query_id, result) + def save_prepared_inline_message( + self, user_id: int, result: types.InlineQueryResultBase, allow_user_chats: Optional[bool]=None, + allow_bot_chats: Optional[bool]=None, allow_group_chats: Optional[bool]=None, + allow_channel_chats: Optional[bool]=None) -> types.PreparedInlineMessage: + """ + Use this method to store a message that can be sent by a user of a Mini App. + Returns a PreparedInlineMessage object. + + Telegram Documentation: https://core.telegram.org/bots/api#savepreparedinlinemessage + + :param user_id: Unique identifier of the target user that can use the prepared message + :type user_id: :obj:`int` + + :param result: A JSON-serialized object describing the message to be sent + :type result: :class:`telebot.types.InlineQueryResultBase` + + :param allow_user_chats: Pass True if the message can be sent to private chats with users + :type allow_user_chats: :obj:`bool` + + :param allow_bot_chats: Pass True if the message can be sent to private chats with bots + :type allow_bot_chats: :obj:`bool` + + :param allow_group_chats: Pass True if the message can be sent to group and supergroup chats + :type allow_group_chats: :obj:`bool` + + :param allow_channel_chats: Pass True if the message can be sent to channel chats + :type allow_channel_chats: :obj:`bool` + + :return: On success, a PreparedInlineMessage object is returned. + :rtype: :class:`telebot.types.PreparedInlineMessage` + """ + return types.PreparedInlineMessage.de_json( + apihelper.save_prepared_inline_message( + self.token, user_id, result, allow_user_chats=allow_user_chats, allow_bot_chats=allow_bot_chats, + allow_group_chats=allow_group_chats, allow_channel_chats=allow_channel_chats) + ) def register_for_reply(self, message: types.Message, callback: Callable, *args, **kwargs) -> None: """ diff --git a/telebot/apihelper.py b/telebot/apihelper.py index 92d419c45..5ea37c4fd 100644 --- a/telebot/apihelper.py +++ b/telebot/apihelper.py @@ -341,6 +341,16 @@ def get_user_profile_photos(token, user_id, offset=None, limit=None): payload['limit'] = limit return _make_request(token, method_url, params=payload) + +def set_user_emoji_status(token, user_id, emoji_status_custom_emoji_id=None, emoji_status_expiration_date=None): + method_url = r'setUserEmojiStatus' + payload = {'user_id': user_id} + if emoji_status_custom_emoji_id: + payload['emoji_status_custom_emoji_id'] = emoji_status_custom_emoji_id + if emoji_status_expiration_date: + payload['emoji_status_expiration_date'] = emoji_status_expiration_date + return _make_request(token, method_url, params=payload) + def set_message_reaction(token, chat_id, message_id, reaction=None, is_big=None): method_url = r'setMessageReaction' payload = {'chat_id': chat_id, 'message_id': message_id} @@ -1805,6 +1815,11 @@ def refund_star_payment(token, user_id, telegram_payment_charge_id): payload = {'user_id': user_id, 'telegram_payment_charge_id': telegram_payment_charge_id} return _make_request(token, method_url, params=payload) +def edit_user_star_subscription(token, user_id, telegram_payment_charge_id, is_canceled): + method_url = 'editUserStarSubscription' + payload = {'user_id': user_id, 'telegram_payment_charge_id': telegram_payment_charge_id, 'is_canceled': is_canceled} + return _make_request(token, method_url, params=payload) + def unpin_all_general_forum_topic_messages(token, chat_id): method_url = 'unpinAllGeneralForumTopicMessages' @@ -1909,6 +1924,22 @@ def delete_sticker_set(token, name): return _make_request(token, method_url, params=payload, method='post') +def get_available_gifts(token): + method_url = 'getAvailableGifts' + return _make_request(token, method_url) + + +def send_gift(token, user_id, gift_id, text=None, text_parse_mode=None, text_entities=None): + method_url = 'sendGift' + payload = {'user_id': user_id, 'gift_id': gift_id} + if text: + payload['text'] = text + if text_parse_mode: + payload['text_parse_mode'] = text_parse_mode + if text_entities: + payload['text_entities'] = json.dumps(types.MessageEntity.to_list_of_dicts(text_entities)) + return _make_request(token, method_url, params=payload, method='post') + def set_sticker_emoji_list(token, sticker, emoji_list): method_url = 'setStickerEmojiList' payload = {'sticker': sticker, 'emoji_list': json.dumps(emoji_list)} @@ -1966,11 +1997,26 @@ def answer_web_app_query(token, web_app_query_id, result: types.InlineQueryResul return _make_request(token, method_url, params=payload, method='post') +def save_prepared_inline_message(token, user_id, result: types.InlineQueryResultBase, allow_user_chats=None, + allow_bot_chats=None, allow_group_chats=None, allow_channel_chats=None): + method_url = 'savePreparedInlineMessage' + payload = {'user_id': user_id, 'result': result.to_json()} + if allow_user_chats is not None: + payload['allow_user_chats'] = allow_user_chats + if allow_bot_chats is not None: + payload['allow_bot_chats'] = allow_bot_chats + if allow_group_chats is not None: + payload['allow_group_chats'] = allow_group_chats + if allow_channel_chats is not None: + payload['allow_channel_chats'] = allow_channel_chats + return _make_request(token, method_url, params=payload, method='post') + + def create_invoice_link(token, title, description, payload, provider_token, currency, prices, max_tip_amount=None, suggested_tip_amounts=None, provider_data=None, photo_url=None, photo_size=None, photo_width=None, photo_height=None, need_name=None, need_phone_number=None, need_email=None, need_shipping_address=None, send_phone_number_to_provider=None, - send_email_to_provider=None, is_flexible=None): + send_email_to_provider=None, is_flexible=None, subscription_period=None, business_connection_id=None): method_url = r'createInvoiceLink' payload = {'title': title, 'description': description, 'payload': payload, 'currency': currency, 'prices': _convert_list_json_serializable(prices)} @@ -2004,6 +2050,10 @@ def create_invoice_link(token, title, description, payload, provider_token, payload['is_flexible'] = is_flexible if provider_token is not None: payload['provider_token'] = provider_token + if subscription_period: + payload['subscription_period'] = subscription_period + if business_connection_id: + payload['business_connection_id'] = business_connection_id return _make_request(token, method_url, params=payload, method='post') diff --git a/telebot/async_telebot.py b/telebot/async_telebot.py index 75ce41346..7f50b1c86 100644 --- a/telebot/async_telebot.py +++ b/telebot/async_telebot.py @@ -2987,6 +2987,26 @@ async def get_user_profile_photos(self, user_id: int, offset: Optional[int]=None """ result = await asyncio_helper.get_user_profile_photos(self.token, user_id, offset, limit) return types.UserProfilePhotos.de_json(result) + + async def set_user_emoji_status(self, user_id: int, emoji_status_custom_emoji_id: Optional[str]=None, emoji_status_expiration_date: Optional[int]=None) -> bool: + """ + Use this method to change the emoji status for a given user that previously allowed the bot to manage their emoji status via the Mini App method requestEmojiStatusAccess. + + Telegram documentation: https://core.telegram.org/bots/api#setuseremojistatus + + :param user_id: Unique identifier of the target user + :type user_id: :obj:`int` + + :param emoji_status_custom_emoji_id: Custom emoji identifier of the emoji status to set. Pass an empty string to remove the status. + :type emoji_status_custom_emoji_id: :obj:`str`, optional + + :param emoji_status_expiration_date: Expiration date of the emoji status, if any + :type emoji_status_expiration_date: :obj:`int`, optional + + :return: :obj:`bool` + """ + result = await asyncio_helper.set_user_emoji_status(self.token, user_id, emoji_status_custom_emoji_id, emoji_status_expiration_date) + return result async def get_chat(self, chat_id: Union[int, str]) -> types.ChatFullInfo: """ @@ -3128,6 +3148,36 @@ async def answer_web_app_query(self, web_app_query_id: str, result: types.Inline return await asyncio_helper.answer_web_app_query(self.token, web_app_query_id, result) + async def save_prepared_inline_message(self, user_id: int, result: types.InlineQueryResultBase, allow_user_chats: Optional[bool]=None, + allow_bot_chats: Optional[bool]=None, allow_group_chats: Optional[bool]=None, allow_channel_chats: Optional[bool]=None) -> types.PreparedInlineMessage: + """ + Stores a message that can be sent by a user of a Mini App. Returns a PreparedInlineMessage object. + + Telegram Documentation: https://core.telegram.org/bots/api#savepreparedinlinemessage + + :param user_id: Unique identifier of the target user that can use the prepared message + :type user_id: :obj:`int` + + :param result: A JSON-serialized object describing the message to be sent + :type result: :class:`telebot.types.InlineQueryResultBase` + + :param allow_user_chats: Pass True if the message can be sent to private chats with users + :type allow_user_chats: :obj:`bool`, optional + + :param allow_bot_chats: Pass True if the message can be sent to private chats with bots + :type allow_bot_chats: :obj:`bool`, optional + + :param allow_group_chats: Pass True if the message can be sent to group and supergroup chats + :type allow_group_chats: :obj:`bool`, optional + + :param allow_channel_chats: Pass True if the message can be sent to channel chats + :type allow_channel_chats: :obj:`bool`, optional + + :return: :class:`telebot.types.PreparedInlineMessage` + """ + result = await asyncio_helper.save_prepared_inline_message(self.token, user_id, result, allow_user_chats, allow_bot_chats, allow_group_chats, allow_channel_chats) + return types.PreparedInlineMessage.de_json(result) + async def get_chat_member(self, chat_id: Union[int, str], user_id: int) -> types.ChatMember: """ Use this method to get information about a member of a chat. Returns a ChatMember object on success. @@ -6836,7 +6886,9 @@ async def create_invoice_link(self, need_shipping_address: Optional[bool]=None, send_phone_number_to_provider: Optional[bool]=None, send_email_to_provider: Optional[bool]=None, - is_flexible: Optional[bool]=None) -> str: + is_flexible: Optional[bool]=None, + subscription_period: Optional[int]=None, + business_connection_id: Optional[str]=None) -> str: """ Use this method to create a link for an invoice. @@ -6844,6 +6896,9 @@ async def create_invoice_link(self, Telegram documentation: https://core.telegram.org/bots/api#createinvoicelink + + :param business_connection_id: Unique identifier of the business connection on behalf of which the link will be created + :type business_connection_id: :obj:`str` :param title: Product name, 1-32 characters :type title: :obj:`str` @@ -6867,6 +6922,11 @@ async def create_invoice_link(self, (e.g. product price, tax, discount, delivery cost, delivery tax, bonus, etc.) :type prices: :obj:`list` of :obj:`types.LabeledPrice` + :subscription_period: The number of seconds the subscription will be active for before the next payment. + The currency must be set to “XTR” (Telegram Stars) if the parameter is used. Currently, it must always + be 2592000 (30 days) if specified. + :type subscription_period: :obj:`int` + :param max_tip_amount: The maximum accepted amount for tips in the smallest units of the currency :type max_tip_amount: :obj:`int` @@ -6921,7 +6981,7 @@ async def create_invoice_link(self, currency, prices, max_tip_amount, suggested_tip_amounts, provider_data, photo_url, photo_size, photo_width, photo_height, need_name, need_phone_number, need_email, need_shipping_address, send_phone_number_to_provider, - send_email_to_provider, is_flexible) + send_email_to_provider, is_flexible, subscription_period=subscription_period, business_connection_id=business_connection_id) return result # noinspection PyShadowingBuiltins @@ -7210,6 +7270,26 @@ async def refund_star_payment(self, user_id: int, telegram_payment_charge_id: st """ return await asyncio_helper.refund_star_payment(self.token, user_id, telegram_payment_charge_id) + async def edit_user_star_subscription(self, user_id: int, telegram_payment_charge_id: str, is_canceled: bool) -> bool: + """ + Allows the bot to cancel or re-enable extension of a subscription paid in Telegram Stars. Returns True on success. + + Telegram documentation: https://core.telegram.org/bots/api#edituserstarsubscription + + :param user_id: Identifier of the user whose subscription will be edited + :type user_id: :obj:`int` + + :param telegram_payment_charge_id: Telegram payment identifier for the subscription + :type telegram_payment_charge_id: :obj:`str` + + :param is_canceled: Pass True to cancel extension of the user subscription; the subscription must be active up to the end of the current subscription period. Pass False to allow the user to re-enable a subscription that was previously canceled by the bot. + :type is_canceled: :obj:`bool` + + :return: On success, True is returned. + :rtype: :obj:`bool` + """ + return await asyncio_helper.edit_user_star_subscription(self.token, user_id, telegram_payment_charge_id, is_canceled) + async def edit_message_caption( self, caption: str, chat_id: Optional[Union[int, str]]=None, message_id: Optional[int]=None, @@ -7626,6 +7706,44 @@ async def delete_sticker_set(self, name:str) -> bool: """ return await asyncio_helper.delete_sticker_set(self.token, name) + + async def send_gift(self, user_id: int, gift_id: str, text: Optional[str]=None, text_parse_mode: Optional[str]=None, text_entities: Optional[List[types.MessageEntity]]=None) -> bool: + """ + Sends a gift to the given user. The gift can't be converted to Telegram Stars by the user. Returns True on success. + + Telegram documentation: https://core.telegram.org/bots/api#sendgift + + :param user_id: Unique identifier of the target user that will receive the gift + :type user_id: :obj:`int` + + :param gift_id: Identifier of the gift + :type gift_id: :obj:`str` + + :param text: Text that will be shown along with the gift; 0-255 characters + :type text: :obj:`str` + + :param text_parse_mode: Mode for parsing entities in the text. See formatting options for more details. Entities other than “bold”, “italic”, “underline”, “strikethrough”, “spoiler”, and “custom_emoji” are ignored. + :type text_parse_mode: :obj:`str` + + :param text_entities: A JSON-serialized list of special entities that appear in the gift text. It can be specified instead of text_parse_mode. Entities other than “bold”, “italic”, “underline”, “strikethrough”, “spoiler”, and “custom_emoji” are ignored. + :type text_entities: :obj:`list` of :obj:`types.MessageEntity` + + :return: Returns True on success. + :rtype: :obj:`bool` + """ + return await asyncio_helper.send_gift(self.token, user_id, gift_id, text, text_parse_mode, text_entities) + + async def get_available_gifts(self) -> types.Gifts: + """ + Returns the list of gifts that can be sent by the bot to users. Requires no parameters. Returns a Gifts object. + + Telegram documentation: https://core.telegram.org/bots/api#getavailablegifts + + :return: On success, a Gifts object is returned. + :rtype: :class:`telebot.types.Gifts` + """ + + return types.Gifts.de_json(await asyncio_helper.get_available_gifts(self.token)) async def replace_sticker_in_set(self, user_id: int, name: str, old_sticker: str, sticker: types.InputSticker) -> bool: """ diff --git a/telebot/asyncio_helper.py b/telebot/asyncio_helper.py index b21b7f9f0..56604c750 100644 --- a/telebot/asyncio_helper.py +++ b/telebot/asyncio_helper.py @@ -325,6 +325,16 @@ async def get_user_profile_photos(token, user_id, offset=None, limit=None): payload['limit'] = limit return await _process_request(token, method_url, params=payload) + +async def set_user_emoji_status(token, user_id, emoji_status_custom_emoji_id=None, emoji_status_expiration_date=None): + method_url = r'setUserEmojiStatus' + payload = {'user_id': user_id} + if emoji_status_custom_emoji_id: + payload['emoji_status_custom_emoji_id'] = emoji_status_custom_emoji_id + if emoji_status_expiration_date: + payload['emoji_status_expiration_date'] = emoji_status_expiration_date + return await _process_request(token, method_url, params=payload) + async def set_message_reaction(token, chat_id, message_id, reaction=None, is_big=None): method_url = r'setMessageReaction' payload = {'chat_id': chat_id, 'message_id': message_id} @@ -396,6 +406,20 @@ async def answer_web_app_query(token, web_app_query_id, result: types.InlineQuer return await _process_request(token, method_url, params=payload, method='post') +async def save_prepared_inline_message(token, user_id, result: types.InlineQueryResultBase, allow_user_chats=None, allow_bot_chats=None, allow_group_chats=None, allow_channel_chats=None): + method_url = r'savePreparedInlineMessage' + payload = {'user_id': user_id, 'result': result.to_json()} + if allow_user_chats is not None: + payload['allow_user_chats'] = allow_user_chats + if allow_bot_chats is not None: + payload['allow_bot_chats'] = allow_bot_chats + if allow_group_chats is not None: + payload['allow_group_chats'] = allow_group_chats + if allow_channel_chats is not None: + payload['allow_channel_chats'] = allow_channel_chats + return await _process_request(token, method_url, params=payload) + + async def get_chat_member(token, chat_id, user_id): method_url = r'getChatMember' payload = {'chat_id': chat_id, 'user_id': user_id} @@ -1793,6 +1817,12 @@ async def refund_star_payment(token, user_id, telegram_payment_charge_id): return await _process_request(token, method_url, params=payload) +async def edit_user_star_subscription(token, user_id, telegram_payment_charge_id, is_canceled): + method_url = 'editUserStarSubscription' + payload = {'user_id': user_id, 'telegram_payment_charge_id': telegram_payment_charge_id, 'is_canceled': is_canceled} + return await _process_request(token, method_url, params=payload) + + async def unpin_all_general_forum_topic_messages(token, chat_id): method_url = 'unpinAllGeneralForumTopicMessages' payload = {'chat_id': chat_id} @@ -1886,6 +1916,21 @@ async def delete_sticker_set(token, name): payload = {'name': name} return await _process_request(token, method_url, params=payload, method='post') +async def send_gift(token, user_id, gift_id, text=None, text_parse_mode=None, text_entities=None): + method_url = 'sendGift' + payload = {'user_id': user_id, 'gift_id': gift_id} + if text: + payload['text'] = text + if text_parse_mode: + payload['text_parse_mode'] = text_parse_mode + if text_entities: + payload['text_entities'] = json.dumps(types.MessageEntity.to_list_of_dicts(text_entities)) + return await _process_request(token, method_url, params=payload, method='post') + +async def get_available_gifts(token): + method_url = 'getAvailableGifts' + return await _process_request(token, method_url) + async def set_custom_emoji_sticker_set_thumbnail(token, name, custom_emoji_id=None): method_url = 'setCustomEmojiStickerSetThumbnail' payload = {'name': name} @@ -1952,7 +1997,7 @@ async def create_invoice_link(token, title, description, payload, provider_token currency, prices, max_tip_amount=None, suggested_tip_amounts=None, provider_data=None, photo_url=None, photo_size=None, photo_width=None, photo_height=None, need_name=None, need_phone_number=None, need_email=None, need_shipping_address=None, send_phone_number_to_provider=None, - send_email_to_provider=None, is_flexible=None): + send_email_to_provider=None, is_flexible=None, subscription_period=None, business_connection_id=None): method_url = r'createInvoiceLink' payload = {'title': title, 'description': description, 'payload': payload, 'currency': currency, 'prices': await _convert_list_json_serializable(prices)} @@ -1986,6 +2031,10 @@ async def create_invoice_link(token, title, description, payload, provider_token payload['is_flexible'] = is_flexible if provider_token is not None: payload['provider_token'] = provider_token + if subscription_period: + payload['subscription_period'] = subscription_period + if business_connection_id: + payload['business_connection_id'] = business_connection_id return await _process_request(token, method_url, params=payload, method='post') diff --git a/telebot/types.py b/telebot/types.py index 66ad984bc..3a71887de 100644 --- a/telebot/types.py +++ b/telebot/types.py @@ -6318,6 +6318,15 @@ class SuccessfulPayment(JsonDeserializable): :param invoice_payload: Bot specified invoice payload :type invoice_payload: :obj:`str` + :param subscription_expiration_date: Optional. Expiration date of the subscription, in Unix time; for recurring payments only + :type subscription_expiration_date: :obj:`int` + + :param is_recurring: Optional. True, if the payment is a recurring payment, false otherwise + :type is_recurring: :obj:`bool` + + :param is_first_recurring: Optional. True, if the payment is the first payment for a subscription + :type is_first_recurring: :obj:`bool` + :param shipping_option_id: Optional. Identifier of the shipping option chosen by the user :type shipping_option_id: :obj:`str` @@ -6341,7 +6350,8 @@ def de_json(cls, json_string): return cls(**obj) def __init__(self, currency, total_amount, invoice_payload, shipping_option_id=None, order_info=None, - telegram_payment_charge_id=None, provider_payment_charge_id=None, **kwargs): + telegram_payment_charge_id=None, provider_payment_charge_id=None, + subscription_expiration_date=None, is_recurring=None, is_first_recurring=None, **kwargs): self.currency: str = currency self.total_amount: int = total_amount self.invoice_payload: str = invoice_payload @@ -6349,6 +6359,9 @@ def __init__(self, currency, total_amount, invoice_payload, shipping_option_id=N self.order_info: OrderInfo = order_info self.telegram_payment_charge_id: str = telegram_payment_charge_id self.provider_payment_charge_id: str = provider_payment_charge_id + self.subscription_expiration_date: Optional[int] = subscription_expiration_date + self.is_recurring: Optional[bool] = is_recurring + self.is_first_recurring: Optional[bool] = is_first_recurring # noinspection PyShadowingBuiltins @@ -10476,18 +10489,27 @@ class TransactionPartnerUser(TransactionPartner): :param invoice_payload: Optional, Bot-specified invoice payload :type invoice_payload: :obj:`str` + :param subscription_period: Optional. The duration of the paid subscription + :type subscription_period: :obj:`int` + :param paid_media: Optional. Information about the paid media bought by the user :type paid_media: :obj:`list` of :class:`PaidMedia` + :param gift: Optional. The gift sent to the user by the bot + :type gift: :class:`Gift` + :return: Instance of the class :rtype: :class:`TransactionPartnerUser` """ - def __init__(self, type, user, invoice_payload=None, paid_media: Optional[List[PaidMedia]] = None, **kwargs): + def __init__(self, type, user, invoice_payload=None, paid_media: Optional[List[PaidMedia]] = None, + subscription_period=None, gift: Optional[Gift] = None, **kwargs): self.type: str = type self.user: User = user self.invoice_payload: Optional[str] = invoice_payload self.paid_media: Optional[List[PaidMedia]] = paid_media + self.subscription_period: Optional[int] = subscription_period + self.gift: Optional[Gift] = gift @classmethod def de_json(cls, json_string): @@ -10496,6 +10518,8 @@ def de_json(cls, json_string): obj['user'] = User.de_json(obj['user']) if 'paid_media' in obj: obj['paid_media'] = [PaidMedia.de_json(media) for media in obj['paid_media']] + if 'gift' in obj: + obj['gift'] = Gift.de_json(obj['gift']) return cls(**obj) @@ -10979,3 +11003,94 @@ def de_json(cls, json_string): if json_string is None: return None obj = cls.check_json(json_string) return cls(**obj) + + +class PreparedInlineMessage(JsonDeserializable): + """ + Describes an inline message to be sent by a user of a Mini App. + + Telegram documentation: https://core.telegram.org/bots/api#preparedinlinemessage + + :param id: Unique identifier of the prepared message + :type id: :obj:`str` + + :param expiration_date: Expiration date of the prepared message, in Unix time. Expired prepared messages can no longer be used + :type expiration_date: :obj:`int` + + :return: Instance of the class + :rtype: :class:`PreparedInlineMessage` + """ + + def __init__(self, id, expiration_date, **kwargs): + self.id: str = id + self.expiration_date: int = expiration_date + + @classmethod + def de_json(cls, json_string): + if json_string is None: return None + obj = cls.check_json(json_string) + return cls(**obj) + + +class Gift(JsonDeserializable): + """ + This object represents a gift that can be sent by the bot. + + Telegram documentation: https://core.telegram.org/bots/api#gift + + :param id: Unique identifier of the gift + :type id: :obj:`str` + + :param sticker: The sticker that represents the gift + :type sticker: :class:`Sticker` + + :param star_count: The number of Telegram Stars that must be paid to send the sticker + :type star_count: :obj:`int` + + :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` + + :return: Instance of the class + :rtype: :class:`Gift` + """ + + def __init__(self, id, sticker, star_count, total_count=None, remaining_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 + + @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']) + return cls(**obj) + +class Gifts(JsonDeserializable): + """ + This object represent a list of gifts. + + Telegram documentation: https://core.telegram.org/bots/api#gifts + + :param gifts: The list of gifts + :type gifts: :obj:`list` of :class:`Gift` + + :return: Instance of the class + :rtype: :class:`Gifts` + """ + + def __init__(self, gifts, **kwargs): + self.gifts: List[Gift] = gifts + + @classmethod + def de_json(cls, json_string): + if json_string is None: return None + obj = cls.check_json(json_string) + obj['gifts'] = [Gift.de_json(gift) for gift in obj['gifts']] + return cls(**obj) + \ No newline at end of file