Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bot API 7.9 #2377

Merged
merged 9 commits into from
Aug 17, 2024
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<p align="center">A simple, but extensible Python implementation for the <a href="https://core.telegram.org/bots/api">Telegram Bot API</a>.</p>
<p align="center">Both synchronous and asynchronous.</p>

## <p align="center">Supported Bot API version: <a href="https://core.telegram.org/bots/api-changelog#july-31-2024"><img src="https://img.shields.io/badge/Bot%20API-7.8-blue?logo=telegram" alt="Supported Bot API version"></a>
## <p align="center">Supported Bot API version: <a href="https://core.telegram.org/bots/api#august-14-2024"><img src="https://img.shields.io/badge/Bot%20API-7.9-blue?logo=telegram" alt="Supported Bot API version"></a>

<h2><a href='https://pytba.readthedocs.io/en/latest/index.html'>Official documentation</a></h2>
<h2><a href='https://pytba.readthedocs.io/ru/latest/index.html'>Official ru documentation</a></h2>
Expand Down
64 changes: 62 additions & 2 deletions telebot/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down Expand Up @@ -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`
"""
Expand All @@ -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)
)


Expand Down Expand Up @@ -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:
Expand Down
25 changes: 24 additions & 1 deletion telebot/apihelper.py
Original file line number Diff line number Diff line change
Expand Up @@ -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}
Expand All @@ -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',
Expand Down Expand Up @@ -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'
Expand Down
65 changes: 62 additions & 3 deletions telebot/async_telebot.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down Expand Up @@ -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`
"""
Expand All @@ -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],
Expand Down Expand Up @@ -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:
Expand Down
29 changes: 27 additions & 2 deletions telebot/asyncio_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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}
Expand All @@ -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',
Expand Down Expand Up @@ -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 = {
Expand Down
29 changes: 28 additions & 1 deletion telebot/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -8465,6 +8465,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.
Expand Down Expand Up @@ -10377,20 +10398,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)

class TransactionPartnerTelegramAds(TransactionPartner):
Expand Down
Loading