Skip to content

Commit 0493a85

Browse files
authored
Merge pull request #2418 from coder2020official/botapi-8
Bot API 8.0 - Subscription plans, Emoji Statuses, Gifts and many more
2 parents f918c4e + 9c7c47f commit 0493a85

File tree

6 files changed

+466
-9
lines changed

6 files changed

+466
-9
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
<p align="center">A simple, but extensible Python implementation for the <a href="https://core.telegram.org/bots/api">Telegram Bot API</a>.</p>
1111
<p align="center">Both synchronous and asynchronous.</p>
1212

13-
## <p align="center">Supported Bot API version: <a href="https://core.telegram.org/bots/api#october-31-2024"><img src="https://img.shields.io/badge/Bot%20API-7.11-blue?logo=telegram" alt="Supported Bot API version"></a>
13+
## <p align="center">Supported Bot API version: <a href="https://core.telegram.org/bots/api#november-17-2024"><img src="https://img.shields.io/badge/Bot%20API-8.0-blue?logo=telegram" alt="Supported Bot API version"></a>
1414

1515
<h2><a href='https://pytba.readthedocs.io/en/latest/index.html'>Official documentation</a></h2>
1616
<h2><a href='https://pytba.readthedocs.io/ru/latest/index.html'>Official ru documentation</a></h2>

telebot/__init__.py

Lines changed: 127 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1512,6 +1512,26 @@ def get_user_profile_photos(self, user_id: int, offset: Optional[int]=None,
15121512
apihelper.get_user_profile_photos(self.token, user_id, offset=offset, limit=limit)
15131513
)
15141514

1515+
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:
1516+
"""
1517+
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.
1518+
1519+
Telegram documentation: https://core.telegram.org/bots/api#setuseremojistatus
1520+
1521+
:param user_id: Unique identifier of the target user
1522+
:type user_id: :obj:`int`
1523+
1524+
:param emoji_status_custom_emoji_id: Custom emoji identifier of the emoji status to set. Pass an empty string to remove the status.
1525+
:type emoji_status_custom_emoji_id: :obj:`str`
1526+
1527+
:param emoji_status_expiration_date: Expiration date of the emoji status, if any
1528+
:type emoji_status_expiration_date: :obj:`int`
1529+
1530+
:return: :obj:`bool`
1531+
"""
1532+
return apihelper.set_user_emoji_status(
1533+
self.token, user_id, emoji_status_custom_emoji_id=emoji_status_custom_emoji_id, emoji_status_expiration_date=emoji_status_expiration_date)
1534+
15151535

