diff --git a/README.md b/README.md
index 5f70cad2f..1959744fa 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:
diff --git a/telebot/__init__.py b/telebot/__init__.py
index 95b6cca46..a79c2ea50 100644
--- a/telebot/__init__.py
+++ b/telebot/__init__.py
@@ -248,6 +248,7 @@ def __init__(
self.business_message_handlers = []
self.edited_business_message_handlers = []
self.deleted_business_messages_handlers = []
+ self.purchased_paid_media_handlers = []
self.custom_filters = {}
self.state_handlers = []
@@ -724,6 +725,7 @@ def process_new_updates(self, updates: List[types.Update]):
new_business_messages = None
new_edited_business_messages = None
new_deleted_business_messages = None
+ new_purchased_paid_media = None
for update in updates:
if apihelper.ENABLE_MIDDLEWARE and not self.use_class_middlewares:
@@ -805,8 +807,10 @@ def process_new_updates(self, updates: List[types.Update]):
if update.deleted_business_messages:
if new_deleted_business_messages is None: new_deleted_business_messages = []
new_deleted_business_messages.append(update.deleted_business_messages)
-
-
+ if update.purchased_paid_media:
+ if new_purchased_paid_media is None: new_purchased_paid_media = []
+ new_purchased_paid_media.append(update.purchased_paid_media)
+
if new_messages:
self.process_new_messages(new_messages)
if new_edited_messages:
@@ -851,6 +855,8 @@ def process_new_updates(self, updates: List[types.Update]):
self.process_new_edited_business_message(new_edited_business_messages)
if new_deleted_business_messages:
self.process_new_deleted_business_messages(new_deleted_business_messages)
+ if new_purchased_paid_media:
+ self.process_new_purchased_paid_media(new_purchased_paid_media)
def process_new_messages(self, new_messages):
"""
@@ -987,8 +993,11 @@ def process_new_deleted_business_messages(self, new_deleted_business_messages):
"""
self._notify_command_handlers(self.deleted_business_messages_handlers, new_deleted_business_messages, 'deleted_business_messages')
-
-
+ def process_new_purchased_paid_media(self, new_purchased_paid_media):
+ """
+ :meta private:
+ """
+ self._notify_command_handlers(self.purchased_paid_media_handlers, new_purchased_paid_media, 'purchased_paid_media')
def process_middlewares(self, update):
"""
@@ -3137,6 +3146,7 @@ def send_paid_media(
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, business_connection_id: Optional[str]=None,
+ payload: Optional[str]=None
) -> types.Message:
"""
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(
:param business_connection_id: Identifier of a business connection, in which the message will be sent
:type business_connection_id: :obj:`str`
+ :param payload: Bot-defined paid media payload, 0-128 bytes. This will not be displayed to the user, use it for your internal processes.
+ :type payload: :obj:`str`
+
:return: On success, the sent Message is returned.
:rtype: :class:`telebot.types.Message`
"""
@@ -3187,7 +3200,8 @@ 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, business_connection_id=business_connection_id)
+ reply_parameters=reply_parameters, reply_markup=reply_markup, business_connection_id=business_connection_id,
+ payload=payload)
)
@@ -8035,6 +8049,55 @@ def register_pre_checkout_query_handler(self, callback: Callable, func: Callable
handler_dict = self._build_handler_dict(callback, func=func, pass_bot=pass_bot, **kwargs)
self.add_pre_checkout_query_handler(handler_dict)
+ def purchased_paid_media_handler(self, func=None, **kwargs):
+ """
+ Handles new incoming purchased paid media.
+
+ :param func: Function executed as a filter
+ :type func: :obj:`function`
+
+ :param kwargs: Optional keyword arguments(custom filters)
+
+ :return: None
+ """
+ def decorator(handler):
+ handler_dict = self._build_handler_dict(handler, func=func, **kwargs)
+ self.add_purchased_paid_media_handler(handler_dict)
+ return handler
+
+ return decorator
+
+ def add_purchased_paid_media_handler(self, handler_dict):
+ """
+ Adds a purchased paid media handler
+ Note that you should use register_purchased_paid_media_handler to add purchased_paid_media_handler to the bot.
+
+ :meta private:
+
+ :param handler_dict:
+ :return:
+ """
+ self.purchased_paid_media_handlers.append(handler_dict)
+
+ def register_purchased_paid_media_handler(self, callback: Callable, func: Callable, pass_bot: Optional[bool]=False, **kwargs):
+ """
+ Registers purchased paid media handler.
+
+ :param callback: function to be called
+ :type callback: :obj:`function`
+
+ :param func: Function executed as a filter
+ :type func: :obj:`function`
+
+ :param pass_bot: True if you need to pass TeleBot instance to handler(useful for separating handlers into different files)
+ :type pass_bot: :obj:`bool`
+
+ :param kwargs: Optional keyword arguments(custom filters)
+
+ :return: None
+ """
+ handler_dict = self._build_handler_dict(callback, func=func, pass_bot=pass_bot, **kwargs)
+ self.add_purchased_paid_media_handler(handler_dict)
def poll_handler(self, func, **kwargs):
"""
diff --git a/telebot/apihelper.py b/telebot/apihelper.py
index bc15e9316..c46b108c8 100644
--- a/telebot/apihelper.py
+++ b/telebot/apihelper.py
@@ -530,30 +530,32 @@ 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,
- business_connection_id=None):
+ business_connection_id=None, payload=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}
+ _payload = {'chat_id': chat_id, 'star_count': star_count, 'media': media_json}
if caption:
- payload['caption'] = caption
+ _payload['caption'] = caption
if parse_mode:
- payload['parse_mode'] = parse_mode
+ _payload['parse_mode'] = parse_mode
if caption_entities:
- payload['caption_entities'] = json.dumps(types.MessageEntity.to_list_of_dicts(caption_entities))
+ _payload['caption_entities'] = json.dumps(types.MessageEntity.to_list_of_dicts(caption_entities))
if show_caption_above_media is not None:
- payload['show_caption_above_media'] = show_caption_above_media
+ _payload['show_caption_above_media'] = show_caption_above_media
if disable_notification is not None:
- payload['disable_notification'] = disable_notification
+ _payload['disable_notification'] = disable_notification
if protect_content is not None:
- payload['protect_content'] = protect_content
+ _payload['protect_content'] = protect_content
if reply_parameters is not None:
- payload['reply_parameters'] = reply_parameters.to_json()
+ _payload['reply_parameters'] = reply_parameters.to_json()
if reply_markup:
- payload['reply_markup'] = _convert_markup(reply_markup)
+ _payload['reply_markup'] = _convert_markup(reply_markup)
if business_connection_id:
- payload['business_connection_id'] = business_connection_id
+ _payload['business_connection_id'] = business_connection_id
+ if payload:
+ _payload['payload'] = payload
return _make_request(
- token, method_url, params=payload,
+ token, method_url, params=_payload,
method='post' if files else 'get',
files=files if files else None)
diff --git a/telebot/async_telebot.py b/telebot/async_telebot.py
index 4a71772a4..ef35d109a 100644
--- a/telebot/async_telebot.py
+++ b/telebot/async_telebot.py
@@ -183,6 +183,7 @@ def __init__(self, token: str, parse_mode: Optional[str]=None, offset: Optional[
self.business_message_handlers = []
self.edited_business_message_handlers = []
self.deleted_business_messages_handlers = []
+ self.purchased_paid_media_handlers = []
self.custom_filters = {}
self.state_handlers = []
@@ -636,6 +637,7 @@ async def process_new_updates(self, updates: List[types.Update]):
new_business_messages = None
new_edited_business_messages = None
new_deleted_business_messages = None
+ new_purchased_paid_media = None
for update in updates:
@@ -706,6 +708,9 @@ async def process_new_updates(self, updates: List[types.Update]):
if update.deleted_business_messages:
if new_deleted_business_messages is None: new_deleted_business_messages = []
new_deleted_business_messages.append(update.deleted_business_messages)
+ if update.purchased_paid_media:
+ if new_purchased_paid_media is None: new_purchased_paid_media = []
+ new_purchased_paid_media.append(update.purchased_paid_media)
if new_messages:
@@ -750,6 +755,8 @@ async def process_new_updates(self, updates: List[types.Update]):
await self.process_new_edited_business_message(new_edited_business_messages)
if new_deleted_business_messages:
await self.process_new_deleted_business_messages(new_deleted_business_messages)
+ if new_purchased_paid_media:
+ await self.process_new_purchased_paid_media(new_purchased_paid_media)
async def process_new_messages(self, new_messages):
"""
@@ -884,6 +891,12 @@ async def process_new_deleted_business_messages(self, new_deleted_business_messa
"""
await self._process_updates(self.deleted_business_messages_handlers, new_deleted_business_messages, 'deleted_business_messages')
+ async def process_new_purchased_paid_media(self, new_purchased_paid_media):
+ """
+ :meta private:
+ """
+ await self._process_updates(self.purchased_paid_media_handlers, new_purchased_paid_media, 'purchased_paid_media')
+
async def _get_middlewares(self, update_type):
"""
:meta private:
@@ -1867,6 +1880,56 @@ def register_pre_checkout_query_handler(self, callback: Callable[[Any], Awaitabl
handler_dict = self._build_handler_dict(callback, func=func, pass_bot=pass_bot, **kwargs)
self.add_pre_checkout_query_handler(handler_dict)
+ def purchased_paid_media_handler(self, func=None, **kwargs):
+ """
+ Handles new incoming purchased paid media.
+
+ :param func: Function executed as a filter
+ :type func: :obj:`function`
+
+ :param kwargs: Optional keyword arguments(custom filters)
+
+ :return: None
+ """
+ def decorator(handler):
+ handler_dict = self._build_handler_dict(handler, func=func, **kwargs)
+ self.add_purchased_paid_media_handler(handler_dict)
+ return handler
+
+ return decorator
+
+ def add_purchased_paid_media_handler(self, handler_dict):
+ """
+ Adds a purchased paid media handler
+ Note that you should use register_purchased_paid_media_handler to add purchased_paid_media_handler to the bot.
+
+ :meta private:
+
+ :param handler_dict:
+ :return:
+ """
+ self.purchased_paid_media_handlers.append(handler_dict)
+
+ def register_purchased_paid_media_handler(self, callback: Callable, func: Callable, pass_bot: Optional[bool]=False, **kwargs):
+ """
+ Registers purchased paid media handler.
+
+ :param callback: function to be called
+ :type callback: :obj:`function`
+
+ :param func: Function executed as a filter
+ :type func: :obj:`function`
+
+ :param pass_bot: True if you need to pass TeleBot instance to handler(useful for separating handlers into different files)
+ :type pass_bot: :obj:`bool`
+
+ :param kwargs: Optional keyword arguments(custom filters)
+
+ :return: None
+ """
+ handler_dict = self._build_handler_dict(callback, func=func, pass_bot=pass_bot, **kwargs)
+ self.add_purchased_paid_media_handler(handler_dict)
+
def poll_handler(self, func, **kwargs):
"""
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(
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, business_connection_id: Optional[str]=None) -> types.Message:
+ reply_markup: Optional[REPLY_MARKUP_TYPES]=None, business_connection_id: Optional[str]=None,
+ payload: Optional[str]=None) -> types.Message:
"""
Use this method to send paid media to channel chats. On success, the sent Message is returned.
@@ -4606,6 +4670,9 @@ async def send_paid_media(
:param business_connection_id: Identifier of a business connection, in which the message will be sent
:type business_connection_id: :obj:`str`
+ :param payload: Bot-defined paid media payload, 0-128 bytes. This will not be displayed to the user, use it for your internal processes.
+ :type payload: :obj:`str`
+
:return: On success, the sent Message is returned.
:rtype: :class:`telebot.types.Message`
"""
@@ -4614,7 +4681,8 @@ 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, business_connection_id=business_connection_id))
+ reply_parameters=reply_parameters, reply_markup=reply_markup, business_connection_id=business_connection_id,
+ payload=payload))
async def send_media_group(
self, chat_id: Union[int, str],
diff --git a/telebot/asyncio_helper.py b/telebot/asyncio_helper.py
index c31bf53da..0bd447f18 100644
--- a/telebot/asyncio_helper.py
+++ b/telebot/asyncio_helper.py
@@ -520,30 +520,34 @@ 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,
- business_connection_id=None):
+ business_connection_id=None, payload=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}
+ _payload = {'chat_id': chat_id, 'star_count': star_count, 'media': media_json}
+ # USE _payload for request payload
if caption:
- payload['caption'] = caption
+ _payload['caption'] = caption
if parse_mode:
- payload['parse_mode'] = parse_mode
+ _payload['parse_mode'] = parse_mode
if caption_entities:
- payload['caption_entities'] = json.dumps(types.MessageEntity.to_list_of_dicts(caption_entities))
+ _payload['caption_entities'] = json.dumps(types.MessageEntity.to_list_of_dicts(caption_entities))
if show_caption_above_media is not None:
- payload['show_caption_above_media'] = show_caption_above_media
+ _payload['show_caption_above_media'] = show_caption_above_media
if disable_notification is not None:
- payload['disable_notification'] = disable_notification
+ _payload['disable_notification'] = disable_notification
if protect_content is not None:
- payload['protect_content'] = protect_content
+ _payload['protect_content'] = protect_content
if reply_parameters is not None:
- payload['reply_parameters'] = reply_parameters.to_json()
+ _payload['reply_parameters'] = reply_parameters.to_json()
if reply_markup:
- payload['reply_markup'] = _convert_markup(reply_markup)
+ _payload['reply_markup'] = _convert_markup(reply_markup)
if business_connection_id:
- payload['business_connection_id'] = business_connection_id
+ _payload['business_connection_id'] = business_connection_id
+ if payload:
+ _payload['payload'] = payload
+
return await _process_request(
- token, method_url, params=payload,
+ token, method_url, params=_payload,
method='post' if files else 'get',
files=files if files else None)
diff --git a/telebot/types.py b/telebot/types.py
index 8b4c30469..043473aee 100644
--- a/telebot/types.py
+++ b/telebot/types.py
@@ -153,6 +153,9 @@ class Update(JsonDeserializable):
checkout
:type pre_checkout_query: :class:`telebot.types.PreCheckoutQuery`
+ :purchased_paid_media: Optional. A user purchased paid media with a non-empty payload sent by the bot in a non-channel chat
+ :type purchased_paid_media: :class:`telebot.types.PaidMediaPurchased`
+
:param poll: Optional. New poll state. Bots receive only updates about stopped polls and polls, which are sent by the
bot
:type poll: :class:`telebot.types.Poll`
@@ -222,18 +225,19 @@ def de_json(cls, json_string):
business_message = Message.de_json(obj.get('business_message'))
edited_business_message = Message.de_json(obj.get('edited_business_message'))
deleted_business_messages = BusinessMessagesDeleted.de_json(obj.get('deleted_business_messages'))
+ purchased_paid_media = PaidMediaPurchased.de_json(obj.get('purchased_paid_media'))
return cls(update_id, message, edited_message, channel_post, edited_channel_post, inline_query,
chosen_inline_result, callback_query, shipping_query, pre_checkout_query, poll, poll_answer,
my_chat_member, chat_member, chat_join_request, message_reaction, message_reaction_count,
removed_chat_boost, chat_boost, business_connection, business_message, edited_business_message,
- deleted_business_messages)
+ deleted_business_messages, purchased_paid_media)
def __init__(self, update_id, message, edited_message, channel_post, edited_channel_post, inline_query,
chosen_inline_result, callback_query, shipping_query, pre_checkout_query, poll, poll_answer,
my_chat_member, chat_member, chat_join_request, message_reaction, message_reaction_count,
removed_chat_boost, chat_boost, business_connection, business_message, edited_business_message,
- deleted_business_messages, **kwargs):
+ deleted_business_messages, purchased_paid_media):
self.update_id: int = update_id
self.message: Optional[Message] = message
self.edited_message: Optional[Message] = edited_message
@@ -257,6 +261,7 @@ def __init__(self, update_id, message, edited_message, channel_post, edited_chan
self.business_message: Optional[Message] = business_message
self.edited_business_message: Optional[Message] = edited_business_message
self.deleted_business_messages: Optional[BusinessMessagesDeleted] = deleted_business_messages
+ self.purchased_paid_media: Optional[PaidMediaPurchased] = purchased_paid_media
@@ -8989,6 +8994,9 @@ class Giveaway(JsonDeserializable):
:param country_codes: Optional. A list of two-letter ISO 3166-1 alpha-2 country codes indicating the countries from which eligible users for the giveaway must come. If empty, then all users can participate in the giveaway.
:type country_codes: :obj:`list` of :obj:`str`
+ :param prize_star_count: Optional. The number of Telegram Stars to be split between giveaway winners; for Telegram Star giveaways only
+ :type prize_star_count: :obj:`int`
+
:param premium_subscription_month_count: Optional. The number of months the Telegram Premium subscription won from the giveaway will be active for
:type premium_subscription_month_count: :obj:`int`
@@ -9006,7 +9014,7 @@ def de_json(cls, json_string):
def __init__(self, chats: List[Chat], winners_selection_date: int, winner_count: int,
only_new_members: Optional[bool] = None, has_public_winners: Optional[bool] = None,
prize_description: Optional[str] = None, country_codes: Optional[List[str]] = None,
- premium_subscription_month_count: Optional[int] = None, **kwargs) -> None:
+ premium_subscription_month_count: Optional[int] = None, prize_star_count: Optional[int] = None, **kwargs) -> None:
self.chats: List[Chat] = chats
self.winners_selection_date: int = winners_selection_date
self.winner_count: int = winner_count
@@ -9015,6 +9023,7 @@ def __init__(self, chats: List[Chat], winners_selection_date: int, winner_count:
self.prize_description: Optional[str] = prize_description
self.country_codes: Optional[List[str]] = country_codes
self.premium_subscription_month_count: Optional[int] = premium_subscription_month_count
+ self.prize_star_count: Optional[int] = prize_star_count
class GiveawayWinners(JsonDeserializable):
@@ -9056,6 +9065,9 @@ class GiveawayWinners(JsonDeserializable):
:param prize_description: Optional. Description of additional giveaway prize
:type prize_description: :obj:`str`
+ :param prize_star_count: Optional. The number of Telegram Stars to be split between giveaway winners; for Telegram Star giveaways only
+ :type prize_star_count: :obj:`int`
+
:return: Instance of the class
:rtype: :class:`GiveawayWinners`
"""
@@ -9072,7 +9084,7 @@ def __init__(self, chat: Chat, giveaway_message_id: int, winners_selection_date:
winners: List[User], additional_chat_count: Optional[int] = None,
premium_subscription_month_count: Optional[int] = None, unclaimed_prize_count: Optional[int] = None,
only_new_members: Optional[bool] = None, was_refunded: Optional[bool] = None,
- prize_description: Optional[str] = None, **kwargs) -> None:
+ prize_description: Optional[str] = None, prize_star_count: Optional[int] = None, **kwargs) -> None:
self.chat: Chat = chat
self.giveaway_message_id: int = giveaway_message_id
self.winners_selection_date: int = winners_selection_date
@@ -9084,6 +9096,7 @@ def __init__(self, chat: Chat, giveaway_message_id: int, winners_selection_date:
self.only_new_members: Optional[bool] = only_new_members
self.was_refunded: Optional[bool] = was_refunded
self.prize_description: Optional[str] = prize_description
+ self.prize_star_count: Optional[int] = prize_star_count
class GiveawayCompleted(JsonDeserializable):
@@ -9101,6 +9114,9 @@ class GiveawayCompleted(JsonDeserializable):
:param giveaway_message: Optional. Message with the giveaway that was completed, if it wasn't deleted
:type giveaway_message: :class:`Message`
+ :param is_star_giveaway: Optional. True, if the giveaway was a Telegram Star giveaway
+ :type is_star_giveaway: :obj:`bool`
+
:return: Instance of the class
:rtype: :class:`GiveawayCompleted`
"""
@@ -9114,15 +9130,21 @@ def de_json(cls, json_string):
return cls(**obj)
def __init__(self, winner_count: int, unclaimed_prize_count: Optional[int] = None,
- giveaway_message: Optional[Message] = None, **kwargs) -> None:
+ giveaway_message: Optional[Message] = None, is_star_giveaway: Optional[bool] = None, **kwargs) -> None:
self.winner_count: int = winner_count
self.unclaimed_prize_count: Optional[int] = unclaimed_prize_count
self.giveaway_message: Optional[Message] = giveaway_message
+ self.is_star_giveaway: Optional[bool] = is_star_giveaway
class GiveawayCreated(JsonDeserializable):
"""
- This object represents a service message about the creation of a scheduled giveaway. Currently holds no information.
+ This object represents a service message about the creation of a scheduled giveaway.
+
+ :prize_star_count: Optional. The number of Telegram Stars to be split between giveaway winners; for Telegram Star giveaways only
+ :type prize_star_count: :obj:`int`
+
+ :return: Instance of the class
"""
@classmethod
@@ -9131,8 +9153,8 @@ def de_json(cls, json_string):
obj = cls.check_json(json_string)
return cls(**obj)
- def __init__(self, **kwargs) -> None:
- pass
+ def __init__(self, prize_star_count=None, **kwargs) -> None:
+ self.prize_star_count: Optional[str] = prize_star_count
class TextQuote(JsonDeserializable):
@@ -9463,6 +9485,9 @@ class ChatBoostSourceGiveaway(ChatBoostSource):
:param is_unclaimed: True, if the giveaway was completed, but there was no user to win the prize
:type is_unclaimed: :obj:`bool`
+ :param prize_star_count: Optional. The number of Telegram Stars to be split between giveaway winners; for Telegram Star giveaways only
+ :type prize_star_count: :obj:`int`
+
:return: Instance of the class
:rtype: :class:`ChatBoostSourceGiveaway`
"""
@@ -9474,11 +9499,12 @@ def de_json(cls, json_string):
obj['user'] = User.de_json(obj.get('user'))
return cls(**obj)
- def __init__(self, source, giveaway_message_id, user=None, is_unclaimed=None, **kwargs):
+ def __init__(self, source, giveaway_message_id, user=None, is_unclaimed=None, prize_star_count=None, **kwargs):
self.source: str = source
self.giveaway_message_id: int = giveaway_message_id
- self.user: User = user
- self.is_unclaimed: bool = is_unclaimed
+ self.user: Optional[User] = user
+ self.is_unclaimed: Optional[bool] = is_unclaimed
+ self.prize_star_count: Optional[int] = prize_star_count
class ChatBoost(JsonDeserializable):
@@ -10857,3 +10883,30 @@ def de_json(cls, json_string):
return cls(**obj)
+class PaidMediaPurchased(JsonDeserializable):
+ """
+ This object contains information about a paid media purchase.
+
+ Telegram documentation: https://core.telegram.org/bots/api#paidmediapurchased
+
+ :param from_user: User who purchased the media
+ :type from_user: :class:`User`
+
+ :param paid_media_payload: Bot-specified paid media payload
+ :type paid_media_payload: :obj:`str`
+
+ :return: Instance of the class
+ :rtype: :class:`PaidMediaPurchased`
+ """
+
+ def __init__(self, from_user, paid_media_payload, **kwargs):
+ self.from_user: User = from_user
+ self.paid_media_payload: str = paid_media_payload
+
+ @classmethod
+ def de_json(cls, json_string):
+ if json_string is None: return None
+ obj = cls.check_json(json_string)
+ obj['from_user'] = User.de_json(obj['from_user'])
+ return cls(**obj)
+
diff --git a/telebot/util.py b/telebot/util.py
index 0448893e1..bed0e8c19 100644
--- a/telebot/util.py
+++ b/telebot/util.py
@@ -48,7 +48,7 @@
"message", "edited_message", "channel_post", "edited_channel_post", "inline_query", "chosen_inline_result",
"callback_query", "shipping_query", "pre_checkout_query", "poll", "poll_answer", "my_chat_member", "chat_member",
"chat_join_request", "message_reaction", "message_reaction_count", "chat_boost", "removed_chat_boost",
- "business_connection", "business_message", "edited_business_message", "deleted_business_messages"
+ "business_connection", "business_message", "edited_business_message", "deleted_business_messages", "purchased_paid_media"
]
diff --git a/tests/test_handler_backends.py b/tests/test_handler_backends.py
index b74d6fad0..4df760ebc 100644
--- a/tests/test_handler_backends.py
+++ b/tests/test_handler_backends.py
@@ -71,7 +71,7 @@ def update_type(message):
chat_boost_removed = None
return types.Update(1001234038283, message, edited_message, channel_post, edited_channel_post, inline_query,
chosen_inline_result, callback_query, shipping_query, pre_checkout_query, poll, poll_answer,
- my_chat_member, chat_member, chat_join_request, message_reaction, message_reaction_count, chat_boost, chat_boost_removed, None, None, None, None)
+ my_chat_member, chat_member, chat_join_request, message_reaction, message_reaction_count, chat_boost, chat_boost_removed, None, None, None, None, None)
@pytest.fixture()
@@ -95,7 +95,7 @@ def reply_to_message_update_type(reply_to_message):
chat_boost_removed = None
return types.Update(1001234038284, reply_to_message, edited_message, channel_post, edited_channel_post,
inline_query, chosen_inline_result, callback_query, shipping_query, pre_checkout_query,
- poll, poll_answer, my_chat_member, chat_member, chat_join_request, message_reaction, message_reaction_count, chat_boost, chat_boost_removed, None, None, None, None)
+ poll, poll_answer, my_chat_member, chat_member, chat_join_request, message_reaction, message_reaction_count, chat_boost, chat_boost_removed, None, None, None, None, None)
def next_handler(message):
diff --git a/tests/test_telebot.py b/tests/test_telebot.py
index 52adbc2fe..8b04ac402 100644
--- a/tests/test_telebot.py
+++ b/tests/test_telebot.py
@@ -546,9 +546,11 @@ def create_message_update(text):
message_reaction_count = None
chat_boost = None
chat_boost_removed = None
+ purchased_paid_media = None
return types.Update(-1001234038283, message, edited_message, channel_post, edited_channel_post, inline_query,
chosen_inline_result, callback_query, shipping_query, pre_checkout_query, poll, poll_answer,
- my_chat_member, chat_member, chat_join_request, message_reaction, message_reaction_count, chat_boost, chat_boost_removed)
+ my_chat_member, chat_member, chat_join_request, message_reaction, message_reaction_count, chat_boost, chat_boost_removed,
+ purchased_paid_media)
def test_is_string_unicode(self):
s1 = u'string'