Skip to content

Commit 6aab790

Browse files
authored
Merge pull request #2395 from coder2020official/botapi-710
bot API 7.10
2 parents 290b8d3 + 3759a95 commit 6aab790

File tree

9 files changed

+239
-47
lines changed

9 files changed

+239
-47
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#august-14-2024"><img src="https://img.shields.io/badge/Bot%20API-7.9-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#september-6-2024"><img src="https://img.shields.io/badge/Bot%20API-7.10-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: 68 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,7 @@ def __init__(
248248
self.business_message_handlers = []
249249
self.edited_business_message_handlers = []
250250
self.deleted_business_messages_handlers = []
251+
self.purchased_paid_media_handlers = []
251252

252253
self.custom_filters = {}
253254
self.state_handlers = []
@@ -724,6 +725,7 @@ def process_new_updates(self, updates: List[types.Update]):
724725
new_business_messages = None
725726
new_edited_business_messages = None
726727
new_deleted_business_messages = None
728+
new_purchased_paid_media = None
727729

728730
for update in updates:
729731
if apihelper.ENABLE_MIDDLEWARE and not self.use_class_middlewares:
@@ -805,8 +807,10 @@ def process_new_updates(self, updates: List[types.Update]):
805807
if update.deleted_business_messages:
806808
if new_deleted_business_messages is None: new_deleted_business_messages = []
807809
new_deleted_business_messages.append(update.deleted_business_messages)
808-
809-
810+
if update.purchased_paid_media:
811+
if new_purchased_paid_media is None: new_purchased_paid_media = []
812+
new_purchased_paid_media.append(update.purchased_paid_media)
813+
810814
if new_messages:
811815
self.process_new_messages(new_messages)
812816
if new_edited_messages:
@@ -851,6 +855,8 @@ def process_new_updates(self, updates: List[types.Update]):
851855
self.process_new_edited_business_message(new_edited_business_messages)
852856
if new_deleted_business_messages:
853857
self.process_new_deleted_business_messages(new_deleted_business_messages)
858+
if new_purchased_paid_media:
859+
self.process_new_purchased_paid_media(new_purchased_paid_media)
854860

855861
def process_new_messages(self, new_messages):
856862
"""
@@ -987,8 +993,11 @@ def process_new_deleted_business_messages(self, new_deleted_business_messages):
987993
"""
988994
self._notify_command_handlers(self.deleted_business_messages_handlers, new_deleted_business_messages, 'deleted_business_messages')
989995

990-
991-
996+
def process_new_purchased_paid_media(self, new_purchased_paid_media):
997+
"""
998+
:meta private:
999+
"""
1000+
self._notify_command_handlers(self.purchased_paid_media_handlers, new_purchased_paid_media, 'purchased_paid_media')
9921001

