This commit is contained in:
Bibo-Joshi 2024-08-02 13:43:27 +02:00 committed by GitHub
parent a967dbe37a
commit 6578c76068
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 93 additions and 15 deletions

View file

@ -11,7 +11,7 @@
:target: https://pypi.org/project/python-telegram-bot/ :target: https://pypi.org/project/python-telegram-bot/
:alt: Supported Python versions :alt: Supported Python versions
.. image:: https://img.shields.io/badge/Bot%20API-7.7-blue?logo=telegram .. image:: https://img.shields.io/badge/Bot%20API-7.8-blue?logo=telegram
:target: https://core.telegram.org/bots/api-changelog :target: https://core.telegram.org/bots/api-changelog
:alt: Supported Bot API version :alt: Supported Bot API version
@ -81,7 +81,7 @@ After installing_ the library, be sure to check out the section on `working with
Telegram API support Telegram API support
~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~
All types and methods of the Telegram Bot API **7.7** are natively supported by this library. All types and methods of the Telegram Bot API **7.8** are natively supported by this library.
In addition, Bot API functionality not yet natively included can still be used as described `in our wiki <https://github.com/python-telegram-bot/python-telegram-bot/wiki/Bot-API-Forward-Compatibility>`_. In addition, Bot API functionality not yet natively included can still be used as described `in our wiki <https://github.com/python-telegram-bot/python-telegram-bot/wiki/Bot-API-Forward-Compatibility>`_.
Notable Features Notable Features

View file

