mirror of
https://github.com/python-telegram-bot/python-telegram-bot.git
synced 2025-03-14 11:43:50 +01:00
Full Support for Bot API 8.2 (#4633)
Co-authored-by: Harshil <37377066+harshil21@users.noreply.github.com> Co-authored-by: Bibo-Joshi <22366557+Bibo-Joshi@users.noreply.github.com>
This commit is contained in:
parent
a781a4fddb
commit
f2dc0175cd
15 changed files with 643 additions and 9 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-8.1-blue?logo=telegram
|
||||
.. image:: https://img.shields.io/badge/Bot%20API-8.2-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 **8.1** are natively supported by this library.
|
||||
All types and methods of the Telegram Bot API **8.2** 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
|
||||
|
|
|
@ -183,6 +183,29 @@
|
|||
</details>
|
||||
<br>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<details>
|
||||
<summary>Verification on behalf of an organization</summary>
|
||||
|
||||
.. list-table::
|
||||
:align: left
|
||||
:widths: 1 4
|
||||
|
||||
* - :meth:`~telegram.Bot.verify_chat`
|
||||
- Used for verifying a chat
|
||||
* - :meth:`~telegram.Bot.verify_user`
|
||||
- Used for verifying a user
|
||||
* - :meth:`~telegram.Bot.remove_chat_verification`
|
||||
- Used for removing the verification from a chat
|
||||
* - :meth:`~telegram.Bot.remove_user_verification`
|
||||
- Used for removing the verification from a user
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</details>
|
||||
<br>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<details>
|
||||
|
|
176
telegram/_bot.py
176
telegram/_bot.py
|
@ -9721,6 +9721,7 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
|||
text: Optional[str] = None,
|
||||
text_parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
text_entities: Optional[Sequence["MessageEntity"]] = None,
|
||||
pay_for_upgrade: Optional[bool] = None,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
|
@ -9752,6 +9753,10 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
|||
:attr:`~MessageEntity.ITALIC`, :attr:`~MessageEntity.UNDERLINE`,
|
||||
:attr:`~MessageEntity.STRIKETHROUGH`, :attr:`~MessageEntity.SPOILER`, and
|
||||
:attr:`~MessageEntity.CUSTOM_EMOJI` are ignored.
|
||||
pay_for_upgrade (:obj:`bool`, optional): Pass :obj:`True` to pay for the gift upgrade
|
||||
from the bot's balance, thereby making the upgrade free for the receiver.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
Returns:
|
||||
:obj:`bool`: On success, :obj:`True` is returned.
|
||||
|
@ -9765,6 +9770,7 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
|||
"text": text,
|
||||
"text_parse_mode": text_parse_mode,
|
||||
"text_entities": text_entities,
|
||||
"pay_for_upgrade": pay_for_upgrade,
|
||||
}
|
||||
return await self._post(
|
||||
"sendGift",
|
||||
|
@ -9776,6 +9782,168 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
|||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
async def verify_chat(
|
||||
self,
|
||||
chat_id: Union[int, str],
|
||||
custom_description: 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,
|
||||
) -> bool:
|
||||
"""Verifies a chat on behalf of the organization which is represented by the bot.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
Args:
|
||||
chat_id (:obj:`int` | :obj:`str`): |chat_id_channel|
|
||||
custom_description (:obj:`str`, optional): Custom description for the verification;
|
||||
0- :tg-const:`telegram.constants.VerifyLimit.MAX_TEXT_LENGTH` characters. Must be
|
||||
empty if the organization isn't allowed to provide a custom verification
|
||||
description.
|
||||
|
||||
Returns:
|
||||
:obj:`bool`: On success, :obj:`True` is returned.
|
||||
|
||||
Raises:
|
||||
:class:`telegram.error.TelegramError`
|
||||
"""
|
||||
data: JSONDict = {
|
||||
"chat_id": chat_id,
|
||||
"custom_description": custom_description,
|
||||
}
|
||||
return await self._post(
|
||||
"verifyChat",
|
||||
data,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
async def verify_user(
|
||||
self,
|
||||
user_id: int,
|
||||
custom_description: 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,
|
||||
) -> bool:
|
||||
"""Verifies a user on behalf of the organization which is represented by the bot.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
Args:
|
||||
user_id (:obj:`int`): Unique identifier of the target user.
|
||||
custom_description (:obj:`str`, optional): Custom description for the verification;
|
||||
0- :tg-const:`telegram.constants.VerifyLimit.MAX_TEXT_LENGTH` characters. Must be
|
||||
empty if the organization isn't allowed to provide a custom verification
|
||||
description.
|
||||
|
||||
Returns:
|
||||
:obj:`bool`: On success, :obj:`True` is returned.
|
||||
|
||||
Raises:
|
||||
:class:`telegram.error.TelegramError`
|
||||
"""
|
||||
data: JSONDict = {
|
||||
"user_id": user_id,
|
||||
"custom_description": custom_description,
|
||||
}
|
||||
return await self._post(
|
||||
"verifyUser",
|
||||
data,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
async def remove_chat_verification(
|
||||
self,
|
||||
chat_id: Union[int, str],
|
||||
*,
|
||||
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,
|
||||
) -> bool:
|
||||
"""Removes verification from a chat that is currently verified on behalf of the
|
||||
organization represented by the bot.
|
||||
|
||||
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
Args:
|
||||
chat_id (:obj:`int` | :obj:`str`): |chat_id_channel|
|
||||
|
||||
Returns:
|
||||
:obj:`bool`: On success, :obj:`True` is returned.
|
||||
|
||||
Raises:
|
||||
:class:`telegram.error.TelegramError`
|
||||
"""
|
||||
data: JSONDict = {
|
||||
"chat_id": chat_id,
|
||||
}
|
||||
return await self._post(
|
||||
"removeChatVerification",
|
||||
data,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
async def remove_user_verification(
|
||||
self,
|
||||
user_id: int,
|
||||
*,
|
||||
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,
|
||||
) -> bool:
|
||||
"""Removes verification from a user who is currently verified on behalf of the
|
||||
organization represented by the bot.
|
||||
|
||||
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
Args:
|
||||
user_id (:obj:`int`): Unique identifier of the target user.
|
||||
|
||||
Returns:
|
||||
:obj:`bool`: On success, :obj:`True` is returned.
|
||||
|
||||
Raises:
|
||||
:class:`telegram.error.TelegramError`
|
||||
"""
|
||||
data: JSONDict = {
|
||||
"user_id": user_id,
|
||||
}
|
||||
return await self._post(
|
||||
"removeUserVerification",
|
||||
data,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
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}
|
||||
|
@ -10046,3 +10214,11 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
|||
"""Alias for :meth:`get_available_gifts`"""
|
||||
sendGift = send_gift
|
||||
"""Alias for :meth:`send_gift`"""
|
||||
verifyChat = verify_chat
|
||||
"""Alias for :meth:`verify_chat`"""
|
||||
verifyUser = verify_user
|
||||
"""Alias for :meth:`verify_user`"""
|
||||
removeChatVerification = remove_chat_verification
|
||||
"""Alias for :meth:`remove_chat_verification`"""
|
||||
removeUserVerification = remove_user_verification
|
||||
"""Alias for :meth:`remove_user_verification`"""
|
||||
|
|
|
@ -3443,6 +3443,7 @@ class _ChatBase(TelegramObject):
|
|||
text: Optional[str] = None,
|
||||
text_parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
text_entities: Optional[Sequence["MessageEntity"]] = None,
|
||||
pay_for_upgrade: Optional[bool] = None,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
|
@ -3470,6 +3471,69 @@ class _ChatBase(TelegramObject):
|
|||
text=text,
|
||||
text_parse_mode=text_parse_mode,
|
||||
text_entities=text_entities,
|
||||
pay_for_upgrade=pay_for_upgrade,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
async def verify(
|
||||
self,
|
||||
custom_description: 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,
|
||||
) -> bool:
|
||||
"""Shortcut for::
|
||||
|
||||
await bot.verify_chat(chat_id=update.effective_chat.id, *args, **kwargs)
|
||||
|
||||
For the documentation of the arguments, please see
|
||||
:meth:`telegram.Bot.verify_chat`.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
Returns:
|
||||
:obj:`bool`: On success, :obj:`True` is returned.
|
||||
"""
|
||||
return await self.get_bot().verify_chat(
|
||||
chat_id=self.id,
|
||||
custom_description=custom_description,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
async def remove_verification(
|
||||
self,
|
||||
*,
|
||||
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,
|
||||
) -> bool:
|
||||
"""Shortcut for::
|
||||
|
||||
await bot.remove_chat_verification(chat_id=update.effective_chat.id, *args, **kwargs)
|
||||
|
||||
For the documentation of the arguments, please see
|
||||
:meth:`telegram.Bot.remove_chat_verification`.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
Returns:
|
||||
:obj:`bool`: On success, :obj:`True` is returned.
|
||||
"""
|
||||
return await self.get_bot().remove_chat_verification(
|
||||
chat_id=self.id,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
|
|
|
@ -46,6 +46,10 @@ class Gift(TelegramObject):
|
|||
sent; 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
|
||||
upgrade_star_count (:obj:`int`, optional): The number of Telegram Stars that must be paid
|
||||
to upgrade the gift to a unique one
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
Attributes:
|
||||
id (:obj:`str`): Unique identifier of the gift
|
||||
|
@ -55,10 +59,21 @@ class Gift(TelegramObject):
|
|||
sent; 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
|
||||
upgrade_star_count (:obj:`int`): Optional. The number of Telegram Stars that must be paid
|
||||
to upgrade the gift to a unique one
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
"""
|
||||
|
||||
__slots__ = ("id", "remaining_count", "star_count", "sticker", "total_count")
|
||||
__slots__ = (
|
||||
"id",
|
||||
"remaining_count",
|
||||
"star_count",
|
||||
"sticker",
|
||||
"total_count",
|
||||
"upgrade_star_count",
|
||||
)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
|
@ -67,6 +82,7 @@ class Gift(TelegramObject):
|
|||
star_count: int,
|
||||
total_count: Optional[int] = None,
|
||||
remaining_count: Optional[int] = None,
|
||||
upgrade_star_count: Optional[int] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
|
@ -76,6 +92,7 @@ class Gift(TelegramObject):
|
|||
self.star_count: int = star_count
|
||||
self.total_count: Optional[int] = total_count
|
||||
self.remaining_count: Optional[int] = remaining_count
|
||||
self.upgrade_star_count: Optional[int] = upgrade_star_count
|
||||
|
||||
self._id_attrs = (self.id,)
|
||||
|
||||
|
|
|
@ -23,7 +23,9 @@ from typing import TYPE_CHECKING, Optional
|
|||
from telegram._inline.inlinekeyboardmarkup import InlineKeyboardMarkup
|
||||
from telegram._inline.inlinequeryresult import InlineQueryResult
|
||||
from telegram._utils.types import JSONDict
|
||||
from telegram._utils.warnings import warn
|
||||
from telegram.constants import InlineQueryResultType
|
||||
from telegram.warnings import PTBDeprecationWarning
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from telegram import InputMessageContent
|
||||
|
@ -50,6 +52,10 @@ class InlineQueryResultArticle(InlineQueryResult):
|
|||
url (:obj:`str`, optional): URL of the result.
|
||||
hide_url (:obj:`bool`, optional): Pass :obj:`True`, if you don't want the URL to be shown
|
||||
in the message.
|
||||
|
||||
.. deprecated:: NEXT.VERSION
|
||||
This attribute will be removed in future PTB versions. Pass an empty string as URL
|
||||
instead.
|
||||
description (:obj:`str`, optional): Short description of the result.
|
||||
thumbnail_url (:obj:`str`, optional): Url of the thumbnail for the result.
|
||||
|
||||
|
@ -74,6 +80,10 @@ class InlineQueryResultArticle(InlineQueryResult):
|
|||
url (:obj:`str`): Optional. URL of the result.
|
||||
hide_url (:obj:`bool`): Optional. Pass :obj:`True`, if you don't want the URL to be shown
|
||||
in the message.
|
||||
|
||||
.. deprecated:: NEXT.VERSION
|
||||
This attribute will be removed in future PTB versions. Pass an empty string as URL
|
||||
instead.
|
||||
description (:obj:`str`): Optional. Short description of the result.
|
||||
thumbnail_url (:obj:`str`): Optional. Url of the thumbnail for the result.
|
||||
|
||||
|
@ -123,6 +133,15 @@ class InlineQueryResultArticle(InlineQueryResult):
|
|||
# Optional
|
||||
self.reply_markup: Optional[InlineKeyboardMarkup] = reply_markup
|
||||
self.url: Optional[str] = url
|
||||
if hide_url is not None:
|
||||
warn(
|
||||
PTBDeprecationWarning(
|
||||
"NEXT.VERSION",
|
||||
"The argument `hide_url` will be removed in future PTB"
|
||||
"versions. Pass an empty string as URL instead.",
|
||||
),
|
||||
stacklevel=2,
|
||||
)
|
||||
self.hide_url: Optional[bool] = hide_url
|
||||
self.description: Optional[str] = description
|
||||
self.thumbnail_url: Optional[str] = thumbnail_url
|
||||
|
|
|
@ -1653,6 +1653,7 @@ class User(TelegramObject):
|
|||
text: Optional[str] = None,
|
||||
text_parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
text_entities: Optional[Sequence["MessageEntity"]] = None,
|
||||
pay_for_upgrade: Optional[bool] = None,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
|
@ -1677,6 +1678,7 @@ class User(TelegramObject):
|
|||
text=text,
|
||||
text_parse_mode=text_parse_mode,
|
||||
text_entities=text_entities,
|
||||
pay_for_upgrade=pay_for_upgrade,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
|
@ -2270,3 +2272,65 @@ class User(TelegramObject):
|
|||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
async def verify(
|
||||
self,
|
||||
custom_description: 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,
|
||||
) -> bool:
|
||||
"""Shortcut for::
|
||||
|
||||
await bot.verify_user(user_id=update.effective_user.id, *args, **kwargs)
|
||||
|
||||
For the documentation of the arguments, please see
|
||||
:meth:`telegram.Bot.verify_user`.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
Returns:
|
||||
:obj:`bool`: On success, :obj:`True` is returned.
|
||||
"""
|
||||
return await self.get_bot().verify_user(
|
||||
user_id=self.id,
|
||||
custom_description=custom_description,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
async def remove_verification(
|
||||
self,
|
||||
*,
|
||||
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,
|
||||
) -> bool:
|
||||
"""Shortcut for::
|
||||
|
||||
await bot.remove_user_verification(user_id=update.effective_user.id, *args, **kwargs)
|
||||
|
||||
For the documentation of the arguments, please see
|
||||
:meth:`telegram.Bot.remove_user_verification`.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
Returns:
|
||||
:obj:`bool`: On success, :obj:`True` is returned.
|
||||
"""
|
||||
return await self.get_bot().remove_user_verification(
|
||||
user_id=self.id,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
|
|
@ -104,6 +104,7 @@ __all__ = [
|
|||
"TransactionPartnerType",
|
||||
"UpdateType",
|
||||
"UserProfilePhotosLimit",
|
||||
"VerifyLimit",
|
||||
"WebhookLimit",
|
||||
]
|
||||
|
||||
|
@ -154,7 +155,7 @@ class _AccentColor(NamedTuple):
|
|||
#: :data:`telegram.__bot_api_version_info__`.
|
||||
#:
|
||||
#: .. versionadded:: 20.0
|
||||
BOT_API_VERSION_INFO: Final[_BotAPIVersion] = _BotAPIVersion(major=8, minor=1)
|
||||
BOT_API_VERSION_INFO: Final[_BotAPIVersion] = _BotAPIVersion(major=8, minor=2)
|
||||
#: :obj:`str`: Telegram Bot API
|
||||
#: version supported by this version of `python-telegram-bot`. Also available as
|
||||
#: :data:`telegram.__bot_api_version__`.
|
||||
|
@ -3229,3 +3230,20 @@ class ReactionEmoji(StringEnum):
|
|||
""":obj:`str`: Woman Shrugging"""
|
||||
POUTING_FACE = "😡"
|
||||
""":obj:`str`: Pouting face"""
|
||||
|
||||
|
||||
class VerifyLimit(IntEnum):
|
||||
"""This enum contains limitations for :meth:`~telegram.Bot.verify_chat` and
|
||||
:meth:`~telegram.Bot.verify_user`.
|
||||
The enum members of this enumeration are instances of :class:`int` and can be treated as such.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
"""
|
||||
|
||||
__slots__ = ()
|
||||
|
||||
MAX_TEXT_LENGTH = 70
|
||||
""":obj:`int`: Maximum number of characters in a :obj:`str` passed as the
|
||||
:paramref:`~telegram.Bot.verify_chat.custom_description` or
|
||||
:paramref:`~telegram.Bot.verify_user.custom_description` parameter.
|
||||
"""
|
||||
|
|
|
@ -4465,6 +4465,7 @@ class ExtBot(Bot, Generic[RLARGS]):
|
|||
text: Optional[str] = None,
|
||||
text_parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
text_entities: Optional[Sequence["MessageEntity"]] = None,
|
||||
pay_for_upgrade: Optional[bool] = None,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
|
@ -4479,6 +4480,91 @@ class ExtBot(Bot, Generic[RLARGS]):
|
|||
text=text,
|
||||
text_parse_mode=text_parse_mode,
|
||||
text_entities=text_entities,
|
||||
pay_for_upgrade=pay_for_upgrade,
|
||||
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 verify_chat(
|
||||
self,
|
||||
chat_id: Union[int, str],
|
||||
custom_description: 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,
|
||||
) -> bool:
|
||||
return await super().verify_chat(
|
||||
chat_id=chat_id,
|
||||
custom_description=custom_description,
|
||||
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 verify_user(
|
||||
self,
|
||||
user_id: int,
|
||||
custom_description: 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,
|
||||
) -> bool:
|
||||
return await super().verify_user(
|
||||
user_id=user_id,
|
||||
custom_description=custom_description,
|
||||
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 remove_chat_verification(
|
||||
self,
|
||||
chat_id: Union[int, str],
|
||||
*,
|
||||
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,
|
||||
) -> bool:
|
||||
return await super().remove_chat_verification(
|
||||
chat_id=chat_id,
|
||||
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 remove_user_verification(
|
||||
self,
|
||||
user_id: int,
|
||||
*,
|
||||
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,
|
||||
) -> bool:
|
||||
return await super().remove_user_verification(
|
||||
user_id=user_id,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
|
@ -4617,3 +4703,7 @@ class ExtBot(Bot, Generic[RLARGS]):
|
|||
sendPaidMedia = send_paid_media
|
||||
getAvailableGifts = get_available_gifts
|
||||
sendGift = send_gift
|
||||
verifyChat = verify_chat
|
||||
verifyUser = verify_user
|
||||
removeChatVerification = remove_chat_verification
|
||||
removeUserVerification = remove_user_verification
|
||||
|
|
|
@ -28,6 +28,7 @@ from telegram import (
|
|||
InputTextMessageContent,
|
||||
)
|
||||
from telegram.constants import InlineQueryResultType
|
||||
from telegram.warnings import PTBDeprecationWarning
|
||||
from tests.auxil.slots import mro_slots
|
||||
|
||||
|
||||
|
@ -157,3 +158,31 @@ class TestInlineQueryResultArticleWithoutRequest(InlineQueryResultArticleTestBas
|
|||
|
||||
assert a != e
|
||||
assert hash(a) != hash(e)
|
||||
|
||||
def test_deprecation_warning_for_hide_url(self):
|
||||
with pytest.warns(PTBDeprecationWarning, match="The argument `hide_url`") as record:
|
||||
InlineQueryResultArticle(
|
||||
self.id_, self.title, self.input_message_content, hide_url=True
|
||||
)
|
||||
|
||||
assert record[0].filename == __file__, "wrong stacklevel!"
|
||||
|
||||
with pytest.warns(PTBDeprecationWarning, match="The argument `hide_url`") as record:
|
||||
InlineQueryResultArticle(
|
||||
self.id_, self.title, self.input_message_content, hide_url=False
|
||||
)
|
||||
|
||||
assert record[0].filename == __file__, "wrong stacklevel!"
|
||||
|
||||
assert (
|
||||
InlineQueryResultArticle(
|
||||
self.id_, self.title, self.input_message_content, hide_url=True
|
||||
).hide_url
|
||||
is True
|
||||
)
|
||||
assert (
|
||||
InlineQueryResultArticle(
|
||||
self.id_, self.title, self.input_message_content, hide_url=False
|
||||
).hide_url
|
||||
is False
|
||||
)
|
||||
|
|
|
@ -2386,6 +2386,48 @@ class TestBotWithoutRequest:
|
|||
4242, "emoji_status_custom_emoji_id", dtm.datetime(2024, 1, 1)
|
||||
)
|
||||
|
||||
async def test_verify_user(self, offline_bot, monkeypatch):
|
||||
"No way to test this without getting verified"
|
||||
|
||||
async def make_assertion(url, request_data: RequestData, *args, **kwargs):
|
||||
assert request_data.parameters.get("user_id") == 1234
|
||||
assert request_data.parameters.get("custom_description") == "this is so custom"
|
||||
|
||||
monkeypatch.setattr(offline_bot.request, "post", make_assertion)
|
||||
|
||||
await offline_bot.verify_user(1234, "this is so custom")
|
||||
|
||||
async def test_verify_chat(self, offline_bot, monkeypatch):
|
||||
"No way to test this without getting verified"
|
||||
|
||||
async def make_assertion(url, request_data: RequestData, *args, **kwargs):
|
||||
assert request_data.parameters.get("chat_id") == 1234
|
||||
assert request_data.parameters.get("custom_description") == "this is so custom"
|
||||
|
||||
monkeypatch.setattr(offline_bot.request, "post", make_assertion)
|
||||
|
||||
await offline_bot.verify_chat(1234, "this is so custom")
|
||||
|
||||
async def test_unverify_user(self, offline_bot, monkeypatch):
|
||||
"No way to test this without getting verified"
|
||||
|
||||
async def make_assertion(url, request_data: RequestData, *args, **kwargs):
|
||||
assert request_data.parameters.get("user_id") == 1234
|
||||
|
||||
monkeypatch.setattr(offline_bot.request, "post", make_assertion)
|
||||
|
||||
await offline_bot.remove_user_verification(1234)
|
||||
|
||||
async def test_unverify_chat(self, offline_bot, monkeypatch):
|
||||
"No way to test this without getting verified"
|
||||
|
||||
async def make_assertion(url, request_data: RequestData, *args, **kwargs):
|
||||
assert request_data.parameters.get("chat_id") == 1234
|
||||
|
||||
monkeypatch.setattr(offline_bot.request, "post", make_assertion)
|
||||
|
||||
await offline_bot.remove_chat_verification(1234)
|
||||
|
||||
|
||||
class TestBotWithRequest:
|
||||
"""
|
||||
|
|
|
@ -1333,6 +1333,37 @@ class TestChatWithoutRequest(ChatTestBase):
|
|||
text_entities="text_entities",
|
||||
)
|
||||
|
||||
async def test_instance_method_verify_chat(self, monkeypatch, chat):
|
||||
async def make_assertion(*_, **kwargs):
|
||||
return (
|
||||
kwargs["chat_id"] == chat.id
|
||||
and kwargs["custom_description"] == "This is a custom description"
|
||||
)
|
||||
|
||||
assert check_shortcut_signature(Chat.verify, Bot.verify_chat, ["chat_id"], [])
|
||||
assert await check_shortcut_call(chat.verify, chat.get_bot(), "verify_chat")
|
||||
assert await check_defaults_handling(chat.verify, chat.get_bot())
|
||||
|
||||
monkeypatch.setattr(chat.get_bot(), "verify_chat", make_assertion)
|
||||
assert await chat.verify(
|
||||
custom_description="This is a custom description",
|
||||
)
|
||||
|
||||
async def test_instance_method_remove_chat_verification(self, monkeypatch, chat):
|
||||
async def make_assertion(*_, **kwargs):
|
||||
return kwargs["chat_id"] == chat.id
|
||||
|
||||
assert check_shortcut_signature(
|
||||
Chat.remove_verification, Bot.remove_chat_verification, ["chat_id"], []
|
||||
)
|
||||
assert await check_shortcut_call(
|
||||
chat.remove_verification, chat.get_bot(), "remove_chat_verification"
|
||||
)
|
||||
assert await check_defaults_handling(chat.remove_verification, chat.get_bot())
|
||||
|
||||
monkeypatch.setattr(chat.get_bot(), "remove_chat_verification", make_assertion)
|
||||
assert await chat.remove_verification()
|
||||
|
||||
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"):
|
||||
|
|
|
@ -34,6 +34,7 @@ def gift(request):
|
|||
star_count=GiftTestBase.star_count,
|
||||
total_count=GiftTestBase.total_count,
|
||||
remaining_count=GiftTestBase.remaining_count,
|
||||
upgrade_star_count=GiftTestBase.upgrade_star_count,
|
||||
)
|
||||
|
||||
|
||||
|
@ -51,6 +52,7 @@ class GiftTestBase:
|
|||
star_count = 5
|
||||
total_count = 10
|
||||
remaining_count = 5
|
||||
upgrade_star_count = 10
|
||||
|
||||
|
||||
class TestGiftWithoutRequest(GiftTestBase):
|
||||
|
@ -66,6 +68,7 @@ class TestGiftWithoutRequest(GiftTestBase):
|
|||
"star_count": self.star_count,
|
||||
"total_count": self.total_count,
|
||||
"remaining_count": self.remaining_count,
|
||||
"upgrade_star_count": self.upgrade_star_count,
|
||||
}
|
||||
gift = Gift.de_json(json_dict, offline_bot)
|
||||
assert gift.api_kwargs == {}
|
||||
|
@ -75,6 +78,7 @@ class TestGiftWithoutRequest(GiftTestBase):
|
|||
assert gift.star_count == self.star_count
|
||||
assert gift.total_count == self.total_count
|
||||
assert gift.remaining_count == self.remaining_count
|
||||
assert gift.upgrade_star_count == self.upgrade_star_count
|
||||
|
||||
assert Gift.de_json(None, offline_bot) is None
|
||||
|
||||
|
@ -87,12 +91,25 @@ class TestGiftWithoutRequest(GiftTestBase):
|
|||
assert gift_dict["star_count"] == self.star_count
|
||||
assert gift_dict["total_count"] == self.total_count
|
||||
assert gift_dict["remaining_count"] == self.remaining_count
|
||||
assert gift_dict["upgrade_star_count"] == self.upgrade_star_count
|
||||
|
||||
def test_equality(self, gift):
|
||||
a = gift
|
||||
b = Gift(self.id, self.sticker, self.star_count, self.total_count, self.remaining_count)
|
||||
b = Gift(
|
||||
self.id,
|
||||
self.sticker,
|
||||
self.star_count,
|
||||
self.total_count,
|
||||
self.remaining_count,
|
||||
self.upgrade_star_count,
|
||||
)
|
||||
c = Gift(
|
||||
"other_uid", self.sticker, self.star_count, self.total_count, self.remaining_count
|
||||
"other_uid",
|
||||
self.sticker,
|
||||
self.star_count,
|
||||
self.total_count,
|
||||
self.remaining_count,
|
||||
self.upgrade_star_count,
|
||||
)
|
||||
d = BotCommand("start", "description")
|
||||
|
||||
|
@ -115,6 +132,7 @@ class TestGiftWithoutRequest(GiftTestBase):
|
|||
5,
|
||||
10,
|
||||
5,
|
||||
10,
|
||||
),
|
||||
],
|
||||
ids=["string", "Gift"],
|
||||
|
@ -134,11 +152,18 @@ class TestGiftWithoutRequest(GiftTestBase):
|
|||
tes = request_data.parameters["text_entities"] == [
|
||||
me.to_dict() for me in text_entities
|
||||
]
|
||||
return user_id and gift_id and text and text_parse_mode and tes
|
||||
pay_for_upgrade = request_data.parameters["pay_for_upgrade"] is True
|
||||
|
||||
return user_id and gift_id and text and text_parse_mode and tes and pay_for_upgrade
|
||||
|
||||
monkeypatch.setattr(offline_bot.request, "post", make_assertion)
|
||||
assert await offline_bot.send_gift(
|
||||
"user_id", gift, "text", text_parse_mode="text_parse_mode", text_entities=text_entities
|
||||
"user_id",
|
||||
gift,
|
||||
"text",
|
||||
text_parse_mode="text_parse_mode",
|
||||
text_entities=text_entities,
|
||||
pay_for_upgrade=True,
|
||||
)
|
||||
|
||||
@pytest.mark.parametrize("default_bot", [{"parse_mode": "Markdown"}], indirect=True)
|
||||
|
@ -184,6 +209,7 @@ class GiftsTestBase:
|
|||
star_count=5,
|
||||
total_count=5,
|
||||
remaining_count=5,
|
||||
upgrade_star_count=5,
|
||||
),
|
||||
Gift(
|
||||
id="id2",
|
||||
|
@ -199,6 +225,7 @@ class GiftsTestBase:
|
|||
star_count=6,
|
||||
total_count=6,
|
||||
remaining_count=6,
|
||||
upgrade_star_count=6,
|
||||
),
|
||||
Gift(
|
||||
id="id3",
|
||||
|
@ -214,6 +241,7 @@ class GiftsTestBase:
|
|||
star_count=7,
|
||||
total_count=7,
|
||||
remaining_count=7,
|
||||
upgrade_star_count=7,
|
||||
),
|
||||
]
|
||||
|
||||
|
@ -236,6 +264,7 @@ class TestGiftsWithoutRequest(GiftsTestBase):
|
|||
assert de_json_gift.star_count == original_gift.star_count
|
||||
assert de_json_gift.total_count == original_gift.total_count
|
||||
assert de_json_gift.remaining_count == original_gift.remaining_count
|
||||
assert de_json_gift.upgrade_star_count == original_gift.upgrade_star_count
|
||||
|
||||
assert Gifts.de_json(None, offline_bot) is None
|
||||
|
||||
|
|
|
@ -200,7 +200,8 @@ 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]] = {
|
||||
"send_invoice|create_invoice_link|InputInvoiceMessageContent": {"provider_token"}
|
||||
"send_invoice|create_invoice_link|InputInvoiceMessageContent": {"provider_token"},
|
||||
"InlineQueryResultArticle": {"hide_url"},
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -742,3 +742,34 @@ class TestUserWithoutRequest(UserTestBase):
|
|||
text_parse_mode="text_parse_mode",
|
||||
text_entities="text_entities",
|
||||
)
|
||||
|
||||
async def test_instance_method_verify_user(self, monkeypatch, user):
|
||||
async def make_assertion(*_, **kwargs):
|
||||
return (
|
||||
kwargs["user_id"] == user.id
|
||||
and kwargs["custom_description"] == "This is a custom description"
|
||||
)
|
||||
|
||||
assert check_shortcut_signature(user.verify, Bot.verify_user, ["user_id"], [])
|
||||
assert await check_shortcut_call(user.verify, user.get_bot(), "verify_user")
|
||||
assert await check_defaults_handling(user.verify, user.get_bot())
|
||||
|
||||
monkeypatch.setattr(user.get_bot(), "verify_user", make_assertion)
|
||||
assert await user.verify(
|
||||
custom_description="This is a custom description",
|
||||
)
|
||||
|
||||
async def test_instance_method_remove_user_verification(self, monkeypatch, user):
|
||||
async def make_assertion(*_, **kwargs):
|
||||
return kwargs["user_id"] == user.id
|
||||
|
||||
assert check_shortcut_signature(
|
||||
user.remove_verification, Bot.remove_user_verification, ["user_id"], []
|
||||
)
|
||||
assert await check_shortcut_call(
|
||||
user.remove_verification, user.get_bot(), "remove_user_verification"
|
||||
)
|
||||
assert await check_defaults_handling(user.remove_verification, user.get_bot())
|
||||
|
||||
monkeypatch.setattr(user.get_bot(), "remove_user_verification", make_assertion)
|
||||
assert await user.remove_verification()
|
||||
|
|
Loading…
Add table
Reference in a new issue