9931002
def process_middlewares(self, update):
9941003
"""
@@ -3137,6 +3146,7 @@ def send_paid_media(
31373146
show_caption_above_media: Optional[bool]=None, disable_notification: Optional[bool]=None,
31383147
protect_content: Optional[bool]=None, reply_parameters: Optional[types.ReplyParameters]=None,
31393148
reply_markup: Optional[REPLY_MARKUP_TYPES]=None, business_connection_id: Optional[str]=None,
3149+
payload: Optional[str]=None
31403150
) -> types.Message:
31413151
"""
31423152
Use this method to send paid media to channel chats. On success, the sent Message is returned.
@@ -3179,6 +3189,9 @@ def send_paid_media(
31793189
:param business_connection_id: Identifier of a business connection, in which the message will be sent
31803190
:type business_connection_id: :obj:`str`
31813191
3192+
:param payload: Bot-defined paid media payload, 0-128 bytes. This will not be displayed to the user, use it for your internal processes.
3193+
:type payload: :obj:`str`
3194+
31823195
:return: On success, the sent Message is returned.
31833196
:rtype: :class:`telebot.types.Message`
31843197
"""
@@ -3187,7 +3200,8 @@ def send_paid_media(
31873200
self.token, chat_id, star_count, media, caption=caption, parse_mode=parse_mode,
31883201
caption_entities=caption_entities, show_caption_above_media=show_caption_above_media,
31893202
disable_notification=disable_notification, protect_content=protect_content,
3190-
reply_parameters=reply_parameters, reply_markup=reply_markup, business_connection_id=business_connection_id)
3203+
reply_parameters=reply_parameters, reply_markup=reply_markup, business_connection_id=business_connection_id,
3204+
payload=payload)
31913205
)
31923206

31933207

@@ -8035,6 +8049,55 @@ def register_pre_checkout_query_handler(self, callback: Callable, func: Callable
80358049
handler_dict = self._build_handler_dict(callback, func=func, pass_bot=pass_bot, **kwargs)
80368050
self.add_pre_checkout_query_handler(handler_dict)
80378051

8052+
def purchased_paid_media_handler(self, func=None, **kwargs):
8053+
"""
8054+
Handles new incoming purchased paid media.
8055+
8056+
:param func: Function executed as a filter
8057+
:type func: :obj:`function`
8058+
8059+
:param kwargs: Optional keyword arguments(custom filters)
8060+
8061+
:return: None
8062+
"""
8063+
def decorator(handler):
8064+
handler_dict = self._build_handler_dict(handler, func=func, **kwargs)
8065+
self.add_purchased_paid_media_handler(handler_dict)
8066+
return handler
8067+
8068+
return decorator
8069+
8070+
def add_purchased_paid_media_handler(self, handler_dict):
8071+
"""
8072+
Adds a purchased paid media handler
8073+
Note that you should use register_purchased_paid_media_handler to add purchased_paid_media_handler to the bot.
8074+
8075+
:meta private:
8076+
8077+
:param handler_dict:
8078+
:return:
8079+
"""
8080+
self.purchased_paid_media_handlers.append(handler_dict)
8081+
8082+
def register_purchased_paid_media_handler(self, callback: Callable, func: Callable, pass_bot: Optional[bool]=False, **kwargs):
8083+
"""
8084+
Registers purchased paid media handler.
8085+
8086+
:param callback: function to be called
8087+
:type callback: :obj:`function`
8088+
8089+
:param func: Function executed as a filter
8090+
:type func: :obj:`function`
8091+
8092+
:param pass_bot: True if you need to pass TeleBot instance to handler(useful for separating handlers into different files)
8093+
:type pass_bot: :obj:`bool`
8094+
8095+
:param kwargs: Optional keyword arguments(custom filters)
8096+
8097+
:return: None
8098+
"""
8099+
handler_dict = self._build_handler_dict(callback, func=func, pass_bot=pass_bot, **kwargs)
8100+
self.add_purchased_paid_media_handler(handler_dict)
80388101

80398102
def poll_handler(self, func, **kwargs):
80408103
"""

telebot/apihelper.py

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -530,30 +530,32 @@ def send_paid_media(
530530
token, chat_id, star_count, media,
531531
caption=None, parse_mode=None, caption_entities=None, show_caption_above_media=None,
532532
disable_notification=None, protect_content=None, reply_parameters=None, reply_markup=None,
533-
business_connection_id=None):
533+
business_connection_id=None, payload=None):
534534
method_url = r'sendPaidMedia'
535535
media_json, files = convert_input_media_array(media)
536-
payload = {'chat_id': chat_id, 'star_count': star_count, 'media': media_json}
536+
_payload = {'chat_id': chat_id, 'star_count': star_count, 'media': media_json}
537537
if caption:
538-
payload['caption'] = caption
538+
_payload['caption'] = caption
539539
if parse_mode:
540-
payload['parse_mode'] = parse_mode
540+
_payload['parse_mode'] = parse_mode
541541
if caption_entities:
542-
payload['caption_entities'] = json.dumps(types.MessageEntity.to_list_of_dicts(caption_entities))
542+
_payload['caption_entities'] = json.dumps(types.MessageEntity.to_list_of_dicts(caption_entities))
543543
if show_caption_above_media is not None:
544-
payload['show_caption_above_media'] = show_caption_above_media
544+
_payload['show_caption_above_media'] = show_caption_above_media
545545
if disable_notification is not None:
546-
payload['disable_notification'] = disable_notification
546+
_payload['disable_notification'] = disable_notification
547547
if protect_content is not None:
548-
payload['protect_content'] = protect_content
548+
_payload['protect_content'] = protect_content
549549
if reply_parameters is not None:
550-
payload['reply_parameters'] = reply_parameters.to_json()
550+
_payload['reply_parameters'] = reply_parameters.to_json()
551551
if reply_markup:
552-
payload['reply_markup'] = _convert_markup(reply_markup)
552+
_payload['reply_markup'] = _convert_markup(reply_markup)
553553
if business_connection_id:
554-
payload['business_connection_id'] = business_connection_id
554+
_payload['business_connection_id'] = business_connection_id
555+
if payload:
556+
_payload['payload'] = payload
555557
return _make_request(
556-
token, method_url, params=payload,
558+
token, method_url, params=_payload,
557559
method='post' if files else 'get',
558560
files=files if files else None)
559561

telebot/async_telebot.py

