mirror of
https://github.com/python-telegram-bot/python-telegram-bot.git
synced 2024-11-21 14:46:29 +01:00
Co-authored-by: aelkheir <90580077+aelkheir@users.noreply.github.com> Co-authored-by: Bibo-Joshi <22366557+Bibo-Joshi@users.noreply.github.com>
This commit is contained in:
parent
9248c539d0
commit
67a97ae5a7
26 changed files with 668 additions and 81 deletions
|
@ -11,7 +11,7 @@
|
||||||
:target: https://pypi.org/project/python-telegram-bot/
|
:target: https://pypi.org/project/python-telegram-bot/
|
||||||
:alt: Supported Python versions
|
:alt: Supported Python versions
|
||||||
|
|
||||||
.. image:: https://img.shields.io/badge/Bot%20API-7.9-blue?logo=telegram
|
.. image:: https://img.shields.io/badge/Bot%20API-7.10-blue?logo=telegram
|
||||||
:target: https://core.telegram.org/bots/api-changelog
|
:target: https://core.telegram.org/bots/api-changelog
|
||||||
:alt: Supported Bot API version
|
:alt: Supported Bot API version
|
||||||
|
|
||||||
|
@ -81,7 +81,7 @@ After installing_ the library, be sure to check out the section on `working with
|
||||||
Telegram API support
|
Telegram API support
|
||||||
~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
All types and methods of the Telegram Bot API **7.9** are natively supported by this library.
|
All types and methods of the Telegram Bot API **7.10** are natively supported by this library.
|
||||||
In addition, Bot API functionality not yet natively included can still be used as described `in our wiki <https://github.com/python-telegram-bot/python-telegram-bot/wiki/Bot-API-Forward-Compatibility>`_.
|
In addition, Bot API functionality not yet natively included can still be used as described `in our wiki <https://github.com/python-telegram-bot/python-telegram-bot/wiki/Bot-API-Forward-Compatibility>`_.
|
||||||
|
|
||||||
Notable Features
|
Notable Features
|
||||||
|
|
|
@ -120,6 +120,7 @@ Available Types
|
||||||
telegram.paidmediainfo
|
telegram.paidmediainfo
|
||||||
telegram.paidmediaphoto
|
telegram.paidmediaphoto
|
||||||
telegram.paidmediapreview
|
telegram.paidmediapreview
|
||||||
|
telegram.paidmediapurchased
|
||||||
telegram.paidmediavideo
|
telegram.paidmediavideo
|
||||||
telegram.photosize
|
telegram.photosize
|
||||||
telegram.poll
|
telegram.poll
|
||||||
|
|
|
@ -18,6 +18,7 @@ Handlers
|
||||||
telegram.ext.inlinequeryhandler
|
telegram.ext.inlinequeryhandler
|
||||||
telegram.ext.messagehandler
|
telegram.ext.messagehandler
|
||||||
telegram.ext.messagereactionhandler
|
telegram.ext.messagereactionhandler
|
||||||
|
telegram.ext.paidmediapurchasedhandler
|
||||||
telegram.ext.pollanswerhandler
|
telegram.ext.pollanswerhandler
|
||||||
telegram.ext.pollhandler
|
telegram.ext.pollhandler
|
||||||
telegram.ext.precheckoutqueryhandler
|
telegram.ext.precheckoutqueryhandler
|
||||||
|
|
6
docs/source/telegram.ext.paidmediapurchasedhandler.rst
Normal file
6
docs/source/telegram.ext.paidmediapurchasedhandler.rst
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
PaidMediaPurchasedHandler
|
||||||
|
=========================
|
||||||
|
|
||||||
|
.. autoclass:: telegram.ext.PaidMediaPurchasedHandler
|
||||||
|
:members:
|
||||||
|
:show-inheritance:
|
6
docs/source/telegram.paidmediapurchased.rst
Normal file
6
docs/source/telegram.paidmediapurchased.rst
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
PaidMediaPurchased
|
||||||
|
==================
|
||||||
|
|
||||||
|
.. autoclass:: telegram.PaidMediaPurchased
|
||||||
|
:members:
|
||||||
|
:show-inheritance:
|
|
@ -180,6 +180,7 @@ __all__ = (
|
||||||
"PaidMediaInfo",
|
"PaidMediaInfo",
|
||||||
"PaidMediaPhoto",
|
"PaidMediaPhoto",
|
||||||
"PaidMediaPreview",
|
"PaidMediaPreview",
|
||||||
|
"PaidMediaPurchased",
|
||||||
"PaidMediaVideo",
|
"PaidMediaVideo",
|
||||||
"PassportData",
|
"PassportData",
|
||||||
"PassportElementError",
|
"PassportElementError",
|
||||||
|
@ -419,7 +420,14 @@ from ._messageorigin import (
|
||||||
MessageOriginUser,
|
MessageOriginUser,
|
||||||
)
|
)
|
||||||
from ._messagereactionupdated import MessageReactionCountUpdated, MessageReactionUpdated
|
from ._messagereactionupdated import MessageReactionCountUpdated, MessageReactionUpdated
|
||||||
from ._paidmedia import PaidMedia, PaidMediaInfo, PaidMediaPhoto, PaidMediaPreview, PaidMediaVideo
|
from ._paidmedia import (
|
||||||
|
PaidMedia,
|
||||||
|
PaidMediaInfo,
|
||||||
|
PaidMediaPhoto,
|
||||||
|
PaidMediaPreview,
|
||||||
|
PaidMediaPurchased,
|
||||||
|
PaidMediaVideo,
|
||||||
|
)
|
||||||
from ._passport.credentials import (
|
from ._passport.credentials import (
|
||||||
Credentials,
|
Credentials,
|
||||||
DataCredentials,
|
DataCredentials,
|
||||||
|
|
|
@ -9193,6 +9193,7 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
||||||
reply_parameters: Optional["ReplyParameters"] = None,
|
reply_parameters: Optional["ReplyParameters"] = None,
|
||||||
reply_markup: Optional[ReplyMarkup] = None,
|
reply_markup: Optional[ReplyMarkup] = None,
|
||||||
business_connection_id: Optional[str] = None,
|
business_connection_id: Optional[str] = None,
|
||||||
|
payload: Optional[str] = None,
|
||||||
*,
|
*,
|
||||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||||
reply_to_message_id: Optional[int] = None,
|
reply_to_message_id: Optional[int] = None,
|
||||||
|
@ -9211,9 +9212,15 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
||||||
Telegram Star proceeds from this media will be credited to the chat's balance.
|
Telegram Star proceeds from this media will be credited to the chat's balance.
|
||||||
Otherwise, they will be credited to the bot's balance.
|
Otherwise, they will be credited to the bot's balance.
|
||||||
star_count (:obj:`int`): The number of Telegram Stars that must be paid to buy access
|
star_count (:obj:`int`): The number of Telegram Stars that must be paid to buy access
|
||||||
to the media.
|
to the media; :tg-const:`telegram.constants.InvoiceLimit.MIN_STAR_COUNT` -
|
||||||
|
:tg-const:`telegram.constants.InvoiceLimit.MAX_STAR_COUNT`.
|
||||||
media (Sequence[:class:`telegram.InputPaidMedia`]): A list describing the media to be
|
media (Sequence[:class:`telegram.InputPaidMedia`]): A list describing the media to be
|
||||||
sent; up to :tg-const:`telegram.constants.MediaGroupLimit.MAX_MEDIA_LENGTH` items.
|
sent; up to :tg-const:`telegram.constants.MediaGroupLimit.MAX_MEDIA_LENGTH` items.
|
||||||
|
payload (:obj:`str`, optional): Bot-defined paid media payload,
|
||||||
|
0-:tg-const:`telegram.constants.InvoiceLimit.MAX_PAYLOAD_LENGTH` bytes. This will
|
||||||
|
not be displayed to the user, use it for your internal processes.
|
||||||
|
|
||||||
|
.. versionadded:: NEXT.VERSION
|
||||||
caption (:obj:`str`, optional): Caption of the media to be sent,
|
caption (:obj:`str`, optional): Caption of the media to be sent,
|
||||||
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters.
|
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters.
|
||||||
parse_mode (:obj:`str`, optional): |parse_mode|
|
parse_mode (:obj:`str`, optional): |parse_mode|
|
||||||
|
@ -9252,6 +9259,7 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
||||||
"star_count": star_count,
|
"star_count": star_count,
|
||||||
"media": media,
|
"media": media,
|
||||||
"show_caption_above_media": show_caption_above_media,
|
"show_caption_above_media": show_caption_above_media,
|
||||||
|
"payload": payload,
|
||||||
}
|
}
|
||||||
|
|
||||||
return await self._send_message(
|
return await self._send_message(
|
||||||
|
|
|
@ -3350,6 +3350,7 @@ class _ChatBase(TelegramObject):
|
||||||
reply_parameters: Optional["ReplyParameters"] = None,
|
reply_parameters: Optional["ReplyParameters"] = None,
|
||||||
reply_markup: Optional[ReplyMarkup] = None,
|
reply_markup: Optional[ReplyMarkup] = None,
|
||||||
business_connection_id: Optional[str] = None,
|
business_connection_id: Optional[str] = None,
|
||||||
|
payload: Optional[str] = None,
|
||||||
*,
|
*,
|
||||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||||
reply_to_message_id: Optional[int] = None,
|
reply_to_message_id: Optional[int] = None,
|
||||||
|
@ -3391,6 +3392,7 @@ class _ChatBase(TelegramObject):
|
||||||
pool_timeout=pool_timeout,
|
pool_timeout=pool_timeout,
|
||||||
api_kwargs=api_kwargs,
|
api_kwargs=api_kwargs,
|
||||||
business_connection_id=business_connection_id,
|
business_connection_id=business_connection_id,
|
||||||
|
payload=payload,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -187,15 +187,22 @@ class ChatBoostSourceGiftCode(ChatBoostSource):
|
||||||
|
|
||||||
class ChatBoostSourceGiveaway(ChatBoostSource):
|
class ChatBoostSourceGiveaway(ChatBoostSource):
|
||||||
"""
|
"""
|
||||||
The boost was obtained by the creation of a Telegram Premium giveaway. This boosts the chat 4
|
The boost was obtained by the creation of a Telegram Premium giveaway or a Telegram Star.
|
||||||
times for the duration of the corresponding Telegram Premium subscription.
|
This boosts the chat 4 times for the duration of the corresponding Telegram Premium
|
||||||
|
subscription for Telegram Premium giveaways and :attr:`prize_star_count` / 500 times for
|
||||||
|
one year for Telegram Star giveaways.
|
||||||
|
|
||||||
.. versionadded:: 20.8
|
.. versionadded:: 20.8
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
giveaway_message_id (:obj:`int`): Identifier of a message in the chat with the giveaway;
|
giveaway_message_id (:obj:`int`): Identifier of a message in the chat with the giveaway;
|
||||||
the message could have been deleted already. May be 0 if the message isn't sent yet.
|
the message could have been deleted already. May be 0 if the message isn't sent yet.
|
||||||
user (:class:`telegram.User`, optional): User that won the prize in the giveaway if any.
|
user (:class:`telegram.User`, optional): User that won the prize in the giveaway if any;
|
||||||
|
for Telegram Premium giveaways only.
|
||||||
|
prize_star_count (:obj:`int`, optional): The number of Telegram Stars to be split between
|
||||||
|
giveaway winners; for Telegram Star giveaways only.
|
||||||
|
|
||||||
|
.. versionadded:: NEXT.VERSION
|
||||||
is_unclaimed (:obj:`bool`, optional): :obj:`True`, if the giveaway was completed, but
|
is_unclaimed (:obj:`bool`, optional): :obj:`True`, if the giveaway was completed, but
|
||||||
there was no user to win the prize.
|
there was no user to win the prize.
|
||||||
|
|
||||||
|
@ -205,17 +212,22 @@ class ChatBoostSourceGiveaway(ChatBoostSource):
|
||||||
giveaway_message_id (:obj:`int`): Identifier of a message in the chat with the giveaway;
|
giveaway_message_id (:obj:`int`): Identifier of a message in the chat with the giveaway;
|
||||||
the message could have been deleted already. May be 0 if the message isn't sent yet.
|
the message could have been deleted already. May be 0 if the message isn't sent yet.
|
||||||
user (:class:`telegram.User`): Optional. User that won the prize in the giveaway if any.
|
user (:class:`telegram.User`): Optional. User that won the prize in the giveaway if any.
|
||||||
|
prize_star_count (:obj:`int`): Optional. The number of Telegram Stars to be split between
|
||||||
|
giveaway winners; for Telegram Star giveaways only.
|
||||||
|
|
||||||
|
.. versionadded:: NEXT.VERSION
|
||||||
is_unclaimed (:obj:`bool`): Optional. :obj:`True`, if the giveaway was completed, but
|
is_unclaimed (:obj:`bool`): Optional. :obj:`True`, if the giveaway was completed, but
|
||||||
there was no user to win the prize.
|
there was no user to win the prize.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = ("giveaway_message_id", "is_unclaimed", "user")
|
__slots__ = ("giveaway_message_id", "is_unclaimed", "prize_star_count", "user")
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
giveaway_message_id: int,
|
giveaway_message_id: int,
|
||||||
user: Optional[User] = None,
|
user: Optional[User] = None,
|
||||||
is_unclaimed: Optional[bool] = None,
|
is_unclaimed: Optional[bool] = None,
|
||||||
|
prize_star_count: Optional[int] = None,
|
||||||
*,
|
*,
|
||||||
api_kwargs: Optional[JSONDict] = None,
|
api_kwargs: Optional[JSONDict] = None,
|
||||||
):
|
):
|
||||||
|
@ -224,6 +236,7 @@ class ChatBoostSourceGiveaway(ChatBoostSource):
|
||||||
with self._unfrozen():
|
with self._unfrozen():
|
||||||
self.giveaway_message_id: int = giveaway_message_id
|
self.giveaway_message_id: int = giveaway_message_id
|
||||||
self.user: Optional[User] = user
|
self.user: Optional[User] = user
|
||||||
|
self.prize_star_count: Optional[int] = prize_star_count
|
||||||
self.is_unclaimed: Optional[bool] = is_unclaimed
|
self.is_unclaimed: Optional[bool] = is_unclaimed
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -56,8 +56,13 @@ class Giveaway(TelegramObject):
|
||||||
country codes indicating the countries from which eligible users for the giveaway must
|
country codes indicating the countries from which eligible users for the giveaway must
|
||||||
come. If empty, then all users can participate in the giveaway. Users with a phone
|
come. If empty, then all users can participate in the giveaway. Users with a phone
|
||||||
number that was bought on Fragment can always participate in giveaways.
|
number that was bought on Fragment can always participate in giveaways.
|
||||||
|
prize_star_count (:obj:`int`, optional): The number of Telegram Stars to be split between
|
||||||
|
giveaway winners; for Telegram Star giveaways only.
|
||||||
|
|
||||||
|
.. versionadded:: NEXT.VERSION
|
||||||
premium_subscription_month_count (:obj:`int`, optional): The number of months the Telegram
|
premium_subscription_month_count (:obj:`int`, optional): The number of months the Telegram
|
||||||
Premium subscription won from the giveaway will be active for.
|
Premium subscription won from the giveaway will be active for; for Telegram Premium
|
||||||
|
giveaways only.
|
||||||
|
|
||||||
Attributes:
|
Attributes:
|
||||||
chats (Sequence[:class:`telegram.Chat`]): The list of chats which the user must join to
|
chats (Sequence[:class:`telegram.Chat`]): The list of chats which the user must join to
|
||||||
|
@ -75,8 +80,13 @@ class Giveaway(TelegramObject):
|
||||||
country codes indicating the countries from which eligible users for the giveaway must
|
country codes indicating the countries from which eligible users for the giveaway must
|
||||||
come. If empty, then all users can participate in the giveaway. Users with a phone
|
come. If empty, then all users can participate in the giveaway. Users with a phone
|
||||||
number that was bought on Fragment can always participate in giveaways.
|
number that was bought on Fragment can always participate in giveaways.
|
||||||
|
prize_star_count (:obj:`int`): Optional. The number of Telegram Stars to be split between
|
||||||
|
giveaway winners; for Telegram Star giveaways only.
|
||||||
|
|
||||||
|
.. versionadded:: NEXT.VERSION
|
||||||
premium_subscription_month_count (:obj:`int`): Optional. The number of months the Telegram
|
premium_subscription_month_count (:obj:`int`): Optional. The number of months the Telegram
|
||||||
Premium subscription won from the giveaway will be active for.
|
Premium subscription won from the giveaway will be active for; for Telegram Premium
|
||||||
|
giveaways only.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = (
|
__slots__ = (
|
||||||
|
@ -86,6 +96,7 @@ class Giveaway(TelegramObject):
|
||||||
"only_new_members",
|
"only_new_members",
|
||||||
"premium_subscription_month_count",
|
"premium_subscription_month_count",
|
||||||
"prize_description",
|
"prize_description",
|
||||||
|
"prize_star_count",
|
||||||
"winner_count",
|
"winner_count",
|
||||||
"winners_selection_date",
|
"winners_selection_date",
|
||||||
)
|
)
|
||||||
|
@ -100,6 +111,7 @@ class Giveaway(TelegramObject):
|
||||||
prize_description: Optional[str] = None,
|
prize_description: Optional[str] = None,
|
||||||
country_codes: Optional[Sequence[str]] = None,
|
country_codes: Optional[Sequence[str]] = None,
|
||||||
premium_subscription_month_count: Optional[int] = None,
|
premium_subscription_month_count: Optional[int] = None,
|
||||||
|
prize_star_count: Optional[int] = None,
|
||||||
*,
|
*,
|
||||||
api_kwargs: Optional[JSONDict] = None,
|
api_kwargs: Optional[JSONDict] = None,
|
||||||
):
|
):
|
||||||
|
@ -113,6 +125,7 @@ class Giveaway(TelegramObject):
|
||||||
self.prize_description: Optional[str] = prize_description
|
self.prize_description: Optional[str] = prize_description
|
||||||
self.country_codes: Tuple[str, ...] = parse_sequence_arg(country_codes)
|
self.country_codes: Tuple[str, ...] = parse_sequence_arg(country_codes)
|
||||||
self.premium_subscription_month_count: Optional[int] = premium_subscription_month_count
|
self.premium_subscription_month_count: Optional[int] = premium_subscription_month_count
|
||||||
|
self.prize_star_count: Optional[int] = prize_star_count
|
||||||
|
|
||||||
self._id_attrs = (
|
self._id_attrs = (
|
||||||
self.chats,
|
self.chats,
|
||||||
|
@ -145,13 +158,28 @@ class Giveaway(TelegramObject):
|
||||||
|
|
||||||
class GiveawayCreated(TelegramObject):
|
class GiveawayCreated(TelegramObject):
|
||||||
"""This object represents a service message about the creation of a scheduled giveaway.
|
"""This object represents a service message about the creation of a scheduled giveaway.
|
||||||
Currently holds no information.
|
|
||||||
|
Args:
|
||||||
|
prize_star_count (:obj:`int`, optional): The number of Telegram Stars to be
|
||||||
|
split between giveaway winners; for Telegram Star giveaways only.
|
||||||
|
|
||||||
|
.. versionadded:: NEXT.VERSION
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
prize_star_count (:obj:`int`): Optional. The number of Telegram Stars to be
|
||||||
|
split between giveaway winners; for Telegram Star giveaways only.
|
||||||
|
|
||||||
|
.. versionadded:: NEXT.VERSION
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = ()
|
__slots__ = ("prize_star_count",)
|
||||||
|
|
||||||
def __init__(self, *, api_kwargs: Optional[JSONDict] = None):
|
def __init__(
|
||||||
|
self, prize_star_count: Optional[int] = None, *, api_kwargs: Optional[JSONDict] = None
|
||||||
|
):
|
||||||
super().__init__(api_kwargs=api_kwargs)
|
super().__init__(api_kwargs=api_kwargs)
|
||||||
|
self.prize_star_count: Optional[int] = prize_star_count
|
||||||
|
|
||||||
self._freeze()
|
self._freeze()
|
||||||
|
|
||||||
|
@ -173,6 +201,10 @@ class GiveawayWinners(TelegramObject):
|
||||||
winner_count (:obj:`int`): Total number of winners in the giveaway
|
winner_count (:obj:`int`): Total number of winners in the giveaway
|
||||||
winners (Sequence[:class:`telegram.User`]): List of up to
|
winners (Sequence[:class:`telegram.User`]): List of up to
|
||||||
:tg-const:`telegram.constants.GiveawayLimit.MAX_WINNERS` winners of the giveaway
|
:tg-const:`telegram.constants.GiveawayLimit.MAX_WINNERS` winners of the giveaway
|
||||||
|
prize_star_count (:obj:`int`, optional): The number of Telegram Stars to be split between
|
||||||
|
giveaway winners; for Telegram Star giveaways only.
|
||||||
|
|
||||||
|
.. versionadded:: NEXT.VERSION
|
||||||
additional_chat_count (:obj:`int`, optional): The number of other chats the user had to
|
additional_chat_count (:obj:`int`, optional): The number of other chats the user had to
|
||||||
join in order to be eligible for the giveaway
|
join in order to be eligible for the giveaway
|
||||||
premium_subscription_month_count (:obj:`int`, optional): The number of months the Telegram
|
premium_subscription_month_count (:obj:`int`, optional): The number of months the Telegram
|
||||||
|
@ -194,6 +226,10 @@ class GiveawayWinners(TelegramObject):
|
||||||
:tg-const:`telegram.constants.GiveawayLimit.MAX_WINNERS` winners of the giveaway
|
:tg-const:`telegram.constants.GiveawayLimit.MAX_WINNERS` winners of the giveaway
|
||||||
additional_chat_count (:obj:`int`): Optional. The number of other chats the user had to
|
additional_chat_count (:obj:`int`): Optional. The number of other chats the user had to
|
||||||
join in order to be eligible for the giveaway
|
join in order to be eligible for the giveaway
|
||||||
|
prize_star_count (:obj:`int`): Optional. The number of Telegram Stars to be split between
|
||||||
|
giveaway winners; for Telegram Star giveaways only.
|
||||||
|
|
||||||
|
.. versionadded:: NEXT.VERSION
|
||||||
premium_subscription_month_count (:obj:`int`): Optional. The number of months the Telegram
|
premium_subscription_month_count (:obj:`int`): Optional. The number of months the Telegram
|
||||||
Premium subscription won from the giveaway will be active for
|
Premium subscription won from the giveaway will be active for
|
||||||
unclaimed_prize_count (:obj:`int`): Optional. Number of undistributed prizes
|
unclaimed_prize_count (:obj:`int`): Optional. Number of undistributed prizes
|
||||||
|
@ -211,6 +247,7 @@ class GiveawayWinners(TelegramObject):
|
||||||
"only_new_members",
|
"only_new_members",
|
||||||
"premium_subscription_month_count",
|
"premium_subscription_month_count",
|
||||||
"prize_description",
|
"prize_description",
|
||||||
|
"prize_star_count",
|
||||||
"unclaimed_prize_count",
|
"unclaimed_prize_count",
|
||||||
"was_refunded",
|
"was_refunded",
|
||||||
"winner_count",
|
"winner_count",
|
||||||
|
@ -231,6 +268,7 @@ class GiveawayWinners(TelegramObject):
|
||||||
only_new_members: Optional[bool] = None,
|
only_new_members: Optional[bool] = None,
|
||||||
was_refunded: Optional[bool] = None,
|
was_refunded: Optional[bool] = None,
|
||||||
prize_description: Optional[str] = None,
|
prize_description: Optional[str] = None,
|
||||||
|
prize_star_count: Optional[int] = None,
|
||||||
*,
|
*,
|
||||||
api_kwargs: Optional[JSONDict] = None,
|
api_kwargs: Optional[JSONDict] = None,
|
||||||
):
|
):
|
||||||
|
@ -247,6 +285,7 @@ class GiveawayWinners(TelegramObject):
|
||||||
self.only_new_members: Optional[bool] = only_new_members
|
self.only_new_members: Optional[bool] = only_new_members
|
||||||
self.was_refunded: Optional[bool] = was_refunded
|
self.was_refunded: Optional[bool] = was_refunded
|
||||||
self.prize_description: Optional[str] = prize_description
|
self.prize_description: Optional[str] = prize_description
|
||||||
|
self.prize_star_count: Optional[int] = prize_star_count
|
||||||
|
|
||||||
self._id_attrs = (
|
self._id_attrs = (
|
||||||
self.chat,
|
self.chat,
|
||||||
|
@ -295,21 +334,29 @@ class GiveawayCompleted(TelegramObject):
|
||||||
unclaimed_prize_count (:obj:`int`, optional): Number of undistributed prizes
|
unclaimed_prize_count (:obj:`int`, optional): Number of undistributed prizes
|
||||||
giveaway_message (:class:`telegram.Message`, optional): Message with the giveaway that was
|
giveaway_message (:class:`telegram.Message`, optional): Message with the giveaway that was
|
||||||
completed, if it wasn't deleted
|
completed, if it wasn't deleted
|
||||||
|
is_star_giveaway (:obj:`bool`, optional): :obj:`True`, if the giveaway is a Telegram Star
|
||||||
|
giveaway. Otherwise, currently, the giveaway is a Telegram Premium giveaway.
|
||||||
|
|
||||||
|
.. versionadded:: NEXT.VERSION
|
||||||
Attributes:
|
Attributes:
|
||||||
winner_count (:obj:`int`): Number of winners in the giveaway
|
winner_count (:obj:`int`): Number of winners in the giveaway
|
||||||
unclaimed_prize_count (:obj:`int`): Optional. Number of undistributed prizes
|
unclaimed_prize_count (:obj:`int`): Optional. Number of undistributed prizes
|
||||||
giveaway_message (:class:`telegram.Message`): Optional. Message with the giveaway that was
|
giveaway_message (:class:`telegram.Message`): Optional. Message with the giveaway that was
|
||||||
completed, if it wasn't deleted
|
completed, if it wasn't deleted
|
||||||
|
is_star_giveaway (:obj:`bool`): Optional. :obj:`True`, if the giveaway is a Telegram Star
|
||||||
|
giveaway. Otherwise, currently, the giveaway is a Telegram Premium giveaway.
|
||||||
|
|
||||||
|
.. versionadded:: NEXT.VERSION
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = ("giveaway_message", "unclaimed_prize_count", "winner_count")
|
__slots__ = ("giveaway_message", "is_star_giveaway", "unclaimed_prize_count", "winner_count")
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
winner_count: int,
|
winner_count: int,
|
||||||
unclaimed_prize_count: Optional[int] = None,
|
unclaimed_prize_count: Optional[int] = None,
|
||||||
giveaway_message: Optional["Message"] = None,
|
giveaway_message: Optional["Message"] = None,
|
||||||
|
is_star_giveaway: Optional[bool] = None,
|
||||||
*,
|
*,
|
||||||
api_kwargs: Optional[JSONDict] = None,
|
api_kwargs: Optional[JSONDict] = None,
|
||||||
):
|
):
|
||||||
|
@ -318,6 +365,7 @@ class GiveawayCompleted(TelegramObject):
|
||||||
self.winner_count: int = winner_count
|
self.winner_count: int = winner_count
|
||||||
self.unclaimed_prize_count: Optional[int] = unclaimed_prize_count
|
self.unclaimed_prize_count: Optional[int] = unclaimed_prize_count
|
||||||
self.giveaway_message: Optional[Message] = giveaway_message
|
self.giveaway_message: Optional[Message] = giveaway_message
|
||||||
|
self.is_star_giveaway: Optional[bool] = is_star_giveaway
|
||||||
|
|
||||||
self._id_attrs = (
|
self._id_attrs = (
|
||||||
self.winner_count,
|
self.winner_count,
|
||||||
|
|
|
@ -24,6 +24,7 @@ from telegram import constants
|
||||||
from telegram._files.photosize import PhotoSize
|
from telegram._files.photosize import PhotoSize
|
||||||
from telegram._files.video import Video
|
from telegram._files.video import Video
|
||||||
from telegram._telegramobject import TelegramObject
|
from telegram._telegramobject import TelegramObject
|
||||||
|
from telegram._user import User
|
||||||
from telegram._utils import enum
|
from telegram._utils import enum
|
||||||
from telegram._utils.argumentparsing import parse_sequence_arg
|
from telegram._utils.argumentparsing import parse_sequence_arg
|
||||||
from telegram._utils.types import JSONDict
|
from telegram._utils.types import JSONDict
|
||||||
|
@ -288,3 +289,52 @@ class PaidMediaInfo(TelegramObject):
|
||||||
|
|
||||||
data["paid_media"] = PaidMedia.de_list(data.get("paid_media"), bot=bot)
|
data["paid_media"] = PaidMedia.de_list(data.get("paid_media"), bot=bot)
|
||||||
return super().de_json(data=data, bot=bot)
|
return super().de_json(data=data, bot=bot)
|
||||||
|
|
||||||
|
|
||||||
|
class PaidMediaPurchased(TelegramObject):
|
||||||
|
"""This object contains information about a paid media purchase.
|
||||||
|
|
||||||
|
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||||
|
considered equal, if their :attr:`from_user` and :attr:`paid_media_payload` are equal.
|
||||||
|
|
||||||
|
Note:
|
||||||
|
In Python :keyword:`from` is a reserved word. Use :paramref:`from_user` instead.
|
||||||
|
|
||||||
|
.. versionadded:: NEXT.VERSION
|
||||||
|
|
||||||
|
Args:
|
||||||
|
from_user (:class:`telegram.User`): User who purchased the media.
|
||||||
|
paid_media_payload (:obj:`str`): Bot-specified paid media payload.
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
from_user (:class:`telegram.User`): User who purchased the media.
|
||||||
|
paid_media_payload (:obj:`str`): Bot-specified paid media payload.
|
||||||
|
"""
|
||||||
|
|
||||||
|
__slots__ = ("from_user", "paid_media_payload")
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
from_user: "User",
|
||||||
|
paid_media_payload: str,
|
||||||
|
*,
|
||||||
|
api_kwargs: Optional[JSONDict] = None,
|
||||||
|
) -> None:
|
||||||
|
super().__init__(api_kwargs=api_kwargs)
|
||||||
|
self.from_user: User = from_user
|
||||||
|
self.paid_media_payload: str = paid_media_payload
|
||||||
|
|
||||||
|
self._id_attrs = (self.from_user, self.paid_media_payload)
|
||||||
|
self._freeze()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def de_json(
|
||||||
|
cls, data: Optional[JSONDict], bot: Optional["Bot"] = None
|
||||||
|
) -> Optional["PaidMediaPurchased"]:
|
||||||
|
data = cls._parse_data(data)
|
||||||
|
|
||||||
|
if not data:
|
||||||
|
return None
|
||||||
|
|
||||||
|
data["from_user"] = User.de_json(data=data.pop("from"), bot=bot)
|
||||||
|
return super().de_json(data=data, bot=bot)
|
||||||
|
|
|
@ -328,6 +328,9 @@ class TransactionPartnerUser(TransactionPartner):
|
||||||
media bought by the user.
|
media bought by the user.
|
||||||
|
|
||||||
.. versionadded:: 21.5
|
.. versionadded:: 21.5
|
||||||
|
paid_media_payload (:obj:`str`, optional): Optional. Bot-specified paid media payload.
|
||||||
|
|
||||||
|
.. versionadded:: NEXT.VERSION
|
||||||
|
|
||||||
Attributes:
|
Attributes:
|
||||||
type (:obj:`str`): The type of the transaction partner,
|
type (:obj:`str`): The type of the transaction partner,
|
||||||
|
@ -338,19 +341,20 @@ class TransactionPartnerUser(TransactionPartner):
|
||||||
media bought by the user.
|
media bought by the user.
|
||||||
|
|
||||||
.. versionadded:: 21.5
|
.. versionadded:: 21.5
|
||||||
|
paid_media_payload (:obj:`str`): Optional. Optional. Bot-specified paid media payload.
|
||||||
|
|
||||||
|
.. versionadded:: NEXT.VERSION
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = (
|
__slots__ = ("invoice_payload", "paid_media", "paid_media_payload", "user")
|
||||||
"invoice_payload",
|
|
||||||
"paid_media",
|
|
||||||
"user",
|
|
||||||
)
|
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
user: "User",
|
user: "User",
|
||||||
invoice_payload: Optional[str] = None,
|
invoice_payload: Optional[str] = None,
|
||||||
paid_media: Optional[Sequence[PaidMedia]] = None,
|
paid_media: Optional[Sequence[PaidMedia]] = None,
|
||||||
|
paid_media_payload: Optional[str] = None,
|
||||||
*,
|
*,
|
||||||
api_kwargs: Optional[JSONDict] = None,
|
api_kwargs: Optional[JSONDict] = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
|
@ -360,6 +364,7 @@ class TransactionPartnerUser(TransactionPartner):
|
||||||
self.user: User = user
|
self.user: User = user
|
||||||
self.invoice_payload: Optional[str] = invoice_payload
|
self.invoice_payload: Optional[str] = invoice_payload
|
||||||
self.paid_media: Optional[Tuple[PaidMedia, ...]] = parse_sequence_arg(paid_media)
|
self.paid_media: Optional[Tuple[PaidMedia, ...]] = parse_sequence_arg(paid_media)
|
||||||
|
self.paid_media_payload: Optional[str] = paid_media_payload
|
||||||
self._id_attrs = (
|
self._id_attrs = (
|
||||||
self.type,
|
self.type,
|
||||||
self.user,
|
self.user,
|
||||||
|
|
|
@ -30,6 +30,7 @@ from telegram._choseninlineresult import ChosenInlineResult
|
||||||
from telegram._inline.inlinequery import InlineQuery
|
from telegram._inline.inlinequery import InlineQuery
|
||||||
from telegram._message import Message
|
from telegram._message import Message
|
||||||
from telegram._messagereactionupdated import MessageReactionCountUpdated, MessageReactionUpdated
|
from telegram._messagereactionupdated import MessageReactionCountUpdated, MessageReactionUpdated
|
||||||
|
from telegram._paidmedia import PaidMediaPurchased
|
||||||
from telegram._payment.precheckoutquery import PreCheckoutQuery
|
from telegram._payment.precheckoutquery import PreCheckoutQuery
|
||||||
from telegram._payment.shippingquery import ShippingQuery
|
from telegram._payment.shippingquery import ShippingQuery
|
||||||
from telegram._poll import Poll, PollAnswer
|
from telegram._poll import Poll, PollAnswer
|
||||||
|
@ -156,6 +157,11 @@ class Update(TelegramObject):
|
||||||
|
|
||||||
.. versionadded:: 21.1
|
.. versionadded:: 21.1
|
||||||
|
|
||||||
|
purchased_paid_media (:class:`telegram.PaidMediaPurchased`, optional): A user purchased
|
||||||
|
paid media with a non-empty payload sent by the bot in a non-channel chat.
|
||||||
|
|
||||||
|
.. versionadded:: NEXT.VERSION
|
||||||
|
|
||||||
|
|
||||||
Attributes:
|
Attributes:
|
||||||
update_id (:obj:`int`): The update's unique identifier. Update identifiers start from a
|
update_id (:obj:`int`): The update's unique identifier. Update identifiers start from a
|
||||||
|
@ -263,6 +269,11 @@ class Update(TelegramObject):
|
||||||
were deleted from a connected business account.
|
were deleted from a connected business account.
|
||||||
|
|
||||||
.. versionadded:: 21.1
|
.. versionadded:: 21.1
|
||||||
|
|
||||||
|
purchased_paid_media (:class:`telegram.PaidMediaPurchased`): Optional. A user purchased
|
||||||
|
paid media with a non-empty payload sent by the bot in a non-channel chat.
|
||||||
|
|
||||||
|
.. versionadded:: NEXT.VERSION
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = (
|
__slots__ = (
|
||||||
|
@ -290,6 +301,7 @@ class Update(TelegramObject):
|
||||||
"poll",
|
"poll",
|
||||||
"poll_answer",
|
"poll_answer",
|
||||||
"pre_checkout_query",
|
"pre_checkout_query",
|
||||||
|
"purchased_paid_media",
|
||||||
"removed_chat_boost",
|
"removed_chat_boost",
|
||||||
"shipping_query",
|
"shipping_query",
|
||||||
"update_id",
|
"update_id",
|
||||||
|
@ -383,6 +395,13 @@ class Update(TelegramObject):
|
||||||
""":const:`telegram.constants.UpdateType.DELETED_BUSINESS_MESSAGES`
|
""":const:`telegram.constants.UpdateType.DELETED_BUSINESS_MESSAGES`
|
||||||
|
|
||||||
.. versionadded:: 21.1"""
|
.. versionadded:: 21.1"""
|
||||||
|
|
||||||
|
PURCHASED_PAID_MEDIA: Final[str] = constants.UpdateType.PURCHASED_PAID_MEDIA
|
||||||
|
""":const:`telegram.constants.UpdateType.PURCHASED_PAID_MEDIA`
|
||||||
|
|
||||||
|
.. versionadded:: NEXT.VERSION
|
||||||
|
"""
|
||||||
|
|
||||||
ALL_TYPES: Final[List[str]] = list(constants.UpdateType)
|
ALL_TYPES: Final[List[str]] = list(constants.UpdateType)
|
||||||
"""List[:obj:`str`]: A list of all available update types.
|
"""List[:obj:`str`]: A list of all available update types.
|
||||||
|
|
||||||
|
@ -413,6 +432,7 @@ class Update(TelegramObject):
|
||||||
business_message: Optional[Message] = None,
|
business_message: Optional[Message] = None,
|
||||||
edited_business_message: Optional[Message] = None,
|
edited_business_message: Optional[Message] = None,
|
||||||
deleted_business_messages: Optional[BusinessMessagesDeleted] = None,
|
deleted_business_messages: Optional[BusinessMessagesDeleted] = None,
|
||||||
|
purchased_paid_media: Optional[PaidMediaPurchased] = None,
|
||||||
*,
|
*,
|
||||||
api_kwargs: Optional[JSONDict] = None,
|
api_kwargs: Optional[JSONDict] = None,
|
||||||
):
|
):
|
||||||
|
@ -444,6 +464,7 @@ class Update(TelegramObject):
|
||||||
self.deleted_business_messages: Optional[BusinessMessagesDeleted] = (
|
self.deleted_business_messages: Optional[BusinessMessagesDeleted] = (
|
||||||
deleted_business_messages
|
deleted_business_messages
|
||||||
)
|
)
|
||||||
|
self.purchased_paid_media: Optional[PaidMediaPurchased] = purchased_paid_media
|
||||||
|
|
||||||
self._effective_user: Optional[User] = None
|
self._effective_user: Optional[User] = None
|
||||||
self._effective_sender: Optional[Union[User, Chat]] = None
|
self._effective_sender: Optional[Union[User, Chat]] = None
|
||||||
|
@ -475,6 +496,9 @@ class Update(TelegramObject):
|
||||||
This property now also considers :attr:`business_connection`, :attr:`business_message`
|
This property now also considers :attr:`business_connection`, :attr:`business_message`
|
||||||
and :attr:`edited_business_message`.
|
and :attr:`edited_business_message`.
|
||||||
|
|
||||||
|
.. versionchanged:: NEXT.VERSION
|
||||||
|
This property now also considers :attr:`purchased_paid_media`.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
* If :attr:`message` is present, this will give
|
* If :attr:`message` is present, this will give
|
||||||
:attr:`telegram.Message.from_user`.
|
:attr:`telegram.Message.from_user`.
|
||||||
|
@ -531,6 +555,9 @@ class Update(TelegramObject):
|
||||||
elif self.business_connection:
|
elif self.business_connection:
|
||||||
user = self.business_connection.user
|
user = self.business_connection.user
|
||||||
|
|
||||||
|
elif self.purchased_paid_media:
|
||||||
|
user = self.purchased_paid_media.from_user
|
||||||
|
|
||||||
self._effective_user = user
|
self._effective_user = user
|
||||||
return user
|
return user
|
||||||
|
|
||||||
|
@ -601,7 +628,8 @@ class Update(TelegramObject):
|
||||||
This is the case, if :attr:`inline_query`,
|
This is the case, if :attr:`inline_query`,
|
||||||
:attr:`chosen_inline_result`, :attr:`callback_query` from inline messages,
|
:attr:`chosen_inline_result`, :attr:`callback_query` from inline messages,
|
||||||
:attr:`shipping_query`, :attr:`pre_checkout_query`, :attr:`poll`,
|
:attr:`shipping_query`, :attr:`pre_checkout_query`, :attr:`poll`,
|
||||||
:attr:`poll_answer`, or :attr:`business_connection` is present.
|
:attr:`poll_answer`, :attr:`business_connection`, or :attr:`purchased_paid_media`
|
||||||
|
is present.
|
||||||
|
|
||||||
.. versionchanged:: 21.1
|
.. versionchanged:: 21.1
|
||||||
This property now also considers :attr:`business_message`,
|
This property now also considers :attr:`business_message`,
|
||||||
|
@ -768,5 +796,8 @@ class Update(TelegramObject):
|
||||||
data["deleted_business_messages"] = BusinessMessagesDeleted.de_json(
|
data["deleted_business_messages"] = BusinessMessagesDeleted.de_json(
|
||||||
data.get("deleted_business_messages"), bot
|
data.get("deleted_business_messages"), bot
|
||||||
)
|
)
|
||||||
|
data["purchased_paid_media"] = PaidMediaPurchased.de_json(
|
||||||
|
data.get("purchased_paid_media"), bot
|
||||||
|
)
|
||||||
|
|
||||||
return super().de_json(data=data, bot=bot)
|
return super().de_json(data=data, bot=bot)
|
||||||
|
|
|
@ -152,7 +152,7 @@ class _AccentColor(NamedTuple):
|
||||||
#: :data:`telegram.__bot_api_version_info__`.
|
#: :data:`telegram.__bot_api_version_info__`.
|
||||||
#:
|
#:
|
||||||
#: .. versionadded:: 20.0
|
#: .. versionadded:: 20.0
|
||||||
BOT_API_VERSION_INFO: Final[_BotAPIVersion] = _BotAPIVersion(major=7, minor=9)
|
BOT_API_VERSION_INFO: Final[_BotAPIVersion] = _BotAPIVersion(major=7, minor=10)
|
||||||
#: :obj:`str`: Telegram Bot API
|
#: :obj:`str`: Telegram Bot API
|
||||||
#: version supported by this version of `python-telegram-bot`. Also available as
|
#: version supported by this version of `python-telegram-bot`. Also available as
|
||||||
#: :data:`telegram.__bot_api_version__`.
|
#: :data:`telegram.__bot_api_version__`.
|
||||||
|
@ -552,6 +552,42 @@ class AccentColor(Enum):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class BackgroundTypeType(StringEnum):
|
||||||
|
"""This enum contains the available types of :class:`telegram.BackgroundType`. The enum
|
||||||
|
members of this enumeration are instances of :class:`str` and can be treated as such.
|
||||||
|
|
||||||
|
.. versionadded:: 21.2
|
||||||
|
"""
|
||||||
|
|
||||||
|
__slots__ = ()
|
||||||
|
|
||||||
|
FILL = "fill"
|
||||||
|
""":obj:`str`: A :class:`telegram.BackgroundType` with fill background."""
|
||||||
|
WALLPAPER = "wallpaper"
|
||||||
|
""":obj:`str`: A :class:`telegram.BackgroundType` with wallpaper background."""
|
||||||
|
PATTERN = "pattern"
|
||||||
|
""":obj:`str`: A :class:`telegram.BackgroundType` with pattern background."""
|
||||||
|
CHAT_THEME = "chat_theme"
|
||||||
|
""":obj:`str`: A :class:`telegram.BackgroundType` with chat_theme background."""
|
||||||
|
|
||||||
|
|
||||||
|
class BackgroundFillType(StringEnum):
|
||||||
|
"""This enum contains the available types of :class:`telegram.BackgroundFill`. The enum
|
||||||
|
members of this enumeration are instances of :class:`str` and can be treated as such.
|
||||||
|
|
||||||
|
.. versionadded:: 21.2
|
||||||
|
"""
|
||||||
|
|
||||||
|
__slots__ = ()
|
||||||
|
|
||||||
|
SOLID = "solid"
|
||||||
|
""":obj:`str`: A :class:`telegram.BackgroundFill` with solid fill."""
|
||||||
|
GRADIENT = "gradient"
|
||||||
|
""":obj:`str`: A :class:`telegram.BackgroundFill` with gradient fill."""
|
||||||
|
FREEFORM_GRADIENT = "freeform_gradient"
|
||||||
|
""":obj:`str`: A :class:`telegram.BackgroundFill` with freeform_gradient fill."""
|
||||||
|
|
||||||
|
|
||||||
class BotCommandLimit(IntEnum):
|
class BotCommandLimit(IntEnum):
|
||||||
"""This enum contains limitations for :class:`telegram.BotCommand` and
|
"""This enum contains limitations for :class:`telegram.BotCommand` and
|
||||||
:meth:`telegram.Bot.set_my_commands`.
|
:meth:`telegram.Bot.set_my_commands`.
|
||||||
|
@ -833,6 +869,25 @@ class ChatLimit(IntEnum):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class ChatSubscriptionLimit(IntEnum):
|
||||||
|
"""This enum contains limitations for
|
||||||
|
:paramref:`telegram.Bot.create_chat_subscription_invite_link.subscription_period` and
|
||||||
|
:paramref:`telegram.Bot.create_chat_subscription_invite_link.subscription_price`.
|
||||||
|
The enum members of this enumeration are instances of :class:`int` and can be treated as such.
|
||||||
|
|
||||||
|
.. versionadded:: 21.5
|
||||||
|
"""
|
||||||
|
|
||||||
|
__slots__ = ()
|
||||||
|
|
||||||
|
SUBSCRIPTION_PERIOD = 2592000
|
||||||
|
""":obj:`int`: The number of seconds the subscription will be active."""
|
||||||
|
MIN_PRICE = 1
|
||||||
|
""":obj:`int`: Amount of stars a user pays, minimum amount the subscription can be set to."""
|
||||||
|
MAX_PRICE = 2500
|
||||||
|
""":obj:`int`: Amount of stars a user pays, maximum amount the subscription can be set to."""
|
||||||
|
|
||||||
|
|
||||||
class BackgroundTypeLimit(IntEnum):
|
class BackgroundTypeLimit(IntEnum):
|
||||||
"""This enum contains limitations for :class:`telegram.BackgroundTypeFill`,
|
"""This enum contains limitations for :class:`telegram.BackgroundTypeFill`,
|
||||||
:class:`telegram.BackgroundTypeWallpaper` and :class:`telegram.BackgroundTypePattern`.
|
:class:`telegram.BackgroundTypeWallpaper` and :class:`telegram.BackgroundTypePattern`.
|
||||||
|
@ -2724,6 +2779,11 @@ class UpdateType(StringEnum):
|
||||||
|
|
||||||
.. versionadded:: 21.1
|
.. versionadded:: 21.1
|
||||||
"""
|
"""
|
||||||
|
PURCHASED_PAID_MEDIA = "purchased_paid_media"
|
||||||
|
""":obj:`str`: Updates with :attr:`telegram.Update.purchased_paid_media`.
|
||||||
|
|
||||||
|
.. versionadded:: NEXT.VERSION
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
class InvoiceLimit(IntEnum):
|
class InvoiceLimit(IntEnum):
|
||||||
|
@ -2795,6 +2855,8 @@ class InvoiceLimit(IntEnum):
|
||||||
:meth:`telegram.Bot.send_invoice`.
|
:meth:`telegram.Bot.send_invoice`.
|
||||||
* :paramref:`~telegram.Bot.create_invoice_link.payload` parameter of
|
* :paramref:`~telegram.Bot.create_invoice_link.payload` parameter of
|
||||||
:meth:`telegram.Bot.create_invoice_link`.
|
:meth:`telegram.Bot.create_invoice_link`.
|
||||||
|
* :paramref:`~telegram.Bot.send_paid_media.payload` parameter of
|
||||||
|
:meth:`telegram.Bot.send_paid_media`.
|
||||||
"""
|
"""
|
||||||
MAX_TIP_AMOUNTS = 4
|
MAX_TIP_AMOUNTS = 4
|
||||||
""":obj:`int`: Maximum length of a :obj:`Sequence` passed as:
|
""":obj:`int`: Maximum length of a :obj:`Sequence` passed as:
|
||||||
|
@ -2804,6 +2866,20 @@ class InvoiceLimit(IntEnum):
|
||||||
* :paramref:`~telegram.Bot.create_invoice_link.suggested_tip_amounts` parameter of
|
* :paramref:`~telegram.Bot.create_invoice_link.suggested_tip_amounts` parameter of
|
||||||
:meth:`telegram.Bot.create_invoice_link`.
|
:meth:`telegram.Bot.create_invoice_link`.
|
||||||
"""
|
"""
|
||||||
|
MIN_STAR_COUNT = 1
|
||||||
|
""":obj:`int`: Minimum amount of starts that must be paid to buy access to a paid media
|
||||||
|
passed as :paramref:`~telegram.Bot.send_paid_media.star_count` parameter of
|
||||||
|
:meth:`telegram.Bot.send_paid_media`.
|
||||||
|
|
||||||
|
.. versionadded:: NEXT.VERSION
|
||||||
|
"""
|
||||||
|
MAX_STAR_COUNT = 2500
|
||||||
|
""":obj:`int`: Maximum amount of starts that must be paid to buy access to a paid media
|
||||||
|
passed as :paramref:`~telegram.Bot.send_paid_media.star_count` parameter of
|
||||||
|
:meth:`telegram.Bot.send_paid_media`.
|
||||||
|
|
||||||
|
.. versionadded:: NEXT.VERSION
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
class UserProfilePhotosLimit(IntEnum):
|
class UserProfilePhotosLimit(IntEnum):
|
||||||
|
@ -3066,58 +3142,3 @@ class ReactionEmoji(StringEnum):
|
||||||
""":obj:`str`: Woman Shrugging"""
|
""":obj:`str`: Woman Shrugging"""
|
||||||
POUTING_FACE = "😡"
|
POUTING_FACE = "😡"
|
||||||
""":obj:`str`: Pouting face"""
|
""":obj:`str`: Pouting face"""
|
||||||
|
|
||||||
|
|
||||||
class BackgroundTypeType(StringEnum):
|
|
||||||
"""This enum contains the available types of :class:`telegram.BackgroundType`. The enum
|
|
||||||
members of this enumeration are instances of :class:`str` and can be treated as such.
|
|
||||||
|
|
||||||
.. versionadded:: 21.2
|
|
||||||
"""
|
|
||||||
|
|
||||||
__slots__ = ()
|
|
||||||
|
|
||||||
FILL = "fill"
|
|
||||||
""":obj:`str`: A :class:`telegram.BackgroundType` with fill background."""
|
|
||||||
WALLPAPER = "wallpaper"
|
|
||||||
""":obj:`str`: A :class:`telegram.BackgroundType` with wallpaper background."""
|
|
||||||
PATTERN = "pattern"
|
|
||||||
""":obj:`str`: A :class:`telegram.BackgroundType` with pattern background."""
|
|
||||||
CHAT_THEME = "chat_theme"
|
|
||||||
""":obj:`str`: A :class:`telegram.BackgroundType` with chat_theme background."""
|
|
||||||
|
|
||||||
|
|
||||||
class BackgroundFillType(StringEnum):
|
|
||||||
"""This enum contains the available types of :class:`telegram.BackgroundFill`. The enum
|
|
||||||
members of this enumeration are instances of :class:`str` and can be treated as such.
|
|
||||||
|
|
||||||
.. versionadded:: 21.2
|
|
||||||
"""
|
|
||||||
|
|
||||||
__slots__ = ()
|
|
||||||
|
|
||||||
SOLID = "solid"
|
|
||||||
""":obj:`str`: A :class:`telegram.BackgroundFill` with solid fill."""
|
|
||||||
GRADIENT = "gradient"
|
|
||||||
""":obj:`str`: A :class:`telegram.BackgroundFill` with gradient fill."""
|
|
||||||
FREEFORM_GRADIENT = "freeform_gradient"
|
|
||||||
""":obj:`str`: A :class:`telegram.BackgroundFill` with freeform_gradient fill."""
|
|
||||||
|
|
||||||
|
|
||||||
class ChatSubscriptionLimit(IntEnum):
|
|
||||||
"""This enum contains limitations for
|
|
||||||
:paramref:`telegram.Bot.create_chat_subscription_invite_link.subscription_period` and
|
|
||||||
:paramref:`telegram.Bot.create_chat_subscription_invite_link.subscription_price`.
|
|
||||||
The enum members of this enumeration are instances of :class:`int` and can be treated as such.
|
|
||||||
|
|
||||||
.. versionadded:: 21.5
|
|
||||||
"""
|
|
||||||
|
|
||||||
__slots__ = ()
|
|
||||||
|
|
||||||
SUBSCRIPTION_PERIOD = 2592000
|
|
||||||
""":obj:`int`: The number of seconds the subscription will be active."""
|
|
||||||
MIN_PRICE = 1
|
|
||||||
""":obj:`int`: Amount of stars a user pays, minimum amount the subscription can be set to."""
|
|
||||||
MAX_PRICE = 2500
|
|
||||||
""":obj:`int`: Amount of stars a user pays, maximum amount the subscription can be set to."""
|
|
||||||
|
|
|
@ -48,6 +48,7 @@ __all__ = (
|
||||||
"JobQueue",
|
"JobQueue",
|
||||||
"MessageHandler",
|
"MessageHandler",
|
||||||
"MessageReactionHandler",
|
"MessageReactionHandler",
|
||||||
|
"PaidMediaPurchasedHandler",
|
||||||
"PersistenceInput",
|
"PersistenceInput",
|
||||||
"PicklePersistence",
|
"PicklePersistence",
|
||||||
"PollAnswerHandler",
|
"PollAnswerHandler",
|
||||||
|
@ -89,6 +90,7 @@ from ._handlers.conversationhandler import ConversationHandler
|
||||||
from ._handlers.inlinequeryhandler import InlineQueryHandler
|
from ._handlers.inlinequeryhandler import InlineQueryHandler
|
||||||
from ._handlers.messagehandler import MessageHandler
|
from ._handlers.messagehandler import MessageHandler
|
||||||
from ._handlers.messagereactionhandler import MessageReactionHandler
|
from ._handlers.messagereactionhandler import MessageReactionHandler
|
||||||
|
from ._handlers.paidmediapurchasedhandler import PaidMediaPurchasedHandler
|
||||||
from ._handlers.pollanswerhandler import PollAnswerHandler
|
from ._handlers.pollanswerhandler import PollAnswerHandler
|
||||||
from ._handlers.pollhandler import PollHandler
|
from ._handlers.pollhandler import PollHandler
|
||||||
from ._handlers.precheckoutqueryhandler import PreCheckoutQueryHandler
|
from ._handlers.precheckoutqueryhandler import PreCheckoutQueryHandler
|
||||||
|
|
|
@ -4235,6 +4235,7 @@ class ExtBot(Bot, Generic[RLARGS]):
|
||||||
reply_parameters: Optional["ReplyParameters"] = None,
|
reply_parameters: Optional["ReplyParameters"] = None,
|
||||||
reply_markup: Optional[ReplyMarkup] = None,
|
reply_markup: Optional[ReplyMarkup] = None,
|
||||||
business_connection_id: Optional[str] = None,
|
business_connection_id: Optional[str] = None,
|
||||||
|
payload: Optional[str] = None,
|
||||||
*,
|
*,
|
||||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||||
reply_to_message_id: Optional[int] = None,
|
reply_to_message_id: Optional[int] = None,
|
||||||
|
@ -4265,6 +4266,7 @@ class ExtBot(Bot, Generic[RLARGS]):
|
||||||
pool_timeout=pool_timeout,
|
pool_timeout=pool_timeout,
|
||||||
api_kwargs=self._merge_api_rl_kwargs(api_kwargs, rate_limit_args),
|
api_kwargs=self._merge_api_rl_kwargs(api_kwargs, rate_limit_args),
|
||||||
business_connection_id=business_connection_id,
|
business_connection_id=business_connection_id,
|
||||||
|
payload=payload,
|
||||||
)
|
)
|
||||||
|
|
||||||
async def create_chat_subscription_invite_link(
|
async def create_chat_subscription_invite_link(
|
||||||
|
|
95
telegram/ext/_handlers/paidmediapurchasedhandler.py
Normal file
95
telegram/ext/_handlers/paidmediapurchasedhandler.py
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
#
|
||||||
|
# A library that provides a Python interface to the Telegram Bot API
|
||||||
|
# Copyright (C) 2015-2024
|
||||||
|
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Lesser Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Lesser Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser Public License
|
||||||
|
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||||
|
"""This module contains the PaidMediaPurchased class."""
|
||||||
|
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
from telegram import Update
|
||||||
|
from telegram._utils.defaultvalue import DEFAULT_TRUE
|
||||||
|
from telegram._utils.types import SCT, DVType
|
||||||
|
from telegram.ext._handlers.basehandler import BaseHandler
|
||||||
|
from telegram.ext._utils._update_parsing import parse_chat_id, parse_username
|
||||||
|
from telegram.ext._utils.types import CCT, RT, HandlerCallback
|
||||||
|
|
||||||
|
|
||||||
|
class PaidMediaPurchasedHandler(BaseHandler[Update, CCT, RT]):
|
||||||
|
"""Handler class to handle Telegram
|
||||||
|
:attr:`purchased paid media <telegram.Update.purchased_paid_media>`.
|
||||||
|
|
||||||
|
.. versionadded:: NEXT.VERSION
|
||||||
|
|
||||||
|
Args:
|
||||||
|
callback (:term:`coroutine function`): The callback function for this handler. Will be
|
||||||
|
called when :meth:`check_update` has determined that an update should be processed by
|
||||||
|
this handler. Callback signature::
|
||||||
|
|
||||||
|
async def callback(update: Update, context: CallbackContext)
|
||||||
|
user_id (:obj:`int` | Collection[:obj:`int`], optional): Filters requests to allow only
|
||||||
|
those which are from the specified user ID(s).
|
||||||
|
|
||||||
|
username (:obj:`str` | Collection[:obj:`str`], optional): Filters requests to allow only
|
||||||
|
those which are from the specified username(s).
|
||||||
|
|
||||||
|
block (:obj:`bool`, optional): Determines whether the return value of the callback should
|
||||||
|
be awaited before processing the next handler in
|
||||||
|
:meth:`telegram.ext.Application.process_update`. Defaults to :obj:`True`.
|
||||||
|
|
||||||
|
.. seealso:: :wiki:`Concurrency`
|
||||||
|
Attributes:
|
||||||
|
callback (:term:`coroutine function`): The callback function for this handler.
|
||||||
|
block (:obj:`bool`): Determines whether the return value of the callback should be
|
||||||
|
awaited before processing the next handler in
|
||||||
|
:meth:`telegram.ext.Application.process_update`.
|
||||||
|
"""
|
||||||
|
|
||||||
|
__slots__ = (
|
||||||
|
"_user_ids",
|
||||||
|
"_usernames",
|
||||||
|
)
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self: "PaidMediaPurchasedHandler[CCT, RT]",
|
||||||
|
callback: HandlerCallback[Update, CCT, RT],
|
||||||
|
user_id: Optional[SCT[int]] = None,
|
||||||
|
username: Optional[SCT[str]] = None,
|
||||||
|
block: DVType[bool] = DEFAULT_TRUE,
|
||||||
|
):
|
||||||
|
super().__init__(callback, block=block)
|
||||||
|
|
||||||
|
self._user_ids = parse_chat_id(user_id)
|
||||||
|
self._usernames = parse_username(username)
|
||||||
|
|
||||||
|
def check_update(self, update: object) -> bool:
|
||||||
|
"""Determines whether an update should be passed to this handler's :attr:`callback`.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
update (:class:`telegram.Update` | :obj:`object`): Incoming update.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
:obj:`bool`
|
||||||
|
|
||||||
|
"""
|
||||||
|
if not isinstance(update, Update) or not update.purchased_paid_media:
|
||||||
|
return False
|
||||||
|
|
||||||
|
if not self._user_ids and not self._usernames:
|
||||||
|
return True
|
||||||
|
if update.purchased_paid_media.from_user.id in self._user_ids:
|
||||||
|
return True
|
||||||
|
return update.purchased_paid_media.from_user.username in self._usernames
|
|
@ -72,7 +72,7 @@ complete and correct. To run it, export an environment variable first:
|
||||||
|
|
||||||
$ export TEST_OFFICIAL=true
|
$ export TEST_OFFICIAL=true
|
||||||
|
|
||||||
and then run ``pytest tests/test_official.py``. Note: You need py 3.10+ to run this test.
|
and then run ``pytest tests/test_official/test_official.py``. Note: You need py 3.10+ to run this test.
|
||||||
|
|
||||||
We also have another marker, ``@pytest.mark.dev``, which you can add to tests that you want to run selectively.
|
We also have another marker, ``@pytest.mark.dev``, which you can add to tests that you want to run selectively.
|
||||||
Use as follows:
|
Use as follows:
|
||||||
|
|
169
tests/ext/test_paidmediapurchasedhandler.py
Normal file
169
tests/ext/test_paidmediapurchasedhandler.py
Normal file
|
@ -0,0 +1,169 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
#
|
||||||
|
# A library that provides a Python interface to the Telegram Bot API
|
||||||
|
# Copyright (C) 2015-2024
|
||||||
|
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Lesser Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Lesser Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser Public License
|
||||||
|
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||||
|
import asyncio
|
||||||
|
import datetime
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from telegram import (
|
||||||
|
Bot,
|
||||||
|
CallbackQuery,
|
||||||
|
Chat,
|
||||||
|
ChosenInlineResult,
|
||||||
|
Message,
|
||||||
|
PaidMediaPurchased,
|
||||||
|
PreCheckoutQuery,
|
||||||
|
ShippingQuery,
|
||||||
|
Update,
|
||||||
|
User,
|
||||||
|
)
|
||||||
|
from telegram._utils.datetime import UTC
|
||||||
|
from telegram.ext import CallbackContext, JobQueue, PaidMediaPurchasedHandler
|
||||||
|
from tests.auxil.slots import mro_slots
|
||||||
|
|
||||||
|
message = Message(1, None, Chat(1, ""), from_user=User(1, "", False), text="Text")
|
||||||
|
|
||||||
|
params = [
|
||||||
|
{"message": message},
|
||||||
|
{"edited_message": message},
|
||||||
|
{"callback_query": CallbackQuery(1, User(1, "", False), "chat", message=message)},
|
||||||
|
{"channel_post": message},
|
||||||
|
{"edited_channel_post": message},
|
||||||
|
{"chosen_inline_result": ChosenInlineResult("id", User(1, "", False), "")},
|
||||||
|
{"shipping_query": ShippingQuery("id", User(1, "", False), "", None)},
|
||||||
|
{"pre_checkout_query": PreCheckoutQuery("id", User(1, "", False), "", 0, "")},
|
||||||
|
{"callback_query": CallbackQuery(1, User(1, "", False), "chat")},
|
||||||
|
]
|
||||||
|
|
||||||
|
ids = (
|
||||||
|
"message",
|
||||||
|
"edited_message",
|
||||||
|
"callback_query",
|
||||||
|
"channel_post",
|
||||||
|
"edited_channel_post",
|
||||||
|
"chosen_inline_result",
|
||||||
|
"shipping_query",
|
||||||
|
"pre_checkout_query",
|
||||||
|
"callback_query_without_message",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(scope="class", params=params, ids=ids)
|
||||||
|
def false_update(request):
|
||||||
|
return Update(update_id=2, **request.param)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(scope="class")
|
||||||
|
def time():
|
||||||
|
return datetime.datetime.now(tz=UTC)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(scope="class")
|
||||||
|
def purchased_paid_media(bot):
|
||||||
|
bc = PaidMediaPurchased(
|
||||||
|
from_user=User(1, "name", username="user_a", is_bot=False),
|
||||||
|
paid_media_payload="payload",
|
||||||
|
)
|
||||||
|
bc.set_bot(bot)
|
||||||
|
return bc
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def purchased_paid_media_update(bot, purchased_paid_media):
|
||||||
|
return Update(0, purchased_paid_media=purchased_paid_media)
|
||||||
|
|
||||||
|
|
||||||
|
class TestPaidMediaPurchasedHandler:
|
||||||
|
test_flag = False
|
||||||
|
|
||||||
|
def test_slot_behaviour(self):
|
||||||
|
action = PaidMediaPurchasedHandler(self.callback)
|
||||||
|
for attr in action.__slots__:
|
||||||
|
assert getattr(action, attr, "err") != "err", f"got extra slot '{attr}'"
|
||||||
|
assert len(mro_slots(action)) == len(set(mro_slots(action))), "duplicate slot"
|
||||||
|
|
||||||
|
@pytest.fixture(autouse=True)
|
||||||
|
def _reset(self):
|
||||||
|
self.test_flag = False
|
||||||
|
|
||||||
|
async def callback(self, update, context):
|
||||||
|
self.test_flag = (
|
||||||
|
isinstance(context, CallbackContext)
|
||||||
|
and isinstance(context.bot, Bot)
|
||||||
|
and isinstance(update, Update)
|
||||||
|
and isinstance(context.update_queue, asyncio.Queue)
|
||||||
|
and isinstance(context.job_queue, JobQueue)
|
||||||
|
and isinstance(context.user_data, dict)
|
||||||
|
and isinstance(context.bot_data, dict)
|
||||||
|
and isinstance(
|
||||||
|
update.purchased_paid_media,
|
||||||
|
PaidMediaPurchased,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_with_user_id(self, purchased_paid_media_update):
|
||||||
|
handler = PaidMediaPurchasedHandler(self.callback, user_id=1)
|
||||||
|
assert handler.check_update(purchased_paid_media_update)
|
||||||
|
handler = PaidMediaPurchasedHandler(self.callback, user_id=[1])
|
||||||
|
assert handler.check_update(purchased_paid_media_update)
|
||||||
|
handler = PaidMediaPurchasedHandler(self.callback, user_id=2, username="@user_a")
|
||||||
|
assert handler.check_update(purchased_paid_media_update)
|
||||||
|
|
||||||
|
handler = PaidMediaPurchasedHandler(self.callback, user_id=2)
|
||||||
|
assert not handler.check_update(purchased_paid_media_update)
|
||||||
|
handler = PaidMediaPurchasedHandler(self.callback, user_id=[2])
|
||||||
|
assert not handler.check_update(purchased_paid_media_update)
|
||||||
|
|
||||||
|
def test_with_username(self, purchased_paid_media_update):
|
||||||
|
handler = PaidMediaPurchasedHandler(self.callback, username="user_a")
|
||||||
|
assert handler.check_update(purchased_paid_media_update)
|
||||||
|
handler = PaidMediaPurchasedHandler(self.callback, username="@user_a")
|
||||||
|
assert handler.check_update(purchased_paid_media_update)
|
||||||
|
handler = PaidMediaPurchasedHandler(self.callback, username=["user_a"])
|
||||||
|
assert handler.check_update(purchased_paid_media_update)
|
||||||
|
handler = PaidMediaPurchasedHandler(self.callback, username=["@user_a"])
|
||||||
|
assert handler.check_update(purchased_paid_media_update)
|
||||||
|
handler = PaidMediaPurchasedHandler(self.callback, user_id=1, username="@user_b")
|
||||||
|
assert handler.check_update(purchased_paid_media_update)
|
||||||
|
|
||||||
|
handler = PaidMediaPurchasedHandler(self.callback, username="user_b")
|
||||||
|
assert not handler.check_update(purchased_paid_media_update)
|
||||||
|
handler = PaidMediaPurchasedHandler(self.callback, username="@user_b")
|
||||||
|
assert not handler.check_update(purchased_paid_media_update)
|
||||||
|
handler = PaidMediaPurchasedHandler(self.callback, username=["user_b"])
|
||||||
|
assert not handler.check_update(purchased_paid_media_update)
|
||||||
|
handler = PaidMediaPurchasedHandler(self.callback, username=["@user_b"])
|
||||||
|
assert not handler.check_update(purchased_paid_media_update)
|
||||||
|
|
||||||
|
purchased_paid_media_update.purchased_paid_media.from_user._unfreeze()
|
||||||
|
purchased_paid_media_update.purchased_paid_media.from_user.username = None
|
||||||
|
assert not handler.check_update(purchased_paid_media_update)
|
||||||
|
|
||||||
|
def test_other_update_types(self, false_update):
|
||||||
|
handler = PaidMediaPurchasedHandler(self.callback)
|
||||||
|
assert not handler.check_update(false_update)
|
||||||
|
assert not handler.check_update(True)
|
||||||
|
|
||||||
|
async def test_context(self, app, purchased_paid_media_update):
|
||||||
|
handler = PaidMediaPurchasedHandler(callback=self.callback)
|
||||||
|
app.add_handler(handler)
|
||||||
|
|
||||||
|
async with app:
|
||||||
|
await app.process_update(purchased_paid_media_update)
|
||||||
|
assert self.test_flag
|
|
@ -1299,6 +1299,7 @@ class TestChatWithoutRequest(ChatTestBase):
|
||||||
and kwargs["media"] == "media"
|
and kwargs["media"] == "media"
|
||||||
and kwargs["star_count"] == 42
|
and kwargs["star_count"] == 42
|
||||||
and kwargs["caption"] == "stars"
|
and kwargs["caption"] == "stars"
|
||||||
|
and kwargs["payload"] == "payload"
|
||||||
)
|
)
|
||||||
|
|
||||||
assert check_shortcut_signature(Chat.send_paid_media, Bot.send_paid_media, ["chat_id"], [])
|
assert check_shortcut_signature(Chat.send_paid_media, Bot.send_paid_media, ["chat_id"], [])
|
||||||
|
@ -1306,7 +1307,9 @@ class TestChatWithoutRequest(ChatTestBase):
|
||||||
assert await check_defaults_handling(chat.send_paid_media, chat.get_bot())
|
assert await check_defaults_handling(chat.send_paid_media, chat.get_bot())
|
||||||
|
|
||||||
monkeypatch.setattr(chat.get_bot(), "send_paid_media", make_assertion)
|
monkeypatch.setattr(chat.get_bot(), "send_paid_media", make_assertion)
|
||||||
assert await chat.send_paid_media(media="media", star_count=42, caption="stars")
|
assert await chat.send_paid_media(
|
||||||
|
media="media", star_count=42, caption="stars", payload="payload"
|
||||||
|
)
|
||||||
|
|
||||||
def test_mention_html(self):
|
def test_mention_html(self):
|
||||||
chat = Chat(id=1, type="foo")
|
chat = Chat(id=1, type="foo")
|
||||||
|
|
|
@ -50,6 +50,7 @@ class ChatBoostDefaults:
|
||||||
user = User(1, "user", False)
|
user = User(1, "user", False)
|
||||||
date = to_timestamp(datetime.datetime.utcnow())
|
date = to_timestamp(datetime.datetime.utcnow())
|
||||||
default_source = ChatBoostSourcePremium(user)
|
default_source = ChatBoostSourcePremium(user)
|
||||||
|
prize_star_count = 99
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="module")
|
@pytest.fixture(scope="module")
|
||||||
|
@ -91,6 +92,7 @@ def chat_boost_source_giveaway():
|
||||||
user=ChatBoostDefaults.user,
|
user=ChatBoostDefaults.user,
|
||||||
giveaway_message_id=ChatBoostDefaults.giveaway_message_id,
|
giveaway_message_id=ChatBoostDefaults.giveaway_message_id,
|
||||||
is_unclaimed=ChatBoostDefaults.is_unclaimed,
|
is_unclaimed=ChatBoostDefaults.is_unclaimed,
|
||||||
|
prize_star_count=ChatBoostDefaults.prize_star_count,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -48,6 +48,7 @@ def giveaway():
|
||||||
premium_subscription_month_count=(
|
premium_subscription_month_count=(
|
||||||
TestGiveawayWithoutRequest.premium_subscription_month_count
|
TestGiveawayWithoutRequest.premium_subscription_month_count
|
||||||
),
|
),
|
||||||
|
prize_star_count=TestGiveawayWithoutRequest.prize_star_count,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -60,6 +61,7 @@ class TestGiveawayWithoutRequest:
|
||||||
prize_description = "prize_description"
|
prize_description = "prize_description"
|
||||||
country_codes = ["DE", "US"]
|
country_codes = ["DE", "US"]
|
||||||
premium_subscription_month_count = 3
|
premium_subscription_month_count = 3
|
||||||
|
prize_star_count = 99
|
||||||
|
|
||||||
def test_slot_behaviour(self, giveaway):
|
def test_slot_behaviour(self, giveaway):
|
||||||
for attr in giveaway.__slots__:
|
for attr in giveaway.__slots__:
|
||||||
|
@ -76,6 +78,7 @@ class TestGiveawayWithoutRequest:
|
||||||
"prize_description": self.prize_description,
|
"prize_description": self.prize_description,
|
||||||
"country_codes": self.country_codes,
|
"country_codes": self.country_codes,
|
||||||
"premium_subscription_month_count": self.premium_subscription_month_count,
|
"premium_subscription_month_count": self.premium_subscription_month_count,
|
||||||
|
"prize_star_count": self.prize_star_count,
|
||||||
}
|
}
|
||||||
|
|
||||||
giveaway = Giveaway.de_json(json_dict, offline_bot)
|
giveaway = Giveaway.de_json(json_dict, offline_bot)
|
||||||
|
@ -89,6 +92,7 @@ class TestGiveawayWithoutRequest:
|
||||||
assert giveaway.prize_description == self.prize_description
|
assert giveaway.prize_description == self.prize_description
|
||||||
assert giveaway.country_codes == tuple(self.country_codes)
|
assert giveaway.country_codes == tuple(self.country_codes)
|
||||||
assert giveaway.premium_subscription_month_count == self.premium_subscription_month_count
|
assert giveaway.premium_subscription_month_count == self.premium_subscription_month_count
|
||||||
|
assert giveaway.prize_star_count == self.prize_star_count
|
||||||
|
|
||||||
assert Giveaway.de_json(None, offline_bot) is None
|
assert Giveaway.de_json(None, offline_bot) is None
|
||||||
|
|
||||||
|
@ -102,6 +106,7 @@ class TestGiveawayWithoutRequest:
|
||||||
"prize_description": self.prize_description,
|
"prize_description": self.prize_description,
|
||||||
"country_codes": self.country_codes,
|
"country_codes": self.country_codes,
|
||||||
"premium_subscription_month_count": self.premium_subscription_month_count,
|
"premium_subscription_month_count": self.premium_subscription_month_count,
|
||||||
|
"prize_star_count": self.prize_star_count,
|
||||||
}
|
}
|
||||||
|
|
||||||
giveaway_raw = Giveaway.de_json(json_dict, raw_bot)
|
giveaway_raw = Giveaway.de_json(json_dict, raw_bot)
|
||||||
|
@ -133,6 +138,7 @@ class TestGiveawayWithoutRequest:
|
||||||
giveaway_dict["premium_subscription_month_count"]
|
giveaway_dict["premium_subscription_month_count"]
|
||||||
== self.premium_subscription_month_count
|
== self.premium_subscription_month_count
|
||||||
)
|
)
|
||||||
|
assert giveaway_dict["prize_star_count"] == self.prize_star_count
|
||||||
|
|
||||||
def test_equality(self, giveaway):
|
def test_equality(self, giveaway):
|
||||||
a = giveaway
|
a = giveaway
|
||||||
|
@ -164,15 +170,40 @@ class TestGiveawayWithoutRequest:
|
||||||
assert hash(a) != hash(e)
|
assert hash(a) != hash(e)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(scope="module")
|
||||||
|
def giveaway_created():
|
||||||
|
return GiveawayCreated(
|
||||||
|
prize_star_count=TestGiveawayCreatedWithoutRequest.prize_star_count,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class TestGiveawayCreatedWithoutRequest:
|
class TestGiveawayCreatedWithoutRequest:
|
||||||
def test_slot_behaviour(self):
|
prize_star_count = 99
|
||||||
giveaway_created = GiveawayCreated()
|
|
||||||
|
def test_slot_behaviour(self, giveaway_created):
|
||||||
for attr in giveaway_created.__slots__:
|
for attr in giveaway_created.__slots__:
|
||||||
assert getattr(giveaway_created, attr, "err") != "err", f"got extra slot '{attr}'"
|
assert getattr(giveaway_created, attr, "err") != "err", f"got extra slot '{attr}'"
|
||||||
assert len(mro_slots(giveaway_created)) == len(
|
assert len(mro_slots(giveaway_created)) == len(
|
||||||
set(mro_slots(giveaway_created))
|
set(mro_slots(giveaway_created))
|
||||||
), "duplicate slot"
|
), "duplicate slot"
|
||||||
|
|
||||||
|
def test_de_json(self, bot):
|
||||||
|
json_dict = {
|
||||||
|
"prize_star_count": self.prize_star_count,
|
||||||
|
}
|
||||||
|
|
||||||
|
gac = GiveawayCreated.de_json(json_dict, bot)
|
||||||
|
assert gac.api_kwargs == {}
|
||||||
|
assert gac.prize_star_count == self.prize_star_count
|
||||||
|
|
||||||
|
assert Giveaway.de_json(None, bot) is None
|
||||||
|
|
||||||
|
def test_to_dict(self, giveaway_created):
|
||||||
|
gac_dict = giveaway_created.to_dict()
|
||||||
|
|
||||||
|
assert isinstance(gac_dict, dict)
|
||||||
|
assert gac_dict["prize_star_count"] == self.prize_star_count
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="module")
|
@pytest.fixture(scope="module")
|
||||||
def giveaway_winners():
|
def giveaway_winners():
|
||||||
|
@ -190,6 +221,7 @@ def giveaway_winners():
|
||||||
additional_chat_count=TestGiveawayWinnersWithoutRequest.additional_chat_count,
|
additional_chat_count=TestGiveawayWinnersWithoutRequest.additional_chat_count,
|
||||||
unclaimed_prize_count=TestGiveawayWinnersWithoutRequest.unclaimed_prize_count,
|
unclaimed_prize_count=TestGiveawayWinnersWithoutRequest.unclaimed_prize_count,
|
||||||
was_refunded=TestGiveawayWinnersWithoutRequest.was_refunded,
|
was_refunded=TestGiveawayWinnersWithoutRequest.was_refunded,
|
||||||
|
prize_star_count=TestGiveawayWinnersWithoutRequest.prize_star_count,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -205,6 +237,7 @@ class TestGiveawayWinnersWithoutRequest:
|
||||||
only_new_members = True
|
only_new_members = True
|
||||||
was_refunded = True
|
was_refunded = True
|
||||||
prize_description = "prize_description"
|
prize_description = "prize_description"
|
||||||
|
prize_star_count = 99
|
||||||
|
|
||||||
def test_slot_behaviour(self, giveaway_winners):
|
def test_slot_behaviour(self, giveaway_winners):
|
||||||
for attr in giveaway_winners.__slots__:
|
for attr in giveaway_winners.__slots__:
|
||||||
|
@ -226,6 +259,7 @@ class TestGiveawayWinnersWithoutRequest:
|
||||||
"only_new_members": self.only_new_members,
|
"only_new_members": self.only_new_members,
|
||||||
"was_refunded": self.was_refunded,
|
"was_refunded": self.was_refunded,
|
||||||
"prize_description": self.prize_description,
|
"prize_description": self.prize_description,
|
||||||
|
"prize_star_count": self.prize_star_count,
|
||||||
}
|
}
|
||||||
|
|
||||||
giveaway_winners = GiveawayWinners.de_json(json_dict, offline_bot)
|
giveaway_winners = GiveawayWinners.de_json(json_dict, offline_bot)
|
||||||
|
@ -245,6 +279,7 @@ class TestGiveawayWinnersWithoutRequest:
|
||||||
assert giveaway_winners.only_new_members == self.only_new_members
|
assert giveaway_winners.only_new_members == self.only_new_members
|
||||||
assert giveaway_winners.was_refunded == self.was_refunded
|
assert giveaway_winners.was_refunded == self.was_refunded
|
||||||
assert giveaway_winners.prize_description == self.prize_description
|
assert giveaway_winners.prize_description == self.prize_description
|
||||||
|
assert giveaway_winners.prize_star_count == self.prize_star_count
|
||||||
|
|
||||||
assert GiveawayWinners.de_json(None, offline_bot) is None
|
assert GiveawayWinners.de_json(None, offline_bot) is None
|
||||||
|
|
||||||
|
@ -291,6 +326,7 @@ class TestGiveawayWinnersWithoutRequest:
|
||||||
assert giveaway_winners_dict["only_new_members"] == self.only_new_members
|
assert giveaway_winners_dict["only_new_members"] == self.only_new_members
|
||||||
assert giveaway_winners_dict["was_refunded"] == self.was_refunded
|
assert giveaway_winners_dict["was_refunded"] == self.was_refunded
|
||||||
assert giveaway_winners_dict["prize_description"] == self.prize_description
|
assert giveaway_winners_dict["prize_description"] == self.prize_description
|
||||||
|
assert giveaway_winners_dict["prize_star_count"] == self.prize_star_count
|
||||||
|
|
||||||
def test_equality(self, giveaway_winners):
|
def test_equality(self, giveaway_winners):
|
||||||
a = giveaway_winners
|
a = giveaway_winners
|
||||||
|
@ -336,12 +372,14 @@ def giveaway_completed():
|
||||||
winner_count=TestGiveawayCompletedWithoutRequest.winner_count,
|
winner_count=TestGiveawayCompletedWithoutRequest.winner_count,
|
||||||
unclaimed_prize_count=TestGiveawayCompletedWithoutRequest.unclaimed_prize_count,
|
unclaimed_prize_count=TestGiveawayCompletedWithoutRequest.unclaimed_prize_count,
|
||||||
giveaway_message=TestGiveawayCompletedWithoutRequest.giveaway_message,
|
giveaway_message=TestGiveawayCompletedWithoutRequest.giveaway_message,
|
||||||
|
is_star_giveaway=TestGiveawayCompletedWithoutRequest.is_star_giveaway,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class TestGiveawayCompletedWithoutRequest:
|
class TestGiveawayCompletedWithoutRequest:
|
||||||
winner_count = 42
|
winner_count = 42
|
||||||
unclaimed_prize_count = 4
|
unclaimed_prize_count = 4
|
||||||
|
is_star_giveaway = True
|
||||||
giveaway_message = Message(
|
giveaway_message = Message(
|
||||||
message_id=1,
|
message_id=1,
|
||||||
date=dtm.datetime.now(dtm.timezone.utc),
|
date=dtm.datetime.now(dtm.timezone.utc),
|
||||||
|
@ -362,6 +400,7 @@ class TestGiveawayCompletedWithoutRequest:
|
||||||
"winner_count": self.winner_count,
|
"winner_count": self.winner_count,
|
||||||
"unclaimed_prize_count": self.unclaimed_prize_count,
|
"unclaimed_prize_count": self.unclaimed_prize_count,
|
||||||
"giveaway_message": self.giveaway_message.to_dict(),
|
"giveaway_message": self.giveaway_message.to_dict(),
|
||||||
|
"is_star_giveaway": self.is_star_giveaway,
|
||||||
}
|
}
|
||||||
|
|
||||||
giveaway_completed = GiveawayCompleted.de_json(json_dict, offline_bot)
|
giveaway_completed = GiveawayCompleted.de_json(json_dict, offline_bot)
|
||||||
|
@ -370,6 +409,7 @@ class TestGiveawayCompletedWithoutRequest:
|
||||||
assert giveaway_completed.winner_count == self.winner_count
|
assert giveaway_completed.winner_count == self.winner_count
|
||||||
assert giveaway_completed.unclaimed_prize_count == self.unclaimed_prize_count
|
assert giveaway_completed.unclaimed_prize_count == self.unclaimed_prize_count
|
||||||
assert giveaway_completed.giveaway_message == self.giveaway_message
|
assert giveaway_completed.giveaway_message == self.giveaway_message
|
||||||
|
assert giveaway_completed.is_star_giveaway == self.is_star_giveaway
|
||||||
|
|
||||||
assert GiveawayCompleted.de_json(None, offline_bot) is None
|
assert GiveawayCompleted.de_json(None, offline_bot) is None
|
||||||
|
|
||||||
|
@ -380,6 +420,7 @@ class TestGiveawayCompletedWithoutRequest:
|
||||||
assert giveaway_completed_dict["winner_count"] == self.winner_count
|
assert giveaway_completed_dict["winner_count"] == self.winner_count
|
||||||
assert giveaway_completed_dict["unclaimed_prize_count"] == self.unclaimed_prize_count
|
assert giveaway_completed_dict["unclaimed_prize_count"] == self.unclaimed_prize_count
|
||||||
assert giveaway_completed_dict["giveaway_message"] == self.giveaway_message.to_dict()
|
assert giveaway_completed_dict["giveaway_message"] == self.giveaway_message.to_dict()
|
||||||
|
assert giveaway_completed_dict["is_star_giveaway"] == self.is_star_giveaway
|
||||||
|
|
||||||
def test_equality(self, giveaway_completed):
|
def test_equality(self, giveaway_completed):
|
||||||
a = giveaway_completed
|
a = giveaway_completed
|
||||||
|
@ -387,6 +428,7 @@ class TestGiveawayCompletedWithoutRequest:
|
||||||
winner_count=self.winner_count,
|
winner_count=self.winner_count,
|
||||||
unclaimed_prize_count=self.unclaimed_prize_count,
|
unclaimed_prize_count=self.unclaimed_prize_count,
|
||||||
giveaway_message=self.giveaway_message,
|
giveaway_message=self.giveaway_message,
|
||||||
|
is_star_giveaway=self.is_star_giveaway,
|
||||||
)
|
)
|
||||||
c = GiveawayCompleted(
|
c = GiveawayCompleted(
|
||||||
winner_count=self.winner_count + 30,
|
winner_count=self.winner_count + 30,
|
||||||
|
|
|
@ -236,7 +236,7 @@ def message(bot):
|
||||||
winner_count=5,
|
winner_count=5,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
{"giveaway_created": GiveawayCreated()},
|
{"giveaway_created": GiveawayCreated(prize_star_count=99)},
|
||||||
{
|
{
|
||||||
"giveaway_winners": GiveawayWinners(
|
"giveaway_winners": GiveawayWinners(
|
||||||
chat=Chat(1, Chat.CHANNEL),
|
chat=Chat(1, Chat.CHANNEL),
|
||||||
|
|
|
@ -27,8 +27,10 @@ from telegram import (
|
||||||
PaidMediaInfo,
|
PaidMediaInfo,
|
||||||
PaidMediaPhoto,
|
PaidMediaPhoto,
|
||||||
PaidMediaPreview,
|
PaidMediaPreview,
|
||||||
|
PaidMediaPurchased,
|
||||||
PaidMediaVideo,
|
PaidMediaVideo,
|
||||||
PhotoSize,
|
PhotoSize,
|
||||||
|
User,
|
||||||
Video,
|
Video,
|
||||||
)
|
)
|
||||||
from telegram.constants import PaidMediaType
|
from telegram.constants import PaidMediaType
|
||||||
|
@ -122,6 +124,14 @@ def paid_media_info():
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(scope="module")
|
||||||
|
def paid_media_purchased():
|
||||||
|
return PaidMediaPurchased(
|
||||||
|
from_user=PaidMediaPurchasedTestBase.from_user,
|
||||||
|
paid_media_payload=PaidMediaPurchasedTestBase.paid_media_payload,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class PaidMediaTestBase:
|
class PaidMediaTestBase:
|
||||||
width = 640
|
width = 640
|
||||||
height = 480
|
height = 480
|
||||||
|
@ -323,3 +333,54 @@ class TestPaidMediaInfoWithoutRequest(PaidMediaInfoTestBase):
|
||||||
|
|
||||||
assert pmi1 != pmi3
|
assert pmi1 != pmi3
|
||||||
assert hash(pmi1) != hash(pmi3)
|
assert hash(pmi1) != hash(pmi3)
|
||||||
|
|
||||||
|
|
||||||
|
class PaidMediaPurchasedTestBase:
|
||||||
|
from_user = User(1, "user", False)
|
||||||
|
paid_media_payload = "payload"
|
||||||
|
|
||||||
|
|
||||||
|
class TestPaidMediaPurchasedWithoutRequest(PaidMediaPurchasedTestBase):
|
||||||
|
def test_slot_behaviour(self, paid_media_purchased):
|
||||||
|
inst = paid_media_purchased
|
||||||
|
for attr in inst.__slots__:
|
||||||
|
assert getattr(inst, attr, "err") != "err", f"got extra slot '{attr}'"
|
||||||
|
assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot"
|
||||||
|
|
||||||
|
def test_de_json(self, bot):
|
||||||
|
json_dict = {
|
||||||
|
"from": self.from_user.to_dict(),
|
||||||
|
"paid_media_payload": self.paid_media_payload,
|
||||||
|
}
|
||||||
|
pmp = PaidMediaPurchased.de_json(json_dict, bot)
|
||||||
|
pmp_none = PaidMediaPurchased.de_json(None, bot)
|
||||||
|
assert pmp.from_user == self.from_user
|
||||||
|
assert pmp.paid_media_payload == self.paid_media_payload
|
||||||
|
assert pmp.api_kwargs == {}
|
||||||
|
assert pmp_none is None
|
||||||
|
|
||||||
|
def test_to_dict(self, paid_media_purchased):
|
||||||
|
assert paid_media_purchased.to_dict() == {
|
||||||
|
"from": self.from_user.to_dict(),
|
||||||
|
"paid_media_payload": self.paid_media_payload,
|
||||||
|
}
|
||||||
|
|
||||||
|
def test_equality(self):
|
||||||
|
pmp1 = PaidMediaPurchased(
|
||||||
|
from_user=self.from_user,
|
||||||
|
paid_media_payload=self.paid_media_payload,
|
||||||
|
)
|
||||||
|
pmp2 = PaidMediaPurchased(
|
||||||
|
from_user=self.from_user,
|
||||||
|
paid_media_payload=self.paid_media_payload,
|
||||||
|
)
|
||||||
|
pmp3 = PaidMediaPurchased(
|
||||||
|
from_user=User(2, "user", False),
|
||||||
|
paid_media_payload="other",
|
||||||
|
)
|
||||||
|
|
||||||
|
assert pmp1 == pmp2
|
||||||
|
assert hash(pmp1) == hash(pmp2)
|
||||||
|
|
||||||
|
assert pmp1 != pmp3
|
||||||
|
assert hash(pmp1) != hash(pmp3)
|
||||||
|
|
|
@ -74,6 +74,7 @@ def transaction_partner_user():
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
|
paid_media_payload="payload",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,7 @@ from telegram import (
|
||||||
Message,
|
Message,
|
||||||
MessageReactionCountUpdated,
|
MessageReactionCountUpdated,
|
||||||
MessageReactionUpdated,
|
MessageReactionUpdated,
|
||||||
|
PaidMediaPurchased,
|
||||||
Poll,
|
Poll,
|
||||||
PollAnswer,
|
PollAnswer,
|
||||||
PollOption,
|
PollOption,
|
||||||
|
@ -143,6 +144,11 @@ business_message = Message(
|
||||||
User(1, "", False),
|
User(1, "", False),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
purchased_paid_media = PaidMediaPurchased(
|
||||||
|
from_user=User(1, "", False),
|
||||||
|
paid_media_payload="payload",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
params = [
|
params = [
|
||||||
{"message": message},
|
{"message": message},
|
||||||
|
@ -178,6 +184,7 @@ params = [
|
||||||
{"deleted_business_messages": deleted_business_messages},
|
{"deleted_business_messages": deleted_business_messages},
|
||||||
{"business_message": business_message},
|
{"business_message": business_message},
|
||||||
{"edited_business_message": business_message},
|
{"edited_business_message": business_message},
|
||||||
|
{"purchased_paid_media": purchased_paid_media},
|
||||||
# Must be last to conform with `ids` below!
|
# Must be last to conform with `ids` below!
|
||||||
{"callback_query": CallbackQuery(1, User(1, "", False), "chat")},
|
{"callback_query": CallbackQuery(1, User(1, "", False), "chat")},
|
||||||
]
|
]
|
||||||
|
@ -205,6 +212,7 @@ all_types = (
|
||||||
"deleted_business_messages",
|
"deleted_business_messages",
|
||||||
"business_message",
|
"business_message",
|
||||||
"edited_business_message",
|
"edited_business_message",
|
||||||
|
"purchased_paid_media",
|
||||||
)
|
)
|
||||||
|
|
||||||
ids = (*all_types, "callback_query_without_message")
|
ids = (*all_types, "callback_query_without_message")
|
||||||
|
@ -290,6 +298,7 @@ class TestUpdateWithoutRequest(UpdateTestBase):
|
||||||
or update.poll is not None
|
or update.poll is not None
|
||||||
or update.poll_answer is not None
|
or update.poll_answer is not None
|
||||||
or update.business_connection is not None
|
or update.business_connection is not None
|
||||||
|
or update.purchased_paid_media is not None
|
||||||
):
|
):
|
||||||
assert chat.id == 1
|
assert chat.id == 1
|
||||||
else:
|
else:
|
||||||
|
@ -403,6 +412,7 @@ class TestUpdateWithoutRequest(UpdateTestBase):
|
||||||
or update.message_reaction_count is not None
|
or update.message_reaction_count is not None
|
||||||
or update.deleted_business_messages is not None
|
or update.deleted_business_messages is not None
|
||||||
or update.business_connection is not None
|
or update.business_connection is not None
|
||||||
|
or update.purchased_paid_media is not None
|
||||||
):
|
):
|
||||||
assert eff_message.message_id == message.message_id
|
assert eff_message.message_id == message.message_id
|
||||||
else:
|
else:
|
||||||
|
|
Loading…
Reference in a new issue