@ -6131,6 +6131,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
chat_id: Union[str, int], chat_id: Union[str, int],
message_id: int, message_id: int,
disable_notification: ODVInput[bool] = DEFAULT_NONE, disable_notification: ODVInput[bool] = DEFAULT_NONE,
business_connection_id: Optional[str] = None,
*, *,
read_timeout: ODVInput[float] = DEFAULT_NONE, read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE, write_timeout: ODVInput[float] = DEFAULT_NONE,
@ -6151,6 +6152,10 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
disable_notification (:obj:`bool`, optional): Pass :obj:`True`, if it is not necessary disable_notification (:obj:`bool`, optional): Pass :obj:`True`, if it is not necessary
to send a notification to all chat members about the new pinned message. to send a notification to all chat members about the new pinned message.
Notifications are always disabled in channels and private chats. Notifications are always disabled in channels and private chats.
business_connection_id (:obj:`str`, optional): Unique identifier of the business
connection on behalf of which the message will be pinned.
.. versionadded:: NEXT.VERSION
Returns: Returns:
:obj:`bool`: On success, :obj:`True` is returned. :obj:`bool`: On success, :obj:`True` is returned.
@ -6163,6 +6168,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
"chat_id": chat_id, "chat_id": chat_id,
"message_id": message_id, "message_id": message_id,
"disable_notification": disable_notification, "disable_notification": disable_notification,
"business_connection_id": business_connection_id,
} }
return await self._post( return await self._post(
@ -6179,6 +6185,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
self, self,
chat_id: Union[str, int], chat_id: Union[str, int],
message_id: Optional[int] = None, message_id: Optional[int] = None,
business_connection_id: Optional[str] = None,
*, *,
read_timeout: ODVInput[float] = DEFAULT_NONE, read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE, write_timeout: ODVInput[float] = DEFAULT_NONE,
@ -6195,8 +6202,13 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
Args: Args:
chat_id (:obj:`int` | :obj:`str`): |chat_id_channel| chat_id (:obj:`int` | :obj:`str`): |chat_id_channel|
message_id (:obj:`int`, optional): Identifier of a message to unpin. If not specified, message_id (:obj:`int`, optional): Identifier of the message to unpin. Required if
:paramref:`business_connection_id` is specified. If not specified,
the most recent pinned message (by sending date) will be unpinned. the most recent pinned message (by sending date) will be unpinned.
business_connection_id (:obj:`str`, optional): Unique identifier of the business
connection on behalf of which the message will be unpinned.
.. versionadded:: NEXT.VERSION
Returns: Returns:
:obj:`bool`: On success, :obj:`True` is returned. :obj:`bool`: On success, :obj:`True` is returned.
@ -6205,7 +6217,11 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
:class:`telegram.error.TelegramError` :class:`telegram.error.TelegramError`
""" """
data: JSONDict = {"chat_id": chat_id, "message_id": message_id} data: JSONDict = {
"chat_id": chat_id,
"message_id": message_id,
"business_connection_id": business_connection_id,
}
return await self._post( return await self._post(
"unpinChatMessage", "unpinChatMessage",

View file

@ -905,6 +905,7 @@ class _ChatBase(TelegramObject):
self, self,
message_id: int, message_id: int,
disable_notification: ODVInput[bool] = DEFAULT_NONE, disable_notification: ODVInput[bool] = DEFAULT_NONE,
business_connection_id: Optional[str] = None,
*, *,
read_timeout: ODVInput[float] = DEFAULT_NONE, read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE, write_timeout: ODVInput[float] = DEFAULT_NONE,
@ -932,11 +933,13 @@ class _ChatBase(TelegramObject):
connect_timeout=connect_timeout, connect_timeout=connect_timeout,
pool_timeout=pool_timeout, pool_timeout=pool_timeout,
api_kwargs=api_kwargs, api_kwargs=api_kwargs,
business_connection_id=business_connection_id,
) )
async def unpin_message( async def unpin_message(
self, self,
message_id: Optional[int] = None, message_id: Optional[int] = None,
business_connection_id: Optional[str] = None,
*, *,
read_timeout: ODVInput[float] = DEFAULT_NONE, read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE, write_timeout: ODVInput[float] = DEFAULT_NONE,
@ -963,6 +966,7 @@ class _ChatBase(TelegramObject):
pool_timeout=pool_timeout, pool_timeout=pool_timeout,
api_kwargs=api_kwargs, api_kwargs=api_kwargs,
message_id=message_id, message_id=message_id,
business_connection_id=business_connection_id,
) )
async def unpin_all_messages( async def unpin_all_messages(

View file

@ -4106,11 +4106,18 @@ class Message(MaybeInaccessibleMessage):
"""Shortcut for:: """Shortcut for::
await bot.pin_chat_message( await bot.pin_chat_message(
chat_id=message.chat_id, message_id=message.message_id, *args, **kwargs chat_id=message.chat_id,
message_id=message.message_id,
business_connection_id=message.business_connection_id,
*args, **kwargs
) )
For the documentation of the arguments, please see :meth:`telegram.Bot.pin_chat_message`. For the documentation of the arguments, please see :meth:`telegram.Bot.pin_chat_message`.
.. versionchanged:: NEXT.VERSION
Now also passes :attr:`business_connection_id` to
:meth:`telegram.Bot.pin_chat_message`.
Returns: Returns:
:obj:`bool`: On success, :obj:`True` is returned. :obj:`bool`: On success, :obj:`True` is returned.
@ -4118,6 +4125,7 @@ class Message(MaybeInaccessibleMessage):
return await self.get_bot().pin_chat_message( return await self.get_bot().pin_chat_message(
chat_id=self.chat_id, chat_id=self.chat_id,
message_id=self.message_id, message_id=self.message_id,
business_connection_id=self.business_connection_id,
disable_notification=disable_notification, disable_notification=disable_notification,
read_timeout=read_timeout, read_timeout=read_timeout,
write_timeout=write_timeout, write_timeout=write_timeout,
@ -4138,11 +4146,18 @@ class Message(MaybeInaccessibleMessage):
"""Shortcut for:: """Shortcut for::
await bot.unpin_chat_message( await bot.unpin_chat_message(
chat_id=message.chat_id, message_id=message.message_id, *args, **kwargs chat_id=message.chat_id,
message_id=message.message_id,
business_connection_id=message.business_connection_id,
*args, **kwargs
) )
For the documentation of the arguments, please see :meth:`telegram.Bot.unpin_chat_message`. For the documentation of the arguments, please see :meth:`telegram.Bot.unpin_chat_message`.
.. versionchanged:: NEXT.VERSION
Now also passes :attr:`business_connection_id` to
:meth:`telegram.Bot.pin_chat_message`.
Returns: Returns:
:obj:`bool`: On success, :obj:`True` is returned. :obj:`bool`: On success, :obj:`True` is returned.
@ -4150,6 +4165,7 @@ class Message(MaybeInaccessibleMessage):
return await self.get_bot().unpin_chat_message( return await self.get_bot().unpin_chat_message(
chat_id=self.chat_id, chat_id=self.chat_id,
message_id=self.message_id, message_id=self.message_id,
business_connection_id=self.business_connection_id,
read_timeout=read_timeout, read_timeout=read_timeout,
write_timeout=write_timeout, write_timeout=write_timeout,
connect_timeout=connect_timeout, connect_timeout=connect_timeout,

View file

@ -97,6 +97,10 @@ class User(TelegramObject):
:meth:`telegram.Bot.get_me`. :meth:`telegram.Bot.get_me`.
.. versionadded:: 21.1 .. versionadded:: 21.1
has_main_web_app (:obj:`bool`, optional): :obj:`True`, if the bot has the main Web App.
Returned only in :meth:`telegram.Bot.get_me`.
.. versionadded:: NEXT.VERSION
Attributes: Attributes:
id (:obj:`int`): Unique identifier for this user or bot. id (:obj:`int`): Unique identifier for this user or bot.
@ -124,6 +128,11 @@ class User(TelegramObject):
:meth:`telegram.Bot.get_me`. :meth:`telegram.Bot.get_me`.
.. versionadded:: 21.1 .. versionadded:: 21.1
has_main_web_app (:obj:`bool`) Optional. :obj:`True`, if the bot has the main Web App.
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` .. |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 coincides with the :attr:`Chat.id` of the private chat with the user. This has been the
case so far, but Telegram does not guarantee that this stays this way. case so far, but Telegram does not guarantee that this stays this way.
@ -135,6 +144,7 @@ class User(TelegramObject):
"can_join_groups", "can_join_groups",
"can_read_all_group_messages", "can_read_all_group_messages",
"first_name", "first_name",
"has_main_web_app",
"id", "id",
"is_bot", "is_bot",
"is_premium", "is_premium",
@ -158,6 +168,7 @@ class User(TelegramObject):
is_premium: Optional[bool] = None, is_premium: Optional[bool] = None,
added_to_attachment_menu: Optional[bool] = None, added_to_attachment_menu: Optional[bool] = None,
can_connect_to_business: Optional[bool] = None, can_connect_to_business: Optional[bool] = None,
has_main_web_app: Optional[bool] = None,
*, *,
api_kwargs: Optional[JSONDict] = None, api_kwargs: Optional[JSONDict] = None,
): ):
@ -176,6 +187,7 @@ class User(TelegramObject):
self.is_premium: Optional[bool] = is_premium self.is_premium: Optional[bool] = is_premium
self.added_to_attachment_menu: Optional[bool] = added_to_attachment_menu self.added_to_attachment_menu: Optional[bool] = added_to_attachment_menu
self.can_connect_to_business: Optional[bool] = can_connect_to_business self.can_connect_to_business: Optional[bool] = can_connect_to_business
self.has_main_web_app: Optional[bool] = has_main_web_app
self._id_attrs = (self.id,) self._id_attrs = (self.id,)
@ -301,6 +313,7 @@ class User(TelegramObject):
self, self,
message_id: int, message_id: int,
disable_notification: ODVInput[bool] = DEFAULT_NONE, disable_notification: ODVInput[bool] = DEFAULT_NONE,
business_connection_id: Optional[str] = None,
*, *,
read_timeout: ODVInput[float] = DEFAULT_NONE, read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE, write_timeout: ODVInput[float] = DEFAULT_NONE,
@ -329,12 +342,14 @@ class User(TelegramObject):
write_timeout=write_timeout, write_timeout=write_timeout,
connect_timeout=connect_timeout, connect_timeout=connect_timeout,
pool_timeout=pool_timeout, pool_timeout=pool_timeout,
business_connection_id=business_connection_id,
api_kwargs=api_kwargs, api_kwargs=api_kwargs,
) )
async def unpin_message( async def unpin_message(
self, self,
message_id: Optional[int] = None, message_id: Optional[int] = None,
business_connection_id: Optional[str] = None,
*, *,
read_timeout: ODVInput[float] = DEFAULT_NONE, read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE, write_timeout: ODVInput[float] = DEFAULT_NONE,
@ -363,6 +378,7 @@ class User(TelegramObject):
pool_timeout=pool_timeout, pool_timeout=pool_timeout,
api_kwargs=api_kwargs, api_kwargs=api_kwargs,
message_id=message_id, message_id=message_id,
business_connection_id=business_connection_id,
) )
async def unpin_all_messages( async def unpin_all_messages(

View file

@ -151,7 +151,7 @@ class _AccentColor(NamedTuple):
#: :data:`telegram.__bot_api_version_info__`. #: :data:`telegram.__bot_api_version_info__`.
#: #:
#: .. versionadded:: 20.0 #: .. versionadded:: 20.0
BOT_API_VERSION_INFO: Final[_BotAPIVersion] = _BotAPIVersion(major=7, minor=7) BOT_API_VERSION_INFO: Final[_BotAPIVersion] = _BotAPIVersion(major=7, minor=8)
#: :obj:`str`: Telegram Bot API #: :obj:`str`: Telegram Bot API
#: version supported by this version of `python-telegram-bot`. Also available as #: version supported by this version of `python-telegram-bot`. Also available as
#: :data:`telegram.__bot_api_version__`. #: :data:`telegram.__bot_api_version__`.

View file

@ -2238,6 +2238,7 @@ class ExtBot(Bot, Generic[RLARGS]):
chat_id: Union[str, int], chat_id: Union[str, int],
message_id: int, message_id: int,
disable_notification: ODVInput[bool] = DEFAULT_NONE, disable_notification: ODVInput[bool] = DEFAULT_NONE,
business_connection_id: Optional[str] = None,
*, *,
read_timeout: ODVInput[float] = DEFAULT_NONE, read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE, write_timeout: ODVInput[float] = DEFAULT_NONE,
@ -2254,6 +2255,7 @@ class ExtBot(Bot, Generic[RLARGS]):
write_timeout=write_timeout, write_timeout=write_timeout,
connect_timeout=connect_timeout, connect_timeout=connect_timeout,
pool_timeout=pool_timeout, pool_timeout=pool_timeout,
business_connection_id=business_connection_id,
api_kwargs=self._merge_api_rl_kwargs(api_kwargs, rate_limit_args), api_kwargs=self._merge_api_rl_kwargs(api_kwargs, rate_limit_args),
) )
@ -3739,6 +3741,7 @@ class ExtBot(Bot, Generic[RLARGS]):
self, self,
chat_id: Union[str, int], chat_id: Union[str, int],
message_id: Optional[int] = None, message_id: Optional[int] = None,
business_connection_id: Optional[str] = None,
*, *,
read_timeout: ODVInput[float] = DEFAULT_NONE, read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE, write_timeout: ODVInput[float] = DEFAULT_NONE,
@ -3754,6 +3757,7 @@ class ExtBot(Bot, Generic[RLARGS]):
write_timeout=write_timeout, write_timeout=write_timeout,
connect_timeout=connect_timeout, connect_timeout=connect_timeout,
pool_timeout=pool_timeout, pool_timeout=pool_timeout,
business_connection_id=business_connection_id,
api_kwargs=self._merge_api_rl_kwargs(api_kwargs, rate_limit_args), api_kwargs=self._merge_api_rl_kwargs(api_kwargs, rate_limit_args),
) )

View file

@ -2207,6 +2207,8 @@ class TestBotWithoutRequest:
await bot.send_message(2, "text", business_connection_id=42) await bot.send_message(2, "text", business_connection_id=42)
await bot.stop_poll(chat_id=1, message_id=2, business_connection_id=42) await bot.stop_poll(chat_id=1, message_id=2, business_connection_id=42)
await bot.pin_chat_message(chat_id=1, message_id=2, business_connection_id=42)
await bot.unpin_chat_message(chat_id=1, business_connection_id=42)
async def test_message_effect_id_argument(self, bot, monkeypatch): async def test_message_effect_id_argument(self, bot, monkeypatch):
"""We can't test every single method easily, so we just test one. Our linting will catch """We can't test every single method easily, so we just test one. Our linting will catch

View file

@ -465,11 +465,14 @@ class TestCallbackQueryWithoutRequest(TestCallbackQueryBase):
assert check_shortcut_signature( assert check_shortcut_signature(
CallbackQuery.pin_message, CallbackQuery.pin_message,
Bot.pin_chat_message, Bot.pin_chat_message,
["message_id", "chat_id"], ["message_id", "chat_id", "business_connection_id"],
[], [],
) )
assert await check_shortcut_call( assert await check_shortcut_call(
callback_query.pin_message, callback_query.get_bot(), "pin_chat_message" callback_query.pin_message,
callback_query.get_bot(),
"pin_chat_message",
["business_connection_id"],
) )
assert await check_defaults_handling(callback_query.pin_message, callback_query.get_bot()) assert await check_defaults_handling(callback_query.pin_message, callback_query.get_bot())
@ -490,14 +493,15 @@ class TestCallbackQueryWithoutRequest(TestCallbackQueryBase):
assert check_shortcut_signature( assert check_shortcut_signature(
CallbackQuery.unpin_message, CallbackQuery.unpin_message,
Bot.unpin_chat_message, Bot.unpin_chat_message,
["message_id", "chat_id"], ["message_id", "chat_id", "business_connection_id"],
[], [],
) )
assert await check_shortcut_call( assert await check_shortcut_call(
callback_query.unpin_message, callback_query.unpin_message,
callback_query.get_bot(), callback_query.get_bot(),
"unpin_chat_message", "unpin_chat_message",
shortcut_kwargs=["message_id", "chat_id"], shortcut_kwargs=["message_id"],
skip_params=["business_connection_id"],
) )
assert await check_defaults_handling( assert await check_defaults_handling(
callback_query.unpin_message, callback_query.get_bot() callback_query.unpin_message, callback_query.get_bot()

View file

@ -2592,9 +2592,17 @@ class TestMessageWithoutRequest(TestMessageBase):
return chat_id and message_id return chat_id and message_id
assert check_shortcut_signature( assert check_shortcut_signature(
Message.pin, Bot.pin_chat_message, ["chat_id", "message_id"], [] Message.pin,
Bot.pin_chat_message,
["chat_id", "message_id", "business_connection_id"],
[],
)
assert await check_shortcut_call(
message.pin,
message.get_bot(),
"pin_chat_message",
shortcut_kwargs=["chat_id", "message_id", "business_connection_id"],
) )
assert await check_shortcut_call(message.pin, message.get_bot(), "pin_chat_message")
assert await check_defaults_handling(message.pin, message.get_bot()) assert await check_defaults_handling(message.pin, message.get_bot())
monkeypatch.setattr(message.get_bot(), "pin_chat_message", make_assertion) monkeypatch.setattr(message.get_bot(), "pin_chat_message", make_assertion)
@ -2607,13 +2615,16 @@ class TestMessageWithoutRequest(TestMessageBase):
return chat_id and message_id return chat_id and message_id
assert check_shortcut_signature( assert check_shortcut_signature(
Message.unpin, Bot.unpin_chat_message, ["chat_id", "message_id"], [] Message.unpin,
Bot.unpin_chat_message,
["chat_id", "message_id", "business_connection_id"],
[],
) )
assert await check_shortcut_call( assert await check_shortcut_call(
message.unpin, message.unpin,
message.get_bot(), message.get_bot(),
"unpin_chat_message", "unpin_chat_message",
shortcut_kwargs=["chat_id", "message_id"], shortcut_kwargs=["chat_id", "message_id", "business_connection_id"],
) )
assert await check_defaults_handling(message.unpin, message.get_bot()) assert await check_defaults_handling(message.unpin, message.get_bot())

View file

@ -43,6 +43,7 @@ def json_dict():
"is_premium": TestUserBase.is_premium, "is_premium": TestUserBase.is_premium,
"added_to_attachment_menu": TestUserBase.added_to_attachment_menu, "added_to_attachment_menu": TestUserBase.added_to_attachment_menu,
"can_connect_to_business": TestUserBase.can_connect_to_business, "can_connect_to_business": TestUserBase.can_connect_to_business,
"has_main_web_app": TestUserBase.has_main_web_app,
} }
@ -61,6 +62,7 @@ def user(bot):
is_premium=TestUserBase.is_premium, is_premium=TestUserBase.is_premium,
added_to_attachment_menu=TestUserBase.added_to_attachment_menu, added_to_attachment_menu=TestUserBase.added_to_attachment_menu,
can_connect_to_business=TestUserBase.can_connect_to_business, can_connect_to_business=TestUserBase.can_connect_to_business,
has_main_web_app=TestUserBase.has_main_web_app,
) )
user.set_bot(bot) user.set_bot(bot)
user._unfreeze() user._unfreeze()
@ -80,6 +82,7 @@ class TestUserBase:
is_premium = True is_premium = True
added_to_attachment_menu = False added_to_attachment_menu = False
can_connect_to_business = True can_connect_to_business = True
has_main_web_app = False
class TestUserWithoutRequest(TestUserBase): class TestUserWithoutRequest(TestUserBase):
@ -104,6 +107,7 @@ class TestUserWithoutRequest(TestUserBase):
assert user.is_premium == self.is_premium assert user.is_premium == self.is_premium
assert user.added_to_attachment_menu == self.added_to_attachment_menu assert user.added_to_attachment_menu == self.added_to_attachment_menu
assert user.can_connect_to_business == self.can_connect_to_business assert user.can_connect_to_business == self.can_connect_to_business
assert user.has_main_web_app == self.has_main_web_app
def test_to_dict(self, user): def test_to_dict(self, user):
user_dict = user.to_dict() user_dict = user.to_dict()
@ -121,6 +125,7 @@ class TestUserWithoutRequest(TestUserBase):
assert user_dict["is_premium"] == user.is_premium assert user_dict["is_premium"] == user.is_premium
assert user_dict["added_to_attachment_menu"] == user.added_to_attachment_menu 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["can_connect_to_business"] == user.can_connect_to_business
assert user_dict["has_main_web_app"] == user.has_main_web_app
def test_equality(self): def test_equality(self):
a = User(self.id_, self.first_name, self.is_bot, self.last_name) a = User(self.id_, self.first_name, self.is_bot, self.last_name)