Lines changed: 70 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,7 @@ def __init__(self, token: str, parse_mode: Optional[str]=None, offset: Optional[
183183
self.business_message_handlers = []
184184
self.edited_business_message_handlers = []
185185
self.deleted_business_messages_handlers = []
186+
self.purchased_paid_media_handlers = []
186187

187188
self.custom_filters = {}
188189
self.state_handlers = []
@@ -636,6 +637,7 @@ async def process_new_updates(self, updates: List[types.Update]):
636637
new_business_messages = None
637638
new_edited_business_messages = None
638639
new_deleted_business_messages = None
640+
new_purchased_paid_media = None
639641

640642

641643
for update in updates:
@@ -706,6 +708,9 @@ async def process_new_updates(self, updates: List[types.Update]):
706708
if update.deleted_business_messages:
707709
if new_deleted_business_messages is None: new_deleted_business_messages = []
708710
new_deleted_business_messages.append(update.deleted_business_messages)
711+
if update.purchased_paid_media:
712+
if new_purchased_paid_media is None: new_purchased_paid_media = []
713+
new_purchased_paid_media.append(update.purchased_paid_media)
709714

710715

711716
if new_messages:
@@ -750,6 +755,8 @@ async def process_new_updates(self, updates: List[types.Update]):
750755
await self.process_new_edited_business_message(new_edited_business_messages)
751756
if new_deleted_business_messages:
752757
await self.process_new_deleted_business_messages(new_deleted_business_messages)
758+
if new_purchased_paid_media:
759+
await self.process_new_purchased_paid_media(new_purchased_paid_media)
753760

754761
async def process_new_messages(self, new_messages):
755762
"""
@@ -884,6 +891,12 @@ async def process_new_deleted_business_messages(self, new_deleted_business_messa
884891
"""
885892
await self._process_updates(self.deleted_business_messages_handlers, new_deleted_business_messages, 'deleted_business_messages')
886893

894+
async def process_new_purchased_paid_media(self, new_purchased_paid_media):
895+
"""
896+
:meta private:
897+
"""
898+
await self._process_updates(self.purchased_paid_media_handlers, new_purchased_paid_media, 'purchased_paid_media')
899+
887900
async def _get_middlewares(self, update_type):
888901
"""
889902
:meta private:
@@ -1867,6 +1880,56 @@ def register_pre_checkout_query_handler(self, callback: Callable[[Any], Awaitabl
18671880
handler_dict = self._build_handler_dict(callback, func=func, pass_bot=pass_bot, **kwargs)
18681881
self.add_pre_checkout_query_handler(handler_dict)
18691882

1883+
def purchased_paid_media_handler(self, func=None, **kwargs):
1884+
"""
1885+
Handles new incoming purchased paid media.
1886+
1887+
:param func: Function executed as a filter
1888+
:type func: :obj:`function`
1889+
1890+
:param kwargs: Optional keyword arguments(custom filters)
1891+
1892+
:return: None
1893+
"""
1894+
def decorator(handler):
1895+
handler_dict = self._build_handler_dict(handler, func=func, **kwargs)
1896+
self.add_purchased_paid_media_handler(handler_dict)
1897+
return handler
1898+
1899+
return decorator
1900+
1901+
def add_purchased_paid_media_handler(self, handler_dict):
1902+
"""
1903+
Adds a purchased paid media handler
1904+
Note that you should use register_purchased_paid_media_handler to add purchased_paid_media_handler to the bot.
1905+
1906+
:meta private:
1907+
1908+
:param handler_dict:
1909+
:return:
1910+
"""
1911+
self.purchased_paid_media_handlers.append(handler_dict)
1912+
1913+
def register_purchased_paid_media_handler(self, callback: Callable, func: Callable, pass_bot: Optional[bool]=False, **kwargs):
1914+
"""
1915+
Registers purchased paid media handler.
1916+
1917+
:param callback: function to be called
1918+
:type callback: :obj:`function`
1919+
1920+
:param func: Function executed as a filter
1921+
:type func: :obj:`function`
1922+
1923+
:param pass_bot: True if you need to pass TeleBot instance to handler(useful for separating handlers into different files)
1924+
:type pass_bot: :obj:`bool`
1925+
1926+
:param kwargs: Optional keyword arguments(custom filters)
1927+
1928+
:return: None
1929+
"""
1930+
handler_dict = self._build_handler_dict(callback, func=func, pass_bot=pass_bot, **kwargs)
1931+
self.add_purchased_paid_media_handler(handler_dict)
1932+
18701933
def poll_handler(self, func, **kwargs):
18711934
"""
18721935
Handles new state of a poll. Bots receive only updates about stopped polls and polls, which are sent by the bot
@@ -4564,7 +4627,8 @@ async def send_paid_media(
45644627
caption: Optional[str]=None, parse_mode: Optional[str]=None, caption_entities: Optional[List[types.MessageEntity]]=None,
45654628
show_caption_above_media: Optional[bool]=None, disable_notification: Optional[bool]=None,
45664629
protect_content: Optional[bool]=None, reply_parameters: Optional[types.ReplyParameters]=None,
4567-
reply_markup: Optional[REPLY_MARKUP_TYPES]=None, business_connection_id: Optional[str]=None) -> types.Message:
4630+
reply_markup: Optional[REPLY_MARKUP_TYPES]=None, business_connection_id: Optional[str]=None,
4631+
payload: Optional[str]=None) -> types.Message:
45684632
"""
45694633
Use this method to send paid media to channel chats. On success, the sent Message is returned.
45704634
@@ -4606,6 +4670,9 @@ async def send_paid_media(
46064670
:param business_connection_id: Identifier of a business connection, in which the message will be sent
46074671
:type business_connection_id: :obj:`str`
46084672
4673+
:param payload: Bot-defined paid media payload, 0-128 bytes. This will not be displayed to the user, use it for your internal processes.
4674+
:type payload: :obj:`str`
4675+
46094676
:return: On success, the sent Message is returned.
46104677
:rtype: :class:`telebot.types.Message`
46114678
"""
@@ -4614,7 +4681,8 @@ async def send_paid_media(
46144681
self.token, chat_id, star_count, media, caption=caption, parse_mode=parse_mode,
46154682
caption_entities=caption_entities, show_caption_above_media=show_caption_above_media,
46164683
disable_notification=disable_notification, protect_content=protect_content,
4617-
reply_parameters=reply_parameters, reply_markup=reply_markup, business_connection_id=business_connection_id))
4684+
reply_parameters=reply_parameters, reply_markup=reply_markup, business_connection_id=business_connection_id,
4685+
payload=payload))
46184686