15161536
def get_chat(self, chat_id: Union[int, str]) -> types.ChatFullInfo:
15171537
"""
@@ -5418,7 +5438,9 @@ def create_invoice_link(self,
54185438
need_shipping_address: Optional[bool]=None,
54195439
send_phone_number_to_provider: Optional[bool]=None,
54205440
send_email_to_provider: Optional[bool]=None,
5421-
is_flexible: Optional[bool]=None) -> str:
5441+
is_flexible: Optional[bool]=None,
5442+
subscription_period: Optional[int]=None,
5443+
business_connection_id: Optional[str]=None) -> str:
54225444

54235445
"""
54245446
Use this method to create a link for an invoice.
@@ -5427,6 +5449,9 @@ def create_invoice_link(self,
54275449
Telegram documentation:
54285450
https://core.telegram.org/bots/api#createinvoicelink
54295451
5452+
:param business_connection_id: Unique identifier of the business connection on behalf of which the link will be created
5453+
:type business_connection_id: :obj:`str`
5454+
54305455
:param title: Product name, 1-32 characters
54315456
:type title: :obj:`str`
54325457
@@ -5449,6 +5474,11 @@ def create_invoice_link(self,
54495474
(e.g. product price, tax, discount, delivery cost, delivery tax, bonus, etc.)
54505475
:type prices: :obj:`list` of :obj:`types.LabeledPrice`
54515476
5477+
:subscription_period: The number of seconds the subscription will be active for before the next payment.
5478+
The currency must be set to “XTR” (Telegram Stars) if the parameter is used. Currently, it must always
5479+
be 2592000 (30 days) if specified.
5480+
:type subscription_period: :obj:`int`
5481+
54525482
:param max_tip_amount: The maximum accepted amount for tips in the smallest units of the currency
54535483
:type max_tip_amount: :obj:`int`
54545484
@@ -5505,7 +5535,8 @@ def create_invoice_link(self,
55055535
photo_width=photo_width, photo_height=photo_height, need_name=need_name,
55065536
need_phone_number=need_phone_number, need_email=need_email,
55075537
need_shipping_address=need_shipping_address, send_phone_number_to_provider=send_phone_number_to_provider,
5508-
send_email_to_provider=send_email_to_provider, is_flexible=is_flexible)
5538+
send_email_to_provider=send_email_to_provider, is_flexible=is_flexible ,subscription_period=subscription_period,
5539+
business_connection_id=business_connection_id)
55095540

55105541

55115542
# noinspection PyShadowingBuiltins
@@ -5803,6 +5834,26 @@ def refund_star_payment(self, user_id: int, telegram_payment_charge_id: str) ->
58035834
"""
58045835
return apihelper.refund_star_payment(self.token, user_id, telegram_payment_charge_id)
58055836

5837+
def edit_user_star_subscription(self, user_id: int, telegram_payment_charge_id: str, is_canceled: bool) -> bool:
5838+
"""
5839+
Allows the bot to cancel or re-enable extension of a subscription paid in Telegram Stars. Returns True on success.
5840+
5841+
Telegram documentation: https://core.telegram.org/bots/api#edituserstarsubscription
5842+
5843+
:param user_id: Identifier of the user whose subscription will be edited
5844+
:type user_id: :obj:`int`
5845+
5846+
:param telegram_payment_charge_id: Telegram payment identifier for the subscription
5847+
:type telegram_payment_charge_id: :obj:`str`
5848+
5849+
: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.
5850+
:type is_canceled: :obj:`bool`
5851+
5852+
:return: On success, True is returned.
5853+
:rtype: :obj:`bool`
5854+
"""
5855+
return apihelper.edit_user_star_subscription(self.token, user_id, telegram_payment_charge_id, is_canceled)
5856+
58065857
def edit_message_caption(
58075858
self, caption: str, chat_id: Optional[Union[int, str]]=None,
58085859
message_id: Optional[int]=None,
@@ -6199,6 +6250,44 @@ def delete_sticker_set(self, name:str) -> bool:
61996250
"""
62006251
return apihelper.delete_sticker_set(self.token, name)
62016252

6253+
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:
6254+
"""
6255+
Sends a gift to the given user. The gift can't be converted to Telegram Stars by the user. Returns True on success.
6256+
6257+
Telegram documentation: https://core.telegram.org/bots/api#sendgift
6258+
6259+
:param user_id: Unique identifier of the target user that will receive the gift
6260+
:type user_id: :obj:`int`
6261+
6262+
:param gift_id: Identifier of the gift
6263+
:type gift_id: :obj:`str`
6264+
6265+
:param text: Text that will be shown along with the gift; 0-255 characters
6266+
:type text: :obj:`str`
6267+
6268+
: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.
6269+
:type text_parse_mode: :obj:`str`
6270+
6271+
: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.
6272+
:type text_entities: :obj:`list` of :obj:`types.MessageEntity`
6273+
6274+
:return: Returns True on success.
6275+
:rtype: :obj:`bool`
6276+
"""
6277+
return apihelper.send_gift(self.token, user_id, gift_id, text=text, text_parse_mode=text_parse_mode, text_entities=text_entities)
6278+
6279+
def get_available_gifts(self) -> types.Gifts:
6280+
"""
6281+
Returns the list of gifts that can be sent by the bot to users. Requires no parameters. Returns a Gifts object.
6282+
6283+
Telegram documentation: https://core.telegram.org/bots/api#getavailablegifts
6284+
6285+
:return: On success, a Gifts object is returned.
6286+
:rtype: :class:`telebot.types.Gifts`
6287+
"""
6288+
return types.Gifts.de_json(
6289+
apihelper.get_available_gifts(self.token)
6290+
)
62026291

62036292
def replace_sticker_in_set(self, user_id: int, name: str, old_sticker: str, sticker: types.InputSticker) -> bool:
62046293
"""
@@ -6718,6 +6807,42 @@ def answer_web_app_query(self, web_app_query_id: str, result: types.InlineQueryR
67186807
"""
67196808
return apihelper.answer_web_app_query(self.token, web_app_query_id, result)
67206809

6810+
def save_prepared_inline_message(
6811+
self, user_id: int, result: types.InlineQueryResultBase, allow_user_chats: Optional[bool]=None,
6812+
allow_bot_chats: Optional[bool]=None, allow_group_chats: Optional[bool]=None,
6813+
allow_channel_chats: Optional[bool]=None) -> types.PreparedInlineMessage:
6814+
"""
6815+
Use this method to store a message that can be sent by a user of a Mini App.
6816+
Returns a PreparedInlineMessage object.
6817+
6818+
Telegram Documentation: https://core.telegram.org/bots/api#savepreparedinlinemessage
6819+
6820+
:param user_id: Unique identifier of the target user that can use the prepared message
6821+
:type user_id: :obj:`int`
6822+
6823+
:param result: A JSON-serialized object describing the message to be sent
6824+
:type result: :class:`telebot.types.InlineQueryResultBase`
6825+
6826+
:param allow_user_chats: Pass True if the message can be sent to private chats with users
6827+
:type allow_user_chats: :obj:`bool`
6828+
6829+
:param allow_bot_chats: Pass True if the message can be sent to private chats with bots
6830+
:type allow_bot_chats: :obj:`bool`
6831+
6832+
:param allow_group_chats: Pass True if the message can be sent to group and supergroup chats
6833+
:type allow_group_chats: :obj:`bool`
6834+
6835+
:param allow_channel_chats: Pass True if the message can be sent to channel chats
6836+
:type allow_channel_chats: :obj:`bool`
6837+
6838+
:return: On success, a PreparedInlineMessage object is returned.
6839+
:rtype: :class:`telebot.types.PreparedInlineMessage`
6840+
"""
6841+
return types.PreparedInlineMessage.de_json(
6842+
apihelper.save_prepared_inline_message(
6843+
self.token, user_id, result, allow_user_chats=allow_user_chats, allow_bot_chats=allow_bot_chats,
6844+
allow_group_chats=allow_group_chats, allow_channel_chats=allow_channel_chats)
6845+
)
67216846

67226847
def register_for_reply(self, message: types.Message, callback: Callable, *args, **kwargs) -> None:
67236848
"""

telebot/apihelper.py

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,16 @@ def get_user_profile_photos(token, user_id, offset=None, limit=None):
341341
payload['limit'] = limit
342342
return _make_request(token, method_url, params=payload)
343343

344+
345+
def set_user_emoji_status(token, user_id, emoji_status_custom_emoji_id=None, emoji_status_expiration_date=None):
346+
method_url = r'setUserEmojiStatus'
347+
payload = {'user_id': user_id}
348+
if emoji_status_custom_emoji_id:
349+
payload['emoji_status_custom_emoji_id'] = emoji_status_custom_emoji_id
350+
if emoji_status_expiration_date:
351+
payload['emoji_status_expiration_date'] = emoji_status_expiration_date
352+
return _make_request(token, method_url, params=payload)
353+
344354
def set_message_reaction(token, chat_id, message_id, reaction=None, is_big=None):
345355
method_url = r'setMessageReaction'
346356
payload = {'chat_id': chat_id, 'message_id': message_id}
@@ -1805,6 +1815,11 @@ def refund_star_payment(token, user_id, telegram_payment_charge_id):
18051815
payload = {'user_id': user_id, 'telegram_payment_charge_id': telegram_payment_charge_id}
18061816
return _make_request(token, method_url, params=payload)
18071817

1818+
def edit_user_star_subscription(token, user_id, telegram_payment_charge_id, is_canceled):
1819+
method_url = 'editUserStarSubscription'
1820+
payload = {'user_id': user_id, 'telegram_payment_charge_id': telegram_payment_charge_id, 'is_canceled': is_canceled}
1821+
return _make_request(token, method_url, params=payload)
1822+
18081823

18091824
def unpin_all_general_forum_topic_messages(token, chat_id):
18101825
method_url = 'unpinAllGeneralForumTopicMessages'
@@ -1909,6 +1924,22 @@ def delete_sticker_set(token, name):
19091924
return _make_request(token, method_url, params=payload, method='post')
19101925

19111926

1927+
def get_available_gifts(token):
1928+
method_url = 'getAvailableGifts'
1929+
return _make_request(token, method_url)
1930+
1931+
1932+
def send_gift(token, user_id, gift_id, text=None, text_parse_mode=None, text_entities=None):
1933+
method_url = 'sendGift'
1934+
payload = {'user_id': user_id, 'gift_id': gift_id}
1935+
if text:
1936+
payload['text'] = text
1937+
if text_parse_mode:
1938+
payload['text_parse_mode'] = text_parse_mode
1939+
if text_entities:
1940+
payload['text_entities'] = json.dumps(types.MessageEntity.to_list_of_dicts(text_entities))
1941+
return _make_request(token, method_url, params=payload, method='post')
1942+
19121943
def set_sticker_emoji_list(token, sticker, emoji_list):
19131944
method_url = 'setStickerEmojiList'
19141945
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
19661997
return _make_request(token, method_url, params=payload, method='post')
19671998

19681999

2000+
def save_prepared_inline_message(token, user_id, result: types.InlineQueryResultBase, allow_user_chats=None,
2001+
allow_bot_chats=None, allow_group_chats=None, allow_channel_chats=None):
2002+
method_url = 'savePreparedInlineMessage'
2003+
payload = {'user_id': user_id, 'result': result.to_json()}
2004+
if allow_user_chats is not None:
2005+
payload['allow_user_chats'] = allow_user_chats
2006+
if allow_bot_chats is not None:
2007+
payload['allow_bot_chats'] = allow_bot_chats
2008+
if allow_group_chats is not None:
2009+
payload['allow_group_chats'] = allow_group_chats
2010+
if allow_channel_chats is not None:
2011+
payload['allow_channel_chats'] = allow_channel_chats
2012+
return _make_request(token, method_url, params=payload, method='post')
2013+
2014+
19692015
def create_invoice_link(token, title, description, payload, provider_token,
19702016
currency, prices, max_tip_amount=None, suggested_tip_amounts=None, provider_data=None,
19712017
photo_url=None, photo_size=None, photo_width=None, photo_height=None, need_name=None, need_phone_number=None,
19722018
need_email=None, need_shipping_address=None, send_phone_number_to_provider=None,
1973-
send_email_to_provider=None, is_flexible=None):
2019+
send_email_to_provider=None, is_flexible=None, subscription_period=None, business_connection_id=None):
19742020
method_url = r'createInvoiceLink'
19752021
payload = {'title': title, 'description': description, 'payload': payload,
19762022
'currency': currency, 'prices': _convert_list_json_serializable(prices)}
@@ -2004,6 +2050,10 @@ def create_invoice_link(token, title, description, payload, provider_token,
20042050
payload['is_flexible'] = is_flexible
20052051
if provider_token is not None:
20062052
payload['provider_token'] = provider_token
2053+
if subscription_period:
2054+
payload['subscription_period'] = subscription_period
2055+
if business_connection_id:
2056+
payload['business_connection_id'] = business_connection_id
20072057
return _make_request(token, method_url, params=payload, method='post')
20082058

20092059

0 commit comments

Comments
 (0)