diff --git a/README.md b/README.md index 76f8f487e..5f70cad2f 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 33a353de7..bddcda75b 100644 --- a/telebot/__init__.py +++ b/telebot/__init__.py @@ -3136,7 +3136,8 @@ def send_paid_media( caption: Optional[str]=None, parse_mode: Optional[str]=None, caption_entities: Optional[List[types.MessageEntity]]=None, show_caption_above_media: Optional[bool]=None, disable_notification: Optional[bool]=None, protect_content: Optional[bool]=None, reply_parameters: Optional[types.ReplyParameters]=None, - reply_markup: Optional[REPLY_MARKUP_TYPES]=None) -> types.Message: + reply_markup: Optional[REPLY_MARKUP_TYPES]=None, business_connection_id: Optional[str]=None, + ) -> types.Message: """ Use this method to send paid media to channel chats. On success, the sent Message is returned. @@ -3175,6 +3176,9 @@ def send_paid_media( :param reply_markup: Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove a reply keyboard or to force a reply from the user :type reply_markup: :class:`telebot.types.InlineKeyboardMarkup` or :class:`telebot.types.ReplyKeyboardMarkup` or :class:`telebot.types.ReplyKeyboardRemove` or :class:`telebot.types.ForceReply` + :param business_connection_id: Identifier of a business connection, in which the message will be sent + :type business_connection_id: :obj:`str` + :return: On success, the sent Message is returned. :rtype: :class:`telebot.types.Message` """ @@ -3183,7 +3187,7 @@ def send_paid_media( self.token, chat_id, star_count, media, caption=caption, parse_mode=parse_mode, caption_entities=caption_entities, show_caption_above_media=show_caption_above_media, disable_notification=disable_notification, protect_content=protect_content, - reply_parameters=reply_parameters, reply_markup=reply_markup) + reply_parameters=reply_parameters, reply_markup=reply_markup, business_connection_id=business_connection_id) ) @@ -4195,6 +4199,62 @@ def edit_chat_invite_link( apihelper.edit_chat_invite_link(self.token, chat_id, invite_link, name, expire_date, member_limit, creates_join_request) ) + def create_chat_subscription_invite_link( + self, chat_id: Union[int, str], subscription_period: int, subscription_price: int, + name: Optional[str]=None) -> types.ChatInviteLink: + """ + Use this method to create a subscription invite link for a channel chat. The bot must have the can_invite_users administrator rights. + The link can be edited using the method editChatSubscriptionInviteLink or revoked using the method revokeChatInviteLink. + Returns the new invite link as a ChatInviteLink object. + + Telegram documentation: https://core.telegram.org/bots/api#createchatsubscriptioninvitelink + + :param chat_id: Unique identifier for the target channel chat or username of the target channel + (in the format @channelusername) + :type chat_id: :obj:`int` or :obj:`str` + + :param name: Invite link name; 0-32 characters + :type name: :obj:`str` + + :param subscription_period: The number of seconds the subscription will be active for before the next payment. + Currently, it must always be 2592000 (30 days). + :type subscription_period: :obj:`int` + + :param subscription_price: The amount of Telegram Stars a user must pay initially and after each subsequent + subscription period to be a member of the chat; 1-2500 + :type subscription_price: :obj:`int` + + :return: Returns the new invite link as a ChatInviteLink object. + :rtype: :class:`telebot.types.ChatInviteLink` + """ + return types.ChatInviteLink.de_json( + apihelper.create_chat_subscription_invite_link(self.token, chat_id, subscription_period, subscription_price, name=name) + ) + + def edit_chat_subscription_invite_link( + self, chat_id: Union[int, str], invite_link: str, name: Optional[str]=None) -> types.ChatInviteLink: + """ + Use this method to edit a subscription invite link created by the bot. The bot must have the can_invite_users administrator rights. + Returns the edited invite link as a ChatInviteLink object. + + Telegram documentation: https://core.telegram.org/bots/api#editchatsubscriptioninvitelink + + :param chat_id: Unique identifier for the target chat or username of the target channel + (in the format @channelusername) + :type chat_id: :obj:`int` or :obj:`str` + + :param invite_link: The invite link to edit + :type invite_link: :obj:`str` + + :param name: Invite link name; 0-32 characters + :type name: :obj:`str` + + :return: Returns the edited invite link as a ChatInviteLink object. + :rtype: :class:`telebot.types.ChatInviteLink` + """ + return types.ChatInviteLink.de_json( + apihelper.edit_chat_subscription_invite_link(self.token, chat_id, invite_link, name=name) + ) def revoke_chat_invite_link( self, chat_id: Union[int, str], invite_link: str) -> types.ChatInviteLink: diff --git a/telebot/apihelper.py b/telebot/apihelper.py index 2ee86abab..bc15e9316 100644 --- a/telebot/apihelper.py +++ b/telebot/apihelper.py @@ -529,7 +529,8 @@ def send_photo( def send_paid_media( token, chat_id, star_count, media, caption=None, parse_mode=None, caption_entities=None, show_caption_above_media=None, - disable_notification=None, protect_content=None, reply_parameters=None, reply_markup=None): + disable_notification=None, protect_content=None, reply_parameters=None, reply_markup=None, + business_connection_id=None): method_url = r'sendPaidMedia' media_json, files = convert_input_media_array(media) payload = {'chat_id': chat_id, 'star_count': star_count, 'media': media_json} @@ -549,6 +550,8 @@ def send_paid_media( payload['reply_parameters'] = reply_parameters.to_json() if reply_markup: payload['reply_markup'] = _convert_markup(reply_markup) + if business_connection_id: + payload['business_connection_id'] = business_connection_id return _make_request( token, method_url, params=payload, method='post' if files else 'get', @@ -1202,6 +1205,26 @@ def edit_chat_invite_link(token, chat_id, invite_link, name, expire_date, member return _make_request(token, method_url, params=payload, method='post') +def create_chat_subscription_invite_link(token, chat_id, subscription_period, subscription_price, name=None): + method_url = 'createChatSubscriptionInviteLink' + payload = { + 'chat_id': chat_id, + 'subscription_period': subscription_period, + 'subscription_price': subscription_price + } + if name: + payload['name'] = name + return _make_request(token, method_url, params=payload, method='post') + +def edit_chat_subscription_invite_link(token, chat_id, invite_link, name=None): + method_url = 'editChatSubscriptionInviteLink' + payload = { + 'chat_id': chat_id, + 'invite_link': invite_link + } + if name: + payload['name'] = name + return _make_request(token, method_url, params=payload, method='post') def revoke_chat_invite_link(token, chat_id, invite_link): method_url = 'revokeChatInviteLink' diff --git a/telebot/async_telebot.py b/telebot/async_telebot.py index 8647897b6..e2b77b0e6 100644 --- a/telebot/async_telebot.py +++ b/telebot/async_telebot.py @@ -4564,7 +4564,7 @@ async def send_paid_media( caption: Optional[str]=None, parse_mode: Optional[str]=None, caption_entities: Optional[List[types.MessageEntity]]=None, show_caption_above_media: Optional[bool]=None, disable_notification: Optional[bool]=None, protect_content: Optional[bool]=None, reply_parameters: Optional[types.ReplyParameters]=None, - reply_markup: Optional[REPLY_MARKUP_TYPES]=None) -> types.Message: + reply_markup: Optional[REPLY_MARKUP_TYPES]=None, business_connection_id: Optional[str]=None) -> types.Message: """ Use this method to send paid media to channel chats. On success, the sent Message is returned. @@ -4603,6 +4603,9 @@ async def send_paid_media( :param reply_markup: Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove a reply keyboard or to force a reply from the user :type reply_markup: :class:`telebot.types.InlineKeyboardMarkup` or :class:`telebot.types.ReplyKeyboardMarkup` or :class:`telebot.types.ReplyKeyboardRemove` or :class:`telebot.types.ForceReply` + :param business_connection_id: Identifier of a business connection, in which the message will be sent + :type business_connection_id: :obj:`str` + :return: On success, the sent Message is returned. :rtype: :class:`telebot.types.Message` """ @@ -4611,8 +4614,7 @@ async def send_paid_media( self.token, chat_id, star_count, media, caption=caption, parse_mode=parse_mode, caption_entities=caption_entities, show_caption_above_media=show_caption_above_media, disable_notification=disable_notification, protect_content=protect_content, - reply_parameters=reply_parameters, reply_markup=reply_markup) - ) + reply_parameters=reply_parameters, reply_markup=reply_markup, business_connection_id=business_connection_id)) async def send_media_group( self, chat_id: Union[int, str], @@ -5603,6 +5605,63 @@ async def edit_chat_invite_link( return types.ChatInviteLink.de_json( await asyncio_helper.edit_chat_invite_link(self.token, chat_id, invite_link, name, expire_date, member_limit, creates_join_request) ) + + async def create_chat_subscription_invite_link( + self, chat_id: Union[int, str], subscription_period: int, subscription_price: int, + name: Optional[str]=None) -> types.ChatInviteLink: + """ + Use this method to create a subscription invite link for a channel chat. The bot must have the can_invite_users administrator rights. + The link can be edited using the method editChatSubscriptionInviteLink or revoked using the method revokeChatInviteLink. + Returns the new invite link as a ChatInviteLink object. + + Telegram documentation: https://core.telegram.org/bots/api#createchatsubscriptioninvitelink + + :param chat_id: Unique identifier for the target channel chat or username of the target channel + (in the format @channelusername) + :type chat_id: :obj:`int` or :obj:`str` + + :param name: Invite link name; 0-32 characters + :type name: :obj:`str` + + :param subscription_period: The number of seconds the subscription will be active for before the next payment. + Currently, it must always be 2592000 (30 days). + :type subscription_period: :obj:`int` + + :param subscription_price: The amount of Telegram Stars a user must pay initially and after each subsequent + subscription period to be a member of the chat; 1-2500 + :type subscription_price: :obj:`int` + + :return: Returns the new invite link as a ChatInviteLink object. + :rtype: :class:`telebot.types.ChatInviteLink` + """ + return types.ChatInviteLink.de_json( + await asyncio_helper.create_chat_subscription_invite_link(self.token, chat_id, subscription_period, subscription_price, name=name) + ) + + async def edit_chat_subscription_invite_link( + self, chat_id: Union[int, str], invite_link: str, name: Optional[str]=None) -> types.ChatInviteLink: + """ + Use this method to edit a subscription invite link created by the bot. The bot must have the can_invite_users administrator rights. + Returns the edited invite link as a ChatInviteLink object. + + Telegram documentation: https://core.telegram.org/bots/api#editchatsubscriptioninvitelink + + :param chat_id: Unique identifier for the target chat or username of the target channel + (in the format @channelusername) + :type chat_id: :obj:`int` or :obj:`str` + + :param invite_link: The invite link to edit + :type invite_link: :obj:`str` + + :param name: Invite link name; 0-32 characters + :type name: :obj:`str` + + :return: Returns the edited invite link as a ChatInviteLink object. + :rtype: :class:`telebot.types.ChatInviteLink` + """ + return types.ChatInviteLink.de_json( + await asyncio_helper.edit_chat_subscription_invite_link(self.token, chat_id, invite_link, name=name) + ) async def revoke_chat_invite_link( self, chat_id: Union[int, str], invite_link: str) -> types.ChatInviteLink: diff --git a/telebot/asyncio_helper.py b/telebot/asyncio_helper.py index fa14f6123..c31bf53da 100644 --- a/telebot/asyncio_helper.py +++ b/telebot/asyncio_helper.py @@ -309,7 +309,7 @@ async def send_message( if message_effect_id: params['message_effect_id'] = message_effect_id - return await _process_request(token, method_name, params=params) + return await _process_request(token, method_name, params=params, method='post') # methods @@ -519,7 +519,8 @@ async def send_photo( async def send_paid_media( token, chat_id, star_count, media, caption=None, parse_mode=None, caption_entities=None, show_caption_above_media=None, - disable_notification=None, protect_content=None, reply_parameters=None, reply_markup=None): + disable_notification=None, protect_content=None, reply_parameters=None, reply_markup=None, + business_connection_id=None): method_url = r'sendPaidMedia' media_json, files = convert_input_media_array(media) payload = {'chat_id': chat_id, 'star_count': star_count, 'media': media_json} @@ -539,6 +540,8 @@ async def send_paid_media( payload['reply_parameters'] = reply_parameters.to_json() if reply_markup: payload['reply_markup'] = _convert_markup(reply_markup) + if business_connection_id: + payload['business_connection_id'] = business_connection_id return await _process_request( token, method_url, params=payload, method='post' if files else 'get', @@ -1182,6 +1185,28 @@ async def edit_chat_invite_link(token, chat_id, invite_link, name, expire_date, return await _process_request(token, method_url, params=payload, method='post') +async def create_chat_subscription_invite_link(token, chat_id, subscription_period, subscription_price, name=None): + method_url = 'createChatSubscriptionInviteLink' + payload = { + 'chat_id': chat_id, + 'subscription_period': subscription_period, + 'subscription_price': subscription_price + } + if name: + payload['name'] = name + return await _process_request(token, method_url, params=payload, method='post') + +async def edit_chat_subscription_invite_link(token, chat_id, invite_link, name=None): + method_url = 'editChatSubscriptionInviteLink' + payload = { + 'chat_id': chat_id, + 'invite_link': invite_link + } + if name: + payload['name'] = name + return await _process_request(token, method_url, params=payload, method='post') + + async def revoke_chat_invite_link(token, chat_id, invite_link): method_url = 'revokeChatInviteLink' payload = { diff --git a/telebot/types.py b/telebot/types.py index badd99a75..70907aa1f 100644 --- a/telebot/types.py +++ b/telebot/types.py @@ -8478,6 +8478,27 @@ def to_dict(self) -> dict: return json_dict +class ReactionTypePaid(ReactionType): + """ + This object represents a paid reaction type. + + Telegram documentation: https://core.telegram.org/bots/api#reactiontypepaid + + :param type: Type of the reaction, must be paid + :type type: :obj:`str` + + :return: Instance of the class + :rtype: :class:`ReactionTypePaid` + """ + + def __init__(self, **kwargs) -> None: + super().__init__('paid') + + def to_dict(self) -> dict: + return super().to_dict() + + + class MessageReactionUpdated(JsonDeserializable): """ This object represents a service message about a change in the list of the current user's reactions to a message. @@ -10390,20 +10411,26 @@ class TransactionPartnerUser(TransactionPartner): :param invoice_payload: Optional, Bot-specified invoice payload :type invoice_payload: :obj:`str` + :param paid_media: Optional. Information about the paid media bought by the user + :type paid_media: :obj:`list` of :class:`PaidMedia` + :return: Instance of the class :rtype: :class:`TransactionPartnerUser` """ - def __init__(self, type, user, invoice_payload=None, **kwargs): + def __init__(self, type, user, invoice_payload=None, paid_media: Optional[List[PaidMedia]] = 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 @classmethod def de_json(cls, json_string): if json_string is None: return None obj = cls.check_json(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']] return cls(**obj)