46194687
async def send_media_group(
46204688
self, chat_id: Union[int, str],

telebot/asyncio_helper.py

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -520,30 +520,34 @@ async def send_paid_media(
520520
token, chat_id, star_count, media,
521521
caption=None, parse_mode=None, caption_entities=None, show_caption_above_media=None,
522522
disable_notification=None, protect_content=None, reply_parameters=None, reply_markup=None,
523-
business_connection_id=None):
523+
business_connection_id=None, payload=None):
524524
method_url = r'sendPaidMedia'
525525
media_json, files = convert_input_media_array(media)
526-
payload = {'chat_id': chat_id, 'star_count': star_count, 'media': media_json}
526+
_payload = {'chat_id': chat_id, 'star_count': star_count, 'media': media_json}
527+
# USE _payload for request payload
527528
if caption:
528-
payload['caption'] = caption
529+
_payload['caption'] = caption
529530
if parse_mode:
530-
payload['parse_mode'] = parse_mode
531+
_payload['parse_mode'] = parse_mode
531532
if caption_entities:
532-
payload['caption_entities'] = json.dumps(types.MessageEntity.to_list_of_dicts(caption_entities))
533+
_payload['caption_entities'] = json.dumps(types.MessageEntity.to_list_of_dicts(caption_entities))
533534
if show_caption_above_media is not None:
534-
payload['show_caption_above_media'] = show_caption_above_media
535+
_payload['show_caption_above_media'] = show_caption_above_media
535536
if disable_notification is not None:
536-
payload['disable_notification'] = disable_notification
537+
_payload['disable_notification'] = disable_notification
537538
if protect_content is not None:
538-
payload['protect_content'] = protect_content
539+
_payload['protect_content'] = protect_content
539540
if reply_parameters is not None:
540-
payload['reply_parameters'] = reply_parameters.to_json()
541+
_payload['reply_parameters'] = reply_parameters.to_json()
541542
if reply_markup:
542-
payload['reply_markup'] = _convert_markup(reply_markup)
543+
_payload['reply_markup'] = _convert_markup(reply_markup)
543544
if business_connection_id:
544-
payload['business_connection_id'] = business_connection_id
545+
_payload['business_connection_id'] = business_connection_id
546+
if payload:
547+
_payload['payload'] = payload
548+
545549
return await _process_request(
546-
token, method_url, params=payload,
550+
token, method_url, params=_payload,
547551
method='post' if files else 'get',
548552
files=files if files else None)
549553

0 commit comments

Comments
 (0)