mirror of
https://github.com/python-telegram-bot/python-telegram-bot.git
synced 2026-06-19 07:35:19 +00:00
Full Support for Bot API 9.3 (#5078)
Co-authored-by: Hinrich Mahler <22366557+Bibo-Joshi@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
327f469cb4
commit
432a67efdd
+2
-2
@@ -13,7 +13,7 @@ dummy change for chango debug
|
||||
:target: https://pypi.org/project/python-telegram-bot/
|
||||
:alt: Supported Python versions
|
||||
|
||||
.. image:: https://img.shields.io/badge/Bot%20API-9.2-blue?logo=telegram
|
||||
.. image:: https://img.shields.io/badge/Bot%20API-9.3-blue?logo=telegram
|
||||
:target: https://core.telegram.org/bots/api-changelog
|
||||
:alt: Supported Bot API version
|
||||
|
||||
@@ -83,7 +83,7 @@ After installing_ the library, be sure to check out the section on `working with
|
||||
Telegram API support
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
All types and methods of the Telegram Bot API **9.2** are natively supported by this library.
|
||||
All types and methods of the Telegram Bot API **9.3** 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>`_.
|
||||
|
||||
Notable Features
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
features = """
|
||||
Full Support for Bot API 9.3
|
||||
|
||||
.. warning::
|
||||
|
||||
- Bot API 9.3 deprecates the field ``last_resale_star_count`` of ``UniqueGiftInfo`` in favor of the new fields ``last_resale_currency`` and ``last_resale_amount``. The field ``last_resale_star_count`` is still present in PTB for backward compatibility, but it will be removed in future releases. Please update your code accordingly.
|
||||
|
||||
- Bot API 9.3 deprecates the argument ``exclude_limited`` of ``Bot.get_business_account_gifts`` in favor of the new arguments ``exclude_limited_upgradable`` and ``exclude_limited_non_upgradable``. The argument ``exclude_limited`` is still present in PTB for backward compatibility, but it will be removed in future releases. Please update your code accordingly.
|
||||
|
||||
- Bot API 9.3 introduces a now required argument ``gift_id`` to ``UniqueGift``. For backward compatibility, the argument is currently still marked as optional in the signature and it's presence is enforced through a runtime check. In future versions, this argument will be made required in the signature as well.
|
||||
Please make sure to update your code accordingly to avoid potential issues in the future. We recommend using keyword arguments to ensure compatibility with future updates.
|
||||
"""
|
||||
|
||||
pull_requests = [
|
||||
{ uid = "5086", author_uids = ["Bibo-Joshi"] },
|
||||
{ uid = "5078", author_uid = "aelkheir", closes_threads = ["5077"] },
|
||||
{ uid = "5079", author_uid = "aelkheir" },
|
||||
{ uid = "5084", author_uids = ["Bibo-Joshi"] },
|
||||
{ uid = "5085", author_uids = ["Bibo-Joshi"] },
|
||||
{ uid = "5087", author_uids = ["Bibo-Joshi"] },
|
||||
{ uid = "5091", author_uids = ["Bibo-Joshi"] },
|
||||
{ uid = "5090", author_uids = ["Bibo-Joshi"] },
|
||||
{ uid = "5089", author_uids = ["Bibo-Joshi"] },
|
||||
{ uid = "5092", author_uids = ["Bibo-Joshi"] },
|
||||
{ uid = "5095", author_uids = ["Bibo-Joshi"] },
|
||||
{ uid = "5094", author_uids = ["Bibo-Joshi"] },
|
||||
{ uid = "5106", author_uid = ["aelkheir"] },
|
||||
]
|
||||
@@ -35,6 +35,8 @@
|
||||
- Used for sending media grouped together
|
||||
* - :meth:`~telegram.Bot.send_message`
|
||||
- Used for sending text messages
|
||||
* - :meth:`~telegram.Bot.send_message_draft`
|
||||
- Used for streaming partial text messages
|
||||
* - :meth:`~telegram.Bot.send_paid_media`
|
||||
- Used for sending paid media to channels
|
||||
* - :meth:`~telegram.Bot.send_photo`
|
||||
@@ -443,6 +445,8 @@
|
||||
- Used for setting the business accounts profile photo
|
||||
* - :meth:`~telegram.Bot.post_story`
|
||||
- Used for posting a story on behalf of business account.
|
||||
* - :meth:`~telegram.Bot.repost_story`
|
||||
- Used for reposting an existing story on behalf of business account.
|
||||
* - :meth:`~telegram.Bot.edit_story`
|
||||
- Used for editing business stories posted by the bot.
|
||||
* - :meth:`~telegram.Bot.convert_gift_to_stars`
|
||||
@@ -481,8 +485,12 @@
|
||||
- Used for getting basic info about a file
|
||||
* - :meth:`~telegram.Bot.get_available_gifts`
|
||||
- Used for getting information about gifts available for sending
|
||||
* - :meth:`~telegram.Bot.get_chat_gifts`
|
||||
- Used for getting information about gifts owned and hosted by a chat
|
||||
* - :meth:`~telegram.Bot.get_me`
|
||||
- Used for getting basic information about the bot
|
||||
* - :meth:`~telegram.Bot.get_user_gifts`
|
||||
- Used for getting information about gifts owned and hosted by a user
|
||||
* - :meth:`~telegram.Bot.save_prepared_inline_message`
|
||||
- Used for storing a message to be sent by a user of a Mini App
|
||||
|
||||
|
||||
@@ -83,6 +83,7 @@ Available Types
|
||||
telegram.forumtopicreopened
|
||||
telegram.generalforumtopichidden
|
||||
telegram.generalforumtopicunhidden
|
||||
telegram.giftbackground
|
||||
telegram.giftinfo
|
||||
telegram.giveaway
|
||||
telegram.giveawaycompleted
|
||||
@@ -181,6 +182,7 @@ Available Types
|
||||
telegram.telegramobject
|
||||
telegram.textquote
|
||||
telegram.uniquegift
|
||||
telegram.uniquegiftcolors
|
||||
telegram.uniquegiftbackdrop
|
||||
telegram.uniquegiftbackdropcolors
|
||||
telegram.uniquegiftinfo
|
||||
@@ -190,6 +192,7 @@ Available Types
|
||||
telegram.user
|
||||
telegram.userchatboosts
|
||||
telegram.userprofilephotos
|
||||
telegram.userrating
|
||||
telegram.usersshared
|
||||
telegram.venue
|
||||
telegram.video
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
GiftBackground
|
||||
==============
|
||||
|
||||
.. autoclass:: telegram.GiftBackground
|
||||
:members:
|
||||
:show-inheritance:
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
UniqueGiftColors
|
||||
================
|
||||
|
||||
.. autoclass:: telegram.UniqueGiftColors
|
||||
:members:
|
||||
:show-inheritance:
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
UserRating
|
||||
==========
|
||||
|
||||
.. autoclass:: telegram.UserRating
|
||||
:members:
|
||||
:show-inheritance:
|
||||
@@ -30,7 +30,7 @@
|
||||
|
||||
.. |message_thread_id| replace:: Unique identifier for the target message thread of the forum topic.
|
||||
|
||||
.. |message_thread_id_arg| replace:: Unique identifier for the target message thread (topic) of the forum; for forum supergroups only.
|
||||
.. |message_thread_id_arg| replace:: Unique identifier for the target message thread (topic) of a forum; for forum supergroups and private chats of bots with forum topic mode enabled only.
|
||||
|
||||
.. |parse_mode| replace:: Mode for parsing entities. See :class:`telegram.constants.ParseMode` and `formatting options <https://core.telegram.org/bots/api#formatting-options>`__ for more details.
|
||||
|
||||
|
||||
@@ -111,6 +111,7 @@ __all__ = (
|
||||
"GeneralForumTopicHidden",
|
||||
"GeneralForumTopicUnhidden",
|
||||
"Gift",
|
||||
"GiftBackground",
|
||||
"GiftInfo",
|
||||
"Gifts",
|
||||
"Giveaway",
|
||||
@@ -287,6 +288,7 @@ __all__ = (
|
||||
"UniqueGift",
|
||||
"UniqueGiftBackdrop",
|
||||
"UniqueGiftBackdropColors",
|
||||
"UniqueGiftColors",
|
||||
"UniqueGiftInfo",
|
||||
"UniqueGiftModel",
|
||||
"UniqueGiftSymbol",
|
||||
@@ -294,6 +296,7 @@ __all__ = (
|
||||
"User",
|
||||
"UserChatBoosts",
|
||||
"UserProfilePhotos",
|
||||
"UserRating",
|
||||
"UsersShared",
|
||||
"Venue",
|
||||
"Video",
|
||||
@@ -453,7 +456,7 @@ from ._forumtopic import (
|
||||
from ._games.callbackgame import CallbackGame
|
||||
from ._games.game import Game
|
||||
from ._games.gamehighscore import GameHighScore
|
||||
from ._gifts import AcceptedGiftTypes, Gift, GiftInfo, Gifts
|
||||
from ._gifts import AcceptedGiftTypes, Gift, GiftBackground, GiftInfo, Gifts
|
||||
from ._giveaway import Giveaway, GiveawayCompleted, GiveawayCreated, GiveawayWinners
|
||||
from ._inline.inlinekeyboardbutton import InlineKeyboardButton
|
||||
from ._inline.inlinekeyboardmarkup import InlineKeyboardMarkup
|
||||
@@ -597,6 +600,7 @@ from ._uniquegift import (
|
||||
UniqueGift,
|
||||
UniqueGiftBackdrop,
|
||||
UniqueGiftBackdropColors,
|
||||
UniqueGiftColors,
|
||||
UniqueGiftInfo,
|
||||
UniqueGiftModel,
|
||||
UniqueGiftSymbol,
|
||||
@@ -604,6 +608,7 @@ from ._uniquegift import (
|
||||
from ._update import Update
|
||||
from ._user import User
|
||||
from ._userprofilephotos import UserProfilePhotos
|
||||
from ._userrating import UserRating
|
||||
from ._videochat import (
|
||||
VideoChatEnded,
|
||||
VideoChatParticipantsInvited,
|
||||
|
||||
+359
-10
@@ -106,13 +106,14 @@ from telegram._utils.types import (
|
||||
TimePeriod,
|
||||
)
|
||||
from telegram._utils.warnings import warn
|
||||
from telegram._utils.warnings_transition import build_deprecation_warning_message
|
||||
from telegram._webhookinfo import WebhookInfo
|
||||
from telegram.constants import InlineQueryLimit, ReactionEmoji
|
||||
from telegram.error import EndPointNotFound, InvalidToken
|
||||
from telegram.request import BaseRequest, RequestData
|
||||
from telegram.request._httpxrequest import HTTPXRequest
|
||||
from telegram.request._requestparameter import RequestParameter
|
||||
from telegram.warnings import PTBUserWarning
|
||||
from telegram.warnings import PTBDeprecationWarning, PTBUserWarning
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from telegram import (
|
||||
@@ -1200,6 +1201,69 @@ class Bot(TelegramObject, contextlib.AbstractAsyncContextManager["Bot"]):
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
async def send_message_draft(
|
||||
self,
|
||||
chat_id: int,
|
||||
draft_id: int,
|
||||
text: str,
|
||||
message_thread_id: int | None = None,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
entities: Sequence["MessageEntity"] | None = None,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
connect_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
pool_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict | None = None,
|
||||
) -> bool:
|
||||
"""Use this method to stream a partial message to a user while the message is being
|
||||
generated; supported only for bots with forum topic mode enabled.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
Args:
|
||||
chat_id (:obj:`int`): Unique identifier for the target private chat.
|
||||
draft_id (:obj:`int`): Unique identifier of the message draft; must be non-zero.
|
||||
Changes of drafts with the same identifier are animated.
|
||||
text (:obj:`str`): Text of the message to be sent,
|
||||
:tg-const:`telegram.constants.MessageLimit.MIN_TEXT_LENGTH`-
|
||||
:tg-const:`telegram.constants.MessageLimit.MAX_TEXT_LENGTH` characters after
|
||||
entities parsing.
|
||||
parse_mode (:obj:`str`): |parse_mode|
|
||||
entities (Sequence[:class:`telegram.MessageEntity`], optional): Sequence of special
|
||||
entities that appear in message text, which can be specified instead of
|
||||
:paramref:`parse_mode`.
|
||||
|
||||
|sequenceargs|
|
||||
message_thread_id (:obj:`int`, optional): Unique identifier for the target
|
||||
message thread.
|
||||
|
||||
|
||||
Returns:
|
||||
:obj:`bool`: On success, :obj:`True` is returned.
|
||||
|
||||
Raises:
|
||||
:class:`telegram.error.TelegramError`
|
||||
|
||||
"""
|
||||
data: JSONDict = {
|
||||
"chat_id": chat_id,
|
||||
"draft_id": draft_id,
|
||||
"text": text,
|
||||
"entities": entities,
|
||||
}
|
||||
return await self._send_message(
|
||||
"sendMessageDraft",
|
||||
data,
|
||||
message_thread_id=message_thread_id,
|
||||
parse_mode=parse_mode,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
async def delete_messages(
|
||||
self,
|
||||
chat_id: int | str,
|
||||
@@ -1253,6 +1317,7 @@ class Bot(TelegramObject, contextlib.AbstractAsyncContextManager["Bot"]):
|
||||
video_start_timestamp: int | None = None,
|
||||
direct_messages_topic_id: int | None = None,
|
||||
suggested_post_parameters: "SuggestedPostParameters | None" = None,
|
||||
message_effect_id: str | None = None,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
@@ -1298,6 +1363,10 @@ class Bot(TelegramObject, contextlib.AbstractAsyncContextManager["Bot"]):
|
||||
forwarded to a direct messages chat.
|
||||
|
||||
.. versionadded:: 22.4
|
||||
message_effect_id (:obj:`str`, optional): Unique identifier of the message effect to be
|
||||
added to the message; only available when forwarding to private chats
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, the sent Message is returned.
|
||||
@@ -1325,6 +1394,7 @@ class Bot(TelegramObject, contextlib.AbstractAsyncContextManager["Bot"]):
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
direct_messages_topic_id=direct_messages_topic_id,
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def forward_messages(
|
||||
@@ -5905,7 +5975,9 @@ class Bot(TelegramObject, contextlib.AbstractAsyncContextManager["Bot"]):
|
||||
can_invite_users (:obj:`bool`, optional): Pass :obj:`True`, if the administrator can
|
||||
invite new users to the chat.
|
||||
can_restrict_members (:obj:`bool`, optional): Pass :obj:`True`, if the administrator
|
||||
can restrict, ban or unban chat members, or access supergroup statistics.
|
||||
can restrict, ban or unban chat members, or access supergroup statistics. For
|
||||
backward compatibility, defaults to :obj:`True` for promotions of channel
|
||||
administrators.
|
||||
can_pin_messages (:obj:`bool`, optional): Pass :obj:`True`, if the administrator can
|
||||
pin messages, for supergroups only.
|
||||
can_promote_members (:obj:`bool`, optional): Pass :obj:`True`, if the administrator can
|
||||
@@ -8347,6 +8419,7 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
||||
video_start_timestamp: int | None = None,
|
||||
direct_messages_topic_id: int | None = None,
|
||||
suggested_post_parameters: "SuggestedPostParameters | None" = None,
|
||||
message_effect_id: str | None = None,
|
||||
*,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: int | None = None,
|
||||
@@ -8408,6 +8481,10 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
||||
direct_messages_topic_id (:obj:`int`, optional): |direct_messages_topic_id|
|
||||
|
||||
.. versionadded:: 22.4
|
||||
message_effect_id (:obj:`str`, optional): Unique identifier of the message effect to be
|
||||
added to the message; only available when copying to private chats
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
Keyword Args:
|
||||
allow_sending_without_reply (:obj:`bool`, optional): |allow_sending_without_reply|
|
||||
@@ -8470,6 +8547,7 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
||||
"direct_messages_topic_id": direct_messages_topic_id,
|
||||
"video_start_timestamp": video_start_timestamp,
|
||||
"suggested_post_parameters": suggested_post_parameters,
|
||||
"message_effect_id": message_effect_id,
|
||||
}
|
||||
|
||||
result = await self._post(
|
||||
@@ -8903,8 +8981,9 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
||||
api_kwargs: JSONDict | None = None,
|
||||
) -> bool:
|
||||
"""
|
||||
Use this method to edit name and icon of a topic in a forum supergroup chat. The bot must
|
||||
be an administrator in the chat for this to work and must have the
|
||||
Use this method to edit name and icon of a topic in a forum supergroup chat or a private
|
||||
chat with a user. In the case of a supergroup chat the bot must be an administrator in the
|
||||
chat for this to work and must have the
|
||||
:paramref:`~telegram.ChatAdministratorRights.can_manage_topics` administrator rights,
|
||||
unless it is the creator of the topic.
|
||||
|
||||
@@ -9046,7 +9125,8 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
||||
) -> bool:
|
||||
"""
|
||||
Use this method to delete a forum topic along with all its messages in a forum supergroup
|
||||
chat. The bot must be an administrator in the chat for this to work and must have
|
||||
chat or a private chat with a user. In the case of a supergroup chat the bot must be an
|
||||
administrator in the chat for this to work and must have the
|
||||
:paramref:`~telegram.ChatAdministratorRights.can_delete_messages` administrator rights.
|
||||
|
||||
.. versionadded:: 20.0
|
||||
@@ -9088,10 +9168,11 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
||||
api_kwargs: JSONDict | None = None,
|
||||
) -> bool:
|
||||
"""
|
||||
Use this method to clear the list of pinned messages in a forum topic. The bot must
|
||||
be an administrator in the chat for this to work and must have
|
||||
:paramref:`~telegram.ChatAdministratorRights.can_pin_messages` administrator rights
|
||||
in the supergroup.
|
||||
Use this method to clear the list of pinned messages in a forum topic in a forum supergroup
|
||||
chat or a private chat with a user. In the case of a supergroup chat the bot must be an
|
||||
administrator in the chat for this to work and must have the
|
||||
:paramref:`~telegram.ChatAdministratorRights.can_pin_messages` administrator right in
|
||||
the supergroup.
|
||||
|
||||
.. versionadded:: 20.0
|
||||
|
||||
@@ -9861,11 +9942,15 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
||||
exclude_unsaved: bool | None = None,
|
||||
exclude_saved: bool | None = None,
|
||||
exclude_unlimited: bool | None = None,
|
||||
# tags: deprecated NEXT.VERSION; bot api 9.3
|
||||
exclude_limited: bool | None = None,
|
||||
exclude_unique: bool | None = None,
|
||||
sort_by_price: bool | None = None,
|
||||
offset: str | None = None,
|
||||
limit: int | None = None,
|
||||
exclude_limited_upgradable: bool | None = None,
|
||||
exclude_limited_non_upgradable: bool | None = None,
|
||||
exclude_from_blockchain: bool | None = None,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
@@ -9889,7 +9974,26 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
||||
be purchased an unlimited number of times.
|
||||
exclude_limited (:obj:`bool`, optional): Pass :obj:`True` to exclude gifts that can be
|
||||
purchased a limited number of times.
|
||||
|
||||
.. deprecated:: NEXT.VERSION
|
||||
Bot API 9.3 deprecated this parameter in favor of
|
||||
:paramref:`exclude_limited_upgradabale` and
|
||||
:paramref:`exclude_limited_non_upgradable`.
|
||||
exclude_limited_upgradable (:obj:`bool`, optional): Pass :obj:`True` to exclude gifts
|
||||
that can be purchased a limited number of times and can be upgraded to unique.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
exclude_limited_non_upgradable (:obj:`bool`, optional): Pass :obj:`True` to exclude
|
||||
gifts that can be purchased a limited number of times and can't be upgraded to
|
||||
unique
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
exclude_unique (:obj:`bool`, optional): Pass :obj:`True` to exclude unique gifts.
|
||||
exclude_from_blockchain (:obj:`bool`, optional): Pass :obj:`True` to exclude gifts
|
||||
that were assigned from the TON blockchain and can't be resold or transferred in
|
||||
Telegram.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
sort_by_price (:obj:`bool`, optional): Pass :obj:`True` to sort results by gift price
|
||||
instead of send date. Sorting is applied before pagination.
|
||||
offset (:obj:`str`, optional): Offset of the first entry to return as received from
|
||||
@@ -9905,13 +10009,29 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
||||
Raises:
|
||||
:class:`telegram.error.TelegramError`
|
||||
"""
|
||||
if exclude_limited is not None:
|
||||
self._warn(
|
||||
PTBDeprecationWarning(
|
||||
version="NEXT.VERSION",
|
||||
message=build_deprecation_warning_message(
|
||||
deprecated_name="exclude_limited",
|
||||
new_name="exclude_limited_(non_)upgradable",
|
||||
bot_api_version="9.3",
|
||||
object_type="parameter",
|
||||
),
|
||||
),
|
||||
stacklevel=2,
|
||||
)
|
||||
data: JSONDict = {
|
||||
"business_connection_id": business_connection_id,
|
||||
"exclude_unsaved": exclude_unsaved,
|
||||
"exclude_saved": exclude_saved,
|
||||
"exclude_unlimited": exclude_unlimited,
|
||||
"exclude_limited": exclude_limited,
|
||||
"exclude_limited_upgradable": exclude_limited_upgradable,
|
||||
"exclude_limited_non_upgradable": exclude_limited_non_upgradable,
|
||||
"exclude_unique": exclude_unique,
|
||||
"exclude_from_blockchain": exclude_from_blockchain,
|
||||
"sort_by_price": sort_by_price,
|
||||
"offset": offset,
|
||||
"limit": limit,
|
||||
@@ -11233,7 +11353,7 @@ CHAT_ACTIVITY_TIMEOUT` seconds.
|
||||
|
||||
Args:
|
||||
gift_id (:obj:`str` | :class:`~telegram.Gift`): Identifier of the gift or a
|
||||
:class:`~telegram.Gift` object
|
||||
:class:`~telegram.Gift` object; limited gifts can't be sent to channel chats
|
||||
user_id (:obj:`int`, optional): Required if :paramref:`chat_id` is not specified.
|
||||
Unique identifier of the target user that will receive the gift.
|
||||
|
||||
@@ -11575,6 +11695,227 @@ CHAT_ACTIVITY_TIMEOUT` seconds.
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
async def repost_story(
|
||||
self,
|
||||
business_connection_id: str,
|
||||
from_chat_id: int,
|
||||
from_story_id: int,
|
||||
active_period: TimePeriod,
|
||||
post_to_chat_page: bool | None = None,
|
||||
protect_content: ODVInput[bool] = DEFAULT_NONE,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
connect_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
pool_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict | None = None,
|
||||
) -> Story:
|
||||
"""
|
||||
Reposts a story on behalf of a business account from another business account.
|
||||
Both business accounts must be managed by the same bot, and the story on the source account
|
||||
must have been posted (or reposted) by the bot. Requires the
|
||||
:attr:`~telegram.BusinessBotRight.can_manage_stories` business bot right for both
|
||||
business accounts.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
Args:
|
||||
business_connection_id (:obj:`str`): Unique identifier of the business
|
||||
from_chat_id (:obj:`int`): Unique identifier of the chat which posted the story that
|
||||
should be reposted
|
||||
from_story_id (:obj:`int`): Unique identifier of the story that should be reposted
|
||||
active_period (:obj:`int` | :class:`datetime.timedelta`): Period after which the story
|
||||
is moved to the archive, in seconds; must be one of
|
||||
:tg-const:`telegram.constants.StoryLimit.SIX_HOURS`,
|
||||
:tg-const:`telegram.constants.StoryLimit.TWELVE_HOURS`,
|
||||
:tg-const:`telegram.constants.StoryLimit.ONE_DAY`, or
|
||||
:tg-const:`telegram.constants.StoryLimit.TWO_DAYS`.
|
||||
post_to_chat_page (:obj:`bool`, optional): Pass :obj:`True` to keep the story
|
||||
accessible after it expires.
|
||||
protect_content (:obj:`bool`, optional): Pass :obj:`True` if the content of the story
|
||||
must be protected from forwarding and screenshotting
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Story`
|
||||
|
||||
Raises:
|
||||
:class:`telegram.error.TelegramError`
|
||||
"""
|
||||
data: JSONDict = {
|
||||
"business_connection_id": business_connection_id,
|
||||
"from_chat_id": from_chat_id,
|
||||
"from_story_id": from_story_id,
|
||||
"active_period": active_period,
|
||||
"post_to_chat_page": post_to_chat_page,
|
||||
"protect_content": protect_content,
|
||||
}
|
||||
return Story.de_json(
|
||||
data=await self._post(
|
||||
"repostStory",
|
||||
data,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
),
|
||||
bot=self,
|
||||
)
|
||||
|
||||
async def get_user_gifts(
|
||||
self,
|
||||
user_id: int,
|
||||
exclude_unlimited: bool | None = None,
|
||||
exclude_limited_upgradable: bool | None = None,
|
||||
exclude_limited_non_upgradable: bool | None = None,
|
||||
exclude_from_blockchain: bool | None = None,
|
||||
exclude_unique: bool | None = None,
|
||||
sort_by_price: bool | None = None,
|
||||
offset: str | None = None,
|
||||
limit: int | None = None,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
connect_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
pool_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict | None = None,
|
||||
) -> OwnedGifts:
|
||||
"""Returns the gifts owned and hosted by a user.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
user_id (:obj:`int`): Unique identifier of the user
|
||||
exclude_unlimited (:obj:`bool`, optional): Pass :obj:`True` to exclude gifts that can be
|
||||
purchased an unlimited number of times
|
||||
exclude_limited_upgradable (:obj:`bool`, optional): Pass :obj:`True` to exclude gifts that
|
||||
can be purchased a limited number of times and can be upgraded to unique
|
||||
exclude_limited_non_upgradable (:obj:`bool`, optional): Pass :obj:`True` to exclude gifts
|
||||
that can be purchased a limited number of times and can't be upgraded to unique
|
||||
exclude_from_blockchain (:obj:`bool`, optional): Pass :obj:`True` to exclude gifts that
|
||||
were assigned from the TON blockchain and can't be resold or transferred in Telegram
|
||||
exclude_unique (:obj:`bool`, optional): Pass :obj:`True` to exclude unique gifts
|
||||
sort_by_price (:obj:`bool`, optional): Pass :obj:`True` to sort results by gift price
|
||||
instead of send date. Sorting is applied before pagination.
|
||||
offset (:obj:`str`, optional): Offset of the first entry to return as received from the
|
||||
previous request; use an empty string to get the first chunk of results
|
||||
limit (:obj:`int`, optional): The maximum number of gifts to be returned;
|
||||
:tg-const:`~telegram.constants.BusinessLimit.MIN_GIFT_RESULTS` -
|
||||
:tg-const:`~telegram.constants.BusinessLimit.MAX_GIFT_RESLUTS`.
|
||||
Defaults to :tg-const:`~telegram.constants.BusinessLimit.MAX_GIFT_RESLUTS`
|
||||
|
||||
Returns:
|
||||
:class:`telegram.OwnedGifts`: The owned gifts for the user.
|
||||
|
||||
Raises:
|
||||
:class:`telegram.error.TelegramError`
|
||||
"""
|
||||
data: JSONDict = {
|
||||
"user_id": user_id,
|
||||
"exclude_unlimited": exclude_unlimited,
|
||||
"exclude_limited_upgradable": exclude_limited_upgradable,
|
||||
"exclude_limited_non_upgradable": exclude_limited_non_upgradable,
|
||||
"exclude_from_blockchain": exclude_from_blockchain,
|
||||
"exclude_unique": exclude_unique,
|
||||
"sort_by_price": sort_by_price,
|
||||
"offset": offset,
|
||||
"limit": limit,
|
||||
}
|
||||
|
||||
result = await self._post(
|
||||
"getUserGifts",
|
||||
data,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
return OwnedGifts.de_json(result, self)
|
||||
|
||||
async def get_chat_gifts(
|
||||
self,
|
||||
chat_id: int | str,
|
||||
exclude_unsaved: bool | None = None,
|
||||
exclude_saved: bool | None = None,
|
||||
exclude_unlimited: bool | None = None,
|
||||
exclude_limited_upgradable: bool | None = None,
|
||||
exclude_limited_non_upgradable: bool | None = None,
|
||||
exclude_from_blockchain: bool | None = None,
|
||||
exclude_unique: bool | None = None,
|
||||
sort_by_price: bool | None = None,
|
||||
offset: str | None = None,
|
||||
limit: int | None = None,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
connect_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
pool_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict | None = None,
|
||||
) -> OwnedGifts:
|
||||
"""Use this method to get gifts owned by a chat.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
Args:
|
||||
chat_id (:obj:`int` | :obj:`str`): |chat_id_channel|
|
||||
exclude_unsaved (:obj:`bool`, optional): Pass :obj:`True` to exclude gifts that aren't
|
||||
saved to the chat's profile page. Always :obj:`True`, unless the bot has the
|
||||
:attr:`~telegram.ChatAdministratorRights..can_post_messages` administrator right in the
|
||||
channel.
|
||||
exclude_saved (:obj:`bool`, optional): Pass :obj:`True` to exclude gifts that are saved to
|
||||
the chat's profile page. Always :obj:`False`, unless the bot has the
|
||||
:attr:`~telegram.ChatAdministratorRights..can_post_messages` administrator right in the
|
||||
channel.
|
||||
exclude_unlimited (:obj:`bool`, optional): Pass :obj:`True` to exclude gifts that can be
|
||||
purchased an unlimited number of times
|
||||
exclude_limited_upgradable (:obj:`bool`, optional): Pass :obj:`True` to exclude gifts that
|
||||
can be purchased a limited number of times and can be upgraded to unique
|
||||
exclude_limited_non_upgradable (:obj:`bool`, optional): Pass :obj:`True` to exclude gifts
|
||||
that can be purchased a limited number of times and can't be upgraded to unique
|
||||
exclude_from_blockchain (:obj:`bool`, optional): Pass :obj:`True` to exclude gifts that
|
||||
were assigned from the TON blockchain and can't be resold or transferred in Telegram
|
||||
exclude_unique (:obj:`bool`, optional): Pass :obj:`True` to exclude unique gifts
|
||||
sort_by_price (:obj:`bool`, optional): Pass :obj:`True` to sort results by gift price
|
||||
instead of send date. Sorting is applied before pagination.
|
||||
offset (:obj:`str`, optional): Offset of the first entry to return as received from the
|
||||
previous request; use an empty string to get the first chunk of results
|
||||
limit (:obj:`int`, optional): The maximum number of gifts to be returned;
|
||||
:tg-const:`~telegram.constants.BusinessLimit.MIN_GIFT_RESULTS` -
|
||||
:tg-const:`~telegram.constants.BusinessLimit.MAX_GIFT_RESLUTS`.
|
||||
Defaults to :tg-const:`~telegram.constants.BusinessLimit.MAX_GIFT_RESLUTS`
|
||||
|
||||
Returns:
|
||||
:class:`telegram.OwnedGifts`: The owned gifts for the chat.
|
||||
|
||||
Raises:
|
||||
:class:`telegram.error.TelegramError`
|
||||
"""
|
||||
|
||||
data: JSONDict = {
|
||||
"chat_id": chat_id,
|
||||
"exclude_unsaved": exclude_unsaved,
|
||||
"exclude_saved": exclude_saved,
|
||||
"exclude_unlimited": exclude_unlimited,
|
||||
"exclude_limited_upgradable": exclude_limited_upgradable,
|
||||
"exclude_limited_non_upgradable": exclude_limited_non_upgradable,
|
||||
"exclude_from_blockchain": exclude_from_blockchain,
|
||||
"exclude_unique": exclude_unique,
|
||||
"sort_by_price": sort_by_price,
|
||||
"offset": offset,
|
||||
"limit": limit,
|
||||
}
|
||||
|
||||
result = await self._post(
|
||||
"getChatGifts",
|
||||
data,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
return OwnedGifts.de_json(result, self)
|
||||
|
||||
def to_dict(self, recursive: bool = True) -> JSONDict: # noqa: ARG002
|
||||
"""See :meth:`telegram.TelegramObject.to_dict`."""
|
||||
data: JSONDict = {"id": self.id, "username": self.username, "first_name": self.first_name}
|
||||
@@ -11589,6 +11930,8 @@ CHAT_ACTIVITY_TIMEOUT` seconds.
|
||||
"""Alias for :meth:`get_me`"""
|
||||
sendMessage = send_message
|
||||
"""Alias for :meth:`send_message`"""
|
||||
sendMessageDraft = send_message_draft
|
||||
"""Alias for :meth:`send_message_draft`"""
|
||||
deleteMessage = delete_message
|
||||
"""Alias for :meth:`delete_message`"""
|
||||
deleteMessages = delete_messages
|
||||
@@ -11899,3 +12242,9 @@ CHAT_ACTIVITY_TIMEOUT` seconds.
|
||||
"""Alias for :meth:`approve_suggested_post`"""
|
||||
declineSuggestedPost = decline_suggested_post
|
||||
"""Alias for :meth:`decline_suggested_post`"""
|
||||
repostStory = repost_story
|
||||
"""Alias for :meth:`repost_story`"""
|
||||
getUserGifts = get_user_gifts
|
||||
"""Alias for :meth:`get_user_gifts`"""
|
||||
getChatGifts = get_chat_gifts
|
||||
"""Alias for :meth:`get_chat_gifts`"""
|
||||
|
||||
@@ -874,6 +874,7 @@ class CallbackQuery(TelegramObject):
|
||||
allow_paid_broadcast: bool | None = None,
|
||||
video_start_timestamp: int | None = None,
|
||||
suggested_post_parameters: "SuggestedPostParameters | None" = None,
|
||||
message_effect_id: str | None = None,
|
||||
*,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: int | None = None,
|
||||
@@ -925,6 +926,7 @@ class CallbackQuery(TelegramObject):
|
||||
show_caption_above_media=show_caption_above_media,
|
||||
allow_paid_broadcast=allow_paid_broadcast,
|
||||
suggested_post_parameters=suggested_post_parameters,
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
MAX_ANSWER_TEXT_LENGTH: Final[int] = (
|
||||
|
||||
@@ -67,9 +67,11 @@ if TYPE_CHECKING:
|
||||
Message,
|
||||
MessageEntity,
|
||||
MessageId,
|
||||
OwnedGifts,
|
||||
PhotoSize,
|
||||
ReplyParameters,
|
||||
Sticker,
|
||||
Story,
|
||||
SuggestedPostParameters,
|
||||
UserChatBoosts,
|
||||
Venue,
|
||||
@@ -1080,6 +1082,44 @@ class _ChatBase(TelegramObject):
|
||||
suggested_post_parameters=suggested_post_parameters,
|
||||
)
|
||||
|
||||
async def send_message_draft(
|
||||
self,
|
||||
draft_id: int,
|
||||
text: str,
|
||||
message_thread_id: int | None = None,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
entities: Sequence["MessageEntity"] | None = None,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
connect_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
pool_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict | None = None,
|
||||
) -> bool:
|
||||
"""Shortcut for::
|
||||
|
||||
await bot.send_message_draft(update.effective_chat.id, *args, **kwargs)
|
||||
|
||||
For the documentation of the arguments, please see :meth:`telegram.Bot.send_message_draft`.
|
||||
|
||||
Returns:
|
||||
:obj:`bool`: On success, :obj:`True` is returned.
|
||||
|
||||
"""
|
||||
return await self.get_bot().send_message_draft(
|
||||
chat_id=self.id,
|
||||
draft_id=draft_id,
|
||||
text=text,
|
||||
message_thread_id=message_thread_id,
|
||||
parse_mode=parse_mode,
|
||||
entities=entities,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
async def delete_message(
|
||||
self,
|
||||
message_id: int,
|
||||
@@ -2323,6 +2363,7 @@ class _ChatBase(TelegramObject):
|
||||
video_start_timestamp: int | None = None,
|
||||
direct_messages_topic_id: int | None = None,
|
||||
suggested_post_parameters: "SuggestedPostParameters | None" = None,
|
||||
message_effect_id: str | None = None,
|
||||
*,
|
||||
reply_to_message_id: int | None = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
@@ -2368,6 +2409,7 @@ class _ChatBase(TelegramObject):
|
||||
allow_paid_broadcast=allow_paid_broadcast,
|
||||
direct_messages_topic_id=direct_messages_topic_id,
|
||||
suggested_post_parameters=suggested_post_parameters,
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def copy_message(
|
||||
@@ -2387,6 +2429,7 @@ class _ChatBase(TelegramObject):
|
||||
video_start_timestamp: int | None = None,
|
||||
direct_messages_topic_id: int | None = None,
|
||||
suggested_post_parameters: "SuggestedPostParameters | None" = None,
|
||||
message_effect_id: str | None = None,
|
||||
*,
|
||||
reply_to_message_id: int | None = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
@@ -2432,6 +2475,7 @@ class _ChatBase(TelegramObject):
|
||||
allow_paid_broadcast=allow_paid_broadcast,
|
||||
direct_messages_topic_id=direct_messages_topic_id,
|
||||
suggested_post_parameters=suggested_post_parameters,
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def send_copies(
|
||||
@@ -2538,6 +2582,7 @@ class _ChatBase(TelegramObject):
|
||||
video_start_timestamp: int | None = None,
|
||||
direct_messages_topic_id: int | None = None,
|
||||
suggested_post_parameters: "SuggestedPostParameters | None" = None,
|
||||
message_effect_id: str | None = None,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
@@ -2574,6 +2619,7 @@ class _ChatBase(TelegramObject):
|
||||
message_thread_id=message_thread_id,
|
||||
direct_messages_topic_id=direct_messages_topic_id,
|
||||
suggested_post_parameters=suggested_post_parameters,
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def forward_to(
|
||||
@@ -2586,6 +2632,7 @@ class _ChatBase(TelegramObject):
|
||||
video_start_timestamp: int | None = None,
|
||||
direct_messages_topic_id: int | None = None,
|
||||
suggested_post_parameters: "SuggestedPostParameters | None" = None,
|
||||
message_effect_id: str | None = None,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
@@ -2623,6 +2670,7 @@ class _ChatBase(TelegramObject):
|
||||
message_thread_id=message_thread_id,
|
||||
direct_messages_topic_id=direct_messages_topic_id,
|
||||
suggested_post_parameters=suggested_post_parameters,
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def forward_messages_from(
|
||||
@@ -3854,6 +3902,99 @@ class _ChatBase(TelegramObject):
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
async def repost_story(
|
||||
self,
|
||||
business_connection_id: str,
|
||||
from_story_id: int,
|
||||
active_period: TimePeriod,
|
||||
post_to_chat_page: bool | None = None,
|
||||
protect_content: ODVInput[bool] = DEFAULT_NONE,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
connect_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
pool_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict | None = None,
|
||||
) -> "Story":
|
||||
"""Shortcut for::
|
||||
|
||||
await bot.repost_story(
|
||||
from_chat_id=update.effective_chat.id,
|
||||
*args, **kwargs
|
||||
)
|
||||
|
||||
For the documentation of the arguments, please see :meth:`telegram.Bot.repost_story`.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
Returns:
|
||||
:class:`Story`: On success, :class:`Story` is returned.
|
||||
|
||||
"""
|
||||
return await self.get_bot().repost_story(
|
||||
business_connection_id=business_connection_id,
|
||||
from_chat_id=self.id,
|
||||
from_story_id=from_story_id,
|
||||
active_period=active_period,
|
||||
post_to_chat_page=post_to_chat_page,
|
||||
protect_content=protect_content,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
async def get_gifts(
|
||||
self,
|
||||
exclude_unsaved: bool | None = None,
|
||||
exclude_saved: bool | None = None,
|
||||
exclude_unlimited: bool | None = None,
|
||||
exclude_limited_upgradable: bool | None = None,
|
||||
exclude_limited_non_upgradable: bool | None = None,
|
||||
exclude_from_blockchain: bool | None = None,
|
||||
exclude_unique: bool | None = None,
|
||||
sort_by_price: bool | None = None,
|
||||
offset: str | None = None,
|
||||
limit: int | None = None,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
connect_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
pool_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict | None = None,
|
||||
) -> "OwnedGifts":
|
||||
"""Shortcut for::
|
||||
|
||||
await bot.get_chat_gifts(chat_id=update.effective_chat.id)
|
||||
|
||||
For the documentation of the arguments, please see
|
||||
:meth:`telegram.Bot.get_chat_gifts`.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
Returns:
|
||||
:class:`telegram.OwnedGifts`: On success, returns the gifts owned by the chat.
|
||||
"""
|
||||
return await self.get_bot().get_chat_gifts(
|
||||
chat_id=self.id,
|
||||
exclude_unsaved=exclude_unsaved,
|
||||
exclude_saved=exclude_saved,
|
||||
exclude_unlimited=exclude_unlimited,
|
||||
exclude_limited_upgradable=exclude_limited_upgradable,
|
||||
exclude_limited_non_upgradable=exclude_limited_non_upgradable,
|
||||
exclude_from_blockchain=exclude_from_blockchain,
|
||||
exclude_unique=exclude_unique,
|
||||
sort_by_price=sort_by_price,
|
||||
offset=offset,
|
||||
limit=limit,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
|
||||
class Chat(_ChatBase):
|
||||
"""This object represents a chat.
|
||||
|
||||
@@ -30,6 +30,8 @@ from telegram._chatpermissions import ChatPermissions
|
||||
from telegram._files.chatphoto import ChatPhoto
|
||||
from telegram._gifts import AcceptedGiftTypes
|
||||
from telegram._reaction import ReactionType
|
||||
from telegram._uniquegift import UniqueGiftColors
|
||||
from telegram._userrating import UserRating
|
||||
from telegram._utils.argumentparsing import (
|
||||
de_json_optional,
|
||||
de_list_optional,
|
||||
@@ -232,6 +234,19 @@ class ChatFullInfo(_ChatBase):
|
||||
chat; for direct messages chats only.
|
||||
|
||||
.. versionadded:: 22.4
|
||||
rating (:class:`telegram.UserRating`, optional): For private chats, the rating of the user
|
||||
if any.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
unique_gift_colors (:class:`telegram.UniqueGiftColors`, optional): The color scheme based
|
||||
on a unique gift that must be used for the chat's name, message replies and link
|
||||
previews
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
paid_message_star_count (:obj:`int`, optional): The number of Telegram Stars a general user
|
||||
have to pay to send a message to the chat
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
Attributes:
|
||||
id (:obj:`int`): Unique identifier for this chat.
|
||||
@@ -404,6 +419,19 @@ class ChatFullInfo(_ChatBase):
|
||||
chat; for direct messages chats only.
|
||||
|
||||
.. versionadded:: 22.4
|
||||
rating (:class:`telegram.UserRating`): Optional. For private chats, the rating of the user
|
||||
if any.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
unique_gift_colors (:class:`telegram.UniqueGiftColors`): Optional. The color scheme based
|
||||
on a unique gift that must be used for the chat's name, message replies and link
|
||||
previews
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
paid_message_star_count (:obj:`int`): Optional. The number of Telegram Stars a general user
|
||||
have to pay to send a message to the chat
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
.. _accent colors: https://core.telegram.org/bots/api#accent-colors
|
||||
.. _topics: https://telegram.org/blog/topics-in-groups-collectible-usernames#topics-in-groups
|
||||
@@ -440,6 +468,7 @@ class ChatFullInfo(_ChatBase):
|
||||
"linked_chat_id",
|
||||
"location",
|
||||
"max_reaction_count",
|
||||
"paid_message_star_count",
|
||||
"parent_chat",
|
||||
"permissions",
|
||||
"personal_chat",
|
||||
@@ -447,7 +476,9 @@ class ChatFullInfo(_ChatBase):
|
||||
"pinned_message",
|
||||
"profile_accent_color_id",
|
||||
"profile_background_custom_emoji_id",
|
||||
"rating",
|
||||
"sticker_set_name",
|
||||
"unique_gift_colors",
|
||||
"unrestrict_boost_count",
|
||||
)
|
||||
|
||||
@@ -500,6 +531,9 @@ class ChatFullInfo(_ChatBase):
|
||||
can_send_paid_media: bool | None = None,
|
||||
is_direct_messages: bool | None = None,
|
||||
parent_chat: Chat | None = None,
|
||||
rating: UserRating | None = None,
|
||||
unique_gift_colors: UniqueGiftColors | None = None,
|
||||
paid_message_star_count: int | None = None,
|
||||
*,
|
||||
api_kwargs: JSONDict | None = None,
|
||||
):
|
||||
@@ -563,6 +597,9 @@ class ChatFullInfo(_ChatBase):
|
||||
self.can_send_paid_media: bool | None = can_send_paid_media
|
||||
self.accepted_gift_types: AcceptedGiftTypes = accepted_gift_types
|
||||
self.parent_chat: Chat | None = parent_chat
|
||||
self.rating: UserRating | None = rating
|
||||
self.unique_gift_colors: UniqueGiftColors | None = unique_gift_colors
|
||||
self.paid_message_star_count: int | None = paid_message_star_count
|
||||
|
||||
@property
|
||||
def slow_mode_delay(self) -> int | dtm.timedelta | None:
|
||||
@@ -615,4 +652,9 @@ class ChatFullInfo(_ChatBase):
|
||||
)
|
||||
data["parent_chat"] = de_json_optional(data.get("parent_chat"), Chat, bot)
|
||||
|
||||
data["rating"] = de_json_optional(data.get("rating"), UserRating, bot)
|
||||
data["unique_gift_colors"] = de_json_optional(
|
||||
data.get("unique_gift_colors"), UniqueGiftColors, bot
|
||||
)
|
||||
|
||||
return super().de_json(data=data, bot=bot)
|
||||
|
||||
@@ -22,6 +22,7 @@ import datetime as dtm
|
||||
from collections.abc import Sequence
|
||||
from typing import TYPE_CHECKING, Optional
|
||||
|
||||
from telegram._chat import Chat
|
||||
from telegram._messageentity import MessageEntity
|
||||
from telegram._telegramobject import TelegramObject
|
||||
from telegram._user import User
|
||||
@@ -51,6 +52,10 @@ class ChecklistTask(TelegramObject):
|
||||
entities that appear in the task text.
|
||||
completed_by_user (:class:`telegram.User`, optional): User that completed the task; omitted
|
||||
if the task wasn't completed
|
||||
completed_by_chat (:class:`telegram.Chat`, optional): Chat that completed the task; omitted
|
||||
if the task wasn't completed by a chat
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
completion_date (:class:`datetime.datetime`, optional): Point in time when
|
||||
the task was completed; :attr:`~telegram.constants.ZERO_DATE` if the task wasn't
|
||||
completed
|
||||
@@ -64,6 +69,10 @@ class ChecklistTask(TelegramObject):
|
||||
entities that appear in the task text.
|
||||
completed_by_user (:class:`telegram.User`): Optional. User that completed the task; omitted
|
||||
if the task wasn't completed
|
||||
completed_by_chat (:class:`telegram.Chat`): Optional. Chat that completed the task; omitted
|
||||
if the task wasn't completed by a chat
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
completion_date (:class:`datetime.datetime`): Optional. Point in time when
|
||||
the task was completed; :attr:`~telegram.constants.ZERO_DATE` if the task wasn't
|
||||
completed
|
||||
@@ -72,6 +81,7 @@ class ChecklistTask(TelegramObject):
|
||||
"""
|
||||
|
||||
__slots__ = (
|
||||
"completed_by_chat",
|
||||
"completed_by_user",
|
||||
"completion_date",
|
||||
"id",
|
||||
@@ -86,6 +96,7 @@ class ChecklistTask(TelegramObject):
|
||||
text_entities: Sequence[MessageEntity] | None = None,
|
||||
completed_by_user: User | None = None,
|
||||
completion_date: dtm.datetime | None = None,
|
||||
completed_by_chat: Chat | None = None,
|
||||
*,
|
||||
api_kwargs: JSONDict | None = None,
|
||||
):
|
||||
@@ -94,6 +105,7 @@ class ChecklistTask(TelegramObject):
|
||||
self.text: str = text
|
||||
self.text_entities: tuple[MessageEntity, ...] = parse_sequence_arg(text_entities)
|
||||
self.completed_by_user: User | None = completed_by_user
|
||||
self.completed_by_chat: Chat | None = completed_by_chat
|
||||
self.completion_date: dtm.datetime | None = completion_date
|
||||
|
||||
self._id_attrs = (self.id,)
|
||||
@@ -114,6 +126,7 @@ class ChecklistTask(TelegramObject):
|
||||
data["completion_date"] = from_timestamp(date, tzinfo=loc_tzinfo)
|
||||
|
||||
data["completed_by_user"] = de_json_optional(data.get("completed_by_user"), User, bot)
|
||||
data["completed_by_chat"] = de_json_optional(data.get("completed_by_chat"), Chat, bot)
|
||||
data["text_entities"] = de_list_optional(data.get("text_entities"), MessageEntity, bot)
|
||||
|
||||
return super().de_json(data=data, bot=bot)
|
||||
|
||||
@@ -38,6 +38,10 @@ class ForumTopic(TelegramObject):
|
||||
icon_color (:obj:`int`): Color of the topic icon in RGB format
|
||||
icon_custom_emoji_id (:obj:`str`, optional): Unique identifier of the custom emoji shown
|
||||
as the topic icon.
|
||||
is_name_implicit (:obj:`bool`, optional): :obj:`True`, if the name of the topic wasn't
|
||||
specified explicitly by its creator and likely needs to be changed by the bot.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
Attributes:
|
||||
message_thread_id (:obj:`int`): Unique identifier of the forum topic
|
||||
@@ -45,9 +49,19 @@ class ForumTopic(TelegramObject):
|
||||
icon_color (:obj:`int`): Color of the topic icon in RGB format
|
||||
icon_custom_emoji_id (:obj:`str`): Optional. Unique identifier of the custom emoji shown
|
||||
as the topic icon.
|
||||
is_name_implicit (:obj:`bool`): Optional. :obj:`True`, if the name of the topic wasn't
|
||||
specified explicitly by its creator and likely needs to be changed by the bot.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
"""
|
||||
|
||||
__slots__ = ("icon_color", "icon_custom_emoji_id", "message_thread_id", "name")
|
||||
__slots__ = (
|
||||
"icon_color",
|
||||
"icon_custom_emoji_id",
|
||||
"is_name_implicit",
|
||||
"message_thread_id",
|
||||
"name",
|
||||
)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
@@ -55,6 +69,7 @@ class ForumTopic(TelegramObject):
|
||||
name: str,
|
||||
icon_color: int,
|
||||
icon_custom_emoji_id: str | None = None,
|
||||
is_name_implicit: bool | None = None,
|
||||
*,
|
||||
api_kwargs: JSONDict | None = None,
|
||||
):
|
||||
@@ -63,6 +78,7 @@ class ForumTopic(TelegramObject):
|
||||
self.name: str = name
|
||||
self.icon_color: int = icon_color
|
||||
self.icon_custom_emoji_id: str | None = icon_custom_emoji_id
|
||||
self.is_name_implicit: bool | None = is_name_implicit
|
||||
|
||||
self._id_attrs = (self.message_thread_id, self.name, self.icon_color)
|
||||
|
||||
@@ -84,21 +100,30 @@ class ForumTopicCreated(TelegramObject):
|
||||
icon_color (:obj:`int`): Color of the topic icon in RGB format
|
||||
icon_custom_emoji_id (:obj:`str`, optional): Unique identifier of the custom emoji shown
|
||||
as the topic icon.
|
||||
is_name_implicit (:obj:`bool`, optional): :obj:`True`, if the name of the topic wasn't
|
||||
specified explicitly by its creator and likely needs to be changed by the bot.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
Attributes:
|
||||
name (:obj:`str`): Name of the topic
|
||||
icon_color (:obj:`int`): Color of the topic icon in RGB format
|
||||
icon_custom_emoji_id (:obj:`str`): Optional. Unique identifier of the custom emoji shown
|
||||
as the topic icon.
|
||||
is_name_implicit (:obj:`bool`): Optional. :obj:`True`, if the name of the topic wasn't
|
||||
specified explicitly by its creator and likely needs to be changed by the bot.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
"""
|
||||
|
||||
__slots__ = ("icon_color", "icon_custom_emoji_id", "name")
|
||||
__slots__ = ("icon_color", "icon_custom_emoji_id", "is_name_implicit", "name")
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
name: str,
|
||||
icon_color: int,
|
||||
icon_custom_emoji_id: str | None = None,
|
||||
is_name_implicit: bool | None = None,
|
||||
*,
|
||||
api_kwargs: JSONDict | None = None,
|
||||
):
|
||||
@@ -106,6 +131,7 @@ class ForumTopicCreated(TelegramObject):
|
||||
self.name: str = name
|
||||
self.icon_color: int = icon_color
|
||||
self.icon_custom_emoji_id: str | None = icon_custom_emoji_id
|
||||
self.is_name_implicit: bool | None = is_name_implicit
|
||||
|
||||
self._id_attrs = (self.name, self.icon_color)
|
||||
|
||||
|
||||
+157
-7
@@ -34,6 +34,55 @@ if TYPE_CHECKING:
|
||||
from telegram import Bot
|
||||
|
||||
|
||||
class GiftBackground(TelegramObject):
|
||||
"""This object describes the background of a gift.
|
||||
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal if their :attr:`center_color`, :attr:`edge_color` and :attr:`text_color` are
|
||||
equal.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
Args:
|
||||
center_color (:obj:`int`): Center color of the background in RGB format.
|
||||
edge_color (:obj:`int`): Edge color of the background in RGB format.
|
||||
text_color (:obj:`int`): Text color of the background in RGB format.
|
||||
|
||||
Attributes:
|
||||
center_color (:obj:`int`): Center color of the background in RGB format.
|
||||
edge_color (:obj:`int`): Edge color of the background in RGB format.
|
||||
text_color (:obj:`int`): Text color of the background in RGB format.
|
||||
|
||||
"""
|
||||
|
||||
__slots__ = (
|
||||
"center_color",
|
||||
"edge_color",
|
||||
"text_color",
|
||||
)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
center_color: int,
|
||||
edge_color: int,
|
||||
text_color: int,
|
||||
*,
|
||||
api_kwargs: JSONDict | None = None,
|
||||
):
|
||||
super().__init__(api_kwargs=api_kwargs)
|
||||
self.center_color: int = center_color
|
||||
self.edge_color: int = edge_color
|
||||
self.text_color: int = text_color
|
||||
|
||||
self._id_attrs = (
|
||||
self.center_color,
|
||||
self.edge_color,
|
||||
self.text_color,
|
||||
)
|
||||
|
||||
self._freeze()
|
||||
|
||||
|
||||
class Gift(TelegramObject):
|
||||
"""This object represents a gift that can be sent by the bot.
|
||||
|
||||
@@ -48,9 +97,9 @@ class Gift(TelegramObject):
|
||||
star_count (:obj:`int`): The number of Telegram Stars that must be paid to send the
|
||||
sticker.
|
||||
total_count (:obj:`int`, optional): The total number of the gifts of this type that can be
|
||||
sent; for limited gifts only.
|
||||
sent by all users; for limited gifts only.
|
||||
remaining_count (:obj:`int`, optional): The number of remaining gifts of this type that can
|
||||
be sent; for limited gifts only.
|
||||
be sent by all users; for limited gifts only.
|
||||
upgrade_star_count (:obj:`int`, optional): The number of Telegram Stars that must be paid
|
||||
to upgrade the gift to a unique one.
|
||||
|
||||
@@ -59,6 +108,29 @@ class Gift(TelegramObject):
|
||||
published the gift.
|
||||
|
||||
.. versionadded:: 22.4
|
||||
personal_total_count (:obj:`int`, optional): The total number of gifts of this type that
|
||||
can be sent by the bot; for limited gifts only.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
personal_remaining_count (:obj:`int`, optional): The number of remaining gifts of this type
|
||||
that can be sent by the bot; for limited gifts only.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
background (:class:`GiftBackground`, optional): Background of the gift.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
is_premium (:obj:`bool`, optional): :obj:`True`, if the gift can only be purchased by
|
||||
Telegram Premium subscribers.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
has_colors (:obj:`bool`, optional): :obj:`True`, if the gift can be used (after being
|
||||
upgraded) to customize a user's appearance.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
unique_gift_variant_count (:obj:`int`, optional): The total number of different unique
|
||||
gifts that can be obtained by upgrading the gift.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
Attributes:
|
||||
id (:obj:`str`): Unique identifier of the gift.
|
||||
@@ -66,9 +138,9 @@ class Gift(TelegramObject):
|
||||
star_count (:obj:`int`): The number of Telegram Stars that must be paid to send the
|
||||
sticker.
|
||||
total_count (:obj:`int`): Optional. The total number of the gifts of this type that can be
|
||||
sent; for limited gifts only.
|
||||
sent by all users; for limited gifts only.
|
||||
remaining_count (:obj:`int`): Optional. The number of remaining gifts of this type that can
|
||||
be sent; for limited gifts only.
|
||||
be sent by all users; for limited gifts only.
|
||||
upgrade_star_count (:obj:`int`): Optional. The number of Telegram Stars that must be paid
|
||||
to upgrade the gift to a unique one.
|
||||
|
||||
@@ -77,16 +149,45 @@ class Gift(TelegramObject):
|
||||
published the gift.
|
||||
|
||||
.. versionadded:: 22.4
|
||||
personal_total_count (:obj:`int`): Optional. The total number of gifts of this type that
|
||||
can be sent by the bot; for limited gifts only.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
personal_remaining_count (:obj:`int`): Optional. The number of remaining gifts of this type
|
||||
that can be sent by the bot; for limited gifts only.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
background (:class:`GiftBackground`): Optional. Background of the gift.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
is_premium (:obj:`bool`): Optional. :obj:`True`, if the gift can only be purchased by
|
||||
Telegram Premium subscribers.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
has_colors (:obj:`bool`): Optional. :obj:`True`, if the gift can be used (after being
|
||||
upgraded) to customize a user's appearance.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
unique_gift_variant_count (:obj:`int`): Optional. The total number of different unique
|
||||
gifts that can be obtained by upgrading the gift.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
"""
|
||||
|
||||
__slots__ = (
|
||||
"background",
|
||||
"has_colors",
|
||||
"id",
|
||||
"is_premium",
|
||||
"personal_remaining_count",
|
||||
"personal_total_count",
|
||||
"publisher_chat",
|
||||
"remaining_count",
|
||||
"star_count",
|
||||
"sticker",
|
||||
"total_count",
|
||||
"unique_gift_variant_count",
|
||||
"upgrade_star_count",
|
||||
)
|
||||
|
||||
@@ -99,6 +200,12 @@ class Gift(TelegramObject):
|
||||
remaining_count: int | None = None,
|
||||
upgrade_star_count: int | None = None,
|
||||
publisher_chat: Chat | None = None,
|
||||
personal_total_count: int | None = None,
|
||||
personal_remaining_count: int | None = None,
|
||||
background: GiftBackground | None = None,
|
||||
is_premium: bool | None = None,
|
||||
has_colors: bool | None = None,
|
||||
unique_gift_variant_count: int | None = None,
|
||||
*,
|
||||
api_kwargs: JSONDict | None = None,
|
||||
):
|
||||
@@ -110,6 +217,12 @@ class Gift(TelegramObject):
|
||||
self.remaining_count: int | None = remaining_count
|
||||
self.upgrade_star_count: int | None = upgrade_star_count
|
||||
self.publisher_chat: Chat | None = publisher_chat
|
||||
self.personal_total_count: int | None = personal_total_count
|
||||
self.personal_remaining_count: int | None = personal_remaining_count
|
||||
self.background: GiftBackground | None = background
|
||||
self.is_premium: bool | None = is_premium
|
||||
self.has_colors: bool | None = has_colors
|
||||
self.unique_gift_variant_count: int | None = unique_gift_variant_count
|
||||
|
||||
self._id_attrs = (self.id,)
|
||||
|
||||
@@ -122,6 +235,7 @@ class Gift(TelegramObject):
|
||||
|
||||
data["sticker"] = de_json_optional(data.get("sticker"), Sticker, bot)
|
||||
data["publisher_chat"] = de_json_optional(data.get("publisher_chat"), Chat, bot)
|
||||
data["background"] = de_json_optional(data.get("background"), GiftBackground, bot)
|
||||
return super().de_json(data=data, bot=bot)
|
||||
|
||||
|
||||
@@ -181,7 +295,7 @@ class GiftInfo(TelegramObject):
|
||||
the receiver by converting the gift; omitted if conversion to Telegram Stars
|
||||
is impossible.
|
||||
prepaid_upgrade_star_count (:obj:`int`, optional): Number of Telegram Stars that were
|
||||
prepaid by the sender for the ability to upgrade the gift.
|
||||
prepaid for the ability to upgrade the gift.
|
||||
can_be_upgraded (:obj:`bool`, optional): :obj:`True`, if the gift can be upgraded
|
||||
to a unique gift.
|
||||
text (:obj:`str`, optional): Text of the message that was added to the gift.
|
||||
@@ -189,6 +303,14 @@ class GiftInfo(TelegramObject):
|
||||
appear in the text.
|
||||
is_private (:obj:`bool`, optional): :obj:`True`, if the sender and gift text are
|
||||
shown only to the gift receiver; otherwise, everyone will be able to see them.
|
||||
is_upgrade_separate (:obj:`bool`, optional): :obj:`True`, if the gift's upgrade was
|
||||
purchased after the gift was sent.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
unique_gift_number (:obj:`int`, optional): Unique number reserved for this gift when
|
||||
upgraded. See the number field in :class:`~telegram.UniqueGift`.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
Attributes:
|
||||
gift (:class:`Gift`): Information about the gift.
|
||||
@@ -198,7 +320,7 @@ class GiftInfo(TelegramObject):
|
||||
the receiver by converting the gift; omitted if conversion to Telegram Stars
|
||||
is impossible.
|
||||
prepaid_upgrade_star_count (:obj:`int`): Optional. Number of Telegram Stars that were
|
||||
prepaid by the sender for the ability to upgrade the gift.
|
||||
prepaid for the ability to upgrade the gift.
|
||||
can_be_upgraded (:obj:`bool`): Optional. :obj:`True`, if the gift can be upgraded
|
||||
to a unique gift.
|
||||
text (:obj:`str`): Optional. Text of the message that was added to the gift.
|
||||
@@ -206,6 +328,14 @@ class GiftInfo(TelegramObject):
|
||||
appear in the text.
|
||||
is_private (:obj:`bool`): Optional. :obj:`True`, if the sender and gift text are
|
||||
shown only to the gift receiver; otherwise, everyone will be able to see them.
|
||||
is_upgrade_separate (:obj:`bool`): Optional. :obj:`True`, if the gift's upgrade was
|
||||
purchased after the gift was sent.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
unique_gift_number (:obj:`int`): Optional. Unique number reserved for this gift when
|
||||
upgraded. See the number field in :class:`~telegram.UniqueGift`.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
"""
|
||||
|
||||
@@ -215,9 +345,11 @@ class GiftInfo(TelegramObject):
|
||||
"entities",
|
||||
"gift",
|
||||
"is_private",
|
||||
"is_upgrade_separate",
|
||||
"owned_gift_id",
|
||||
"prepaid_upgrade_star_count",
|
||||
"text",
|
||||
"unique_gift_number",
|
||||
)
|
||||
|
||||
def __init__(
|
||||
@@ -230,6 +362,8 @@ class GiftInfo(TelegramObject):
|
||||
text: str | None = None,
|
||||
entities: Sequence[MessageEntity] | None = None,
|
||||
is_private: bool | None = None,
|
||||
unique_gift_number: int | None = None,
|
||||
is_upgrade_separate: bool | None = None,
|
||||
*,
|
||||
api_kwargs: JSONDict | None = None,
|
||||
):
|
||||
@@ -244,6 +378,8 @@ class GiftInfo(TelegramObject):
|
||||
self.text: str | None = text
|
||||
self.entities: tuple[MessageEntity, ...] = parse_sequence_arg(entities)
|
||||
self.is_private: bool | None = is_private
|
||||
self.unique_gift_number: int | None = unique_gift_number
|
||||
self.is_upgrade_separate: bool | None = is_upgrade_separate
|
||||
|
||||
self._id_attrs = (self.gift,)
|
||||
|
||||
@@ -319,9 +455,11 @@ class AcceptedGiftTypes(TelegramObject):
|
||||
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal if their :attr:`unlimited_gifts`, :attr:`limited_gifts`,
|
||||
:attr:`unique_gifts` and :attr:`premium_subscription` are equal.
|
||||
:attr:`unique_gifts`, :attr:`premium_subscription` and :attr:`gifts_from_channels` are equal.
|
||||
|
||||
.. versionadded:: 22.1
|
||||
.. versionchanged:: NEXT.VERSION
|
||||
:attr:`gifts_from_channels` is now considered for equality checks.
|
||||
|
||||
Args:
|
||||
unlimited_gifts (:class:`bool`): :obj:`True`, if unlimited regular gifts are accepted.
|
||||
@@ -330,6 +468,10 @@ class AcceptedGiftTypes(TelegramObject):
|
||||
to unique for free are accepted.
|
||||
premium_subscription (:class:`bool`): :obj:`True`, if a Telegram Premium subscription
|
||||
is accepted.
|
||||
gifts_from_channels (:obj:`bool`): :obj:`True`, if transfers of unique gifts from channels
|
||||
are accepted
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
Attributes:
|
||||
unlimited_gifts (:class:`bool`): :obj:`True`, if unlimited regular gifts are accepted.
|
||||
@@ -338,10 +480,15 @@ class AcceptedGiftTypes(TelegramObject):
|
||||
to unique for free are accepted.
|
||||
premium_subscription (:class:`bool`): :obj:`True`, if a Telegram Premium subscription
|
||||
is accepted.
|
||||
gifts_from_channels (:obj:`bool`): :obj:`True`, if transfers of unique gifts from channels
|
||||
are accepted
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
"""
|
||||
|
||||
__slots__ = (
|
||||
"gifts_from_channels",
|
||||
"limited_gifts",
|
||||
"premium_subscription",
|
||||
"unique_gifts",
|
||||
@@ -354,6 +501,7 @@ class AcceptedGiftTypes(TelegramObject):
|
||||
limited_gifts: bool,
|
||||
unique_gifts: bool,
|
||||
premium_subscription: bool,
|
||||
gifts_from_channels: bool,
|
||||
*,
|
||||
api_kwargs: JSONDict | None = None,
|
||||
):
|
||||
@@ -362,12 +510,14 @@ class AcceptedGiftTypes(TelegramObject):
|
||||
self.limited_gifts: bool = limited_gifts
|
||||
self.unique_gifts: bool = unique_gifts
|
||||
self.premium_subscription: bool = premium_subscription
|
||||
self.gifts_from_channels: bool = gifts_from_channels
|
||||
|
||||
self._id_attrs = (
|
||||
self.unlimited_gifts,
|
||||
self.limited_gifts,
|
||||
self.unique_gifts,
|
||||
self.premium_subscription,
|
||||
self.gifts_from_channels,
|
||||
)
|
||||
|
||||
self._freeze()
|
||||
|
||||
+78
-11
@@ -496,12 +496,12 @@ class Message(MaybeInaccessibleMessage):
|
||||
reply_markup (:class:`telegram.InlineKeyboardMarkup`, optional): Inline keyboard attached
|
||||
to the message. :paramref:`~telegram.InlineKeyboardButton.login_url` buttons are
|
||||
represented as ordinary url buttons.
|
||||
is_topic_message (:obj:`bool`, optional): :obj:`True`, if the message is sent to a forum
|
||||
topic.
|
||||
is_topic_message (:obj:`bool`, optional): :obj:`True`, if the message is sent to a topic
|
||||
in a forum supergroup or a private chat with the bot.
|
||||
|
||||
.. versionadded:: 20.0
|
||||
message_thread_id (:obj:`int`, optional): Unique identifier of a message thread to which
|
||||
the message belongs; for supergroups only.
|
||||
message_thread_id (:obj:`int`, optional): Unique identifier of a message thread or forum
|
||||
topic to which the message belongs; for supergroups and private chats only.
|
||||
|
||||
.. versionadded:: 20.0
|
||||
forum_topic_created (:class:`telegram.ForumTopicCreated`, optional): Service message:
|
||||
@@ -558,6 +558,10 @@ class Message(MaybeInaccessibleMessage):
|
||||
was sent or received
|
||||
|
||||
.. versionadded:: 22.1
|
||||
gift_upgrade_sent (:class:`telegram.GiftInfo`, optional): Service message: upgrade of a
|
||||
gift was purchased after the gift was sent
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
giveaway_created (:class:`telegram.GiveawayCreated`, optional): Service message: a
|
||||
scheduled giveaway was created
|
||||
|
||||
@@ -898,12 +902,12 @@ class Message(MaybeInaccessibleMessage):
|
||||
reply_markup (:class:`telegram.InlineKeyboardMarkup`): Optional. Inline keyboard attached
|
||||
to the message. :paramref:`~telegram.InlineKeyboardButton.login_url` buttons are
|
||||
represented as ordinary url buttons.
|
||||
is_topic_message (:obj:`bool`): Optional. :obj:`True`, if the message is sent to a forum
|
||||
topic.
|
||||
is_topic_message (:obj:`bool`): Optional. :obj:`True`, if the message is sent to a topic
|
||||
in a forum supergroup or a private chat with the bot.
|
||||
|
||||
.. versionadded:: 20.0
|
||||
message_thread_id (:obj:`int`): Optional. Unique identifier of a message thread to which
|
||||
the message belongs; for supergroups only.
|
||||
message_thread_id (:obj:`int`): Optional. Unique identifier of a message thread or forum
|
||||
topic to which the message belongs; for supergroups and private chats only.
|
||||
|
||||
.. versionadded:: 20.0
|
||||
forum_topic_created (:class:`telegram.ForumTopicCreated`): Optional. Service message:
|
||||
@@ -957,6 +961,10 @@ class Message(MaybeInaccessibleMessage):
|
||||
was sent or received
|
||||
|
||||
.. versionadded:: 22.1
|
||||
gift_upgrade_sent (:class:`telegram.GiftInfo`): Optional. Service message: upgrade of a
|
||||
gift was purchased after the gift was sent
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
giveaway_created (:class:`telegram.GiveawayCreated`): Optional. Service message: a
|
||||
scheduled giveaway was created
|
||||
|
||||
@@ -1125,6 +1133,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
"general_forum_topic_hidden",
|
||||
"general_forum_topic_unhidden",
|
||||
"gift",
|
||||
"gift_upgrade_sent",
|
||||
"giveaway",
|
||||
"giveaway_completed",
|
||||
"giveaway_created",
|
||||
@@ -1296,6 +1305,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
suggested_post_info: "SuggestedPostInfo | None" = None,
|
||||
suggested_post_approved: "SuggestedPostApproved | None" = None,
|
||||
suggested_post_approval_failed: "SuggestedPostApprovalFailed | None" = None,
|
||||
gift_upgrade_sent: GiftInfo | None = None,
|
||||
*,
|
||||
api_kwargs: JSONDict | None = None,
|
||||
):
|
||||
@@ -1422,6 +1432,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
self.suggested_post_approval_failed: SuggestedPostApprovalFailed | None = (
|
||||
suggested_post_approval_failed
|
||||
)
|
||||
self.gift_upgrade_sent: GiftInfo | None = gift_upgrade_sent
|
||||
|
||||
self._effective_attachment = DEFAULT_NONE
|
||||
|
||||
@@ -1637,6 +1648,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
data["suggested_post_approval_failed"] = de_json_optional(
|
||||
data.get("suggested_post_approval_failed"), SuggestedPostApprovalFailed, bot
|
||||
)
|
||||
data["gift_upgrade_sent"] = de_json_optional(data.get("gift_upgrade_sent"), GiftInfo, bot)
|
||||
|
||||
api_kwargs = {}
|
||||
# This is a deprecated field that TG still returns for backwards compatibility
|
||||
@@ -1982,9 +1994,9 @@ class Message(MaybeInaccessibleMessage):
|
||||
return message_thread_id
|
||||
|
||||
# self.message_thread_id can be used for send_*.param.message_thread_id only if the
|
||||
# thread is a forum topic. It does not work if the thread is a chain of replies to a
|
||||
# message in a normal group. In that case, self.message_thread_id is just the message_id
|
||||
# of the first message in the chain.
|
||||
# thread is a forum topic (in supergroups or private chats). It does not work if the
|
||||
# thread is a chain of replies to a message in a normal group. In that case,
|
||||
# self.message_thread_id is just the message_id of the first message in the chain.
|
||||
if not self.is_topic_message:
|
||||
return None
|
||||
|
||||
@@ -2077,6 +2089,55 @@ class Message(MaybeInaccessibleMessage):
|
||||
suggested_post_parameters=suggested_post_parameters,
|
||||
)
|
||||
|
||||
async def reply_text_draft(
|
||||
self,
|
||||
draft_id: int,
|
||||
text: str,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
entities: Sequence["MessageEntity"] | None = None,
|
||||
message_thread_id: ODVInput[int] = DEFAULT_NONE,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
connect_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
pool_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict | None = None,
|
||||
) -> bool:
|
||||
"""Shortcut for::
|
||||
|
||||
await bot.send_message_draft(
|
||||
update.effective_message.chat_id,
|
||||
message_thread_id=update.effective_message.message_thread_id,
|
||||
*args,
|
||||
**kwargs,
|
||||
)
|
||||
|
||||
For the documentation of the arguments, please see :meth:`telegram.Bot.send_message_draft`.
|
||||
|
||||
Note:
|
||||
|reply_same_thread|
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
Returns:
|
||||
:obj:`bool`: On success, :obj:`True` is returned.
|
||||
|
||||
"""
|
||||
message_thread_id = self._parse_message_thread_id(self.chat_id, message_thread_id)
|
||||
return await self.get_bot().send_message_draft(
|
||||
chat_id=self.chat_id,
|
||||
draft_id=draft_id,
|
||||
text=text,
|
||||
parse_mode=parse_mode,
|
||||
entities=entities,
|
||||
message_thread_id=message_thread_id,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
async def reply_markdown(
|
||||
self,
|
||||
text: str,
|
||||
@@ -3822,6 +3883,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
message_thread_id: int | None = None,
|
||||
video_start_timestamp: int | None = None,
|
||||
suggested_post_parameters: "SuggestedPostParameters | None" = None,
|
||||
message_effect_id: str | None = None,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
@@ -3868,6 +3930,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
direct_messages_topic_id=self._extract_direct_messages_topic_id(),
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def copy(
|
||||
@@ -3885,6 +3948,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
allow_paid_broadcast: bool | None = None,
|
||||
video_start_timestamp: int | None = None,
|
||||
suggested_post_parameters: "SuggestedPostParameters | None" = None,
|
||||
message_effect_id: str | None = None,
|
||||
*,
|
||||
reply_to_message_id: int | None = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
@@ -3935,6 +3999,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
allow_paid_broadcast=allow_paid_broadcast,
|
||||
direct_messages_topic_id=self._extract_direct_messages_topic_id(),
|
||||
suggested_post_parameters=suggested_post_parameters,
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def reply_copy(
|
||||
@@ -3953,6 +4018,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
allow_paid_broadcast: bool | None = None,
|
||||
video_start_timestamp: int | None = None,
|
||||
suggested_post_parameters: "SuggestedPostParameters | None" = None,
|
||||
message_effect_id: str | None = None,
|
||||
*,
|
||||
reply_to_message_id: int | None = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
@@ -4017,6 +4083,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
allow_paid_broadcast=allow_paid_broadcast,
|
||||
direct_messages_topic_id=self._extract_direct_messages_topic_id(),
|
||||
suggested_post_parameters=suggested_post_parameters,
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def reply_paid_media(
|
||||
|
||||
@@ -183,9 +183,17 @@ class OwnedGiftRegular(OwnedGift):
|
||||
available anymore.
|
||||
convert_star_count (:obj:`int`, optional): Number of Telegram Stars that can be
|
||||
claimed by the receiver instead of the gift; omitted if the gift cannot be converted
|
||||
to Telegram Stars.
|
||||
to Telegram Stars; for gifts received on behalf of business accounts only.
|
||||
prepaid_upgrade_star_count (:obj:`int`, optional): Number of Telegram Stars that were
|
||||
paid by the sender for the ability to upgrade the gift.
|
||||
paid for the ability to upgrade the gift.
|
||||
is_upgrade_separate (:obj:`bool`, optional): :obj:`True`, if the gift's upgrade was
|
||||
purchased after the gift was sent; for gifts received on behalf of business accounts
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
unique_gift_number (:obj:`int`, optional): Unique number reserved for this gift when
|
||||
upgraded. See the number field in :class:`~telegram.UniqueGift`
|
||||
|
||||
... versionadded:: NEXT.VERSION
|
||||
|
||||
Attributes:
|
||||
type (:obj:`str`): Type of the gift, always :attr:`~telegram.OwnedGift.REGULAR`.
|
||||
@@ -208,9 +216,17 @@ class OwnedGiftRegular(OwnedGift):
|
||||
available anymore.
|
||||
convert_star_count (:obj:`int`): Optional. Number of Telegram Stars that can be
|
||||
claimed by the receiver instead of the gift; omitted if the gift cannot be converted
|
||||
to Telegram Stars.
|
||||
to Telegram Stars; for gifts received on behalf of business accounts only.
|
||||
prepaid_upgrade_star_count (:obj:`int`): Optional. Number of Telegram Stars that were
|
||||
paid by the sender for the ability to upgrade the gift.
|
||||
paid for the ability to upgrade the gift.
|
||||
is_upgrade_separate (:obj:`bool`): Optional. :obj:`True`, if the gift's upgrade was
|
||||
purchased after the gift was sent; for gifts received on behalf of business accounts
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
unique_gift_number (:obj:`int`): Optional. Unique number reserved for this gift when
|
||||
upgraded. See the number field in :class:`~telegram.UniqueGift`
|
||||
|
||||
... versionadded:: NEXT.VERSION
|
||||
|
||||
"""
|
||||
|
||||
@@ -221,11 +237,13 @@ class OwnedGiftRegular(OwnedGift):
|
||||
"gift",
|
||||
"is_private",
|
||||
"is_saved",
|
||||
"is_upgrade_separate",
|
||||
"owned_gift_id",
|
||||
"prepaid_upgrade_star_count",
|
||||
"send_date",
|
||||
"sender_user",
|
||||
"text",
|
||||
"unique_gift_number",
|
||||
"was_refunded",
|
||||
)
|
||||
|
||||
@@ -243,6 +261,8 @@ class OwnedGiftRegular(OwnedGift):
|
||||
was_refunded: bool | None = None,
|
||||
convert_star_count: int | None = None,
|
||||
prepaid_upgrade_star_count: int | None = None,
|
||||
is_upgrade_separate: bool | None = None,
|
||||
unique_gift_number: int | None = None,
|
||||
*,
|
||||
api_kwargs: JSONDict | None = None,
|
||||
) -> None:
|
||||
@@ -261,6 +281,8 @@ class OwnedGiftRegular(OwnedGift):
|
||||
self.was_refunded: bool | None = was_refunded
|
||||
self.convert_star_count: int | None = convert_star_count
|
||||
self.prepaid_upgrade_star_count: int | None = prepaid_upgrade_star_count
|
||||
self.is_upgrade_separate: bool | None = is_upgrade_separate
|
||||
self.unique_gift_number: int | None = unique_gift_number
|
||||
|
||||
self._id_attrs = (self.type, self.gift, self.send_date)
|
||||
|
||||
|
||||
+45
-1
@@ -22,7 +22,8 @@ from typing import TYPE_CHECKING
|
||||
|
||||
from telegram._chat import Chat
|
||||
from telegram._telegramobject import TelegramObject
|
||||
from telegram._utils.types import JSONDict
|
||||
from telegram._utils.defaultvalue import DEFAULT_NONE
|
||||
from telegram._utils.types import JSONDict, ODVInput, TimePeriod
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from telegram import Bot
|
||||
@@ -77,3 +78,46 @@ class Story(TelegramObject):
|
||||
|
||||
data["chat"] = Chat.de_json(data.get("chat", {}), bot)
|
||||
return super().de_json(data=data, bot=bot)
|
||||
|
||||
async def repost(
|
||||
self,
|
||||
business_connection_id: str,
|
||||
active_period: TimePeriod,
|
||||
post_to_chat_page: bool | None = None,
|
||||
protect_content: ODVInput[bool] = DEFAULT_NONE,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
connect_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
pool_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict | None = None,
|
||||
) -> "Story":
|
||||
"""Shortcut for::
|
||||
|
||||
await bot.repost_story(
|
||||
from_chat_id=story.chat.id,
|
||||
from_story_id=story.id,
|
||||
*args, **kwargs
|
||||
)
|
||||
|
||||
For the documentation of the arguments, please see :meth:`telegram.Bot.repost_story`.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
Returns:
|
||||
:class:`Story`: On success, :class:`Story` is returned.
|
||||
|
||||
"""
|
||||
return await self.get_bot().repost_story(
|
||||
business_connection_id=business_connection_id,
|
||||
from_chat_id=self.chat.id,
|
||||
from_story_id=self.id,
|
||||
active_period=active_period,
|
||||
post_to_chat_page=post_to_chat_page,
|
||||
protect_content=protect_content,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
+219
-12
@@ -20,6 +20,7 @@
|
||||
"""This module contains classes related to unique gifs."""
|
||||
|
||||
import datetime as dtm
|
||||
from collections.abc import Sequence
|
||||
from typing import TYPE_CHECKING, Final
|
||||
|
||||
from telegram import constants
|
||||
@@ -27,14 +28,94 @@ from telegram._chat import Chat
|
||||
from telegram._files.sticker import Sticker
|
||||
from telegram._telegramobject import TelegramObject
|
||||
from telegram._utils import enum
|
||||
from telegram._utils.argumentparsing import de_json_optional
|
||||
from telegram._utils.argumentparsing import de_json_optional, parse_sequence_arg
|
||||
from telegram._utils.datetime import extract_tzinfo_from_defaults, from_timestamp
|
||||
from telegram._utils.types import JSONDict
|
||||
from telegram._utils.warnings import warn
|
||||
from telegram._utils.warnings_transition import (
|
||||
build_deprecation_warning_message,
|
||||
warn_about_deprecated_attr_in_property,
|
||||
)
|
||||
from telegram.warnings import PTBDeprecationWarning
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from telegram import Bot
|
||||
|
||||
|
||||
class UniqueGiftColors(TelegramObject):
|
||||
"""This object contains information about the color scheme for a user's name, message replies
|
||||
and link previews based on a unique gift.
|
||||
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal if their :attr:`model_custom_emoji_id`, :attr:`symbol_custom_emoji_id`,
|
||||
:attr:`light_theme_main_color`, :attr:`light_theme_other_colors`,
|
||||
:attr:`dark_theme_main_color`, and :attr:`dark_theme_other_colors` are equal.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
Args:
|
||||
model_custom_emoji_id (:obj:`str`): Custom emoji identifier of the unique gift's model.
|
||||
symbol_custom_emoji_id (:obj:`str`): Custom emoji identifier of the unique gift's symbol.
|
||||
light_theme_main_color (:obj:`int`): Main color used in light themes; RGB format.
|
||||
light_theme_other_colors (Sequence[:obj:`int`]): List of 1-3 additional colors used in
|
||||
light themes; RGB format. |sequenceclassargs|
|
||||
dark_theme_main_color (:obj:`int`): Main color used in dark themes; RGB format.
|
||||
dark_theme_other_colors (Sequence[:obj:`int`]): List of 1-3 additional colors used in dark
|
||||
themes; RGB format. |sequenceclassargs|
|
||||
|
||||
Attributes:
|
||||
model_custom_emoji_id (:obj:`str`): Custom emoji identifier of the unique gift's model.
|
||||
symbol_custom_emoji_id (:obj:`str`): Custom emoji identifier of the unique gift's symbol.
|
||||
light_theme_main_color (:obj:`int`): Main color used in light themes; RGB format.
|
||||
light_theme_other_colors (Tuple[:obj:`int`]): Tuple of 1-3 additional colors used in
|
||||
light themes; RGB format.
|
||||
dark_theme_main_color (:obj:`int`): Main color used in dark themes; RGB format.
|
||||
dark_theme_other_colors (Tuple[:obj:`int`]): Tuple of 1-3 additional colors used in dark
|
||||
themes; RGB format.
|
||||
"""
|
||||
|
||||
__slots__ = (
|
||||
"dark_theme_main_color",
|
||||
"dark_theme_other_colors",
|
||||
"light_theme_main_color",
|
||||
"light_theme_other_colors",
|
||||
"model_custom_emoji_id",
|
||||
"symbol_custom_emoji_id",
|
||||
)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
model_custom_emoji_id: str,
|
||||
symbol_custom_emoji_id: str,
|
||||
light_theme_main_color: int,
|
||||
light_theme_other_colors: Sequence[int],
|
||||
dark_theme_main_color: int,
|
||||
dark_theme_other_colors: Sequence[int],
|
||||
*,
|
||||
api_kwargs: JSONDict | None = None,
|
||||
):
|
||||
super().__init__(api_kwargs=api_kwargs)
|
||||
self.model_custom_emoji_id: str = model_custom_emoji_id
|
||||
self.symbol_custom_emoji_id: str = symbol_custom_emoji_id
|
||||
self.light_theme_main_color: int = light_theme_main_color
|
||||
self.light_theme_other_colors: tuple[int, ...] = parse_sequence_arg(
|
||||
light_theme_other_colors
|
||||
)
|
||||
self.dark_theme_main_color: int = dark_theme_main_color
|
||||
self.dark_theme_other_colors: tuple[int, ...] = parse_sequence_arg(dark_theme_other_colors)
|
||||
|
||||
self._id_attrs = (
|
||||
self.model_custom_emoji_id,
|
||||
self.symbol_custom_emoji_id,
|
||||
self.light_theme_main_color,
|
||||
self.light_theme_other_colors,
|
||||
self.dark_theme_main_color,
|
||||
self.dark_theme_other_colors,
|
||||
)
|
||||
|
||||
self._freeze()
|
||||
|
||||
|
||||
class UniqueGiftModel(TelegramObject):
|
||||
"""This object describes the model of a unique gift.
|
||||
|
||||
@@ -260,6 +341,9 @@ class UniqueGift(TelegramObject):
|
||||
.. versionadded:: 22.1
|
||||
|
||||
Args:
|
||||
gift_id (:obj:`str`): Identifier of the regular gift from which the gift was upgraded.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
base_name (:obj:`str`): Human-readable name of the regular gift from which this unique
|
||||
gift was upgraded.
|
||||
name (:obj:`str`): Unique name of the gift. This name can be used
|
||||
@@ -273,8 +357,24 @@ class UniqueGift(TelegramObject):
|
||||
published the gift.
|
||||
|
||||
.. versionadded:: 22.4
|
||||
is_premium (:obj:`bool`, optional): :obj:`True`, if the original regular gift was
|
||||
exclusively purchaseable by Telegram Premium subscribers.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
is_from_blockchain (:obj:`bool`, optional): :obj:`True`, if the gift is assigned from the
|
||||
TON blockchain and can't be resold or transferred in Telegram.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
colors (:class:`telegram.UniqueGiftColors`, optional): The color scheme that can be used
|
||||
by the gift's owner for the chat's name, replies to messages and link previews; for
|
||||
business account gifts and gifts that are currently on sale only.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
Attributes:
|
||||
gift_id (:obj:`str`): Identifier of the regular gift from which the gift was upgraded.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
base_name (:obj:`str`): Human-readable name of the regular gift from which this unique
|
||||
gift was upgraded.
|
||||
name (:obj:`str`): Unique name of the gift. This name can be used
|
||||
@@ -288,12 +388,29 @@ class UniqueGift(TelegramObject):
|
||||
published the gift.
|
||||
|
||||
.. versionadded:: 22.4
|
||||
is_premium (:obj:`bool`): Optional. :obj:`True`, if the original regular gift was
|
||||
exclusively purchaseable by Telegram Premium subscribers.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
is_from_blockchain (:obj:`bool`): Optional. :obj:`True`, if the gift is assigned from the
|
||||
TON blockchain and can't be resold or transferred in Telegram.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
colors (:class:`telegram.UniqueGiftColors`): Optional. The color scheme that can be used
|
||||
by the gift's owner for the chat's name, replies to messages and link previews; for
|
||||
business account gifts and gifts that are currently on sale only.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
"""
|
||||
|
||||
__slots__ = (
|
||||
"backdrop",
|
||||
"base_name",
|
||||
"colors",
|
||||
"gift_id",
|
||||
"is_from_blockchain",
|
||||
"is_premium",
|
||||
"model",
|
||||
"name",
|
||||
"number",
|
||||
@@ -310,10 +427,21 @@ class UniqueGift(TelegramObject):
|
||||
symbol: UniqueGiftSymbol,
|
||||
backdrop: UniqueGiftBackdrop,
|
||||
publisher_chat: Chat | None = None,
|
||||
# tags: deprecated NEXT.VERSION, bot api 9.3
|
||||
# temporarily optional to account for changed signature
|
||||
gift_id: str | None = None,
|
||||
is_from_blockchain: bool | None = None,
|
||||
is_premium: bool | None = None,
|
||||
colors: UniqueGiftColors | None = None,
|
||||
*,
|
||||
api_kwargs: JSONDict | None = None,
|
||||
):
|
||||
# tags: deprecated NEXT.VERSION, bot api 9.3
|
||||
if gift_id is None:
|
||||
raise TypeError("`gift_id` is a required argument since Bot API 9.3")
|
||||
|
||||
super().__init__(api_kwargs=api_kwargs)
|
||||
self.gift_id: str = gift_id
|
||||
self.base_name: str = base_name
|
||||
self.name: str = name
|
||||
self.number: int = number
|
||||
@@ -321,6 +449,9 @@ class UniqueGift(TelegramObject):
|
||||
self.symbol: UniqueGiftSymbol = symbol
|
||||
self.backdrop: UniqueGiftBackdrop = backdrop
|
||||
self.publisher_chat: Chat | None = publisher_chat
|
||||
self.is_from_blockchain: bool | None = is_from_blockchain
|
||||
self.is_premium: bool | None = is_premium
|
||||
self.colors: UniqueGiftColors | None = colors
|
||||
|
||||
self._id_attrs = (
|
||||
self.base_name,
|
||||
@@ -342,6 +473,7 @@ class UniqueGift(TelegramObject):
|
||||
data["symbol"] = de_json_optional(data.get("symbol"), UniqueGiftSymbol, bot)
|
||||
data["backdrop"] = de_json_optional(data.get("backdrop"), UniqueGiftBackdrop, bot)
|
||||
data["publisher_chat"] = de_json_optional(data.get("publisher_chat"), Chat, bot)
|
||||
data["colors"] = de_json_optional(data.get("colors"), UniqueGiftColors, bot)
|
||||
|
||||
return super().de_json(data=data, bot=bot)
|
||||
|
||||
@@ -358,10 +490,14 @@ class UniqueGiftInfo(TelegramObject):
|
||||
gift (:class:`UniqueGift`): Information about the gift.
|
||||
origin (:obj:`str`): Origin of the gift. Currently, either :attr:`UPGRADE` for gifts
|
||||
upgraded from regular gifts, :attr:`TRANSFER` for gifts transferred from other users
|
||||
or channels, or :attr:`RESALE` for gifts bought from other users.
|
||||
or channels, :attr:`RESALE` for gifts bought from other users,
|
||||
:attr:`GIFTED_UPGRADE` for upgrades purchased after the gift was sent, or :attr:`OFFER`
|
||||
for gifts bought or sold through gift purchase offers
|
||||
|
||||
.. versionchanged:: 22.3
|
||||
The :attr:`RESALE` origin was added.
|
||||
.. versionchanged:: NEXT.VERSION
|
||||
Bot API 9.3 added the :attr:`GIFTED_UPGRADE` and :attr:`OFFER` origins.
|
||||
owned_gift_id (:obj:`str`, optional) Unique identifier of the received gift for the
|
||||
bot; only present for gifts received on behalf of business accounts.
|
||||
transfer_star_count (:obj:`int`, optional): Number of Telegram Stars that must be paid
|
||||
@@ -370,6 +506,18 @@ class UniqueGiftInfo(TelegramObject):
|
||||
paid for the gift.
|
||||
|
||||
.. versionadded:: 22.3
|
||||
.. deprecated:: NEXT.VERSION
|
||||
Bot API 9.3 deprecated this field. Use :attr:`last_resale_currency` and
|
||||
:attr:`last_resale_amount` instead.
|
||||
last_resale_currency (:obj:`str`, optional): For gifts bought from other users, the
|
||||
currency in which the payment for the gift was done. Currently, one of ``XTR`` for
|
||||
Telegram Stars or ``TON`` for toncoins.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
last_resale_amount (:obj:`int`, optional): For gifts bought from other users, the price
|
||||
paid for the gift in either Telegram Stars or nanotoncoins.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
next_transfer_date (:obj:`datetime.datetime`, optional): Date when the gift can be
|
||||
transferred. If it's in the past, then the gift can be transferred now.
|
||||
|datetime_localization|
|
||||
@@ -380,18 +528,27 @@ class UniqueGiftInfo(TelegramObject):
|
||||
gift (:class:`UniqueGift`): Information about the gift.
|
||||
origin (:obj:`str`): Origin of the gift. Currently, either :attr:`UPGRADE` for gifts
|
||||
upgraded from regular gifts, :attr:`TRANSFER` for gifts transferred from other users
|
||||
or channels, or :attr:`RESALE` for gifts bought from other users.
|
||||
or channels, :attr:`RESALE` for gifts bought from other users,
|
||||
:attr:`GIFTED_UPGRADE` for upgrades purchased after the gift was sent, or :attr:`OFFER`
|
||||
for gifts bought or sold through gift purchase offers
|
||||
|
||||
.. versionchanged:: 22.3
|
||||
The :attr:`RESALE` origin was added.
|
||||
.. versionchanged:: NEXT.VERSION
|
||||
Bot API 9.3 added the :attr:`GIFTED_UPGRADE` and :attr:`OFFER` origins.
|
||||
owned_gift_id (:obj:`str`) Optional. Unique identifier of the received gift for the
|
||||
bot; only present for gifts received on behalf of business accounts.
|
||||
transfer_star_count (:obj:`int`): Optional. Number of Telegram Stars that must be paid
|
||||
to transfer the gift; omitted if the bot cannot transfer the gift.
|
||||
last_resale_star_count (:obj:`int`): Optional. For gifts bought from other users, the price
|
||||
paid for the gift.
|
||||
last_resale_currency (:obj:`str`): Optional. For gifts bought from other users, the
|
||||
currency in which the payment for the gift was done. Currently, one of ``XTR`` for
|
||||
Telegram Stars or ``TON`` for toncoins.
|
||||
|
||||
.. versionadded:: 22.3
|
||||
.. versionadded:: NEXT.VERSION
|
||||
last_resale_amount (:obj:`int`): Optional. For gifts bought from other users, the price
|
||||
paid for the gift in either Telegram Stars or nanotoncoins.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
next_transfer_date (:obj:`datetime.datetime`): Optional. Date when the gift can be
|
||||
transferred. If it's in the past, then the gift can be transferred now.
|
||||
|datetime_localization|
|
||||
@@ -399,19 +556,31 @@ class UniqueGiftInfo(TelegramObject):
|
||||
.. versionadded:: 22.3
|
||||
"""
|
||||
|
||||
UPGRADE: Final[str] = constants.UniqueGiftInfoOrigin.UPGRADE
|
||||
""":const:`telegram.constants.UniqueGiftInfoOrigin.UPGRADE`"""
|
||||
TRANSFER: Final[str] = constants.UniqueGiftInfoOrigin.TRANSFER
|
||||
""":const:`telegram.constants.UniqueGiftInfoOrigin.TRANSFER`"""
|
||||
GIFTED_UPGRADE: Final[str] = constants.UniqueGiftInfoOrigin.GIFTED_UPGRADE
|
||||
""":const:`telegram.constants.UniqueGiftInfoOrigin.GIFTED_UPGRADE`
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
"""
|
||||
OFFER: Final[str] = constants.UniqueGiftInfoOrigin.OFFER
|
||||
""":const:`telegram.constants.UniqueGiftInfoOrigin.OFFER`
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
"""
|
||||
RESALE: Final[str] = constants.UniqueGiftInfoOrigin.RESALE
|
||||
""":const:`telegram.constants.UniqueGiftInfoOrigin.RESALE`
|
||||
|
||||
.. versionadded:: 22.3
|
||||
"""
|
||||
TRANSFER: Final[str] = constants.UniqueGiftInfoOrigin.TRANSFER
|
||||
""":const:`telegram.constants.UniqueGiftInfoOrigin.TRANSFER`"""
|
||||
UPGRADE: Final[str] = constants.UniqueGiftInfoOrigin.UPGRADE
|
||||
""":const:`telegram.constants.UniqueGiftInfoOrigin.UPGRADE`"""
|
||||
|
||||
__slots__ = (
|
||||
"_last_resale_star_count",
|
||||
"gift",
|
||||
"last_resale_star_count",
|
||||
"last_resale_amount",
|
||||
"last_resale_currency",
|
||||
"next_transfer_date",
|
||||
"origin",
|
||||
"owned_gift_id",
|
||||
@@ -424,11 +593,28 @@ class UniqueGiftInfo(TelegramObject):
|
||||
origin: str,
|
||||
owned_gift_id: str | None = None,
|
||||
transfer_star_count: int | None = None,
|
||||
# tags: deprecated NEXT.VERSION; bot api 9.3
|
||||
last_resale_star_count: int | None = None,
|
||||
next_transfer_date: dtm.datetime | None = None,
|
||||
last_resale_currency: str | None = None,
|
||||
last_resale_amount: int | None = None,
|
||||
*,
|
||||
api_kwargs: JSONDict | None = None,
|
||||
):
|
||||
if last_resale_star_count is not None:
|
||||
warn(
|
||||
PTBDeprecationWarning(
|
||||
version="NEXT.VERSION",
|
||||
message=build_deprecation_warning_message(
|
||||
deprecated_name="last_resale_star_count",
|
||||
new_name="last_resale_currency/amount",
|
||||
bot_api_version="9.3",
|
||||
object_type="parameter",
|
||||
),
|
||||
),
|
||||
stacklevel=2,
|
||||
)
|
||||
|
||||
super().__init__(api_kwargs=api_kwargs)
|
||||
# Required
|
||||
self.gift: UniqueGift = gift
|
||||
@@ -436,13 +622,34 @@ class UniqueGiftInfo(TelegramObject):
|
||||
# Optional
|
||||
self.owned_gift_id: str | None = owned_gift_id
|
||||
self.transfer_star_count: int | None = transfer_star_count
|
||||
self.last_resale_star_count: int | None = last_resale_star_count
|
||||
self._last_resale_star_count: int | None = last_resale_star_count
|
||||
self.next_transfer_date: dtm.datetime | None = next_transfer_date
|
||||
self.last_resale_currency: str | None = last_resale_currency
|
||||
self.last_resale_amount: int | None = last_resale_amount
|
||||
|
||||
self._id_attrs = (self.gift, self.origin)
|
||||
|
||||
self._freeze()
|
||||
|
||||
# tags: deprecated NEXT.VERSION; bot api 9.3
|
||||
@property
|
||||
def last_resale_star_count(self) -> int | None:
|
||||
""":obj:`int`: Optional. For gifts bought from other users, the price
|
||||
paid for the gift.
|
||||
|
||||
.. versionadded:: 22.3
|
||||
.. deprecated:: NEXT.VERSION
|
||||
Bot API 9.3 deprecated this field. Use :attr:`last_resale_currency` and
|
||||
:attr:`last_resale_amount` instead.
|
||||
"""
|
||||
warn_about_deprecated_attr_in_property(
|
||||
deprecated_attr_name="last_resale_star_count",
|
||||
new_attr_name="last_resale_currency/amount",
|
||||
bot_api_version="9.3",
|
||||
ptb_version="NEXT.VERSION",
|
||||
)
|
||||
return self._last_resale_star_count
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: JSONDict, bot: "Bot | None" = None) -> "UniqueGiftInfo":
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
|
||||
@@ -56,9 +56,11 @@ if TYPE_CHECKING:
|
||||
Message,
|
||||
MessageEntity,
|
||||
MessageId,
|
||||
OwnedGifts,
|
||||
PhotoSize,
|
||||
ReplyParameters,
|
||||
Sticker,
|
||||
Story,
|
||||
SuggestedPostParameters,
|
||||
UserChatBoosts,
|
||||
UserProfilePhotos,
|
||||
@@ -112,6 +114,10 @@ class User(TelegramObject):
|
||||
Returned only in :meth:`telegram.Bot.get_me`.
|
||||
|
||||
.. versionadded:: 21.5
|
||||
has_topics_enabled (:obj:`bool`, optional): :obj:`True`, if the bot has forum topic mode
|
||||
enabled in private chats. Returned only in :meth:`telegram.Bot.get_me`.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
Attributes:
|
||||
id (:obj:`int`): Unique identifier for this user or bot.
|
||||
@@ -143,6 +149,10 @@ class User(TelegramObject):
|
||||
Returned only in :meth:`telegram.Bot.get_me`.
|
||||
|
||||
.. versionadded:: 21.5
|
||||
has_topics_enabled (:obj:`bool`): Optional. :obj:`True`, if the bot has forum topic mode
|
||||
enabled in private chats. Returned only in :meth:`telegram.Bot.get_me`.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
.. |user_chat_id_note| replace:: This shortcuts build on the assumption that :attr:`User.id`
|
||||
coincides with the :attr:`Chat.id` of the private chat with the user. This has been the
|
||||
@@ -156,6 +166,7 @@ class User(TelegramObject):
|
||||
"can_read_all_group_messages",
|
||||
"first_name",
|
||||
"has_main_web_app",
|
||||
"has_topics_enabled",
|
||||
"id",
|
||||
"is_bot",
|
||||
"is_premium",
|
||||
@@ -180,6 +191,7 @@ class User(TelegramObject):
|
||||
added_to_attachment_menu: bool | None = None,
|
||||
can_connect_to_business: bool | None = None,
|
||||
has_main_web_app: bool | None = None,
|
||||
has_topics_enabled: bool | None = None,
|
||||
*,
|
||||
api_kwargs: JSONDict | None = None,
|
||||
):
|
||||
@@ -199,6 +211,7 @@ class User(TelegramObject):
|
||||
self.added_to_attachment_menu: bool | None = added_to_attachment_menu
|
||||
self.can_connect_to_business: bool | None = can_connect_to_business
|
||||
self.has_main_web_app: bool | None = has_main_web_app
|
||||
self.has_topics_enabled: bool | None = has_topics_enabled
|
||||
|
||||
self._id_attrs = (self.id,)
|
||||
|
||||
@@ -486,6 +499,49 @@ class User(TelegramObject):
|
||||
suggested_post_parameters=suggested_post_parameters,
|
||||
)
|
||||
|
||||
async def send_message_draft(
|
||||
self,
|
||||
draft_id: int,
|
||||
text: str,
|
||||
message_thread_id: int | None = None,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
entities: Sequence["MessageEntity"] | None = None,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
connect_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
pool_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict | None = None,
|
||||
) -> bool:
|
||||
"""Shortcut for::
|
||||
|
||||
await bot.send_message_draft(update.effective_user.id, *args, **kwargs)
|
||||
|
||||
For the documentation of the arguments, please see :meth:`telegram.Bot.send_message_draft`.
|
||||
|
||||
Note:
|
||||
|user_chat_id_note|
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
Returns:
|
||||
:obj:`bool`: On success, :obj:`True` is returned.
|
||||
|
||||
"""
|
||||
return await self.get_bot().send_message_draft(
|
||||
chat_id=self.id,
|
||||
draft_id=draft_id,
|
||||
text=text,
|
||||
message_thread_id=message_thread_id,
|
||||
parse_mode=parse_mode,
|
||||
entities=entities,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
async def delete_message(
|
||||
self,
|
||||
message_id: int,
|
||||
@@ -1812,6 +1868,7 @@ class User(TelegramObject):
|
||||
video_start_timestamp: int | None = None,
|
||||
direct_messages_topic_id: int | None = None,
|
||||
suggested_post_parameters: "SuggestedPostParameters | None" = None,
|
||||
message_effect_id: str | None = None,
|
||||
*,
|
||||
reply_to_message_id: int | None = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
@@ -1858,6 +1915,7 @@ class User(TelegramObject):
|
||||
allow_paid_broadcast=allow_paid_broadcast,
|
||||
direct_messages_topic_id=direct_messages_topic_id,
|
||||
suggested_post_parameters=suggested_post_parameters,
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def copy_message(
|
||||
@@ -1877,6 +1935,7 @@ class User(TelegramObject):
|
||||
video_start_timestamp: int | None = None,
|
||||
direct_messages_topic_id: int | None = None,
|
||||
suggested_post_parameters: "SuggestedPostParameters | None" = None,
|
||||
message_effect_id: str | None = None,
|
||||
*,
|
||||
reply_to_message_id: int | None = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
@@ -1923,6 +1982,7 @@ class User(TelegramObject):
|
||||
allow_paid_broadcast=allow_paid_broadcast,
|
||||
direct_messages_topic_id=direct_messages_topic_id,
|
||||
suggested_post_parameters=suggested_post_parameters,
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def send_copies(
|
||||
@@ -2029,6 +2089,7 @@ class User(TelegramObject):
|
||||
video_start_timestamp: int | None = None,
|
||||
direct_messages_topic_id: int | None = None,
|
||||
suggested_post_parameters: "SuggestedPostParameters | None" = None,
|
||||
message_effect_id: str | None = None,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
@@ -2065,6 +2126,7 @@ class User(TelegramObject):
|
||||
message_thread_id=message_thread_id,
|
||||
direct_messages_topic_id=direct_messages_topic_id,
|
||||
suggested_post_parameters=suggested_post_parameters,
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def forward_to(
|
||||
@@ -2077,6 +2139,7 @@ class User(TelegramObject):
|
||||
video_start_timestamp: int | None = None,
|
||||
direct_messages_topic_id: int | None = None,
|
||||
suggested_post_parameters: "SuggestedPostParameters | None" = None,
|
||||
message_effect_id: str | None = None,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
@@ -2114,6 +2177,7 @@ class User(TelegramObject):
|
||||
message_thread_id=message_thread_id,
|
||||
direct_messages_topic_id=direct_messages_topic_id,
|
||||
suggested_post_parameters=suggested_post_parameters,
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def forward_messages_from(
|
||||
@@ -2475,3 +2539,92 @@ class User(TelegramObject):
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
async def repost_story(
|
||||
self,
|
||||
business_connection_id: str,
|
||||
from_story_id: int,
|
||||
active_period: TimePeriod,
|
||||
post_to_chat_page: bool | None = None,
|
||||
protect_content: ODVInput[bool] = DEFAULT_NONE,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
connect_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
pool_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict | None = None,
|
||||
) -> "Story":
|
||||
"""Shortcut for::
|
||||
|
||||
await bot.repost_story(
|
||||
from_chat_id=update.effective_user.id,
|
||||
*args, **kwargs
|
||||
)
|
||||
|
||||
For the documentation of the arguments, please see :meth:`telegram.Bot.repost_story`.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
Returns:
|
||||
:class:`Story`: On success, :class:`Story` is returned.
|
||||
|
||||
"""
|
||||
return await self.get_bot().repost_story(
|
||||
business_connection_id=business_connection_id,
|
||||
from_chat_id=self.id,
|
||||
from_story_id=from_story_id,
|
||||
active_period=active_period,
|
||||
post_to_chat_page=post_to_chat_page,
|
||||
protect_content=protect_content,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
async def get_gifts(
|
||||
self,
|
||||
exclude_unlimited: bool | None = None,
|
||||
exclude_limited_upgradable: bool | None = None,
|
||||
exclude_limited_non_upgradable: bool | None = None,
|
||||
exclude_from_blockchain: bool | None = None,
|
||||
exclude_unique: bool | None = None,
|
||||
sort_by_price: bool | None = None,
|
||||
offset: str | None = None,
|
||||
limit: int | None = None,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
connect_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
pool_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict | None = None,
|
||||
) -> "OwnedGifts":
|
||||
"""Shortcut for::
|
||||
|
||||
await bot.get_user_gifts(user_id=update.effective_user.id)
|
||||
|
||||
For the documentation of the arguments, please see
|
||||
:meth:`telegram.Bot.get_user_gifts`.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
Returns:
|
||||
:class:`telegram.OwnedGifts`: On success, returns the gifts owned by the user.
|
||||
"""
|
||||
return await self.get_bot().get_user_gifts(
|
||||
user_id=self.id,
|
||||
exclude_unlimited=exclude_unlimited,
|
||||
exclude_limited_upgradable=exclude_limited_upgradable,
|
||||
exclude_limited_non_upgradable=exclude_limited_non_upgradable,
|
||||
exclude_from_blockchain=exclude_from_blockchain,
|
||||
exclude_unique=exclude_unique,
|
||||
sort_by_price=sort_by_price,
|
||||
offset=offset,
|
||||
limit=limit,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# A library that provides a Python interface to the Telegram Bot API
|
||||
# Copyright (C) 2015-2026
|
||||
# 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 an object that represents a Telegram user rating."""
|
||||
|
||||
from telegram._telegramobject import TelegramObject
|
||||
from telegram._utils.types import JSONDict
|
||||
|
||||
|
||||
class UserRating(TelegramObject):
|
||||
"""
|
||||
This object describes the rating of a user based on their Telegram Star spendings.
|
||||
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal, if their :attr:`level` and :attr:`rating` are equal.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
Args:
|
||||
level (:obj:`int`): Current level of the user, indicating their reliability when purchasing
|
||||
digital goods and services. A higher level suggests a more trustworthy customer; a
|
||||
negative level is likely reason for concern.
|
||||
rating (:obj:`int`): Numerical value of the user's rating; the higher the rating, the
|
||||
better
|
||||
current_level_rating (:obj:`int`): The rating value required to get the current level
|
||||
next_level_rating (:obj:`int`, optional): The rating value required to get to the next
|
||||
level; omitted if the maximum level was reached
|
||||
|
||||
Attributes:
|
||||
level (:obj:`int`): Current level of the user, indicating their reliability when purchasing
|
||||
digital goods and services. A higher level suggests a more trustworthy customer; a
|
||||
negative level is likely reason for concern.
|
||||
rating (:obj:`int`): Numerical value of the user's rating; the higher the rating, the
|
||||
better
|
||||
current_level_rating (:obj:`int`): The rating value required to get the current level
|
||||
next_level_rating (:obj:`int`): Optional. The rating value required to get to the next
|
||||
level; omitted if the maximum level was reached
|
||||
|
||||
"""
|
||||
|
||||
__slots__ = ("current_level_rating", "level", "next_level_rating", "rating")
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
level: int,
|
||||
rating: int,
|
||||
current_level_rating: int,
|
||||
next_level_rating: int | None = None,
|
||||
*,
|
||||
api_kwargs: JSONDict | None = None,
|
||||
) -> None:
|
||||
super().__init__(api_kwargs=api_kwargs)
|
||||
self.level: int = level
|
||||
self.rating: int = rating
|
||||
self.current_level_rating: int = current_level_rating
|
||||
self.next_level_rating: int | None = next_level_rating
|
||||
|
||||
self._id_attrs = (self.level, self.rating)
|
||||
|
||||
self._freeze()
|
||||
+56
-24
@@ -176,7 +176,7 @@ class _AccentColor(NamedTuple):
|
||||
#: :data:`telegram.__bot_api_version_info__`.
|
||||
#:
|
||||
#: .. versionadded:: 20.0
|
||||
BOT_API_VERSION_INFO: Final[_BotAPIVersion] = _BotAPIVersion(major=9, minor=2)
|
||||
BOT_API_VERSION_INFO: Final[_BotAPIVersion] = _BotAPIVersion(major=9, minor=3)
|
||||
#: :obj:`str`: Telegram Bot API
|
||||
#: version supported by this version of `python-telegram-bot`. Also available as
|
||||
#: :data:`telegram.__bot_api_version__`.
|
||||
@@ -761,13 +761,23 @@ class BusinessLimit(IntEnum):
|
||||
"""
|
||||
MIN_GIFT_RESULTS = 1
|
||||
""":obj:`int`: Minimum number of gifts to be returned. Relevant for
|
||||
:paramref:`~telegram.Bot.get_business_account_gifts.limit` of
|
||||
:meth:`telegram.Bot.get_business_account_gifts`.
|
||||
|
||||
* :paramref:`~telegram.Bot.get_business_account_gifts.limit` of
|
||||
:meth:`telegram.Bot.get_business_account_gifts`.
|
||||
* :paramref:`~telegram.Bot.get_chat_gifts.limit` of
|
||||
:meth:`telegram.Bot.get_chat_gifts`.
|
||||
* :paramref:`~telegram.Bot.get_user_gifts.limit` of
|
||||
:meth:`telegram.Bot.get_user_gifts`.
|
||||
"""
|
||||
MAX_GIFT_RESULTS = 100
|
||||
""":obj:`int`: Maximum number of gifts to be returned. Relevant for
|
||||
:paramref:`~telegram.Bot.get_business_account_gifts.limit` of
|
||||
:meth:`telegram.Bot.get_business_account_gifts`.
|
||||
|
||||
* :paramref:`~telegram.Bot.get_business_account_gifts.limit` of
|
||||
:meth:`telegram.Bot.get_business_account_gifts`.
|
||||
* :paramref:`~telegram.Bot.get_chat_gifts.limit` of
|
||||
:meth:`telegram.Bot.get_chat_gifts`.
|
||||
* :paramref:`~telegram.Bot.get_user_gifts.limit` of
|
||||
:meth:`telegram.Bot.get_user_gifts`.
|
||||
"""
|
||||
MIN_STAR_COUNT = 1
|
||||
""":obj:`int`: Minimum number of Telegram Stars to be transfered. Relevant for
|
||||
@@ -2010,6 +2020,8 @@ class MessageLimit(IntEnum):
|
||||
* :paramref:`~telegram.Bot.send_message.text` parameter of :meth:`telegram.Bot.send_message`
|
||||
* :paramref:`~telegram.Bot.edit_message_text.text` parameter of
|
||||
:meth:`telegram.Bot.edit_message_text`
|
||||
* :paramref:`~telegram.Bot.send_message_draft.text` parameter of
|
||||
:meth:`telegram.Bot.send_message_draft`
|
||||
"""
|
||||
CAPTION_LENGTH = 1024
|
||||
""":obj:`int`: Maximum number of characters in a :obj:`str` passed as:
|
||||
@@ -2025,11 +2037,14 @@ class MessageLimit(IntEnum):
|
||||
"""
|
||||
# constants above this line are tested
|
||||
MIN_TEXT_LENGTH = 1
|
||||
""":obj:`int`: Minimum number of characters in a :obj:`str` passed as the
|
||||
:paramref:`~telegram.InputTextMessageContent.message_text` parameter of
|
||||
:class:`telegram.InputTextMessageContent` and the
|
||||
:paramref:`~telegram.Bot.edit_message_text.text` parameter of
|
||||
:meth:`telegram.Bot.edit_message_text`.
|
||||
""":obj:`int`: Minimum number of characters in a :obj:`str` passed as:
|
||||
|
||||
* :paramref:`~telegram.InputTextMessageContent.message_text` parameter of
|
||||
:class:`telegram.InputTextMessageContent`.
|
||||
* :paramref:`~telegram.Bot.edit_message_text.text` parameter of
|
||||
:meth:`telegram.Bot.edit_message_text`.
|
||||
* :paramref:`~telegram.Bot.send_message_draft.text` parameter of
|
||||
:meth:`telegram.Bot.send_message_draft`.
|
||||
"""
|
||||
DEEP_LINK_LENGTH = 64
|
||||
""":obj:`int`: Maximum number of characters for a deep link."""
|
||||
@@ -2175,6 +2190,11 @@ class MessageType(StringEnum):
|
||||
|
||||
.. versionadded:: 22.1
|
||||
"""
|
||||
GIFT_UPGRADE_SENT = "gift_upgrade_sent"
|
||||
""":obj:`str`: Messages with :attr:`telegram.Message.gift_upgrade_sent`.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
"""
|
||||
GIVEAWAY = "giveaway"
|
||||
""":obj:`str`: Messages with :attr:`telegram.Message.giveaway`.
|
||||
|
||||
@@ -3058,7 +3078,7 @@ class StoryAreaTypeType(StringEnum):
|
||||
""":obj:`str`: Type of :class:`telegram.StoryAreaTypeUniqueGift`."""
|
||||
|
||||
|
||||
class StoryLimit(StringEnum):
|
||||
class StoryLimit(IntEnum):
|
||||
"""This enum contains limitations for :meth:`~telegram.Bot.post_story` and
|
||||
:meth:`~telegram.Bot.edit_story`.
|
||||
The enum members of this enumeration are instances of :class:`int` and can be treated as such.
|
||||
@@ -3074,17 +3094,17 @@ class StoryLimit(StringEnum):
|
||||
:meth:`telegram.Bot.edit_story`.
|
||||
"""
|
||||
ACTIVITY_SIX_HOURS = 6 * 3600
|
||||
""":obj:`int`: Possible value for :paramref:`~telegram.Bot.post_story.caption`` parameter of
|
||||
:meth:`telegram.Bot.post_story`."""
|
||||
""":obj:`int`: Possible value for :paramref:`~telegram.Bot.post_story.active_period`` parameter
|
||||
of :meth:`telegram.Bot.post_story`."""
|
||||
ACTIVITY_TWELVE_HOURS = 12 * 3600
|
||||
""":obj:`int`: Possible value for :paramref:`~telegram.Bot.post_story.caption`` parameter of
|
||||
:meth:`telegram.Bot.post_story`."""
|
||||
""":obj:`int`: Possible value for :paramref:`~telegram.Bot.post_story.active_period`` parameter
|
||||
of :meth:`telegram.Bot.post_story`."""
|
||||
ACTIVITY_ONE_DAY = 86400
|
||||
""":obj:`int`: Possible value for :paramref:`~telegram.Bot.post_story.caption`` parameter of
|
||||
:meth:`telegram.Bot.post_story`."""
|
||||
""":obj:`int`: Possible value for :paramref:`~telegram.Bot.post_story.active_period`` parameter
|
||||
of :meth:`telegram.Bot.post_story`."""
|
||||
ACTIVITY_TWO_DAYS = 2 * 86400
|
||||
""":obj:`int`: Possible value for :paramref:`~telegram.Bot.post_story.caption`` parameter of
|
||||
:meth:`telegram.Bot.post_story`."""
|
||||
""":obj:`int`: Possible value for :paramref:`~telegram.Bot.post_story.active_period`` parameter
|
||||
of :meth:`telegram.Bot.post_story`."""
|
||||
|
||||
|
||||
class SuggestedPost(IntEnum):
|
||||
@@ -3328,15 +3348,25 @@ class UniqueGiftInfoOrigin(StringEnum):
|
||||
|
||||
__slots__ = ()
|
||||
|
||||
UPGRADE = "upgrade"
|
||||
""":obj:`str` gift upgraded"""
|
||||
TRANSFER = "transfer"
|
||||
""":obj:`str` gift transfered"""
|
||||
GIFTED_UPGRADE = "gifted_upgrade"
|
||||
""":obj:`str` upgrades purchased after the gift was sent
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
"""
|
||||
OFFER = "OFFER"
|
||||
""":obj:`str` gift bought or sold through gift purchase offers
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
"""
|
||||
RESALE = "resale"
|
||||
""":obj:`str` gift bought from other users
|
||||
|
||||
.. versionadded:: 22.3
|
||||
"""
|
||||
TRANSFER = "transfer"
|
||||
""":obj:`str` gift transfered"""
|
||||
UPGRADE = "upgrade"
|
||||
""":obj:`str` gift upgraded"""
|
||||
|
||||
|
||||
class UpdateType(StringEnum):
|
||||
@@ -3510,7 +3540,7 @@ class InvoiceLimit(IntEnum):
|
||||
|
||||
.. versionadded:: 21.6
|
||||
"""
|
||||
MAX_STAR_COUNT = 10000
|
||||
MAX_STAR_COUNT = 25000
|
||||
""":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`.
|
||||
@@ -3518,6 +3548,8 @@ class InvoiceLimit(IntEnum):
|
||||
.. versionadded:: 21.6
|
||||
.. versionchanged:: 22.1
|
||||
Bot API 9.0 changed the value to 10000.
|
||||
.. versionchanged:: NEXT.VERSION
|
||||
Bot API 9.3 changed the value to 25000.
|
||||
"""
|
||||
SUBSCRIPTION_PERIOD = dtm.timedelta(days=30).total_seconds()
|
||||
""":obj:`int`: The period of time for which the subscription is active before
|
||||
|
||||
@@ -831,6 +831,7 @@ class ExtBot(Bot, Generic[RLARGS]):
|
||||
video_start_timestamp: int | None = None,
|
||||
direct_messages_topic_id: int | None = None,
|
||||
suggested_post_parameters: "SuggestedPostParameters | None" = None,
|
||||
message_effect_id: str | None = None,
|
||||
*,
|
||||
reply_to_message_id: int | None = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
@@ -866,6 +867,7 @@ class ExtBot(Bot, Generic[RLARGS]):
|
||||
allow_paid_broadcast=allow_paid_broadcast,
|
||||
direct_messages_topic_id=direct_messages_topic_id,
|
||||
suggested_post_parameters=suggested_post_parameters,
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def copy_messages(
|
||||
@@ -1776,6 +1778,7 @@ class ExtBot(Bot, Generic[RLARGS]):
|
||||
video_start_timestamp: int | None = None,
|
||||
direct_messages_topic_id: int | None = None,
|
||||
suggested_post_parameters: "SuggestedPostParameters | None" = None,
|
||||
message_effect_id: str | None = None,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
@@ -1799,6 +1802,7 @@ class ExtBot(Bot, Generic[RLARGS]):
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=self._merge_api_rl_kwargs(api_kwargs, rate_limit_args),
|
||||
direct_messages_topic_id=direct_messages_topic_id,
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def forward_messages(
|
||||
@@ -3134,6 +3138,36 @@ class ExtBot(Bot, Generic[RLARGS]):
|
||||
suggested_post_parameters=suggested_post_parameters,
|
||||
)
|
||||
|
||||
async def send_message_draft(
|
||||
self,
|
||||
chat_id: int,
|
||||
draft_id: int,
|
||||
text: str,
|
||||
message_thread_id: int | None = None,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
entities: Sequence["MessageEntity"] | None = None,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
connect_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
pool_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict | None = None,
|
||||
rate_limit_args: RLARGS | None = None,
|
||||
) -> bool:
|
||||
return await super().send_message_draft(
|
||||
chat_id=chat_id,
|
||||
draft_id=draft_id,
|
||||
text=text,
|
||||
message_thread_id=message_thread_id,
|
||||
parse_mode=parse_mode,
|
||||
entities=entities,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=self._merge_api_rl_kwargs(api_kwargs, rate_limit_args),
|
||||
)
|
||||
|
||||
async def send_photo(
|
||||
self,
|
||||
chat_id: int | str,
|
||||
@@ -4463,6 +4497,9 @@ class ExtBot(Bot, Generic[RLARGS]):
|
||||
sort_by_price: bool | None = None,
|
||||
offset: str | None = None,
|
||||
limit: int | None = None,
|
||||
exclude_limited_upgradable: bool | None = None,
|
||||
exclude_limited_non_upgradable: bool | None = None,
|
||||
exclude_from_blockchain: bool | None = None,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
@@ -4477,7 +4514,10 @@ class ExtBot(Bot, Generic[RLARGS]):
|
||||
exclude_saved=exclude_saved,
|
||||
exclude_unlimited=exclude_unlimited,
|
||||
exclude_limited=exclude_limited,
|
||||
exclude_limited_upgradable=exclude_limited_upgradable,
|
||||
exclude_limited_non_upgradable=exclude_limited_non_upgradable,
|
||||
exclude_unique=exclude_unique,
|
||||
exclude_from_blockchain=exclude_from_blockchain,
|
||||
sort_by_price=sort_by_price,
|
||||
offset=offset,
|
||||
limit=limit,
|
||||
@@ -5278,9 +5318,116 @@ class ExtBot(Bot, Generic[RLARGS]):
|
||||
api_kwargs=self._merge_api_rl_kwargs(api_kwargs, rate_limit_args),
|
||||
)
|
||||
|
||||
async def repost_story(
|
||||
self,
|
||||
business_connection_id: str,
|
||||
from_chat_id: int,
|
||||
from_story_id: int,
|
||||
active_period: TimePeriod,
|
||||
post_to_chat_page: bool | None = None,
|
||||
protect_content: ODVInput[bool] = DEFAULT_NONE,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
connect_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
pool_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict | None = None,
|
||||
rate_limit_args: RLARGS | None = None,
|
||||
) -> Story:
|
||||
return await super().repost_story(
|
||||
business_connection_id=business_connection_id,
|
||||
from_chat_id=from_chat_id,
|
||||
from_story_id=from_story_id,
|
||||
active_period=active_period,
|
||||
post_to_chat_page=post_to_chat_page,
|
||||
protect_content=protect_content,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=self._merge_api_rl_kwargs(api_kwargs, rate_limit_args),
|
||||
)
|
||||
|
||||
async def get_user_gifts(
|
||||
self,
|
||||
user_id: int,
|
||||
exclude_unlimited: bool | None = None,
|
||||
exclude_limited_upgradable: bool | None = None,
|
||||
exclude_limited_non_upgradable: bool | None = None,
|
||||
exclude_from_blockchain: bool | None = None,
|
||||
exclude_unique: bool | None = None,
|
||||
sort_by_price: bool | None = None,
|
||||
offset: str | None = None,
|
||||
limit: int | None = None,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
connect_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
pool_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict | None = None,
|
||||
rate_limit_args: RLARGS | None = None,
|
||||
) -> OwnedGifts:
|
||||
return await super().get_user_gifts(
|
||||
user_id=user_id,
|
||||
exclude_unlimited=exclude_unlimited,
|
||||
exclude_limited_upgradable=exclude_limited_upgradable,
|
||||
exclude_limited_non_upgradable=exclude_limited_non_upgradable,
|
||||
exclude_from_blockchain=exclude_from_blockchain,
|
||||
exclude_unique=exclude_unique,
|
||||
sort_by_price=sort_by_price,
|
||||
offset=offset,
|
||||
limit=limit,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=self._merge_api_rl_kwargs(api_kwargs, rate_limit_args),
|
||||
)
|
||||
|
||||
async def get_chat_gifts(
|
||||
self,
|
||||
chat_id: int | str,
|
||||
exclude_unsaved: bool | None = None,
|
||||
exclude_saved: bool | None = None,
|
||||
exclude_unlimited: bool | None = None,
|
||||
exclude_limited_upgradable: bool | None = None,
|
||||
exclude_limited_non_upgradable: bool | None = None,
|
||||
exclude_from_blockchain: bool | None = None,
|
||||
exclude_unique: bool | None = None,
|
||||
sort_by_price: bool | None = None,
|
||||
offset: str | None = None,
|
||||
limit: int | None = None,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
connect_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
pool_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict | None = None,
|
||||
rate_limit_args: RLARGS | None = None,
|
||||
) -> OwnedGifts:
|
||||
return await super().get_chat_gifts(
|
||||
chat_id=chat_id,
|
||||
exclude_unsaved=exclude_unsaved,
|
||||
exclude_saved=exclude_saved,
|
||||
exclude_unlimited=exclude_unlimited,
|
||||
exclude_limited_upgradable=exclude_limited_upgradable,
|
||||
exclude_limited_non_upgradable=exclude_limited_non_upgradable,
|
||||
exclude_from_blockchain=exclude_from_blockchain,
|
||||
exclude_unique=exclude_unique,
|
||||
sort_by_price=sort_by_price,
|
||||
offset=offset,
|
||||
limit=limit,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=self._merge_api_rl_kwargs(api_kwargs, rate_limit_args),
|
||||
)
|
||||
|
||||
# updated camelCase aliases
|
||||
getMe = get_me
|
||||
sendMessage = send_message
|
||||
sendMessageDraft = send_message_draft
|
||||
deleteMessage = delete_message
|
||||
deleteMessages = delete_messages
|
||||
forwardMessage = forward_message
|
||||
@@ -5436,3 +5583,6 @@ class ExtBot(Bot, Generic[RLARGS]):
|
||||
getMyStarBalance = get_my_star_balance
|
||||
approveSuggestedPost = approve_suggested_post
|
||||
declineSuggestedPost = decline_suggested_post
|
||||
repostStory = repost_story
|
||||
getUserGifts = get_user_gifts
|
||||
getChatGifts = get_chat_gifts
|
||||
|
||||
@@ -1978,6 +1978,7 @@ class StatusUpdate:
|
||||
or StatusUpdate.GENERAL_FORUM_TOPIC_HIDDEN.check_update(update)
|
||||
or StatusUpdate.GENERAL_FORUM_TOPIC_UNHIDDEN.check_update(update)
|
||||
or StatusUpdate.GIFT.check_update(update)
|
||||
or StatusUpdate.GIFT_UPGRADE_SENT.check_update(update)
|
||||
or StatusUpdate.GIVEAWAY_COMPLETED.check_update(update)
|
||||
or StatusUpdate.GIVEAWAY_CREATED.check_update(update)
|
||||
or StatusUpdate.LEFT_CHAT_MEMBER.check_update(update)
|
||||
@@ -2188,6 +2189,18 @@ class StatusUpdate:
|
||||
.. versionadded:: 22.1
|
||||
"""
|
||||
|
||||
class _GiftUpgradeSent(MessageFilter):
|
||||
__slots__ = ()
|
||||
|
||||
def filter(self, message: Message) -> bool:
|
||||
return bool(message.gift_upgrade_sent)
|
||||
|
||||
GIFT_UPGRADE_SENT = _GiftUpgradeSent(name="filters.StatusUpdate.GIFT_UPGRADE_SENT")
|
||||
"""Messages that contain :attr:`telegram.Message.gift_upgrade_sent`.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
"""
|
||||
|
||||
class _GiveawayCreated(MessageFilter):
|
||||
__slots__ = ()
|
||||
|
||||
|
||||
@@ -81,7 +81,11 @@ _PREPARED_DUMMY_OBJECTS: dict[str, object] = {
|
||||
accent_color_id=1,
|
||||
max_reaction_count=1,
|
||||
accepted_gift_types=AcceptedGiftTypes(
|
||||
unlimited_gifts=True, limited_gifts=True, unique_gifts=True, premium_subscription=True
|
||||
unlimited_gifts=True,
|
||||
limited_gifts=True,
|
||||
unique_gifts=True,
|
||||
premium_subscription=True,
|
||||
gifts_from_channels=True,
|
||||
),
|
||||
),
|
||||
"ChatInviteLink": ChatInviteLink(
|
||||
|
||||
@@ -1136,6 +1136,11 @@ class TestFilters:
|
||||
assert filters.StatusUpdate.UNIQUE_GIFT.check_update(update)
|
||||
update.message.unique_gift = None
|
||||
|
||||
update.message.gift_upgrade_sent = "gift_upgrade_sent"
|
||||
assert filters.StatusUpdate.ALL.check_update(update)
|
||||
assert filters.StatusUpdate.GIFT_UPGRADE_SENT.check_update(update)
|
||||
update.message.gift_upgrade_sent = None
|
||||
|
||||
update.message.paid_message_price_changed = "paid_message_price_changed"
|
||||
assert filters.StatusUpdate.ALL.check_update(update)
|
||||
assert filters.StatusUpdate.PAID_MESSAGE_PRICE_CHANGED.check_update(update)
|
||||
|
||||
@@ -65,6 +65,7 @@ from telegram import (
|
||||
MenuButtonWebApp,
|
||||
Message,
|
||||
MessageEntity,
|
||||
OwnedGifts,
|
||||
Poll,
|
||||
PollOption,
|
||||
PreparedInlineMessage,
|
||||
@@ -1477,6 +1478,61 @@ class TestBotWithoutRequest:
|
||||
"SoSecretToken",
|
||||
)
|
||||
|
||||
async def test_send_message_draft(self, offline_bot, monkeypatch):
|
||||
entities = [
|
||||
MessageEntity(MessageEntity.BOLD, 0, 3),
|
||||
MessageEntity(MessageEntity.ITALIC, 5, 8),
|
||||
]
|
||||
|
||||
async def make_assertions(*args, **kwargs):
|
||||
params = kwargs.get("request_data").parameters
|
||||
assert params.get("chat_id") == 123
|
||||
assert params.get("draft_id") == 1
|
||||
assert params.get("text") == "test test"
|
||||
assert params.get("message_thread_id") == 9
|
||||
assert params.get("parse_mode") == "markdown"
|
||||
assert params.get("entities") == [e.to_dict() for e in entities]
|
||||
|
||||
return True
|
||||
|
||||
monkeypatch.setattr(offline_bot.request, "post", make_assertions)
|
||||
assert await offline_bot.send_message_draft(
|
||||
chat_id=123,
|
||||
draft_id=1,
|
||||
text="test test",
|
||||
message_thread_id=9,
|
||||
parse_mode="markdown",
|
||||
entities=entities,
|
||||
)
|
||||
|
||||
@pytest.mark.parametrize("default_bot", [{"parse_mode": "Markdown"}], indirect=True)
|
||||
@pytest.mark.parametrize(
|
||||
("passed_value", "expected_value"),
|
||||
[(DEFAULT_NONE, "Markdown"), ("HTML", "HTML"), (None, None)],
|
||||
)
|
||||
async def test_send_message_draft_default_parse_mode(
|
||||
self, default_bot, monkeypatch, passed_value, expected_value
|
||||
):
|
||||
async def make_assertion(url, request_data, *args, **kwargs):
|
||||
assert request_data.parameters.get("parse_mode") == expected_value
|
||||
return True
|
||||
|
||||
monkeypatch.setattr(default_bot.request, "post", make_assertion)
|
||||
kwargs = {
|
||||
"chat_id": 123,
|
||||
"draft_id": 1,
|
||||
"text": "test test",
|
||||
"message_thread_id": 9,
|
||||
"entities": [
|
||||
MessageEntity(MessageEntity.BOLD, 0, 3),
|
||||
MessageEntity(MessageEntity.ITALIC, 5, 8),
|
||||
],
|
||||
}
|
||||
if passed_value is not DEFAULT_NONE:
|
||||
kwargs["parse_mode"] = passed_value
|
||||
|
||||
await default_bot.send_message_draft(**kwargs)
|
||||
|
||||
# TODO: Needs improvement. Need incoming shipping queries to test
|
||||
async def test_answer_shipping_query_ok(self, monkeypatch, offline_bot):
|
||||
# For now just test that our internals pass the correct data
|
||||
@@ -2712,6 +2768,72 @@ class TestBotWithoutRequest:
|
||||
|
||||
await offline_bot.decline_suggested_post(1234, 5678, "declined")
|
||||
|
||||
async def test_get_user_gifts_parameter_passing(self, offline_bot, monkeypatch):
|
||||
async def make_assertion(url, request_data: RequestData, *args, **kwargs):
|
||||
for param in (
|
||||
"user_id",
|
||||
"exclude_unlimited",
|
||||
"exclude_limited_upgradable",
|
||||
"exclude_limited_non_upgradable",
|
||||
"exclude_from_blockchain",
|
||||
"exclude_unique",
|
||||
"sort_by_price",
|
||||
"offset",
|
||||
"limit",
|
||||
):
|
||||
assert request_data.parameters.get(param) == param
|
||||
|
||||
return OwnedGifts(0, [], "null").to_dict()
|
||||
|
||||
monkeypatch.setattr(offline_bot.request, "post", make_assertion)
|
||||
|
||||
await offline_bot.get_user_gifts(
|
||||
user_id="user_id",
|
||||
exclude_unlimited="exclude_unlimited",
|
||||
exclude_limited_upgradable="exclude_limited_upgradable",
|
||||
exclude_limited_non_upgradable="exclude_limited_non_upgradable",
|
||||
exclude_from_blockchain="exclude_from_blockchain",
|
||||
exclude_unique="exclude_unique",
|
||||
sort_by_price="sort_by_price",
|
||||
offset="offset",
|
||||
limit="limit",
|
||||
)
|
||||
|
||||
async def test_get_chat_gifts_parameter_passing(self, offline_bot, monkeypatch):
|
||||
async def make_assertion(url, request_data: RequestData, *args, **kwargs):
|
||||
for param in (
|
||||
"chat_id",
|
||||
"exclude_saved",
|
||||
"exclude_unsaved",
|
||||
"exclude_unlimited",
|
||||
"exclude_limited_upgradable",
|
||||
"exclude_limited_non_upgradable",
|
||||
"exclude_from_blockchain",
|
||||
"exclude_unique",
|
||||
"sort_by_price",
|
||||
"offset",
|
||||
"limit",
|
||||
):
|
||||
assert request_data.parameters.get(param) == param
|
||||
|
||||
return OwnedGifts(0, [], "null").to_dict()
|
||||
|
||||
monkeypatch.setattr(offline_bot.request, "post", make_assertion)
|
||||
|
||||
await offline_bot.get_chat_gifts(
|
||||
chat_id="chat_id",
|
||||
exclude_saved="exclude_saved",
|
||||
exclude_unsaved="exclude_unsaved",
|
||||
exclude_unlimited="exclude_unlimited",
|
||||
exclude_limited_upgradable="exclude_limited_upgradable",
|
||||
exclude_limited_non_upgradable="exclude_limited_non_upgradable",
|
||||
exclude_from_blockchain="exclude_from_blockchain",
|
||||
exclude_unique="exclude_unique",
|
||||
sort_by_price="sort_by_price",
|
||||
offset="offset",
|
||||
limit="limit",
|
||||
)
|
||||
|
||||
|
||||
class TestBotWithRequest:
|
||||
"""
|
||||
@@ -4687,6 +4809,16 @@ class TestBotWithRequest:
|
||||
assert isinstance(balance, StarAmount)
|
||||
assert balance.amount == 0
|
||||
|
||||
async def test_get_user_gifts_basic(self, bot):
|
||||
gifts = await bot.get_user_gifts(bot.bot.id)
|
||||
assert isinstance(gifts, OwnedGifts)
|
||||
assert gifts.total_count == 0
|
||||
|
||||
async def test_get_chat_gifts_basic(self, bot, chat_id):
|
||||
gifts = await bot.get_chat_gifts(chat_id)
|
||||
assert isinstance(gifts, OwnedGifts)
|
||||
assert gifts.total_count == 0
|
||||
|
||||
async def test_initialize_tracks_requests_and_bot_separately(self, offline_bot, monkeypatch):
|
||||
"""Test that requests and bot user are initialized separately and only once."""
|
||||
request_init_count = 0
|
||||
|
||||
@@ -21,6 +21,7 @@ import datetime as dtm
|
||||
import pytest
|
||||
|
||||
from telegram import (
|
||||
Bot,
|
||||
BusinessBotRights,
|
||||
BusinessConnection,
|
||||
Chat,
|
||||
@@ -45,7 +46,10 @@ from telegram._reply import ReplyParameters
|
||||
from telegram._utils.datetime import UTC
|
||||
from telegram._utils.defaultvalue import DEFAULT_NONE
|
||||
from telegram.constants import InputProfilePhotoType, InputStoryContentType
|
||||
from telegram.ext import ExtBot
|
||||
from telegram.warnings import PTBDeprecationWarning
|
||||
from tests.auxil.files import data_file
|
||||
from tests.auxil.networking import OfflineRequest
|
||||
|
||||
|
||||
class BusinessMethodsTestBase:
|
||||
@@ -107,7 +111,10 @@ class TestBusinessMethodsWithoutRequest(BusinessMethodsTestBase):
|
||||
assert data.get("exclude_saved") is bool_param
|
||||
assert data.get("exclude_unlimited") is bool_param
|
||||
assert data.get("exclude_limited") is bool_param
|
||||
assert data.get("exclude_limited_upgradable") is bool_param
|
||||
assert data.get("exclude_limited_non_upgradable") is bool_param
|
||||
assert data.get("exclude_unique") is bool_param
|
||||
assert data.get("exclude_from_blockchain") is bool_param
|
||||
assert data.get("sort_by_price") is bool_param
|
||||
assert data.get("offset") == offset
|
||||
assert data.get("limit") == limit
|
||||
@@ -121,13 +128,50 @@ class TestBusinessMethodsWithoutRequest(BusinessMethodsTestBase):
|
||||
exclude_saved=bool_param,
|
||||
exclude_unlimited=bool_param,
|
||||
exclude_limited=bool_param,
|
||||
exclude_limited_upgradable=bool_param,
|
||||
exclude_limited_non_upgradable=bool_param,
|
||||
exclude_unique=bool_param,
|
||||
exclude_from_blockchain=bool_param,
|
||||
sort_by_price=bool_param,
|
||||
offset=offset,
|
||||
limit=limit,
|
||||
)
|
||||
assert isinstance(obj, OwnedGifts)
|
||||
|
||||
@pytest.mark.parametrize("bot_class", [Bot, ExtBot])
|
||||
async def test_get_business_account_gifts_exclude_limited_deprecation(
|
||||
self, offline_bot, monkeypatch, bot_class
|
||||
):
|
||||
bot = bot_class(offline_bot.token, request=OfflineRequest())
|
||||
|
||||
async def dummy_response(*args, **kwargs):
|
||||
return OwnedGifts(
|
||||
total_count=1,
|
||||
gifts=[
|
||||
OwnedGiftRegular(
|
||||
gift=Gift(
|
||||
id="id1",
|
||||
sticker=Sticker(
|
||||
"file_id", "file_unique_id", 512, 512, False, False, "regular"
|
||||
),
|
||||
star_count=5,
|
||||
),
|
||||
send_date=dtm.datetime.now(tz=UTC).replace(microsecond=0),
|
||||
owned_gift_id="some_id_1",
|
||||
)
|
||||
],
|
||||
).to_dict()
|
||||
|
||||
monkeypatch.setattr(bot.request, "post", dummy_response)
|
||||
with pytest.warns(PTBDeprecationWarning, match=r"9\.3.*exclude_limited") as record:
|
||||
await bot.get_business_account_gifts(
|
||||
business_connection_id=self.bci,
|
||||
exclude_limited=True,
|
||||
)
|
||||
|
||||
assert record[0].category == PTBDeprecationWarning
|
||||
assert record[0].filename == __file__, "wrong stacklevel!"
|
||||
|
||||
async def test_get_business_account_star_balance(self, offline_bot, monkeypatch):
|
||||
star_amount_json = StarAmount(amount=100, nanostar_amount=356).to_json()
|
||||
|
||||
@@ -214,7 +258,7 @@ class TestBusinessMethodsWithoutRequest(BusinessMethodsTestBase):
|
||||
|
||||
async def test_set_business_account_gift_settings(self, offline_bot, monkeypatch):
|
||||
show_gift_button = True
|
||||
accepted_gift_types = AcceptedGiftTypes(True, True, True, True)
|
||||
accepted_gift_types = AcceptedGiftTypes(True, True, True, True, True)
|
||||
|
||||
async def make_assertion(*args, **kwargs):
|
||||
data = kwargs.get("request_data").json_parameters
|
||||
@@ -789,3 +833,55 @@ class TestBusinessMethodsWithoutRequest(BusinessMethodsTestBase):
|
||||
reply_markup=reply_markup,
|
||||
)
|
||||
assert isinstance(obj, Message)
|
||||
|
||||
async def test_repost_story(self, offline_bot, monkeypatch):
|
||||
"""No way to test this without stories"""
|
||||
|
||||
async def make_assertion(url, request_data, *args, **kwargs):
|
||||
for param in (
|
||||
"business_connection_id",
|
||||
"from_chat_id",
|
||||
"from_story_id",
|
||||
"active_period",
|
||||
"post_to_chat_page",
|
||||
"protect_content",
|
||||
):
|
||||
assert request_data.parameters.get(param) == param
|
||||
return Story(chat=Chat(id=1, type=Chat.PRIVATE), id=42).to_dict()
|
||||
|
||||
monkeypatch.setattr(offline_bot.request, "post", make_assertion)
|
||||
|
||||
story = await offline_bot.repost_story(
|
||||
business_connection_id="business_connection_id",
|
||||
from_chat_id="from_chat_id",
|
||||
from_story_id="from_story_id",
|
||||
active_period="active_period",
|
||||
post_to_chat_page="post_to_chat_page",
|
||||
protect_content="protect_content",
|
||||
)
|
||||
assert story.chat.id == 1
|
||||
assert story.id == 42
|
||||
|
||||
@pytest.mark.parametrize("default_bot", [{"protect_content": True}], indirect=True)
|
||||
@pytest.mark.parametrize(
|
||||
("passed_value", "expected_value"),
|
||||
[(DEFAULT_NONE, True), (False, False), (None, None)],
|
||||
)
|
||||
async def test_repost_story_default_protect_content(
|
||||
self, default_bot, monkeypatch, passed_value, expected_value
|
||||
):
|
||||
async def make_assertion(url, request_data, *args, **kwargs):
|
||||
assert request_data.parameters.get("protect_content") == expected_value
|
||||
return Story(chat=Chat(123, "private"), id=123).to_dict()
|
||||
|
||||
monkeypatch.setattr(default_bot.request, "post", make_assertion)
|
||||
kwargs = {
|
||||
"business_connection_id": self.bci,
|
||||
"from_chat_id": 123,
|
||||
"from_story_id": 456,
|
||||
"active_period": dtm.timedelta(seconds=20),
|
||||
}
|
||||
if passed_value is not DEFAULT_NONE:
|
||||
kwargs["protect_content"] = passed_value
|
||||
|
||||
await default_bot.repost_story(**kwargs)
|
||||
|
||||
@@ -524,6 +524,21 @@ class TestChatWithoutRequest(ChatTestBase):
|
||||
monkeypatch.setattr(chat.get_bot(), "send_message", make_assertion)
|
||||
assert await chat.send_message(text="test")
|
||||
|
||||
async def test_instance_method_send_message_draft(self, monkeypatch, chat):
|
||||
async def make_assertion(*_, **kwargs):
|
||||
return kwargs["chat_id"] == chat.id and kwargs["text"] == "test"
|
||||
|
||||
assert check_shortcut_signature(
|
||||
Chat.send_message_draft, Bot.send_message_draft, ["chat_id"], []
|
||||
)
|
||||
assert await check_shortcut_call(
|
||||
chat.send_message_draft, chat.get_bot(), "send_message_draft"
|
||||
)
|
||||
assert await check_defaults_handling(chat.send_message_draft, chat.get_bot())
|
||||
|
||||
monkeypatch.setattr(chat.get_bot(), "send_message_draft", make_assertion)
|
||||
assert await chat.send_message_draft(draft_id=1, text="test")
|
||||
|
||||
async def test_instance_method_send_media_group(self, monkeypatch, chat):
|
||||
async def make_assertion(*_, **kwargs):
|
||||
return kwargs["chat_id"] == chat.id and kwargs["media"] == "test_media_group"
|
||||
@@ -1495,6 +1510,44 @@ class TestChatWithoutRequest(ChatTestBase):
|
||||
monkeypatch.setattr(chat.get_bot(), "decline_suggested_post", make_assertion)
|
||||
assert await chat.decline_suggested_post(message_id="message_id", comment="comment")
|
||||
|
||||
async def test_instance_method_repost_story(self, monkeypatch, chat):
|
||||
async def make_assertion(*_, **kwargs):
|
||||
return kwargs["from_chat_id"] == chat.id
|
||||
|
||||
assert check_shortcut_signature(
|
||||
Chat.repost_story,
|
||||
Bot.repost_story,
|
||||
[
|
||||
"from_chat_id",
|
||||
],
|
||||
additional_kwargs=[],
|
||||
)
|
||||
assert await check_shortcut_call(
|
||||
chat.repost_story,
|
||||
chat.get_bot(),
|
||||
"repost_story",
|
||||
shortcut_kwargs=["from_chat_id"],
|
||||
)
|
||||
assert await check_defaults_handling(chat.repost_story, chat.get_bot())
|
||||
|
||||
monkeypatch.setattr(chat.get_bot(), "repost_story", make_assertion)
|
||||
assert await chat.repost_story(
|
||||
business_connection_id="bcid",
|
||||
from_story_id=123,
|
||||
active_period=3600,
|
||||
)
|
||||
|
||||
async def test_instance_method_get_gifts(self, monkeypatch, chat):
|
||||
async def make_assertion(*_, **kwargs):
|
||||
return kwargs["chat_id"] == chat.id
|
||||
|
||||
assert check_shortcut_signature(Chat.get_gifts, Bot.get_chat_gifts, ["chat_id"], [])
|
||||
assert await check_shortcut_call(chat.get_gifts, chat.get_bot(), "get_chat_gifts")
|
||||
assert await check_defaults_handling(chat.get_gifts, chat.get_bot())
|
||||
|
||||
monkeypatch.setattr(chat.get_bot(), "get_chat_gifts", make_assertion)
|
||||
assert await chat.get_gifts()
|
||||
|
||||
def test_mention_html(self):
|
||||
chat = Chat(id=1, type="foo")
|
||||
with pytest.raises(TypeError, match="Can not create a mention to a private group chat"):
|
||||
|
||||
@@ -33,6 +33,8 @@ from telegram import (
|
||||
Location,
|
||||
ReactionTypeCustomEmoji,
|
||||
ReactionTypeEmoji,
|
||||
UniqueGiftColors,
|
||||
UserRating,
|
||||
)
|
||||
from telegram._gifts import AcceptedGiftTypes
|
||||
from telegram._utils.datetime import UTC, to_timestamp
|
||||
@@ -89,6 +91,9 @@ def chat_full_info(bot):
|
||||
can_send_paid_media=ChatFullInfoTestBase.can_send_paid_media,
|
||||
is_direct_messages=ChatFullInfoTestBase.is_direct_messages,
|
||||
parent_chat=ChatFullInfoTestBase.parent_chat,
|
||||
rating=ChatFullInfoTestBase.rating,
|
||||
unique_gift_colors=ChatFullInfoTestBase.unique_gift_colors,
|
||||
paid_message_star_count=ChatFullInfoTestBase.paid_message_star_count,
|
||||
)
|
||||
chat.set_bot(bot)
|
||||
chat._unfreeze()
|
||||
@@ -147,9 +152,19 @@ class ChatFullInfoTestBase:
|
||||
first_name = "first_name"
|
||||
last_name = "last_name"
|
||||
can_send_paid_media = True
|
||||
accepted_gift_types = AcceptedGiftTypes(True, True, True, True)
|
||||
accepted_gift_types = AcceptedGiftTypes(True, True, True, True, True)
|
||||
is_direct_messages = True
|
||||
parent_chat = Chat(4, "channel", "channel")
|
||||
rating = UserRating(level=1, rating=2, current_level_rating=3, next_level_rating=4)
|
||||
unique_gift_colors = UniqueGiftColors(
|
||||
model_custom_emoji_id="model_custom_emoji_id",
|
||||
symbol_custom_emoji_id="symbol_custom_emoji_id",
|
||||
light_theme_main_color=0xFF5733,
|
||||
light_theme_other_colors=[0x33FF57, 0x3357FF],
|
||||
dark_theme_main_color=0xC70039,
|
||||
dark_theme_other_colors=[0x900C3F, 0x581845],
|
||||
)
|
||||
paid_message_star_count = 1234
|
||||
|
||||
|
||||
class TestChatFullInfoWithoutRequest(ChatFullInfoTestBase):
|
||||
@@ -207,6 +222,9 @@ class TestChatFullInfoWithoutRequest(ChatFullInfoTestBase):
|
||||
"can_send_paid_media": self.can_send_paid_media,
|
||||
"is_direct_messages": self.is_direct_messages,
|
||||
"parent_chat": self.parent_chat.to_dict(),
|
||||
"rating": self.rating.to_dict(),
|
||||
"unique_gift_colors": self.unique_gift_colors.to_dict(),
|
||||
"paid_message_star_count": self.paid_message_star_count,
|
||||
}
|
||||
|
||||
cfi = ChatFullInfo.de_json(json_dict, offline_bot)
|
||||
@@ -258,6 +276,9 @@ class TestChatFullInfoWithoutRequest(ChatFullInfoTestBase):
|
||||
assert cfi.can_send_paid_media == self.can_send_paid_media
|
||||
assert cfi.is_direct_messages == self.is_direct_messages
|
||||
assert cfi.parent_chat == self.parent_chat
|
||||
assert cfi.rating == self.rating
|
||||
assert cfi.unique_gift_colors == self.unique_gift_colors
|
||||
assert cfi.paid_message_star_count == self.paid_message_star_count
|
||||
|
||||
def test_de_json_localization(self, offline_bot, raw_bot, tz_bot):
|
||||
json_dict = {
|
||||
@@ -341,6 +362,9 @@ class TestChatFullInfoWithoutRequest(ChatFullInfoTestBase):
|
||||
assert cfi_dict["max_reaction_count"] == cfi.max_reaction_count
|
||||
assert cfi_dict["is_direct_messages"] == cfi.is_direct_messages
|
||||
assert cfi_dict["parent_chat"] == cfi.parent_chat.to_dict()
|
||||
assert cfi_dict["rating"] == cfi.rating.to_dict()
|
||||
assert cfi_dict["unique_gift_colors"] == cfi.unique_gift_colors.to_dict()
|
||||
assert cfi_dict["paid_message_star_count"] == cfi.paid_message_star_count
|
||||
|
||||
def test_time_period_properties(self, PTB_TIMEDELTA, chat_full_info):
|
||||
cfi = chat_full_info
|
||||
|
||||
@@ -21,6 +21,7 @@ import datetime as dtm
|
||||
import pytest
|
||||
|
||||
from telegram import (
|
||||
Chat,
|
||||
Checklist,
|
||||
ChecklistTask,
|
||||
ChecklistTasksAdded,
|
||||
@@ -43,6 +44,7 @@ class ChecklistTaskTestBase:
|
||||
MessageEntity(type="italic", offset=5, length=2),
|
||||
]
|
||||
completed_by_user = User(id=1, first_name="Test", last_name="User", is_bot=False)
|
||||
completed_by_chat = Chat(id=-100, type=Chat.SUPERGROUP, title="Test Chat")
|
||||
completion_date = dtm.datetime.now(tz=UTC).replace(microsecond=0)
|
||||
|
||||
|
||||
@@ -53,6 +55,7 @@ def checklist_task():
|
||||
text=ChecklistTaskTestBase.text,
|
||||
text_entities=ChecklistTaskTestBase.text_entities,
|
||||
completed_by_user=ChecklistTaskTestBase.completed_by_user,
|
||||
completed_by_chat=ChecklistTaskTestBase.completed_by_chat,
|
||||
completion_date=ChecklistTaskTestBase.completion_date,
|
||||
)
|
||||
|
||||
@@ -72,6 +75,7 @@ class TestChecklistTaskWithoutRequest(ChecklistTaskTestBase):
|
||||
assert clt_dict["text"] == self.text
|
||||
assert clt_dict["text_entities"] == [entity.to_dict() for entity in self.text_entities]
|
||||
assert clt_dict["completed_by_user"] == self.completed_by_user.to_dict()
|
||||
assert clt_dict["completed_by_chat"] == self.completed_by_chat.to_dict()
|
||||
assert clt_dict["completion_date"] == to_timestamp(self.completion_date)
|
||||
|
||||
def test_de_json(self, offline_bot):
|
||||
@@ -80,6 +84,7 @@ class TestChecklistTaskWithoutRequest(ChecklistTaskTestBase):
|
||||
"text": self.text,
|
||||
"text_entities": [entity.to_dict() for entity in self.text_entities],
|
||||
"completed_by_user": self.completed_by_user.to_dict(),
|
||||
"completed_by_chat": self.completed_by_chat.to_dict(),
|
||||
"completion_date": to_timestamp(self.completion_date),
|
||||
}
|
||||
clt = ChecklistTask.de_json(json_dict, offline_bot)
|
||||
@@ -88,6 +93,7 @@ class TestChecklistTaskWithoutRequest(ChecklistTaskTestBase):
|
||||
assert clt.text == self.text
|
||||
assert clt.text_entities == tuple(self.text_entities)
|
||||
assert clt.completed_by_user == self.completed_by_user
|
||||
assert clt.completed_by_chat == self.completed_by_chat
|
||||
assert clt.completion_date == self.completion_date
|
||||
assert clt.api_kwargs == {}
|
||||
|
||||
|
||||
+48
-20
@@ -40,13 +40,20 @@ from tests.auxil.slots import mro_slots
|
||||
async def forum_topic_object(forum_group_id, emoji_id):
|
||||
return ForumTopic(
|
||||
message_thread_id=forum_group_id,
|
||||
name=TEST_TOPIC_NAME,
|
||||
icon_color=TEST_TOPIC_ICON_COLOR,
|
||||
name=ForumTopicTestBase.TEST_TOPIC_NAME,
|
||||
icon_color=ForumTopicTestBase.TEST_TOPIC_ICON_COLOR,
|
||||
icon_custom_emoji_id=emoji_id,
|
||||
is_name_implicit=ForumTopicTestBase.is_name_implicit,
|
||||
)
|
||||
|
||||
|
||||
class TestForumTopicWithoutRequest:
|
||||
class ForumTopicTestBase:
|
||||
TEST_TOPIC_NAME = TEST_TOPIC_NAME
|
||||
TEST_TOPIC_ICON_COLOR = TEST_TOPIC_ICON_COLOR
|
||||
is_name_implicit = False
|
||||
|
||||
|
||||
class TestForumTopicWithoutRequest(ForumTopicTestBase):
|
||||
def test_slot_behaviour(self, forum_topic_object):
|
||||
inst = forum_topic_object
|
||||
for attr in inst.__slots__:
|
||||
@@ -55,33 +62,37 @@ class TestForumTopicWithoutRequest:
|
||||
|
||||
async def test_expected_values(self, emoji_id, forum_group_id, forum_topic_object):
|
||||
assert forum_topic_object.message_thread_id == forum_group_id
|
||||
assert forum_topic_object.icon_color == TEST_TOPIC_ICON_COLOR
|
||||
assert forum_topic_object.name == TEST_TOPIC_NAME
|
||||
assert forum_topic_object.icon_color == self.TEST_TOPIC_ICON_COLOR
|
||||
assert forum_topic_object.name == self.TEST_TOPIC_NAME
|
||||
assert forum_topic_object.icon_custom_emoji_id == emoji_id
|
||||
assert forum_topic_object.is_name_implicit == self.is_name_implicit
|
||||
|
||||
def test_de_json(self, offline_bot, emoji_id, forum_group_id):
|
||||
json_dict = {
|
||||
"message_thread_id": forum_group_id,
|
||||
"name": TEST_TOPIC_NAME,
|
||||
"icon_color": TEST_TOPIC_ICON_COLOR,
|
||||
"name": self.TEST_TOPIC_NAME,
|
||||
"icon_color": self.TEST_TOPIC_ICON_COLOR,
|
||||
"icon_custom_emoji_id": emoji_id,
|
||||
"is_name_implicit": self.is_name_implicit,
|
||||
}
|
||||
topic = ForumTopic.de_json(json_dict, offline_bot)
|
||||
assert topic.api_kwargs == {}
|
||||
|
||||
assert topic.message_thread_id == forum_group_id
|
||||
assert topic.icon_color == TEST_TOPIC_ICON_COLOR
|
||||
assert topic.name == TEST_TOPIC_NAME
|
||||
assert topic.icon_color == self.TEST_TOPIC_ICON_COLOR
|
||||
assert topic.name == self.TEST_TOPIC_NAME
|
||||
assert topic.icon_custom_emoji_id == emoji_id
|
||||
assert topic.is_name_implicit == self.is_name_implicit
|
||||
|
||||
def test_to_dict(self, emoji_id, forum_group_id, forum_topic_object):
|
||||
topic_dict = forum_topic_object.to_dict()
|
||||
|
||||
assert isinstance(topic_dict, dict)
|
||||
assert topic_dict["message_thread_id"] == forum_group_id
|
||||
assert topic_dict["name"] == TEST_TOPIC_NAME
|
||||
assert topic_dict["icon_color"] == TEST_TOPIC_ICON_COLOR
|
||||
assert topic_dict["name"] == self.TEST_TOPIC_NAME
|
||||
assert topic_dict["icon_color"] == self.TEST_TOPIC_ICON_COLOR
|
||||
assert topic_dict["icon_custom_emoji_id"] == emoji_id
|
||||
assert topic_dict["is_name_implicit"] == self.is_name_implicit
|
||||
|
||||
def test_equality(self, emoji_id, forum_group_id):
|
||||
a = ForumTopic(
|
||||
@@ -289,10 +300,20 @@ class TestForumMethodsWithRequest:
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def topic_created():
|
||||
return ForumTopicCreated(name=TEST_TOPIC_NAME, icon_color=TEST_TOPIC_ICON_COLOR)
|
||||
return ForumTopicCreated(
|
||||
name=ForumTopicCreatedTestBase.TEST_TOPIC_NAME,
|
||||
icon_color=ForumTopicCreatedTestBase.TEST_TOPIC_ICON_COLOR,
|
||||
is_name_implicit=ForumTopicCreatedTestBase.is_name_implicit,
|
||||
)
|
||||
|
||||
|
||||
class TestForumTopicCreatedWithoutRequest:
|
||||
class ForumTopicCreatedTestBase:
|
||||
TEST_TOPIC_NAME = TEST_TOPIC_NAME
|
||||
TEST_TOPIC_ICON_COLOR = TEST_TOPIC_ICON_COLOR
|
||||
is_name_implicit = False
|
||||
|
||||
|
||||
class TestForumTopicCreatedWithoutRequest(ForumTopicCreatedTestBase):
|
||||
def test_slot_behaviour(self, topic_created):
|
||||
for attr in topic_created.__slots__:
|
||||
assert getattr(topic_created, attr, "err") != "err", f"got extra slot '{attr}'"
|
||||
@@ -301,23 +322,30 @@ class TestForumTopicCreatedWithoutRequest:
|
||||
)
|
||||
|
||||
def test_expected_values(self, topic_created):
|
||||
assert topic_created.icon_color == TEST_TOPIC_ICON_COLOR
|
||||
assert topic_created.name == TEST_TOPIC_NAME
|
||||
assert topic_created.icon_color == self.TEST_TOPIC_ICON_COLOR
|
||||
assert topic_created.name == self.TEST_TOPIC_NAME
|
||||
assert topic_created.is_name_implicit == self.is_name_implicit
|
||||
|
||||
def test_de_json(self, offline_bot):
|
||||
json_dict = {"icon_color": TEST_TOPIC_ICON_COLOR, "name": TEST_TOPIC_NAME}
|
||||
json_dict = {
|
||||
"icon_color": self.TEST_TOPIC_ICON_COLOR,
|
||||
"name": self.TEST_TOPIC_NAME,
|
||||
"is_name_implicit": self.is_name_implicit,
|
||||
}
|
||||
action = ForumTopicCreated.de_json(json_dict, offline_bot)
|
||||
assert action.api_kwargs == {}
|
||||
|
||||
assert action.icon_color == TEST_TOPIC_ICON_COLOR
|
||||
assert action.name == TEST_TOPIC_NAME
|
||||
assert action.icon_color == self.TEST_TOPIC_ICON_COLOR
|
||||
assert action.name == self.TEST_TOPIC_NAME
|
||||
assert action.is_name_implicit == self.is_name_implicit
|
||||
|
||||
def test_to_dict(self, topic_created):
|
||||
action_dict = topic_created.to_dict()
|
||||
|
||||
assert isinstance(action_dict, dict)
|
||||
assert action_dict["name"] == TEST_TOPIC_NAME
|
||||
assert action_dict["icon_color"] == TEST_TOPIC_ICON_COLOR
|
||||
assert action_dict["name"] == self.TEST_TOPIC_NAME
|
||||
assert action_dict["icon_color"] == self.TEST_TOPIC_ICON_COLOR
|
||||
assert action_dict["is_name_implicit"] == self.is_name_implicit
|
||||
|
||||
def test_equality(self, emoji_id):
|
||||
a = ForumTopicCreated(name=TEST_TOPIC_NAME, icon_color=TEST_TOPIC_ICON_COLOR)
|
||||
|
||||
+117
-2
@@ -21,12 +21,77 @@ from collections.abc import Sequence
|
||||
import pytest
|
||||
|
||||
from telegram import BotCommand, Chat, Gift, GiftInfo, Gifts, MessageEntity, Sticker
|
||||
from telegram._gifts import AcceptedGiftTypes
|
||||
from telegram._gifts import AcceptedGiftTypes, GiftBackground
|
||||
from telegram._utils.defaultvalue import DEFAULT_NONE
|
||||
from telegram.request import RequestData
|
||||
from tests.auxil.slots import mro_slots
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def gift_background():
|
||||
return GiftBackground(
|
||||
center_color=GiftBackgroundTestBase.center_color,
|
||||
edge_color=GiftBackgroundTestBase.edge_color,
|
||||
text_color=GiftBackgroundTestBase.text_color,
|
||||
)
|
||||
|
||||
|
||||
class GiftBackgroundTestBase:
|
||||
center_color = 0xFFFFFF
|
||||
edge_color = 0x000000
|
||||
text_color = 0xFF0000
|
||||
|
||||
|
||||
class TestGiftBackgroundWithoutRequest(GiftBackgroundTestBase):
|
||||
def test_slot_behaviour(self, gift_background):
|
||||
for attr in gift_background.__slots__:
|
||||
assert getattr(gift_background, attr, "err") != "err", f"got extra slot '{attr}'"
|
||||
assert len(mro_slots(gift_background)) == len(set(mro_slots(gift_background))), (
|
||||
"duplicate slot"
|
||||
)
|
||||
|
||||
def test_de_json(self, offline_bot):
|
||||
json_dict = {
|
||||
"center_color": self.center_color,
|
||||
"edge_color": self.edge_color,
|
||||
"text_color": self.text_color,
|
||||
}
|
||||
gift_background = GiftBackground.de_json(json_dict, offline_bot)
|
||||
assert gift_background.api_kwargs == {}
|
||||
assert gift_background.center_color == self.center_color
|
||||
assert gift_background.edge_color == self.edge_color
|
||||
assert gift_background.text_color == self.text_color
|
||||
|
||||
def test_to_dict(self, gift_background):
|
||||
json_dict = gift_background.to_dict()
|
||||
assert json_dict["center_color"] == self.center_color
|
||||
assert json_dict["edge_color"] == self.edge_color
|
||||
assert json_dict["text_color"] == self.text_color
|
||||
|
||||
def test_equality(self, gift_background):
|
||||
a = gift_background
|
||||
b = GiftBackground(
|
||||
self.center_color,
|
||||
self.edge_color,
|
||||
self.text_color,
|
||||
)
|
||||
c = GiftBackground(
|
||||
0x000000,
|
||||
self.edge_color,
|
||||
self.text_color,
|
||||
)
|
||||
d = BotCommand("start", "description")
|
||||
|
||||
assert a == b
|
||||
assert hash(a) == hash(b)
|
||||
|
||||
assert a != c
|
||||
assert hash(a) != hash(c)
|
||||
|
||||
assert a != d
|
||||
assert hash(a) != hash(d)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def gift(request):
|
||||
return Gift(
|
||||
@@ -37,6 +102,12 @@ def gift(request):
|
||||
remaining_count=GiftTestBase.remaining_count,
|
||||
upgrade_star_count=GiftTestBase.upgrade_star_count,
|
||||
publisher_chat=GiftTestBase.publisher_chat,
|
||||
personal_total_count=GiftTestBase.personal_total_count,
|
||||
personal_remaining_count=GiftTestBase.personal_remaining_count,
|
||||
background=GiftTestBase.background,
|
||||
is_premium=GiftTestBase.is_premium,
|
||||
has_colors=GiftTestBase.has_colors,
|
||||
unique_gift_variant_count=GiftTestBase.unique_gift_variant_count,
|
||||
)
|
||||
|
||||
|
||||
@@ -56,6 +127,12 @@ class GiftTestBase:
|
||||
remaining_count = 5
|
||||
upgrade_star_count = 10
|
||||
publisher_chat = Chat(1, Chat.PRIVATE)
|
||||
personal_total_count = 37
|
||||
personal_remaining_count = 23
|
||||
background = GiftBackground(0xFFFFFF, 0x000000, 0xFF0000)
|
||||
is_premium = True
|
||||
has_colors = True
|
||||
unique_gift_variant_count = 42
|
||||
|
||||
|
||||
class TestGiftWithoutRequest(GiftTestBase):
|
||||
@@ -73,6 +150,12 @@ class TestGiftWithoutRequest(GiftTestBase):
|
||||
"remaining_count": self.remaining_count,
|
||||
"upgrade_star_count": self.upgrade_star_count,
|
||||
"publisher_chat": self.publisher_chat.to_dict(),
|
||||
"personal_total_count": self.personal_total_count,
|
||||
"personal_remaining_count": self.personal_remaining_count,
|
||||
"background": self.background.to_dict(),
|
||||
"is_premium": self.is_premium,
|
||||
"has_colors": self.has_colors,
|
||||
"unique_gift_variant_count": self.unique_gift_variant_count,
|
||||
}
|
||||
gift = Gift.de_json(json_dict, offline_bot)
|
||||
assert gift.api_kwargs == {}
|
||||
@@ -84,6 +167,12 @@ class TestGiftWithoutRequest(GiftTestBase):
|
||||
assert gift.remaining_count == self.remaining_count
|
||||
assert gift.upgrade_star_count == self.upgrade_star_count
|
||||
assert gift.publisher_chat == self.publisher_chat
|
||||
assert gift.personal_total_count == self.personal_total_count
|
||||
assert gift.personal_remaining_count == self.personal_remaining_count
|
||||
assert gift.background == self.background
|
||||
assert gift.is_premium == self.is_premium
|
||||
assert gift.has_colors == self.has_colors
|
||||
assert gift.unique_gift_variant_count == self.unique_gift_variant_count
|
||||
|
||||
def test_to_dict(self, gift):
|
||||
gift_dict = gift.to_dict()
|
||||
@@ -96,6 +185,12 @@ class TestGiftWithoutRequest(GiftTestBase):
|
||||
assert gift_dict["remaining_count"] == self.remaining_count
|
||||
assert gift_dict["upgrade_star_count"] == self.upgrade_star_count
|
||||
assert gift_dict["publisher_chat"] == self.publisher_chat.to_dict()
|
||||
assert gift_dict["personal_total_count"] == self.personal_total_count
|
||||
assert gift_dict["personal_remaining_count"] == self.personal_remaining_count
|
||||
assert gift_dict["background"] == self.background.to_dict()
|
||||
assert gift_dict["is_premium"] == self.is_premium
|
||||
assert gift_dict["has_colors"] == self.has_colors
|
||||
assert gift_dict["unique_gift_variant_count"] == self.unique_gift_variant_count
|
||||
|
||||
def test_equality(self, gift):
|
||||
a = gift
|
||||
@@ -316,6 +411,8 @@ def gift_info():
|
||||
text=GiftInfoTestBase.text,
|
||||
entities=GiftInfoTestBase.entities,
|
||||
is_private=GiftInfoTestBase.is_private,
|
||||
is_upgrade_separate=GiftInfoTestBase.is_upgrade_separate,
|
||||
unique_gift_number=GiftInfoTestBase.unique_gift_number,
|
||||
)
|
||||
|
||||
|
||||
@@ -338,6 +435,8 @@ class GiftInfoTestBase:
|
||||
MessageEntity(MessageEntity.ITALIC, 5, 8),
|
||||
)
|
||||
is_private = True
|
||||
is_upgrade_separate = False
|
||||
unique_gift_number = 42
|
||||
|
||||
|
||||
class TestGiftInfoWithoutRequest(GiftInfoTestBase):
|
||||
@@ -356,6 +455,8 @@ class TestGiftInfoWithoutRequest(GiftInfoTestBase):
|
||||
"text": self.text,
|
||||
"entities": [e.to_dict() for e in self.entities],
|
||||
"is_private": self.is_private,
|
||||
"is_upgrade_separate": self.is_upgrade_separate,
|
||||
"unique_gift_number": self.unique_gift_number,
|
||||
}
|
||||
gift_info = GiftInfo.de_json(json_dict, offline_bot)
|
||||
assert gift_info.api_kwargs == {}
|
||||
@@ -367,6 +468,8 @@ class TestGiftInfoWithoutRequest(GiftInfoTestBase):
|
||||
assert gift_info.text == self.text
|
||||
assert gift_info.entities == self.entities
|
||||
assert gift_info.is_private == self.is_private
|
||||
assert gift_info.is_upgrade_separate == self.is_upgrade_separate
|
||||
assert gift_info.unique_gift_number == self.unique_gift_number
|
||||
|
||||
def test_to_dict(self, gift_info):
|
||||
json_dict = gift_info.to_dict()
|
||||
@@ -378,6 +481,8 @@ class TestGiftInfoWithoutRequest(GiftInfoTestBase):
|
||||
assert json_dict["text"] == self.text
|
||||
assert json_dict["entities"] == [e.to_dict() for e in self.entities]
|
||||
assert json_dict["is_private"] == self.is_private
|
||||
assert json_dict["is_upgrade_separate"] == self.is_upgrade_separate
|
||||
assert json_dict["unique_gift_number"] == self.unique_gift_number
|
||||
|
||||
def test_parse_entity(self, gift_info):
|
||||
entity = MessageEntity(MessageEntity.BOLD, 0, 4)
|
||||
@@ -430,6 +535,7 @@ def accepted_gift_types():
|
||||
limited_gifts=AcceptedGiftTypesTestBase.limited_gifts,
|
||||
unique_gifts=AcceptedGiftTypesTestBase.unique_gifts,
|
||||
premium_subscription=AcceptedGiftTypesTestBase.premium_subscription,
|
||||
gifts_from_channels=AcceptedGiftTypesTestBase.gifts_from_channels,
|
||||
)
|
||||
|
||||
|
||||
@@ -438,6 +544,7 @@ class AcceptedGiftTypesTestBase:
|
||||
limited_gifts = True
|
||||
unique_gifts = True
|
||||
premium_subscription = True
|
||||
gifts_from_channels = False
|
||||
|
||||
|
||||
class TestAcceptedGiftTypesWithoutRequest(AcceptedGiftTypesTestBase):
|
||||
@@ -454,6 +561,7 @@ class TestAcceptedGiftTypesWithoutRequest(AcceptedGiftTypesTestBase):
|
||||
"limited_gifts": self.limited_gifts,
|
||||
"unique_gifts": self.unique_gifts,
|
||||
"premium_subscription": self.premium_subscription,
|
||||
"gifts_from_channels": self.gifts_from_channels,
|
||||
}
|
||||
accepted_gift_types = AcceptedGiftTypes.de_json(json_dict, offline_bot)
|
||||
assert accepted_gift_types.api_kwargs == {}
|
||||
@@ -461,6 +569,7 @@ class TestAcceptedGiftTypesWithoutRequest(AcceptedGiftTypesTestBase):
|
||||
assert accepted_gift_types.limited_gifts == self.limited_gifts
|
||||
assert accepted_gift_types.unique_gifts == self.unique_gifts
|
||||
assert accepted_gift_types.premium_subscription == self.premium_subscription
|
||||
assert accepted_gift_types.gifts_from_channels == self.gifts_from_channels
|
||||
|
||||
def test_to_dict(self, accepted_gift_types):
|
||||
json_dict = accepted_gift_types.to_dict()
|
||||
@@ -468,17 +577,23 @@ class TestAcceptedGiftTypesWithoutRequest(AcceptedGiftTypesTestBase):
|
||||
assert json_dict["limited_gifts"] == self.limited_gifts
|
||||
assert json_dict["unique_gifts"] == self.unique_gifts
|
||||
assert json_dict["premium_subscription"] == self.premium_subscription
|
||||
assert json_dict["gifts_from_channels"] == self.gifts_from_channels
|
||||
|
||||
def test_equality(self, accepted_gift_types):
|
||||
a = accepted_gift_types
|
||||
b = AcceptedGiftTypes(
|
||||
self.unlimited_gifts, self.limited_gifts, self.unique_gifts, self.premium_subscription
|
||||
self.unlimited_gifts,
|
||||
self.limited_gifts,
|
||||
self.unique_gifts,
|
||||
self.premium_subscription,
|
||||
self.gifts_from_channels,
|
||||
)
|
||||
c = AcceptedGiftTypes(
|
||||
not self.unlimited_gifts,
|
||||
self.limited_gifts,
|
||||
self.unique_gifts,
|
||||
self.premium_subscription,
|
||||
self.gifts_from_channels,
|
||||
)
|
||||
d = BotCommand("start", "description")
|
||||
|
||||
|
||||
+50
-7
@@ -268,20 +268,21 @@ def message(bot):
|
||||
{
|
||||
"unique_gift": UniqueGiftInfo(
|
||||
gift=UniqueGift(
|
||||
"human_readable_name",
|
||||
"unique_name",
|
||||
2,
|
||||
UniqueGiftModel(
|
||||
gift_id="gift_id",
|
||||
base_name="human_readable_name",
|
||||
name="unique_name",
|
||||
number=2,
|
||||
model=UniqueGiftModel(
|
||||
"model_name",
|
||||
Sticker("file_id1", "file_unique_id1", 512, 512, False, False, "regular"),
|
||||
10,
|
||||
),
|
||||
UniqueGiftSymbol(
|
||||
symbol=UniqueGiftSymbol(
|
||||
"symbol_name",
|
||||
Sticker("file_id2", "file_unique_id2", 512, 512, True, True, "mask"),
|
||||
20,
|
||||
),
|
||||
UniqueGiftBackdrop(
|
||||
backdrop=UniqueGiftBackdrop(
|
||||
"backdrop_name",
|
||||
UniqueGiftBackdropColors(0x00FF00, 0xEE00FF, 0xAA22BB, 0x20FE8F),
|
||||
30,
|
||||
@@ -420,6 +421,15 @@ def message(bot):
|
||||
send_date=dtm.datetime.utcnow(),
|
||||
)
|
||||
},
|
||||
{
|
||||
"gift_upgrade_sent": GiftInfo(
|
||||
gift=Gift(
|
||||
"gift_id",
|
||||
Sticker("file_id", "file_unique_id", 512, 512, False, False, "regular"),
|
||||
5,
|
||||
)
|
||||
)
|
||||
},
|
||||
],
|
||||
ids=[
|
||||
"reply",
|
||||
@@ -510,6 +520,7 @@ def message(bot):
|
||||
"suggested_post_approved",
|
||||
"suggested_post_approval_failed",
|
||||
"suggested_post_info",
|
||||
"gift_upgrade_sent",
|
||||
],
|
||||
)
|
||||
def message_params(bot, request):
|
||||
@@ -735,7 +746,8 @@ class TestMessageWithoutRequest(MessageTestBase):
|
||||
message_thread_id = await method(*args, message_thread_id=None)
|
||||
assert message_thread_id is None
|
||||
|
||||
if bot_method_name == "send_chat_action":
|
||||
# These methods do not accept `do_quote` as passed below
|
||||
if bot_method_name in ["send_chat_action", "send_message_draft"]:
|
||||
return
|
||||
|
||||
message_thread_id = await method(
|
||||
@@ -1831,6 +1843,37 @@ class TestMessageWithoutRequest(MessageTestBase):
|
||||
message, message.reply_html, "send_message", ["test"], monkeypatch
|
||||
)
|
||||
|
||||
async def test_reply_text_draft(self, monkeypatch, message):
|
||||
async def make_assertion(*_, **kwargs):
|
||||
id_ = kwargs["chat_id"] == message.chat_id
|
||||
text = kwargs["text"] == "test"
|
||||
return id_ and text
|
||||
|
||||
assert check_shortcut_signature(
|
||||
Message.reply_text_draft,
|
||||
Bot.send_message_draft,
|
||||
["chat_id"],
|
||||
[],
|
||||
annotation_overrides={"message_thread_id": (ODVInput[int], DEFAULT_NONE)},
|
||||
)
|
||||
assert await check_shortcut_call(
|
||||
message.reply_text_draft,
|
||||
message.get_bot(),
|
||||
"send_message_draft",
|
||||
skip_params=[""],
|
||||
shortcut_kwargs=["chat_id"],
|
||||
)
|
||||
assert await check_defaults_handling(
|
||||
message.reply_text_draft, message.get_bot(), no_default_kwargs={"message_thread_id"}
|
||||
)
|
||||
|
||||
monkeypatch.setattr(message.get_bot(), "send_message_draft", make_assertion)
|
||||
assert await message.reply_text_draft(draft_id=1, text="test")
|
||||
|
||||
await self.check_thread_id_parsing(
|
||||
message, message.reply_text_draft, "send_message_draft", [1, "test"], monkeypatch
|
||||
)
|
||||
|
||||
async def test_reply_media_group(self, monkeypatch, message):
|
||||
async def make_assertion(*_, **kwargs):
|
||||
id_ = kwargs["chat_id"] == message.chat_id
|
||||
|
||||
@@ -159,6 +159,9 @@ PTB_EXTRA_PARAMS = {
|
||||
"InputStoryContent": {"type"}, # attributes common to all subclasses
|
||||
"StoryAreaType": {"type"}, # attributes common to all subclasses
|
||||
"InputProfilePhoto": {"type"}, # attributes common to all subclasses
|
||||
# backwards compatibility for api 9.3 changes
|
||||
# tags: deprecated NEXT.VERSION, bot api 9.3
|
||||
"UniqueGiftInfo": {"last_resale_star_count"},
|
||||
}
|
||||
|
||||
|
||||
@@ -191,8 +194,6 @@ PTB_IGNORED_PARAMS = {
|
||||
r"OwnedGift\w+": {"type"},
|
||||
r"InputStoryContent\w+": {"type"},
|
||||
r"StoryAreaType\w+": {"type"},
|
||||
# Official API field not yet implemented in PTB
|
||||
"User": {"has_topics_enabled"},
|
||||
}
|
||||
|
||||
|
||||
@@ -208,6 +209,9 @@ IGNORED_PARAM_REQUIREMENTS = {
|
||||
"send_venue": {"latitude", "longitude", "title", "address"},
|
||||
"send_contact": {"phone_number", "first_name"},
|
||||
# ---->
|
||||
# backwards compatibility for api 9.3 changes
|
||||
# tags: deprecated NEXT.VERSION, bot api 9.3
|
||||
"UniqueGift": {"gift_id"},
|
||||
}
|
||||
|
||||
|
||||
@@ -216,7 +220,10 @@ def ignored_param_requirements(object_name: str) -> set[str]:
|
||||
|
||||
|
||||
# Arguments that are optional arguments for now for backwards compatibility
|
||||
BACKWARDS_COMPAT_KWARGS: dict[str, set[str]] = {}
|
||||
BACKWARDS_COMPAT_KWARGS: dict[str, set[str]] = {
|
||||
# tags: deprecated NEXT.VERSION, bot api 9.3
|
||||
"get_business_account_gifts": {"exclude_limited"},
|
||||
}
|
||||
|
||||
|
||||
def backwards_compat_kwargs(object_name: str) -> set[str]:
|
||||
|
||||
@@ -60,6 +60,7 @@ class OwnedGiftTestBase:
|
||||
star_count=5,
|
||||
)
|
||||
unique_gift = UniqueGift(
|
||||
gift_id="gift_id",
|
||||
base_name="human_readable",
|
||||
name="unique_name",
|
||||
number=10,
|
||||
@@ -96,6 +97,8 @@ class OwnedGiftTestBase:
|
||||
can_be_transferred = True
|
||||
transfer_star_count = 300
|
||||
next_transfer_date = dtm.datetime.now(tz=UTC).replace(microsecond=0)
|
||||
is_upgrade_separate = False
|
||||
unique_gift_number = 37
|
||||
|
||||
|
||||
class TestOwnedGiftWithoutRequest(OwnedGiftTestBase):
|
||||
@@ -183,6 +186,8 @@ def owned_gift_regular():
|
||||
was_refunded=TestOwnedGiftRegularWithoutRequest.was_refunded,
|
||||
convert_star_count=TestOwnedGiftRegularWithoutRequest.convert_star_count,
|
||||
prepaid_upgrade_star_count=TestOwnedGiftRegularWithoutRequest.prepaid_upgrade_star_count,
|
||||
is_upgrade_separate=TestOwnedGiftRegularWithoutRequest.is_upgrade_separate,
|
||||
unique_gift_number=TestOwnedGiftRegularWithoutRequest.unique_gift_number,
|
||||
)
|
||||
|
||||
|
||||
@@ -209,6 +214,8 @@ class TestOwnedGiftRegularWithoutRequest(OwnedGiftTestBase):
|
||||
"was_refunded": self.was_refunded,
|
||||
"convert_star_count": self.convert_star_count,
|
||||
"prepaid_upgrade_star_count": self.prepaid_upgrade_star_count,
|
||||
"is_upgrade_separate": self.is_upgrade_separate,
|
||||
"unique_gift_number": self.unique_gift_number,
|
||||
}
|
||||
ogr = OwnedGiftRegular.de_json(json_dict, offline_bot)
|
||||
assert ogr.gift == self.gift
|
||||
@@ -223,6 +230,8 @@ class TestOwnedGiftRegularWithoutRequest(OwnedGiftTestBase):
|
||||
assert ogr.was_refunded == self.was_refunded
|
||||
assert ogr.convert_star_count == self.convert_star_count
|
||||
assert ogr.prepaid_upgrade_star_count == self.prepaid_upgrade_star_count
|
||||
assert ogr.is_upgrade_separate == self.is_upgrade_separate
|
||||
assert ogr.unique_gift_number == self.unique_gift_number
|
||||
assert ogr.api_kwargs == {}
|
||||
|
||||
def test_to_dict(self, owned_gift_regular):
|
||||
@@ -241,6 +250,8 @@ class TestOwnedGiftRegularWithoutRequest(OwnedGiftTestBase):
|
||||
assert json_dict["was_refunded"] == self.was_refunded
|
||||
assert json_dict["convert_star_count"] == self.convert_star_count
|
||||
assert json_dict["prepaid_upgrade_star_count"] == self.prepaid_upgrade_star_count
|
||||
assert json_dict["is_upgrade_separate"] == self.is_upgrade_separate
|
||||
assert json_dict["unique_gift_number"] == self.unique_gift_number
|
||||
|
||||
def test_parse_entity(self, owned_gift_regular):
|
||||
entity = MessageEntity(MessageEntity.BOLD, 0, 4)
|
||||
@@ -393,6 +404,7 @@ class OwnedGiftsTestBase:
|
||||
),
|
||||
OwnedGiftUnique(
|
||||
gift=UniqueGift(
|
||||
gift_id="gift_id",
|
||||
base_name="human_readable",
|
||||
name="unique_name",
|
||||
number=10,
|
||||
|
||||
+39
-3
@@ -18,13 +18,20 @@
|
||||
|
||||
import pytest
|
||||
|
||||
from telegram import Chat, Story
|
||||
from telegram import Bot, Chat, Story
|
||||
from tests.auxil.bot_method_checks import (
|
||||
check_defaults_handling,
|
||||
check_shortcut_call,
|
||||
check_shortcut_signature,
|
||||
)
|
||||
from tests.auxil.slots import mro_slots
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def story():
|
||||
return Story(StoryTestBase.chat, StoryTestBase.id)
|
||||
def story(bot):
|
||||
story = Story(StoryTestBase.chat, StoryTestBase.id)
|
||||
story.set_bot(bot)
|
||||
return story
|
||||
|
||||
|
||||
class StoryTestBase:
|
||||
@@ -69,3 +76,32 @@ class TestStoryWithoutRequest(StoryTestBase):
|
||||
|
||||
assert a != e
|
||||
assert hash(a) != hash(e)
|
||||
|
||||
async def test_instance_method_repost(self, monkeypatch, story):
|
||||
async def make_assertion(*_, **kwargs):
|
||||
chat_id = kwargs["from_chat_id"] == story.chat.id
|
||||
story_id = kwargs["from_story_id"] == story.id
|
||||
return chat_id and story_id
|
||||
|
||||
assert check_shortcut_signature(
|
||||
Story.repost,
|
||||
Bot.repost_story,
|
||||
[
|
||||
"from_chat_id",
|
||||
"from_story_id",
|
||||
],
|
||||
additional_kwargs=[],
|
||||
)
|
||||
assert await check_shortcut_call(
|
||||
story.repost,
|
||||
story.get_bot(),
|
||||
"repost_story",
|
||||
shortcut_kwargs=["from_chat_id", "from_story_id"],
|
||||
)
|
||||
assert await check_defaults_handling(story.repost, story.get_bot())
|
||||
|
||||
monkeypatch.setattr(story.get_bot(), "repost_story", make_assertion)
|
||||
assert await story.repost(
|
||||
business_connection_id="bcid",
|
||||
active_period=3600,
|
||||
)
|
||||
|
||||
+180
-21
@@ -28,18 +28,107 @@ from telegram import (
|
||||
UniqueGift,
|
||||
UniqueGiftBackdrop,
|
||||
UniqueGiftBackdropColors,
|
||||
UniqueGiftColors,
|
||||
UniqueGiftInfo,
|
||||
UniqueGiftModel,
|
||||
UniqueGiftSymbol,
|
||||
)
|
||||
from telegram._utils.datetime import UTC, to_timestamp
|
||||
from telegram.constants import UniqueGiftInfoOrigin
|
||||
from telegram.warnings import PTBDeprecationWarning
|
||||
from tests.auxil.slots import mro_slots
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def unique_gift_colors():
|
||||
return UniqueGiftColors(
|
||||
model_custom_emoji_id=UniqueGiftColorsTestBase.model_custom_emoji_id,
|
||||
symbol_custom_emoji_id=UniqueGiftColorsTestBase.symbol_custom_emoji_id,
|
||||
light_theme_main_color=UniqueGiftColorsTestBase.light_theme_main_color,
|
||||
light_theme_other_colors=UniqueGiftColorsTestBase.light_theme_other_colors,
|
||||
dark_theme_main_color=UniqueGiftColorsTestBase.dark_theme_main_color,
|
||||
dark_theme_other_colors=UniqueGiftColorsTestBase.dark_theme_other_colors,
|
||||
)
|
||||
|
||||
|
||||
class UniqueGiftColorsTestBase:
|
||||
model_custom_emoji_id = "model_emoji_id"
|
||||
symbol_custom_emoji_id = "symbol_emoji_id"
|
||||
light_theme_main_color = 0xFFFFFF
|
||||
light_theme_other_colors = [0xAAAAAA, 0xBBBBBB]
|
||||
dark_theme_main_color = 0x000000
|
||||
dark_theme_other_colors = [0x111111, 0x222222]
|
||||
|
||||
|
||||
class TestUniqueGiftColorsWithoutRequest(UniqueGiftColorsTestBase):
|
||||
def test_slot_behaviour(self, unique_gift_colors):
|
||||
for attr in unique_gift_colors.__slots__:
|
||||
assert getattr(unique_gift_colors, attr, "err") != "err", f"got extra slot '{attr}'"
|
||||
assert len(mro_slots(unique_gift_colors)) == len(set(mro_slots(unique_gift_colors))), (
|
||||
"duplicate slot"
|
||||
)
|
||||
|
||||
def test_de_json(self, offline_bot):
|
||||
json_dict = {
|
||||
"model_custom_emoji_id": self.model_custom_emoji_id,
|
||||
"symbol_custom_emoji_id": self.symbol_custom_emoji_id,
|
||||
"light_theme_main_color": self.light_theme_main_color,
|
||||
"light_theme_other_colors": self.light_theme_other_colors,
|
||||
"dark_theme_main_color": self.dark_theme_main_color,
|
||||
"dark_theme_other_colors": self.dark_theme_other_colors,
|
||||
}
|
||||
unique_gift_colors = UniqueGiftColors.de_json(json_dict, offline_bot)
|
||||
assert unique_gift_colors.api_kwargs == {}
|
||||
assert unique_gift_colors.model_custom_emoji_id == self.model_custom_emoji_id
|
||||
assert unique_gift_colors.symbol_custom_emoji_id == self.symbol_custom_emoji_id
|
||||
assert unique_gift_colors.light_theme_main_color == self.light_theme_main_color
|
||||
assert unique_gift_colors.light_theme_other_colors == tuple(self.light_theme_other_colors)
|
||||
assert unique_gift_colors.dark_theme_main_color == self.dark_theme_main_color
|
||||
assert unique_gift_colors.dark_theme_other_colors == tuple(self.dark_theme_other_colors)
|
||||
|
||||
def test_to_dict(self, unique_gift_colors):
|
||||
json_dict = unique_gift_colors.to_dict()
|
||||
assert json_dict["model_custom_emoji_id"] == self.model_custom_emoji_id
|
||||
assert json_dict["symbol_custom_emoji_id"] == self.symbol_custom_emoji_id
|
||||
assert json_dict["light_theme_main_color"] == self.light_theme_main_color
|
||||
assert json_dict["light_theme_other_colors"] == self.light_theme_other_colors
|
||||
assert json_dict["dark_theme_main_color"] == self.dark_theme_main_color
|
||||
assert json_dict["dark_theme_other_colors"] == self.dark_theme_other_colors
|
||||
|
||||
def test_equality(self, unique_gift_colors):
|
||||
a = unique_gift_colors
|
||||
b = UniqueGiftColors(
|
||||
self.model_custom_emoji_id,
|
||||
self.symbol_custom_emoji_id,
|
||||
self.light_theme_main_color,
|
||||
self.light_theme_other_colors,
|
||||
self.dark_theme_main_color,
|
||||
self.dark_theme_other_colors,
|
||||
)
|
||||
c = UniqueGiftColors(
|
||||
"other_model_emoji_id",
|
||||
self.symbol_custom_emoji_id,
|
||||
self.light_theme_main_color,
|
||||
self.light_theme_other_colors,
|
||||
self.dark_theme_main_color,
|
||||
self.dark_theme_other_colors,
|
||||
)
|
||||
d = BotCommand("start", "description")
|
||||
|
||||
assert a == b
|
||||
assert hash(a) == hash(b)
|
||||
|
||||
assert a != c
|
||||
assert hash(a) != hash(c)
|
||||
|
||||
assert a != d
|
||||
assert hash(a) != hash(d)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def unique_gift():
|
||||
return UniqueGift(
|
||||
gift_id=UniqueGiftTestBase.gift_id,
|
||||
base_name=UniqueGiftTestBase.base_name,
|
||||
name=UniqueGiftTestBase.name,
|
||||
number=UniqueGiftTestBase.number,
|
||||
@@ -47,10 +136,14 @@ def unique_gift():
|
||||
symbol=UniqueGiftTestBase.symbol,
|
||||
backdrop=UniqueGiftTestBase.backdrop,
|
||||
publisher_chat=UniqueGiftTestBase.publisher_chat,
|
||||
is_premium=UniqueGiftTestBase.is_premium,
|
||||
is_from_blockchain=UniqueGiftTestBase.is_from_blockchain,
|
||||
colors=UniqueGiftTestBase.colors,
|
||||
)
|
||||
|
||||
|
||||
class UniqueGiftTestBase:
|
||||
gift_id = "gift_id"
|
||||
base_name = "human_readable"
|
||||
name = "unique_name"
|
||||
number = 10
|
||||
@@ -70,6 +163,16 @@ class UniqueGiftTestBase:
|
||||
rarity_per_mille=30,
|
||||
)
|
||||
publisher_chat = Chat(1, Chat.PRIVATE)
|
||||
is_premium = False
|
||||
is_from_blockchain = True
|
||||
colors = UniqueGiftColors(
|
||||
model_custom_emoji_id="M",
|
||||
symbol_custom_emoji_id="S",
|
||||
light_theme_main_color=0xFFFFFF,
|
||||
light_theme_other_colors=[0xAAAAAA],
|
||||
dark_theme_main_color=0x000000,
|
||||
dark_theme_other_colors=[0x111111],
|
||||
)
|
||||
|
||||
|
||||
class TestUniqueGiftWithoutRequest(UniqueGiftTestBase):
|
||||
@@ -80,6 +183,7 @@ class TestUniqueGiftWithoutRequest(UniqueGiftTestBase):
|
||||
|
||||
def test_de_json(self, offline_bot):
|
||||
json_dict = {
|
||||
"gift_id": self.gift_id,
|
||||
"base_name": self.base_name,
|
||||
"name": self.name,
|
||||
"number": self.number,
|
||||
@@ -87,6 +191,9 @@ class TestUniqueGiftWithoutRequest(UniqueGiftTestBase):
|
||||
"symbol": self.symbol.to_dict(),
|
||||
"backdrop": self.backdrop.to_dict(),
|
||||
"publisher_chat": self.publisher_chat.to_dict(),
|
||||
"is_premium": self.is_premium,
|
||||
"is_from_blockchain": self.is_from_blockchain,
|
||||
"colors": self.colors.to_dict(),
|
||||
}
|
||||
unique_gift = UniqueGift.de_json(json_dict, offline_bot)
|
||||
assert unique_gift.api_kwargs == {}
|
||||
@@ -98,11 +205,15 @@ class TestUniqueGiftWithoutRequest(UniqueGiftTestBase):
|
||||
assert unique_gift.symbol == self.symbol
|
||||
assert unique_gift.backdrop == self.backdrop
|
||||
assert unique_gift.publisher_chat == self.publisher_chat
|
||||
assert unique_gift.is_premium == self.is_premium
|
||||
assert unique_gift.is_from_blockchain == self.is_from_blockchain
|
||||
assert unique_gift.colors == self.colors
|
||||
|
||||
def test_to_dict(self, unique_gift):
|
||||
gift_dict = unique_gift.to_dict()
|
||||
|
||||
assert isinstance(gift_dict, dict)
|
||||
assert gift_dict["gift_id"] == self.gift_id
|
||||
assert gift_dict["base_name"] == self.base_name
|
||||
assert gift_dict["name"] == self.name
|
||||
assert gift_dict["number"] == self.number
|
||||
@@ -110,26 +221,31 @@ class TestUniqueGiftWithoutRequest(UniqueGiftTestBase):
|
||||
assert gift_dict["symbol"] == self.symbol.to_dict()
|
||||
assert gift_dict["backdrop"] == self.backdrop.to_dict()
|
||||
assert gift_dict["publisher_chat"] == self.publisher_chat.to_dict()
|
||||
assert gift_dict["is_premium"] == self.is_premium
|
||||
assert gift_dict["is_from_blockchain"] == self.is_from_blockchain
|
||||
assert gift_dict["colors"] == self.colors.to_dict()
|
||||
|
||||
def test_equality(self, unique_gift):
|
||||
a = unique_gift
|
||||
b = UniqueGift(
|
||||
self.base_name,
|
||||
self.name,
|
||||
self.number,
|
||||
self.model,
|
||||
self.symbol,
|
||||
self.backdrop,
|
||||
self.publisher_chat,
|
||||
gift_id=self.gift_id,
|
||||
base_name=self.base_name,
|
||||
name=self.name,
|
||||
number=self.number,
|
||||
model=self.model,
|
||||
symbol=self.symbol,
|
||||
backdrop=self.backdrop,
|
||||
publisher_chat=self.publisher_chat,
|
||||
)
|
||||
c = UniqueGift(
|
||||
"other_base_name",
|
||||
self.name,
|
||||
self.number,
|
||||
self.model,
|
||||
self.symbol,
|
||||
self.backdrop,
|
||||
self.publisher_chat,
|
||||
gift_id=self.gift_id,
|
||||
base_name="other_base_name",
|
||||
name=self.name,
|
||||
number=self.number,
|
||||
model=self.model,
|
||||
symbol=self.symbol,
|
||||
backdrop=self.backdrop,
|
||||
publisher_chat=self.publisher_chat,
|
||||
)
|
||||
d = BotCommand("start", "description")
|
||||
|
||||
@@ -142,6 +258,19 @@ class TestUniqueGiftWithoutRequest(UniqueGiftTestBase):
|
||||
assert a != d
|
||||
assert hash(a) != hash(d)
|
||||
|
||||
def test_gift_id_required_workaround(self):
|
||||
# tags: deprecated NEXT.VERSION, bot api 9.3
|
||||
with pytest.raises(TypeError, match="`gift_id` is a required"):
|
||||
UniqueGift(
|
||||
base_name=self.base_name,
|
||||
name=self.name,
|
||||
number=self.number,
|
||||
model=self.model,
|
||||
symbol=self.symbol,
|
||||
backdrop=self.backdrop,
|
||||
publisher_chat=self.publisher_chat,
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def unique_gift_model():
|
||||
@@ -396,26 +525,29 @@ def unique_gift_info():
|
||||
owned_gift_id=UniqueGiftInfoTestBase.owned_gift_id,
|
||||
transfer_star_count=UniqueGiftInfoTestBase.transfer_star_count,
|
||||
last_resale_star_count=UniqueGiftInfoTestBase.last_resale_star_count,
|
||||
last_resale_currency=UniqueGiftInfoTestBase.last_resale_currency,
|
||||
last_resale_amount=UniqueGiftInfoTestBase.last_resale_amount,
|
||||
next_transfer_date=UniqueGiftInfoTestBase.next_transfer_date,
|
||||
)
|
||||
|
||||
|
||||
class UniqueGiftInfoTestBase:
|
||||
gift = UniqueGift(
|
||||
"human_readable_name",
|
||||
"unique_name",
|
||||
10,
|
||||
UniqueGiftModel(
|
||||
gift_id="gift_id",
|
||||
base_name="human_readable_name",
|
||||
name="unique_name",
|
||||
number=10,
|
||||
model=UniqueGiftModel(
|
||||
name="model_name",
|
||||
sticker=Sticker("file_id1", "file_unique_id1", 512, 512, False, False, "regular"),
|
||||
rarity_per_mille=10,
|
||||
),
|
||||
UniqueGiftSymbol(
|
||||
symbol=UniqueGiftSymbol(
|
||||
name="symbol_name",
|
||||
sticker=Sticker("file_id2", "file_unique_id2", 512, 512, True, True, "mask"),
|
||||
rarity_per_mille=20,
|
||||
),
|
||||
UniqueGiftBackdrop(
|
||||
backdrop=UniqueGiftBackdrop(
|
||||
name="backdrop_name",
|
||||
colors=UniqueGiftBackdropColors(0x00FF00, 0xEE00FF, 0xAA22BB, 0x20FE8F),
|
||||
rarity_per_mille=2,
|
||||
@@ -425,6 +557,8 @@ class UniqueGiftInfoTestBase:
|
||||
owned_gift_id = "some_id"
|
||||
transfer_star_count = 10
|
||||
last_resale_star_count = 5
|
||||
last_resale_currency = "XTR"
|
||||
last_resale_amount = 1234
|
||||
next_transfer_date = dtm.datetime.now(tz=UTC).replace(microsecond=0)
|
||||
|
||||
|
||||
@@ -443,6 +577,8 @@ class TestUniqueGiftInfoWithoutRequest(UniqueGiftInfoTestBase):
|
||||
"owned_gift_id": self.owned_gift_id,
|
||||
"transfer_star_count": self.transfer_star_count,
|
||||
"last_resale_star_count": self.last_resale_star_count,
|
||||
"last_resale_currency": self.last_resale_currency,
|
||||
"last_resale_amount": self.last_resale_amount,
|
||||
"next_transfer_date": to_timestamp(self.next_transfer_date),
|
||||
}
|
||||
unique_gift_info = UniqueGiftInfo.de_json(json_dict, offline_bot)
|
||||
@@ -452,6 +588,8 @@ class TestUniqueGiftInfoWithoutRequest(UniqueGiftInfoTestBase):
|
||||
assert unique_gift_info.owned_gift_id == self.owned_gift_id
|
||||
assert unique_gift_info.transfer_star_count == self.transfer_star_count
|
||||
assert unique_gift_info.last_resale_star_count == self.last_resale_star_count
|
||||
assert unique_gift_info.last_resale_currency == self.last_resale_currency
|
||||
assert unique_gift_info.last_resale_amount == self.last_resale_amount
|
||||
assert unique_gift_info.next_transfer_date == self.next_transfer_date
|
||||
|
||||
def test_de_json_localization(self, tz_bot, offline_bot, raw_bot):
|
||||
@@ -461,6 +599,8 @@ class TestUniqueGiftInfoWithoutRequest(UniqueGiftInfoTestBase):
|
||||
"owned_gift_id": self.owned_gift_id,
|
||||
"transfer_star_count": self.transfer_star_count,
|
||||
"last_resale_star_count": self.last_resale_star_count,
|
||||
"last_resale_currency": self.last_resale_currency,
|
||||
"last_resale_amount": self.last_resale_amount,
|
||||
"next_transfer_date": to_timestamp(self.next_transfer_date),
|
||||
}
|
||||
|
||||
@@ -484,7 +624,8 @@ class TestUniqueGiftInfoWithoutRequest(UniqueGiftInfoTestBase):
|
||||
assert json_dict["origin"] == self.origin
|
||||
assert json_dict["owned_gift_id"] == self.owned_gift_id
|
||||
assert json_dict["transfer_star_count"] == self.transfer_star_count
|
||||
assert json_dict["last_resale_star_count"] == self.last_resale_star_count
|
||||
assert json_dict["last_resale_currency"] == self.last_resale_currency
|
||||
assert json_dict["last_resale_amount"] == self.last_resale_amount
|
||||
assert json_dict["next_transfer_date"] == to_timestamp(self.next_transfer_date)
|
||||
|
||||
def test_enum_type_conversion(self, unique_gift_info):
|
||||
@@ -507,3 +648,21 @@ class TestUniqueGiftInfoWithoutRequest(UniqueGiftInfoTestBase):
|
||||
|
||||
assert a != d
|
||||
assert hash(a) != hash(d)
|
||||
|
||||
def test_last_resale_star_count_argument_deprecation(self):
|
||||
with pytest.warns(PTBDeprecationWarning, match=r"9\.3.*last_resale_star_count") as record:
|
||||
UniqueGiftInfo(
|
||||
gift=self.gift,
|
||||
origin=UniqueGiftInfo.TRANSFER,
|
||||
last_resale_star_count=self.last_resale_star_count,
|
||||
)
|
||||
|
||||
assert record[0].category == PTBDeprecationWarning
|
||||
assert record[0].filename == __file__, "wrong stacklevel!"
|
||||
|
||||
def test_last_resale_star_count_attribute_deprecation(self, unique_gift_info):
|
||||
with pytest.warns(PTBDeprecationWarning, match=r"9\.3.*last_resale_star_count") as record:
|
||||
assert unique_gift_info.last_resale_star_count == self.last_resale_star_count
|
||||
|
||||
assert record[0].category == PTBDeprecationWarning
|
||||
assert record[0].filename == __file__, "wrong stacklevel!"
|
||||
|
||||
@@ -44,6 +44,7 @@ def json_dict():
|
||||
"added_to_attachment_menu": UserTestBase.added_to_attachment_menu,
|
||||
"can_connect_to_business": UserTestBase.can_connect_to_business,
|
||||
"has_main_web_app": UserTestBase.has_main_web_app,
|
||||
"has_topics_enabled": UserTestBase.has_topics_enabled,
|
||||
}
|
||||
|
||||
|
||||
@@ -63,6 +64,7 @@ def user(bot):
|
||||
added_to_attachment_menu=UserTestBase.added_to_attachment_menu,
|
||||
can_connect_to_business=UserTestBase.can_connect_to_business,
|
||||
has_main_web_app=UserTestBase.has_main_web_app,
|
||||
has_topics_enabled=UserTestBase.has_topics_enabled,
|
||||
)
|
||||
user.set_bot(bot)
|
||||
user._unfreeze()
|
||||
@@ -83,6 +85,7 @@ class UserTestBase:
|
||||
added_to_attachment_menu = False
|
||||
can_connect_to_business = True
|
||||
has_main_web_app = False
|
||||
has_topics_enabled = False
|
||||
|
||||
|
||||
class TestUserWithoutRequest(UserTestBase):
|
||||
@@ -108,6 +111,7 @@ class TestUserWithoutRequest(UserTestBase):
|
||||
assert user.added_to_attachment_menu == self.added_to_attachment_menu
|
||||
assert user.can_connect_to_business == self.can_connect_to_business
|
||||
assert user.has_main_web_app == self.has_main_web_app
|
||||
assert user.has_topics_enabled == self.has_topics_enabled
|
||||
|
||||
def test_to_dict(self, user):
|
||||
user_dict = user.to_dict()
|
||||
@@ -126,6 +130,7 @@ class TestUserWithoutRequest(UserTestBase):
|
||||
assert user_dict["added_to_attachment_menu"] == user.added_to_attachment_menu
|
||||
assert user_dict["can_connect_to_business"] == user.can_connect_to_business
|
||||
assert user_dict["has_main_web_app"] == user.has_main_web_app
|
||||
assert user_dict["has_topics_enabled"] == user.has_topics_enabled
|
||||
|
||||
def test_equality(self):
|
||||
a = User(self.id_, self.first_name, self.is_bot, self.last_name)
|
||||
@@ -231,6 +236,25 @@ class TestUserWithoutRequest(UserTestBase):
|
||||
monkeypatch.setattr(user.get_bot(), "send_message", make_assertion)
|
||||
assert await user.send_message("test")
|
||||
|
||||
async def test_instance_method_send_message_draft(self, monkeypatch, user):
|
||||
async def make_assertion(*_, **kwargs):
|
||||
return (
|
||||
kwargs["chat_id"] == user.id
|
||||
and kwargs["draft_id"] == 123
|
||||
and kwargs["text"] == "test"
|
||||
)
|
||||
|
||||
assert check_shortcut_signature(
|
||||
User.send_message_draft, Bot.send_message_draft, ["chat_id"], []
|
||||
)
|
||||
assert await check_shortcut_call(
|
||||
user.send_message_draft, user.get_bot(), "send_message_draft"
|
||||
)
|
||||
assert await check_defaults_handling(user.send_message_draft, user.get_bot())
|
||||
|
||||
monkeypatch.setattr(user.get_bot(), "send_message_draft", make_assertion)
|
||||
assert await user.send_message_draft(123, "test")
|
||||
|
||||
async def test_instance_method_send_photo(self, monkeypatch, user):
|
||||
async def make_assertion(*_, **kwargs):
|
||||
return kwargs["chat_id"] == user.id and kwargs["photo"] == "test_photo"
|
||||
@@ -805,3 +829,41 @@ class TestUserWithoutRequest(UserTestBase):
|
||||
|
||||
monkeypatch.setattr(user.get_bot(), "remove_user_verification", make_assertion)
|
||||
assert await user.remove_verification()
|
||||
|
||||
async def test_instance_method_repost_story(self, monkeypatch, user):
|
||||
async def make_assertion(*_, **kwargs):
|
||||
return kwargs["from_chat_id"] == user.id
|
||||
|
||||
assert check_shortcut_signature(
|
||||
User.repost_story,
|
||||
Bot.repost_story,
|
||||
[
|
||||
"from_chat_id",
|
||||
],
|
||||
additional_kwargs=[],
|
||||
)
|
||||
assert await check_shortcut_call(
|
||||
user.repost_story,
|
||||
user.get_bot(),
|
||||
"repost_story",
|
||||
shortcut_kwargs=["from_chat_id"],
|
||||
)
|
||||
assert await check_defaults_handling(user.repost_story, user.get_bot())
|
||||
|
||||
monkeypatch.setattr(user.get_bot(), "repost_story", make_assertion)
|
||||
assert await user.repost_story(
|
||||
business_connection_id="bcid",
|
||||
from_story_id=123,
|
||||
active_period=3600,
|
||||
)
|
||||
|
||||
async def test_instance_method_get_gifts(self, monkeypatch, user):
|
||||
async def make_assertion(*_, **kwargs):
|
||||
return kwargs["user_id"] == user.id
|
||||
|
||||
assert check_shortcut_signature(user.get_gifts, Bot.get_user_gifts, ["user_id"], [])
|
||||
assert await check_shortcut_call(user.get_gifts, user.get_bot(), "get_user_gifts")
|
||||
assert await check_defaults_handling(user.get_gifts, user.get_bot())
|
||||
|
||||
monkeypatch.setattr(user.get_bot(), "get_user_gifts", make_assertion)
|
||||
assert await user.get_gifts()
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# A library that provides a Python interface to the Telegram Bot API
|
||||
# Copyright (C) 2015-2026
|
||||
# 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 pytest
|
||||
|
||||
from telegram import BotCommand, UserRating
|
||||
from tests.auxil.slots import mro_slots
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def user_rating():
|
||||
return UserRating(
|
||||
level=UserRatingTestBase.level,
|
||||
rating=UserRatingTestBase.rating,
|
||||
current_level_rating=UserRatingTestBase.current_level_rating,
|
||||
next_level_rating=UserRatingTestBase.next_level_rating,
|
||||
)
|
||||
|
||||
|
||||
class UserRatingTestBase:
|
||||
level = 2
|
||||
rating = 120
|
||||
current_level_rating = 100
|
||||
next_level_rating = 180
|
||||
|
||||
|
||||
class TestUserRatingWithoutRequest(UserRatingTestBase):
|
||||
def test_slot_behaviour(self, user_rating):
|
||||
for attr in user_rating.__slots__:
|
||||
assert getattr(user_rating, attr, "err") != "err", f"got extra slot '{attr}'"
|
||||
assert len(mro_slots(user_rating)) == len(set(mro_slots(user_rating))), "duplicate slot"
|
||||
|
||||
def test_de_json_with_next(self, offline_bot):
|
||||
json_dict = {
|
||||
"level": self.level,
|
||||
"rating": self.rating,
|
||||
"current_level_rating": self.current_level_rating,
|
||||
"next_level_rating": self.next_level_rating,
|
||||
}
|
||||
ur = UserRating.de_json(json_dict, offline_bot)
|
||||
assert ur.api_kwargs == {}
|
||||
|
||||
assert ur.level == self.level
|
||||
assert ur.rating == self.rating
|
||||
assert ur.current_level_rating == self.current_level_rating
|
||||
assert ur.next_level_rating == self.next_level_rating
|
||||
|
||||
def test_de_json_no_optional(self, offline_bot):
|
||||
json_dict = {
|
||||
"level": self.level,
|
||||
"rating": self.rating,
|
||||
"current_level_rating": self.current_level_rating,
|
||||
}
|
||||
ur = UserRating.de_json(json_dict, offline_bot)
|
||||
assert ur.api_kwargs == {}
|
||||
|
||||
assert ur.level == self.level
|
||||
assert ur.rating == self.rating
|
||||
assert ur.current_level_rating == self.current_level_rating
|
||||
assert ur.next_level_rating is None
|
||||
|
||||
def test_to_dict(self, user_rating):
|
||||
ur_dict = user_rating.to_dict()
|
||||
|
||||
assert isinstance(ur_dict, dict)
|
||||
assert ur_dict["level"] == user_rating.level
|
||||
assert ur_dict["rating"] == user_rating.rating
|
||||
assert ur_dict["current_level_rating"] == user_rating.current_level_rating
|
||||
assert ur_dict["next_level_rating"] == user_rating.next_level_rating
|
||||
|
||||
def test_equality(self):
|
||||
a = UserRating(3, 200, 150, 300)
|
||||
b = UserRating(3, 200, 100, None)
|
||||
c = UserRating(3, 201, 150, 300)
|
||||
d = UserRating(4, 200, 150, 300)
|
||||
e = BotCommand("start", "description")
|
||||
|
||||
assert a == b
|
||||
assert hash(a) == hash(b)
|
||||
|
||||
assert a != c
|
||||
assert hash(a) != hash(c)
|
||||
|
||||
assert a != d
|
||||
assert hash(a) != hash(d)
|
||||
|
||||
assert a != e
|
||||
assert hash(a) != hash(e)
|
||||
Reference in New Issue
Block a user