mirror of
https://github.com/python-telegram-bot/python-telegram-bot.git
synced 2024-12-22 06:25:12 +01:00
Bot API 7.9 (#4429)
Co-authored-by: Bibo-Joshi <22366557+Bibo-Joshi@users.noreply.github.com> Co-authored-by: Harshil <37377066+harshil21@users.noreply.github.com>
This commit is contained in:
parent
1e05381133
commit
01f689373c
21 changed files with 557 additions and 54 deletions
|
@ -11,7 +11,7 @@
|
|||
:target: https://pypi.org/project/python-telegram-bot/
|
||||
:alt: Supported Python versions
|
||||
|
||||
.. image:: https://img.shields.io/badge/Bot%20API-7.8-blue?logo=telegram
|
||||
.. image:: https://img.shields.io/badge/Bot%20API-7.9-blue?logo=telegram
|
||||
:target: https://core.telegram.org/bots/api-changelog
|
||||
:alt: Supported Bot API version
|
||||
|
||||
|
@ -81,7 +81,7 @@ After installing_ the library, be sure to check out the section on `working with
|
|||
Telegram API support
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
All types and methods of the Telegram Bot API **7.8** are natively supported by this library.
|
||||
All types and methods of the Telegram Bot API **7.9** 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
|
||||
|
|
|
@ -130,6 +130,7 @@ Available Types
|
|||
telegram.reactiontype
|
||||
telegram.reactiontypecustomemoji
|
||||
telegram.reactiontypeemoji
|
||||
telegram.reactiontypepaid
|
||||
telegram.replykeyboardmarkup
|
||||
telegram.replykeyboardremove
|
||||
telegram.replyparameters
|
||||
|
|
6
docs/source/telegram.reactiontypepaid.rst
Normal file
6
docs/source/telegram.reactiontypepaid.rst
Normal file
|
@ -0,0 +1,6 @@
|
|||
ReactionTypePaid
|
||||
================
|
||||
|
||||
.. autoclass:: telegram.ReactionTypePaid
|
||||
:members:
|
||||
:show-inheritance:
|
|
@ -204,6 +204,7 @@ __all__ = (
|
|||
"ReactionType",
|
||||
"ReactionTypeCustomEmoji",
|
||||
"ReactionTypeEmoji",
|
||||
"ReactionTypePaid",
|
||||
"RefundedPayment",
|
||||
"ReplyKeyboardMarkup",
|
||||
"ReplyKeyboardRemove",
|
||||
|
@ -467,7 +468,13 @@ from ._payment.stars import (
|
|||
from ._payment.successfulpayment import SuccessfulPayment
|
||||
from ._poll import InputPollOption, Poll, PollAnswer, PollOption
|
||||
from ._proximityalerttriggered import ProximityAlertTriggered
|
||||
from ._reaction import ReactionCount, ReactionType, ReactionTypeCustomEmoji, ReactionTypeEmoji
|
||||
from ._reaction import (
|
||||
ReactionCount,
|
||||
ReactionType,
|
||||
ReactionTypeCustomEmoji,
|
||||
ReactionTypeEmoji,
|
||||
ReactionTypePaid,
|
||||
)
|
||||
from ._reply import ExternalReplyInfo, ReplyParameters, TextQuote
|
||||
from ._replykeyboardmarkup import ReplyKeyboardMarkup
|
||||
from ._replykeyboardremove import ReplyKeyboardRemove
|
||||
|
|
138
telegram/_bot.py
138
telegram/_bot.py
|
@ -18,6 +18,7 @@
|
|||
# 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 Bot."""
|
||||
|
||||
import asyncio
|
||||
import contextlib
|
||||
import copy
|
||||
|
@ -8179,7 +8180,7 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
|||
) -> 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
|
||||
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.
|
||||
|
||||
|
@ -8447,7 +8448,7 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
|||
) -> bool:
|
||||
"""
|
||||
Use this method to edit the name of the 'General' topic in a forum supergroup chat. The bot
|
||||
must be an administrator in the chat for this to work and must have
|
||||
must be an administrator in the chat for this to work and must have the
|
||||
:attr:`~telegram.ChatAdministratorRights.can_manage_topics` administrator rights.
|
||||
|
||||
.. versionadded:: 20.0
|
||||
|
@ -8946,7 +8947,7 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
|||
"""
|
||||
Use this method to change the chosen reactions on a message. Service messages can't be
|
||||
reacted to. Automatically forwarded messages from a channel to its discussion group have
|
||||
the same available reactions as messages in the channel.
|
||||
the same available reactions as messages in the channel. Bots can't use paid reactions.
|
||||
|
||||
.. versionadded:: 20.8
|
||||
|
||||
|
@ -8959,7 +8960,8 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
|||
:class:`telegram.ReactionType` | :obj:`str`, optional): A list of reaction
|
||||
types to set on the message. Currently, as non-premium users, bots can set up to
|
||||
one reaction per message. A custom emoji reaction can be used if it is either
|
||||
already present on the message or explicitly allowed by chat administrators.
|
||||
already present on the message or explicitly allowed by chat administrators. Paid
|
||||
reactions can't be used by bots.
|
||||
|
||||
Tip:
|
||||
Passed :obj:`str` values will be converted to either
|
||||
|
@ -9201,6 +9203,7 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
|||
protect_content: ODVInput[bool] = DEFAULT_NONE,
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
reply_markup: Optional[ReplyMarkup] = None,
|
||||
business_connection_id: Optional[str] = None,
|
||||
*,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
|
@ -9210,12 +9213,14 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
|||
pool_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
) -> Message:
|
||||
"""Use this method to send paid media to channel chats.
|
||||
"""Use this method to send paid media.
|
||||
|
||||
.. versionadded:: 21.4
|
||||
|
||||
Args:
|
||||
chat_id (:obj:`int` | :obj:`str`): |chat_id_channel|
|
||||
chat_id (:obj:`int` | :obj:`str`): |chat_id_channel| If the chat is a channel, all
|
||||
Telegram Star proceeds from this media will be credited to the chat's balance.
|
||||
Otherwise, they will be credited to the bot's balance.
|
||||
star_count (:obj:`int`): The number of Telegram Stars that must be paid to buy access
|
||||
to the media.
|
||||
media (Sequence[:class:`telegram.InputPaidMedia`]): A list describing the media to be
|
||||
|
@ -9233,6 +9238,9 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
|||
:class:`ReplyKeyboardRemove` | :class:`ForceReply`, optional):
|
||||
Additional interface options. An object for an inline keyboard, custom reply
|
||||
keyboard, instructions to remove reply keyboard or to force a reply from the user.
|
||||
business_connection_id (:obj:`str`, optional): |business_id_str|
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
Keyword Args:
|
||||
allow_sending_without_reply (:obj:`bool`, optional): |allow_sending_without_reply|
|
||||
|
@ -9274,8 +9282,122 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
|||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
business_connection_id=business_connection_id,
|
||||
)
|
||||
|
||||
async def create_chat_subscription_invite_link(
|
||||
self,
|
||||
chat_id: Union[str, int],
|
||||
subscription_period: int,
|
||||
subscription_price: int,
|
||||
name: Optional[str] = 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: Optional[JSONDict] = None,
|
||||
) -> ChatInviteLink:
|
||||
"""
|
||||
Use this method to create a `subscription invite link <https://telegram.org/blog/\
|
||||
superchannels-star-reactions-subscriptions#star-subscriptions>`_ for a channel chat.
|
||||
The bot must have the :attr:`~telegram.ChatPermissions.can_invite_users` administrator
|
||||
right. The link can be edited using the :meth:`edit_chat_subscription_invite_link` or
|
||||
revoked using the :meth:`revoke_chat_invite_link`.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
Args:
|
||||
chat_id (:obj:`int` | :obj:`str`): |chat_id_channel|
|
||||
subscription_period (:obj:`int`): The number of seconds the subscription will be
|
||||
active for before the next payment. Currently, it must always be
|
||||
:tg-const:`telegram.constants.ChatSubscriptionLimit.SUBSCRIPTION_PERIOD` (30 days).
|
||||
subscription_price (:obj:`int`): The number of Telegram Stars a user must pay initially
|
||||
and after each subsequent subscription period to be a member of the chat;
|
||||
:tg-const:`telegram.constants.ChatSubscriptionLimit.MIN_PRICE`-
|
||||
:tg-const:`telegram.constants.ChatSubscriptionLimit.MAX_PRICE`.
|
||||
name (:obj:`str`, optional): Invite link name;
|
||||
0-:tg-const:`telegram.constants.ChatInviteLinkLimit.NAME_LENGTH` characters.
|
||||
|
||||
Returns:
|
||||
:class:`telegram.ChatInviteLink`
|
||||
|
||||
Raises:
|
||||
:class:`telegram.error.TelegramError`
|
||||
|
||||
"""
|
||||
data: JSONDict = {
|
||||
"chat_id": chat_id,
|
||||
"subscription_period": subscription_period,
|
||||
"subscription_price": subscription_price,
|
||||
"name": name,
|
||||
}
|
||||
|
||||
result = await self._post(
|
||||
"createChatSubscriptionInviteLink",
|
||||
data,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
return ChatInviteLink.de_json(result, self) # type: ignore[return-value]
|
||||
|
||||
async def edit_chat_subscription_invite_link(
|
||||
self,
|
||||
chat_id: Union[str, int],
|
||||
invite_link: Union[str, "ChatInviteLink"],
|
||||
name: Optional[str] = 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: Optional[JSONDict] = None,
|
||||
) -> ChatInviteLink:
|
||||
"""
|
||||
Use this method to edit a subscription invite link created by the bot. The bot must have
|
||||
:attr:`telegram.ChatPermissions.can_invite_users` administrator right.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
Args:
|
||||
chat_id (:obj:`int` | :obj:`str`): |chat_id_channel|
|
||||
invite_link (:obj:`str` | :obj:`telegram.ChatInviteLink`): The invite link to edit.
|
||||
name (:obj:`str`, optional): Invite link name;
|
||||
0-:tg-const:`telegram.constants.ChatInviteLinkLimit.NAME_LENGTH` characters.
|
||||
|
||||
Tip:
|
||||
Omitting this argument removes the name of the invite link.
|
||||
|
||||
Returns:
|
||||
:class:`telegram.ChatInviteLink`
|
||||
|
||||
Raises:
|
||||
:class:`telegram.error.TelegramError`
|
||||
|
||||
"""
|
||||
link = invite_link.invite_link if isinstance(invite_link, ChatInviteLink) else invite_link
|
||||
data: JSONDict = {
|
||||
"chat_id": chat_id,
|
||||
"invite_link": link,
|
||||
"name": name,
|
||||
}
|
||||
|
||||
result = await self._post(
|
||||
"editChatSubscriptionInviteLink",
|
||||
data,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
return ChatInviteLink.de_json(result, self) # type: ignore[return-value]
|
||||
|
||||
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}
|
||||
|
@ -9532,3 +9654,7 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
|||
"""Alias for :meth:`get_star_transactions`"""
|
||||
sendPaidMedia = send_paid_media
|
||||
"""Alias for :meth:`send_paid_media`"""
|
||||
createChatSubscriptionInviteLink = create_chat_subscription_invite_link
|
||||
"""Alias for :meth:`create_chat_subscription_invite_link`"""
|
||||
editChatSubscriptionInviteLink = edit_chat_subscription_invite_link
|
||||
"""Alias for :meth:`edit_chat_subscription_invite_link`"""
|
||||
|
|
|
@ -2666,6 +2666,81 @@ class _ChatBase(TelegramObject):
|
|||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
async def create_subscription_invite_link(
|
||||
self,
|
||||
subscription_period: int,
|
||||
subscription_price: int,
|
||||
name: Optional[str] = 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: Optional[JSONDict] = None,
|
||||
) -> "ChatInviteLink":
|
||||
"""Shortcut for::
|
||||
|
||||
await bot.create_chat_subscription_invite_link(
|
||||
chat_id=update.effective_chat.id, *args, **kwargs
|
||||
)
|
||||
|
||||
For the documentation of the arguments, please see
|
||||
:meth:`telegram.Bot.create_chat_subscription_invite_link`.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
Returns:
|
||||
:class:`telegram.ChatInviteLink`
|
||||
"""
|
||||
return await self.get_bot().create_chat_subscription_invite_link(
|
||||
chat_id=self.id,
|
||||
subscription_period=subscription_period,
|
||||
subscription_price=subscription_price,
|
||||
name=name,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
async def edit_subscription_invite_link(
|
||||
self,
|
||||
invite_link: Union[str, "ChatInviteLink"],
|
||||
name: Optional[str] = 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: Optional[JSONDict] = None,
|
||||
) -> "ChatInviteLink":
|
||||
"""Shortcut for::
|
||||
|
||||
await bot.edit_chat_subscription_invite_link(
|
||||
chat_id=update.effective_chat.id, *args, **kwargs
|
||||
)
|
||||
|
||||
For the documentation of the arguments, please see
|
||||
:meth:`telegram.Bot.edit_chat_subscription_invite_link`.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
Returns:
|
||||
:class:`telegram.ChatInviteLink`
|
||||
|
||||
"""
|
||||
return await self.get_bot().edit_chat_subscription_invite_link(
|
||||
chat_id=self.id,
|
||||
invite_link=invite_link,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
name=name,
|
||||
)
|
||||
|
||||
async def approve_join_request(
|
||||
self,
|
||||
user_id: int,
|
||||
|
@ -3274,6 +3349,7 @@ class _ChatBase(TelegramObject):
|
|||
protect_content: ODVInput[bool] = DEFAULT_NONE,
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
reply_markup: Optional[ReplyMarkup] = None,
|
||||
business_connection_id: Optional[str] = None,
|
||||
*,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
|
@ -3314,6 +3390,7 @@ class _ChatBase(TelegramObject):
|
|||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
business_connection_id=business_connection_id,
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -69,6 +69,16 @@ class ChatInviteLink(TelegramObject):
|
|||
created using this link.
|
||||
|
||||
.. versionadded:: 13.8
|
||||
subscription_period (:obj:`int`, optional): The number of seconds the subscription will be
|
||||
active for before the next payment.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
subscription_price (:obj:`int`, optional): The amount of Telegram Stars a user must pay
|
||||
initially and after each subsequent subscription period to be a member of the chat
|
||||
using the link.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
Attributes:
|
||||
invite_link (:obj:`str`): The invite link. If the link was created by another chat
|
||||
administrator, then the second part of the link will be replaced with ``'…'``.
|
||||
|
@ -96,6 +106,15 @@ class ChatInviteLink(TelegramObject):
|
|||
created using this link.
|
||||
|
||||
.. versionadded:: 13.8
|
||||
subscription_period (:obj:`int`): Optional. The number of seconds the subscription will be
|
||||
active for before the next payment.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
subscription_price (:obj:`int`): Optional. The amount of Telegram Stars a user must pay
|
||||
initially and after each subsequent subscription period to be a member of the chat
|
||||
using the link.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
"""
|
||||
|
||||
|
@ -109,6 +128,8 @@ class ChatInviteLink(TelegramObject):
|
|||
"member_limit",
|
||||
"name",
|
||||
"pending_join_request_count",
|
||||
"subscription_period",
|
||||
"subscription_price",
|
||||
)
|
||||
|
||||
def __init__(
|
||||
|
@ -122,6 +143,8 @@ class ChatInviteLink(TelegramObject):
|
|||
member_limit: Optional[int] = None,
|
||||
name: Optional[str] = None,
|
||||
pending_join_request_count: Optional[int] = None,
|
||||
subscription_period: Optional[int] = None,
|
||||
subscription_price: Optional[int] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
|
@ -140,6 +163,9 @@ class ChatInviteLink(TelegramObject):
|
|||
self.pending_join_request_count: Optional[int] = (
|
||||
int(pending_join_request_count) if pending_join_request_count is not None else None
|
||||
)
|
||||
self.subscription_period: Optional[int] = subscription_period
|
||||
self.subscription_price: Optional[int] = subscription_price
|
||||
|
||||
self._id_attrs = (
|
||||
self.invite_link,
|
||||
self.creates_join_request,
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
# 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 ChatMember."""
|
||||
|
||||
import datetime
|
||||
from typing import TYPE_CHECKING, Dict, Final, Optional, Type
|
||||
|
||||
|
@ -391,24 +392,34 @@ class ChatMemberMember(ChatMember):
|
|||
|
||||
Args:
|
||||
user (:class:`telegram.User`): Information about the user.
|
||||
until_date (:class:`datetime.datetime`, optional): Date when the user's subscription will
|
||||
expire.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
Attributes:
|
||||
status (:obj:`str`): The member's status in the chat,
|
||||
always :tg-const:`telegram.ChatMember.MEMBER`.
|
||||
user (:class:`telegram.User`): Information about the user.
|
||||
until_date (:class:`datetime.datetime`): Optional. Date when the user's subscription will
|
||||
expire.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
"""
|
||||
|
||||
__slots__ = ()
|
||||
__slots__ = ("until_date",)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
user: User,
|
||||
until_date: Optional[datetime.datetime] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
super().__init__(status=ChatMember.MEMBER, user=user, api_kwargs=api_kwargs)
|
||||
self._freeze()
|
||||
with self._unfrozen():
|
||||
self.until_date: Optional[datetime.datetime] = until_date
|
||||
|
||||
|
||||
class ChatMemberRestricted(ChatMember):
|
||||
|
|
|
@ -280,15 +280,14 @@ class Message(MaybeInaccessibleMessage):
|
|||
|
||||
Args:
|
||||
message_id (:obj:`int`): Unique message identifier inside this chat.
|
||||
from_user (:class:`telegram.User`, optional): Sender of the message; empty for messages
|
||||
sent to channels. For backward compatibility, this will contain a fake sender user in
|
||||
non-channel chats, if the message was sent on behalf of a chat.
|
||||
sender_chat (:class:`telegram.Chat`, optional): Sender of the message, sent on behalf of a
|
||||
chat. For example, the channel itself for channel posts, the supergroup itself for
|
||||
messages from anonymous group administrators, the linked channel for messages
|
||||
automatically forwarded to the discussion group. For backward compatibility,
|
||||
:attr:`from_user` contains a fake sender user in non-channel chats, if the message was
|
||||
sent on behalf of a chat.
|
||||
from_user (:class:`telegram.User`, optional): Sender of the message; may be empty for
|
||||
messages sent to channels. For backward compatibility, if the message was sent on
|
||||
behalf of a chat, the field contains a fake sender user in non-channel chats.
|
||||
sender_chat (:class:`telegram.Chat`, optional): Sender of the message when sent on behalf
|
||||
of a chat. For example, the supergroup itself for messages sent by its anonymous
|
||||
administrators or a linked channel for messages automatically forwarded to the
|
||||
channel's discussion group. For backward compatibility, if the message was sent on
|
||||
behalf of a chat, the field from contains a fake sender user in non-channel chats.
|
||||
date (:class:`datetime.datetime`): Date the message was sent in Unix time. Converted to
|
||||
:class:`datetime.datetime`.
|
||||
|
||||
|
@ -591,15 +590,14 @@ class Message(MaybeInaccessibleMessage):
|
|||
|
||||
Attributes:
|
||||
message_id (:obj:`int`): Unique message identifier inside this chat.
|
||||
from_user (:class:`telegram.User`): Optional. Sender of the message; empty for messages
|
||||
sent to channels. For backward compatibility, this will contain a fake sender user in
|
||||
non-channel chats, if the message was sent on behalf of a chat.
|
||||
sender_chat (:class:`telegram.Chat`): Optional. Sender of the message, sent on behalf of a
|
||||
chat. For example, the channel itself for channel posts, the supergroup itself for
|
||||
messages from anonymous group administrators, the linked channel for messages
|
||||
automatically forwarded to the discussion group. For backward compatibility,
|
||||
:attr:`from_user` contains a fake sender user in non-channel chats, if the message was
|
||||
sent on behalf of a chat.
|
||||
from_user (:class:`telegram.User`): Optional. Sender of the message; may be empty for
|
||||
messages sent to channels. For backward compatibility, if the message was sent on
|
||||
behalf of a chat, the field contains a fake sender user in non-channel chats.
|
||||
sender_chat (:class:`telegram.Chat`): Optional. Sender of the message when sent on behalf
|
||||
of a chat. For example, the supergroup itself for messages sent by its anonymous
|
||||
administrators or a linked channel for messages automatically forwarded to the
|
||||
channel's discussion group. For backward compatibility, if the message was sent on
|
||||
behalf of a chat, the field from contains a fake sender user in non-channel chats.
|
||||
date (:class:`datetime.datetime`): Date the message was sent in Unix time. Converted to
|
||||
:class:`datetime.datetime`.
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ from datetime import datetime
|
|||
from typing import TYPE_CHECKING, Dict, Final, Optional, Sequence, Tuple, Type
|
||||
|
||||
from telegram import constants
|
||||
from telegram._paidmedia import PaidMedia
|
||||
from telegram._telegramobject import TelegramObject
|
||||
from telegram._user import User
|
||||
from telegram._utils import enum
|
||||
|
@ -310,20 +311,33 @@ class TransactionPartnerUser(TransactionPartner):
|
|||
Args:
|
||||
user (:class:`telegram.User`): Information about the user.
|
||||
invoice_payload (:obj:`str`, optional): Bot-specified invoice payload.
|
||||
paid_media (Sequence[:class:`telegram.PaidMedia`], optional): Information about the paid
|
||||
media bought by the user.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
Attributes:
|
||||
type (:obj:`str`): The type of the transaction partner,
|
||||
always :tg-const:`telegram.TransactionPartner.USER`.
|
||||
user (:class:`telegram.User`): Information about the user.
|
||||
invoice_payload (:obj:`str`): Optional. Bot-specified invoice payload.
|
||||
paid_media (Tuple[:class:`telegram.PaidMedia`]): Optional. Information about the paid
|
||||
media bought by the user.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
"""
|
||||
|
||||
__slots__ = ("invoice_payload", "user")
|
||||
__slots__ = (
|
||||
"invoice_payload",
|
||||
"paid_media",
|
||||
"user",
|
||||
)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
user: "User",
|
||||
invoice_payload: Optional[str] = None,
|
||||
paid_media: Optional[Sequence[PaidMedia]] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
) -> None:
|
||||
|
@ -332,6 +346,7 @@ class TransactionPartnerUser(TransactionPartner):
|
|||
with self._unfrozen():
|
||||
self.user: User = user
|
||||
self.invoice_payload: Optional[str] = invoice_payload
|
||||
self.paid_media: Optional[Tuple[PaidMedia, ...]] = parse_sequence_arg(paid_media)
|
||||
self._id_attrs = (
|
||||
self.type,
|
||||
self.user,
|
||||
|
@ -347,6 +362,7 @@ class TransactionPartnerUser(TransactionPartner):
|
|||
return None
|
||||
|
||||
data["user"] = User.de_json(data.get("user"), bot)
|
||||
data["paid_media"] = PaidMedia.de_list(data.get("paid_media"), bot=bot)
|
||||
|
||||
return super().de_json(data=data, bot=bot) # type: ignore[return-value]
|
||||
|
||||
|
|
|
@ -17,7 +17,8 @@
|
|||
# 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 objects that represents a Telegram ReactionType."""
|
||||
from typing import TYPE_CHECKING, Final, Literal, Optional, Union
|
||||
|
||||
from typing import TYPE_CHECKING, Dict, Final, Literal, Optional, Type, Union
|
||||
|
||||
from telegram import constants
|
||||
from telegram._telegramobject import TelegramObject
|
||||
|
@ -30,16 +31,22 @@ if TYPE_CHECKING:
|
|||
|
||||
class ReactionType(TelegramObject):
|
||||
"""Base class for Telegram ReactionType Objects.
|
||||
There exist :class:`telegram.ReactionTypeEmoji` and :class:`telegram.ReactionTypeCustomEmoji`.
|
||||
There exist :class:`telegram.ReactionTypeEmoji`, :class:`telegram.ReactionTypeCustomEmoji`
|
||||
and :class:`telegram.ReactionTypePaid`.
|
||||
|
||||
.. versionadded:: 20.8
|
||||
.. versionchanged:: NEXT.VERSION
|
||||
|
||||
Added paid reaction.
|
||||
|
||||
Args:
|
||||
type (:obj:`str`): Type of the reaction. Can be
|
||||
:attr:`~telegram.ReactionType.EMOJI` or :attr:`~telegram.ReactionType.CUSTOM_EMOJI`.
|
||||
:attr:`~telegram.ReactionType.EMOJI`, :attr:`~telegram.ReactionType.CUSTOM_EMOJI` or
|
||||
:attr:`~telegram.ReactionType.PAID`.
|
||||
Attributes:
|
||||
type (:obj:`str`): Type of the reaction. Can be
|
||||
:attr:`~telegram.ReactionType.EMOJI` or :attr:`~telegram.ReactionType.CUSTOM_EMOJI`.
|
||||
:attr:`~telegram.ReactionType.EMOJI`, :attr:`~telegram.ReactionType.CUSTOM_EMOJI` or
|
||||
:attr:`~telegram.ReactionType.PAID`.
|
||||
|
||||
"""
|
||||
|
||||
|
@ -49,11 +56,16 @@ class ReactionType(TelegramObject):
|
|||
""":const:`telegram.constants.ReactionType.EMOJI`"""
|
||||
CUSTOM_EMOJI: Final[constants.ReactionType] = constants.ReactionType.CUSTOM_EMOJI
|
||||
""":const:`telegram.constants.ReactionType.CUSTOM_EMOJI`"""
|
||||
PAID: Final[constants.ReactionType] = constants.ReactionType.PAID
|
||||
""":const:`telegram.constants.ReactionType.PAID`
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
type: Union[ # pylint: disable=redefined-builtin
|
||||
Literal["emoji", "custom_emoji"], constants.ReactionType
|
||||
Literal["emoji", "custom_emoji", "paid"], constants.ReactionType
|
||||
],
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
|
@ -71,14 +83,20 @@ class ReactionType(TelegramObject):
|
|||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
data = cls._parse_data(data)
|
||||
|
||||
if not data:
|
||||
if data is None:
|
||||
return None
|
||||
|
||||
if cls is ReactionType and data.get("type") in [cls.EMOJI, cls.CUSTOM_EMOJI]:
|
||||
reaction_type = data.pop("type")
|
||||
if reaction_type == cls.EMOJI:
|
||||
return ReactionTypeEmoji.de_json(data=data, bot=bot)
|
||||
return ReactionTypeCustomEmoji.de_json(data=data, bot=bot)
|
||||
if not data and cls is ReactionType:
|
||||
return None
|
||||
|
||||
_class_mapping: Dict[str, Type[ReactionType]] = {
|
||||
cls.EMOJI: ReactionTypeEmoji,
|
||||
cls.CUSTOM_EMOJI: ReactionTypeCustomEmoji,
|
||||
cls.PAID: ReactionTypePaid,
|
||||
}
|
||||
|
||||
if cls is ReactionType and data.get("type") in _class_mapping:
|
||||
return _class_mapping[data.pop("type")].de_json(data, bot)
|
||||
|
||||
return super().de_json(data=data, bot=bot)
|
||||
|
||||
|
@ -152,6 +170,24 @@ class ReactionTypeCustomEmoji(ReactionType):
|
|||
self._id_attrs = (self.custom_emoji_id,)
|
||||
|
||||
|
||||
class ReactionTypePaid(ReactionType):
|
||||
"""
|
||||
The reaction is paid.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
Attributes:
|
||||
type (:obj:`str`): Type of the reaction,
|
||||
always :tg-const:`telegram.ReactionType.PAID`.
|
||||
"""
|
||||
|
||||
__slots__ = ()
|
||||
|
||||
def __init__(self, *, api_kwargs: Optional[JSONDict] = None):
|
||||
super().__init__(type=ReactionType.PAID, api_kwargs=api_kwargs)
|
||||
self._freeze()
|
||||
|
||||
|
||||
class ReactionCount(TelegramObject):
|
||||
"""This class represents a reaction added to a message along with the number of times it was
|
||||
added.
|
||||
|
|
|
@ -54,6 +54,7 @@ __all__ = [
|
|||
"ChatLimit",
|
||||
"ChatMemberStatus",
|
||||
"ChatPhotoSize",
|
||||
"ChatSubscriptionLimit",
|
||||
"ChatType",
|
||||
"ContactLimit",
|
||||
"CustomEmojiStickerLimit",
|
||||
|
@ -151,7 +152,7 @@ class _AccentColor(NamedTuple):
|
|||
#: :data:`telegram.__bot_api_version_info__`.
|
||||
#:
|
||||
#: .. versionadded:: 20.0
|
||||
BOT_API_VERSION_INFO: Final[_BotAPIVersion] = _BotAPIVersion(major=7, minor=8)
|
||||
BOT_API_VERSION_INFO: Final[_BotAPIVersion] = _BotAPIVersion(major=7, minor=9)
|
||||
#: :obj:`str`: Telegram Bot API
|
||||
#: version supported by this version of `python-telegram-bot`. Also available as
|
||||
#: :data:`telegram.__bot_api_version__`.
|
||||
|
@ -2903,6 +2904,11 @@ class ReactionType(StringEnum):
|
|||
""":obj:`str`: A :class:`telegram.ReactionType` with a normal emoji."""
|
||||
CUSTOM_EMOJI = "custom_emoji"
|
||||
""":obj:`str`: A :class:`telegram.ReactionType` with a custom emoji."""
|
||||
PAID = "paid"
|
||||
""":obj:`str`: A :class:`telegram.ReactionType` with a paid reaction.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
"""
|
||||
|
||||
|
||||
class ReactionEmoji(StringEnum):
|
||||
|
@ -3096,3 +3102,22 @@ class BackgroundFillType(StringEnum):
|
|||
""":obj:`str`: A :class:`telegram.BackgroundFill` with gradient fill."""
|
||||
FREEFORM_GRADIENT = "freeform_gradient"
|
||||
""":obj:`str`: A :class:`telegram.BackgroundFill` with freeform_gradient fill."""
|
||||
|
||||
|
||||
class ChatSubscriptionLimit(IntEnum):
|
||||
"""This enum contains limitations for
|
||||
:paramref:`telegram.Bot.create_chat_subscription_invite_link.subscription_period` and
|
||||
:paramref:`telegram.Bot.create_chat_subscription_invite_link.subscription_price`.
|
||||
The enum members of this enumeration are instances of :class:`int` and can be treated as such.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
"""
|
||||
|
||||
__slots__ = ()
|
||||
|
||||
SUBSCRIPTION_PERIOD = 2592000
|
||||
""":obj:`int`: The number of seconds the subscription will be active."""
|
||||
MIN_PRICE = 1
|
||||
""":obj:`int`: Amount of stars a user pays, minimum amount the subscription can be set to."""
|
||||
MAX_PRICE = 2500
|
||||
""":obj:`int`: Amount of stars a user pays, maximum amount the subscription can be set to."""
|
||||
|
|
|
@ -4234,6 +4234,7 @@ class ExtBot(Bot, Generic[RLARGS]):
|
|||
protect_content: ODVInput[bool] = DEFAULT_NONE,
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
reply_markup: Optional[ReplyMarkup] = None,
|
||||
business_connection_id: Optional[str] = None,
|
||||
*,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
|
@ -4263,6 +4264,57 @@ class ExtBot(Bot, Generic[RLARGS]):
|
|||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=self._merge_api_rl_kwargs(api_kwargs, rate_limit_args),
|
||||
business_connection_id=business_connection_id,
|
||||
)
|
||||
|
||||
async def create_chat_subscription_invite_link(
|
||||
self,
|
||||
chat_id: Union[str, int],
|
||||
subscription_period: int,
|
||||
subscription_price: int,
|
||||
name: Optional[str] = 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: Optional[JSONDict] = None,
|
||||
rate_limit_args: Optional[RLARGS] = None,
|
||||
) -> ChatInviteLink:
|
||||
return await super().create_chat_subscription_invite_link(
|
||||
chat_id=chat_id,
|
||||
subscription_period=subscription_period,
|
||||
subscription_price=subscription_price,
|
||||
name=name,
|
||||
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 edit_chat_subscription_invite_link(
|
||||
self,
|
||||
chat_id: Union[str, int],
|
||||
invite_link: Union[str, "ChatInviteLink"],
|
||||
name: Optional[str] = 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: Optional[JSONDict] = None,
|
||||
rate_limit_args: Optional[RLARGS] = None,
|
||||
) -> ChatInviteLink:
|
||||
return await super().edit_chat_subscription_invite_link(
|
||||
chat_id=chat_id,
|
||||
invite_link=invite_link,
|
||||
name=name,
|
||||
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
|
||||
|
@ -4388,4 +4440,6 @@ class ExtBot(Bot, Generic[RLARGS]):
|
|||
replaceStickerInSet = replace_sticker_in_set
|
||||
refundStarPayment = refund_star_payment
|
||||
getStarTransactions = get_star_transactions
|
||||
createChatSubscriptionInviteLink = create_chat_subscription_invite_link
|
||||
editChatSubscriptionInviteLink = edit_chat_subscription_invite_link
|
||||
sendPaidMedia = send_paid_media
|
||||
|
|
|
@ -29,15 +29,16 @@ from telegram._utils.strings import TextEncoding
|
|||
# purposes than testing.
|
||||
FALLBACKS = (
|
||||
"W3sidG9rZW4iOiAiNTc5Njk0NzE0OkFBRnBLOHc2emtrVXJENHhTZVl3RjNNTzhlLTRHcm1jeTdjIiwgInBheW1lbnRfc"
|
||||
"HJvdmlkZXJfdG9rZW4iOiAiMjg0Njg1MDYzOlRFU1Q6TmpRME5qWmxOekk1WWpKaSIsICJjaGF0X2 lkIjogIjY3NTY2N"
|
||||
"jIyNCIsICJzdXBlcl9ncm91cF9pZCI6ICItMTAwMTMxMDkxMTEzNSIsICJmb3J1bV9ncm91cF9pZCI6ICItMTAwMTgzOD"
|
||||
"AwNDU3NyIsICJjaGFubmVsX2lkIjogIkBweXRob250ZWxlZ3JhbWJvdHRlc3RzIi wgIm5hbWUiOiAiUFRCIHRlc3RzIG"
|
||||
"ZhbGxiYWNrIDEiLCAidXNlcm5hbWUiOiAiQHB0Yl9mYWxsYmFja18xX2JvdCJ9LCB7InRva2VuIjogIjU1ODE5NDA2Njp"
|
||||
"BQUZ3RFBJRmx6R1VsQ2FXSHRUT0VYNFJGclg4dTlETXFmbyIsIC JwYXltZW50X3Byb3ZpZGVyX3Rva2VuIjogIjI4NDY"
|
||||
"4NTA2MzpURVNUOllqRXdPRFF3TVRGbU5EY3kiLCAiY2hhdF9pZCI6ICI2NzU2NjYyMjQiLCAic3VwZXJfZ3JvdXBfaWQi"
|
||||
"OiAiLTEwMDEyMjEyMTY4MzAiLCAiZm9ydW1fZ3 JvdXBfaWQiOiAiLTEwMDE4NTc4NDgzMTQiLCAiY2hhbm5lbF9pZCI6"
|
||||
"ICJAcHl0aG9udGVsZWdyYW1ib3R0ZXN0cyIsICJuYW1lIjogIlBUQiB0ZXN0cyBmYWxsYmFjayAyIiwgInVzZXJuYW1lI"
|
||||
"jogIkBwdGJfZmFsbGJhY2tfMl9ib3QifV0="
|
||||
"HJvdmlkZXJfdG9rZW4iOiAiMjg0Njg1MDYzOlRFU1Q6TmpRME5qWmxOekk1WWpKaSIsICJjaGF0X2lkIjogIjY3NTY2Nj"
|
||||
"IyNCIsICJzdXBlcl9ncm91cF9pZCI6ICItMTAwMTMxMDkxMTEzNSIsICJmb3J1bV9ncm91cF9pZCI6ICItMTAwMTgzODA"
|
||||
"wNDU3NyIsICJjaGFubmVsX2lkIjogIkBweXRob250ZWxlZ3JhbWJvdHRlc3RzIiwgIm5hbWUiOiAiUFRCIHRlc3RzIGZh"
|
||||
"bGxiYWNrIDEiLCAidXNlcm5hbWUiOiAiQHB0Yl9mYWxsYmFja18xX2JvdCIsICJzdWJzY3JpcHRpb25fY2hhbm5lbF9pZ"
|
||||
"CI6IC0xMDAyMjI5NjQ5MzAzfSwgeyJ0b2tlbiI6ICI1NTgxOTQwNjY6QUFGd0RQSUZsekdVbENhV0h0VE9FWDRSRnJYOH"
|
||||
"U5RE1xZm8iLCAicGF5bWVudF9wcm92aWRlcl90b2tlbiI6ICIyODQ2ODUwNjM6VEVTVDpZakV3T0RRd01URm1ORGN5Iiw"
|
||||
"gImNoYXRfaWQiOiAiNjc1NjY2MjI0IiwgInN1cGVyX2dyb3VwX2lkIjogIi0xMDAxMjIxMjE2ODMwIiwgImZvcnVtX2dy"
|
||||
"b3VwX2lkIjogIi0xMDAxODU3ODQ4MzE0IiwgImNoYW5uZWxfaWQiOiAiQHB5dGhvbnRlbGVncmFtYm90dGVzdHMiLCAib"
|
||||
"mFtZSI6ICJQVEIgdGVzdHMgZmFsbGJhY2sgMiIsICJ1c2VybmFtZSI6ICJAcHRiX2ZhbGxiYWNrXzJfYm90IiwgInN1Yn"
|
||||
"NjcmlwdGlvbl9jaGFubmVsX2lkIjogLTEwMDIyMjk2NDkzMDN9XQ=="
|
||||
)
|
||||
|
||||
GITHUB_ACTION = os.getenv("GITHUB_ACTION", None)
|
||||
|
|
|
@ -206,6 +206,11 @@ def provider_token(bot_info):
|
|||
return bot_info["payment_provider_token"]
|
||||
|
||||
|
||||
@pytest.fixture(scope="session")
|
||||
def subscription_channel_id(bot_info):
|
||||
return bot_info["subscription_channel_id"]
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
async def app(bot_info):
|
||||
# We build a new bot each time so that we use `app` in a context manager without problems
|
||||
|
|
|
@ -2265,6 +2265,21 @@ class TestBotWithoutRequest:
|
|||
obj = await bot.get_star_transactions(offset=3)
|
||||
assert isinstance(obj, StarTransactions)
|
||||
|
||||
async def test_create_chat_subscription_invite_link(
|
||||
self,
|
||||
monkeypatch,
|
||||
bot,
|
||||
):
|
||||
# Since the chat invite link object does not say if the sub args are passed we can
|
||||
# only check here
|
||||
async def make_assertion(url, request_data: RequestData, *args, **kwargs):
|
||||
assert request_data.parameters.get("subscription_period") == 2592000
|
||||
assert request_data.parameters.get("subscription_price") == 6
|
||||
|
||||
monkeypatch.setattr(bot.request, "post", make_assertion)
|
||||
|
||||
await bot.create_chat_subscription_invite_link(1234, 2592000, 6)
|
||||
|
||||
|
||||
class TestBotWithRequest:
|
||||
"""
|
||||
|
@ -4261,3 +4276,23 @@ class TestBotWithRequest:
|
|||
transactions = await bot.get_star_transactions(limit=1)
|
||||
assert isinstance(transactions, StarTransactions)
|
||||
assert len(transactions.transactions) == 0
|
||||
|
||||
async def test_create_edit_chat_subscription_link(
|
||||
self, bot, subscription_channel_id, channel_id
|
||||
):
|
||||
sub_link = await bot.create_chat_subscription_invite_link(
|
||||
subscription_channel_id,
|
||||
name="sub_name",
|
||||
subscription_period=2592000,
|
||||
subscription_price=13,
|
||||
)
|
||||
assert sub_link.name == "sub_name"
|
||||
assert sub_link.subscription_period == 2592000
|
||||
assert sub_link.subscription_price == 13
|
||||
|
||||
edited_link = await bot.edit_chat_subscription_invite_link(
|
||||
chat_id=subscription_channel_id, invite_link=sub_link, name="sub_name_2"
|
||||
)
|
||||
assert edited_link.name == "sub_name_2"
|
||||
assert sub_link.subscription_period == 2592000
|
||||
assert sub_link.subscription_price == 13
|
||||
|
|
|
@ -889,6 +889,54 @@ class TestChatWithoutRequest(TestChatBase):
|
|||
monkeypatch.setattr(chat.get_bot(), "revoke_chat_invite_link", make_assertion)
|
||||
assert await chat.revoke_invite_link(invite_link=link)
|
||||
|
||||
async def test_create_subscription_invite_link(self, monkeypatch, chat):
|
||||
async def make_assertion(*_, **kwargs):
|
||||
return (
|
||||
kwargs["chat_id"] == chat.id
|
||||
and kwargs["subscription_price"] == 42
|
||||
and kwargs["subscription_period"] == 42
|
||||
)
|
||||
|
||||
assert check_shortcut_signature(
|
||||
Chat.create_subscription_invite_link,
|
||||
Bot.create_chat_subscription_invite_link,
|
||||
["chat_id"],
|
||||
[],
|
||||
)
|
||||
assert await check_shortcut_call(
|
||||
chat.create_subscription_invite_link,
|
||||
chat.get_bot(),
|
||||
"create_chat_subscription_invite_link",
|
||||
)
|
||||
assert await check_defaults_handling(chat.create_subscription_invite_link, chat.get_bot())
|
||||
|
||||
monkeypatch.setattr(chat.get_bot(), "create_chat_subscription_invite_link", make_assertion)
|
||||
assert await chat.create_subscription_invite_link(
|
||||
subscription_price=42, subscription_period=42
|
||||
)
|
||||
|
||||
async def test_edit_subscription_invite_link(self, monkeypatch, chat):
|
||||
link = "ThisIsALink"
|
||||
|
||||
async def make_assertion(*_, **kwargs):
|
||||
return kwargs["chat_id"] == chat.id and kwargs["invite_link"] == link
|
||||
|
||||
assert check_shortcut_signature(
|
||||
Chat.edit_subscription_invite_link,
|
||||
Bot.edit_chat_subscription_invite_link,
|
||||
["chat_id"],
|
||||
[],
|
||||
)
|
||||
assert await check_shortcut_call(
|
||||
chat.edit_subscription_invite_link,
|
||||
chat.get_bot(),
|
||||
"edit_chat_subscription_invite_link",
|
||||
)
|
||||
assert await check_defaults_handling(chat.edit_subscription_invite_link, chat.get_bot())
|
||||
|
||||
monkeypatch.setattr(chat.get_bot(), "edit_chat_subscription_invite_link", make_assertion)
|
||||
assert await chat.edit_subscription_invite_link(invite_link=link)
|
||||
|
||||
async def test_instance_method_get_menu_button(self, monkeypatch, chat):
|
||||
async def make_assertion(*_, **kwargs):
|
||||
return kwargs["chat_id"] == chat.id
|
||||
|
|
|
@ -42,6 +42,8 @@ def invite_link(creator):
|
|||
member_limit=TestChatInviteLinkBase.member_limit,
|
||||
name=TestChatInviteLinkBase.name,
|
||||
pending_join_request_count=TestChatInviteLinkBase.pending_join_request_count,
|
||||
subscription_period=TestChatInviteLinkBase.subscription_period,
|
||||
subscription_price=TestChatInviteLinkBase.subscription_price,
|
||||
)
|
||||
|
||||
|
||||
|
@ -54,6 +56,8 @@ class TestChatInviteLinkBase:
|
|||
member_limit = 42
|
||||
name = "LinkName"
|
||||
pending_join_request_count = 42
|
||||
subscription_period = 43
|
||||
subscription_price = 44
|
||||
|
||||
|
||||
class TestChatInviteLinkWithoutRequest(TestChatInviteLinkBase):
|
||||
|
@ -91,6 +95,8 @@ class TestChatInviteLinkWithoutRequest(TestChatInviteLinkBase):
|
|||
"member_limit": self.member_limit,
|
||||
"name": self.name,
|
||||
"pending_join_request_count": str(self.pending_join_request_count),
|
||||
"subscription_period": self.subscription_period,
|
||||
"subscription_price": self.subscription_price,
|
||||
}
|
||||
|
||||
invite_link = ChatInviteLink.de_json(json_dict, bot)
|
||||
|
@ -106,6 +112,8 @@ class TestChatInviteLinkWithoutRequest(TestChatInviteLinkBase):
|
|||
assert invite_link.member_limit == self.member_limit
|
||||
assert invite_link.name == self.name
|
||||
assert invite_link.pending_join_request_count == self.pending_join_request_count
|
||||
assert invite_link.subscription_period == self.subscription_period
|
||||
assert invite_link.subscription_price == self.subscription_price
|
||||
|
||||
def test_de_json_localization(self, tz_bot, bot, raw_bot, creator):
|
||||
json_dict = {
|
||||
|
@ -146,6 +154,8 @@ class TestChatInviteLinkWithoutRequest(TestChatInviteLinkBase):
|
|||
assert invite_link_dict["member_limit"] == self.member_limit
|
||||
assert invite_link_dict["name"] == self.name
|
||||
assert invite_link_dict["pending_join_request_count"] == self.pending_join_request_count
|
||||
assert invite_link_dict["subscription_period"] == self.subscription_period
|
||||
assert invite_link_dict["subscription_price"] == self.subscription_price
|
||||
|
||||
def test_equality(self):
|
||||
a = ChatInviteLink("link", User(1, "", False), True, True, True)
|
||||
|
|
|
@ -101,7 +101,7 @@ def chat_member_administrator():
|
|||
|
||||
|
||||
def chat_member_member():
|
||||
return ChatMemberMember(CMDefaults.user)
|
||||
return ChatMemberMember(CMDefaults.user, until_date=CMDefaults.until_date)
|
||||
|
||||
|
||||
def chat_member_restricted():
|
||||
|
@ -230,7 +230,9 @@ class TestChatMemberTypesWithoutRequest:
|
|||
|
||||
def test_de_json_chatmemberbanned_localization(self, chat_member_type, tz_bot, bot, raw_bot):
|
||||
# We only test two classes because the other three don't have datetimes in them.
|
||||
if isinstance(chat_member_type, (ChatMemberBanned, ChatMemberRestricted)):
|
||||
if isinstance(
|
||||
chat_member_type, (ChatMemberBanned, ChatMemberRestricted, ChatMemberMember)
|
||||
):
|
||||
json_dict = make_json_dict(chat_member_type, include_optional_args=True)
|
||||
chatmember_raw = ChatMember.de_json(json_dict, raw_bot)
|
||||
chatmember_bot = ChatMember.de_json(json_dict, bot)
|
||||
|
|
|
@ -28,6 +28,7 @@ from telegram import (
|
|||
ReactionType,
|
||||
ReactionTypeCustomEmoji,
|
||||
ReactionTypeEmoji,
|
||||
ReactionTypePaid,
|
||||
)
|
||||
from telegram.constants import ReactionEmoji
|
||||
from tests.auxil.slots import mro_slots
|
||||
|
@ -48,6 +49,10 @@ def reaction_type_emoji():
|
|||
return ReactionTypeEmoji(RTDefaults.normal_emoji)
|
||||
|
||||
|
||||
def reaction_type_paid():
|
||||
return ReactionTypePaid()
|
||||
|
||||
|
||||
def make_json_dict(instance: ReactionType, include_optional_args: bool = False) -> dict:
|
||||
"""Used to make the json dict which we use for testing de_json. Similar to iter_args()"""
|
||||
json_dict = {"type": instance.type}
|
||||
|
@ -99,6 +104,7 @@ def reaction_type(request):
|
|||
[
|
||||
reaction_type_custom_emoji,
|
||||
reaction_type_emoji,
|
||||
reaction_type_paid,
|
||||
],
|
||||
indirect=True,
|
||||
)
|
||||
|
@ -112,6 +118,7 @@ class TestReactionTypesWithoutRequest:
|
|||
def test_de_json_required_args(self, bot, reaction_type):
|
||||
cls = reaction_type.__class__
|
||||
assert cls.de_json(None, bot) is None
|
||||
assert ReactionType.de_json({}, bot) is None
|
||||
|
||||
json_dict = make_json_dict(reaction_type)
|
||||
const_reaction_type = ReactionType.de_json(json_dict, bot)
|
||||
|
@ -155,7 +162,7 @@ class TestReactionTypesWithoutRequest:
|
|||
assert reaction_type_dict["type"] == reaction_type.type
|
||||
if reaction_type.type == ReactionType.EMOJI:
|
||||
assert reaction_type_dict["emoji"] == reaction_type.emoji
|
||||
else:
|
||||
elif reaction_type.type == ReactionType.CUSTOM_EMOJI:
|
||||
assert reaction_type_dict["custom_emoji_id"] == reaction_type.custom_emoji_id
|
||||
|
||||
for slot in reaction_type.__slots__: # additional verification for the optional args
|
||||
|
|
|
@ -24,6 +24,8 @@ import pytest
|
|||
|
||||
from telegram import (
|
||||
Dice,
|
||||
PaidMediaPhoto,
|
||||
PhotoSize,
|
||||
RevenueWithdrawalState,
|
||||
RevenueWithdrawalStateFailed,
|
||||
RevenueWithdrawalStatePending,
|
||||
|
@ -62,6 +64,16 @@ def withdrawal_state_pending():
|
|||
def transaction_partner_user():
|
||||
return TransactionPartnerUser(
|
||||
user=User(id=1, is_bot=False, first_name="first_name", username="username"),
|
||||
invoice_payload="payload",
|
||||
paid_media=[
|
||||
PaidMediaPhoto(
|
||||
photo=[
|
||||
PhotoSize(
|
||||
file_id="file_id", width=1, height=1, file_unique_id="file_unique_id"
|
||||
)
|
||||
]
|
||||
)
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue