Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions changes/unreleased/5229.87PBN4GFkuAaDhhgFwCYkY.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
features = "Full Support for Bot API 10.0"
[[pull_requests]]
uid = "5229"
author_uids = ["aelkheir"]
closes_threads = []
highlights = "Full Support for Bot API 10.0"

pull_requests = [
{ uid = "5229", author_uid = "aelkheir", closes_threads = ["5228"] },
{ uid = "5230", author_uid = "harshil21" },
]
4 changes: 4 additions & 0 deletions docs/source/inclusions/bot_methods.rst
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,10 @@
- Used for stopping the running poll
* - :meth:`~telegram.Bot.set_message_reaction`
- Used for setting reactions on messages
* - :meth:`~telegram.Bot.delete_message_reaction`
- Used for deleting reactions on messages
* - :meth:`~telegram.Bot.delete_all_message_reactions`
- Used for deleting all reactions by a chat or user

.. raw:: html

Expand Down
116 changes: 112 additions & 4 deletions src/telegram/_bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -5125,6 +5125,7 @@ async def get_chat(
async def get_chat_administrators(
self,
chat_id: str | int,
return_bots: bool | None = None,
*,
read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE,
Expand All @@ -5140,18 +5141,21 @@ async def get_chat_administrators(

Args:
chat_id (:obj:`int` | :obj:`str`): |chat_id_channel|
return_bots (:obj:`bool`, optional): Pass :obj:`True` to additionally receive all bots
that are administrators of the chat. By default, bots other than the current bot
are omitted.

.. versionadded:: NEXT.VERSION

Returns:
tuple[:class:`telegram.ChatMember`]: On success, returns a tuple of ``ChatMember``
objects that contains information about all chat administrators except
other bots. If the chat is a group or a supergroup and no administrators were
appointed, only the creator will be returned.
objects that contains information about all chat administrators.

Raises:
:class:`telegram.error.TelegramError`

"""
data: JSONDict = {"chat_id": chat_id}
data: JSONDict = {"chat_id": chat_id, "return_bots": return_bots}
result = await self._post(
"getChatAdministrators",
data,
Expand Down Expand Up @@ -12283,6 +12287,106 @@ async def save_prepared_keyboard_button(
self,
)

async def delete_message_reaction(
self,
chat_id: int | str,
message_id: int,
user_id: int | None = None,
actor_chat_id: int | None = None,
*,
read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE,
connect_timeout: ODVInput[float] = DEFAULT_NONE,
pool_timeout: ODVInput[float] = DEFAULT_NONE,
api_kwargs: JSONDict | None = None,
) -> bool:
"""
Use this method to remove a reaction from a message in a group or a supergroup chat.
The bot must have the :attr:`~telegram.ChatMemberAdministrator.can_delete_messages`
administrator right in the chat.

.. versionadded:: NEXT.VERSION

Args:
chat_id (:obj:`int` | :obj:`str`): |chat_id_group|
message_id (:obj:`int`): Identifier of the target message.
user_id (:obj:`int`, optional): Identifier of the user whose reaction will be removed,
if the reaction were added by a user.
actor_chat_id (:obj:`int`, optional): Identifier of the chat whose reaction will be
removed, if the reaction were added by a chat.

Returns:
:obj:`bool`: On success, :obj:`True` is returned.

Raises:
:class:`telegram.error.TelegramError`
"""
data: JSONDict = {
"chat_id": chat_id,
"message_id": message_id,
"user_id": user_id,
"actor_chat_id": actor_chat_id,
}

return await self._post(
"deleteMessageReaction",
data,
read_timeout=read_timeout,
write_timeout=write_timeout,
connect_timeout=connect_timeout,
pool_timeout=pool_timeout,
api_kwargs=api_kwargs,
)

async def delete_all_message_reactions(
self,
chat_id: int | str,
user_id: int | None = None,
actor_chat_id: int | None = None,
*,
read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE,
connect_timeout: ODVInput[float] = DEFAULT_NONE,
pool_timeout: ODVInput[float] = DEFAULT_NONE,
api_kwargs: JSONDict | None = None,
) -> bool:
"""
Use this method to remove up to ``10000`` recent reactions in a group or a supergroup chat
added by a given user or chat. The bot must have the
:attr:`~telegram.ChatMemberAdministrator.can_delete_messages` administrator right in the
chat.

.. versionadded:: NEXT.VERSION

Args:
chat_id (:obj:`int` | :obj:`str`): |chat_id_group|
user_id (:obj:`int`, optional): Identifier of the user whose reactions will be removed,
if the reactions were added by a user.
actor_chat_id (:obj:`int`, optional): Identifier of the chat whose reactions will be
removed, if the reactions were added by a chat.

Returns:
:obj:`bool`: On success, :obj:`True` is returned.

Raises:
:class:`telegram.error.TelegramError`
"""
data: JSONDict = {
"chat_id": chat_id,
"user_id": user_id,
"actor_chat_id": actor_chat_id,
}

return await self._post(
"deleteAllMessageReactions",
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}
Expand Down Expand Up @@ -12629,3 +12733,7 @@ def to_dict(self, recursive: bool = True) -> JSONDict: # noqa: ARG002
"""Alias for :meth:`replace_managed_bot_token`"""
savePreparedKeyboardButton = save_prepared_keyboard_button
"""Alias for :meth:`save_prepared_keyboard_button`"""
deleteMessageReaction = delete_message_reaction
"""Alias for :meth:`delete_message_reaction`"""
deleteAllMessageReactions = delete_all_message_reactions
"""Alias for :meth:`delete_all_message_reactions`"""
78 changes: 78 additions & 0 deletions src/telegram/_chat.py
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,7 @@ async def leave(

async def get_administrators(
self,
return_bots: bool | None = None,
Comment thread
harshil21 marked this conversation as resolved.
*,
read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE,
Expand All @@ -334,6 +335,7 @@ async def get_administrators(
"""
return await self.get_bot().get_chat_administrators(
chat_id=self.id,
return_bots=return_bots,
read_timeout=read_timeout,
write_timeout=write_timeout,
connect_timeout=connect_timeout,
Expand Down Expand Up @@ -4049,6 +4051,82 @@ async def set_chat_member_tag(
api_kwargs=api_kwargs,
)

async def delete_reaction(
self,
message_id: int,
user_id: int | None = None,
actor_chat_id: int | None = None,
*,
read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE,
connect_timeout: ODVInput[float] = DEFAULT_NONE,
pool_timeout: ODVInput[float] = DEFAULT_NONE,
api_kwargs: JSONDict | None = None,
) -> bool:
"""
Shortcut for::

await bot.delete_message_reaction(chat_id=update.effective_chat.id, *args, **kwargs)

For the documentation of the arguments, please see
:meth:`telegram.Bot.delete_message_reaction`.

.. versionadded:: NEXT.VERSION

Returns:
:obj:`bool`: On success, :obj:`True` is returned.
"""
return await self.get_bot().delete_message_reaction(
chat_id=self.id,
message_id=message_id,
user_id=user_id,
actor_chat_id=actor_chat_id,
read_timeout=read_timeout,
write_timeout=write_timeout,
connect_timeout=connect_timeout,
pool_timeout=pool_timeout,
api_kwargs=api_kwargs,
)

async def delete_all_reactions(
self,
user_id: int | None = None,
actor_chat_id: int | None = None,
*,
read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE,
connect_timeout: ODVInput[float] = DEFAULT_NONE,
pool_timeout: ODVInput[float] = DEFAULT_NONE,
api_kwargs: JSONDict | None = None,
) -> bool:
"""
Shortcut for::

await bot.delete_all_message_reactions(
chat_id=update.effective_chat.id,
*args,
**kwargs
)

For the documentation of the arguments, please see
:meth:`telegram.Bot.delete_all_message_reactions`.

.. versionadded:: NEXT.VERSION

Returns:
:obj:`bool`: On success, :obj:`True` is returned.
"""
return await self.get_bot().delete_all_message_reactions(
chat_id=self.id,
user_id=user_id,
actor_chat_id=actor_chat_id,
read_timeout=read_timeout,
write_timeout=write_timeout,
connect_timeout=connect_timeout,
pool_timeout=pool_timeout,
api_kwargs=api_kwargs,
)


class Chat(_ChatBase):
"""This object represents a chat.
Expand Down
16 changes: 16 additions & 0 deletions src/telegram/_chatmember.py
Original file line number Diff line number Diff line change
Expand Up @@ -517,6 +517,10 @@ class ChatMemberRestricted(ChatMember):
can_edit_tag (:obj:`bool`): :obj:`True`, if the user is allowed to edit their own tag.

.. versionadded:: 22.7
can_react_to_messages (:obj:`bool`): :obj:`True`, if the user is allowed to react to
messages.

.. versionadded:: NEXT.VERSION
tag (:obj:`str`, optional): Tag of the member.

.. versionadded:: 22.7
Expand Down Expand Up @@ -573,6 +577,10 @@ class ChatMemberRestricted(ChatMember):
can_edit_tag (:obj:`bool`): :obj:`True`, if the user is allowed to edit their own tag.

.. versionadded:: 22.7
can_react_to_messages (:obj:`bool`): :obj:`True`, if the user is allowed to react to
messages.

.. versionadded:: NEXT.VERSION
tag (:obj:`str`): Optional. Tag of the member.

.. versionadded:: 22.7
Expand All @@ -586,6 +594,7 @@ class ChatMemberRestricted(ChatMember):
"can_invite_users",
"can_manage_topics",
"can_pin_messages",
"can_react_to_messages",
"can_send_audios",
"can_send_documents",
"can_send_messages",
Expand Down Expand Up @@ -621,6 +630,9 @@ def __init__(
can_send_voice_notes: bool,
can_edit_tag: bool,
tag: str | None = None,
# tags: NEXT.VERSION
# temporarily optional to make it not breaking
Comment thread
harshil21 marked this conversation as resolved.
can_react_to_messages: bool | None = None,
*,
api_kwargs: JSONDict | None = None,
):
Expand All @@ -643,8 +655,12 @@ def __init__(
self.can_send_video_notes: bool = can_send_video_notes
self.can_send_voice_notes: bool = can_send_voice_notes
self.can_edit_tag: bool = can_edit_tag
self.can_react_to_messages: bool | None = can_react_to_messages
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
self.can_react_to_messages: bool | None = can_react_to_messages
self.can_react_to_messages: bool = can_react_to_messages

and raising TypeError when missing

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that change might break the type completeness CI, I'll add the TypeError though

self.tag: str | None = tag

if self.can_react_to_messages is None:
raise TypeError("`can_react_to_messages` is required and cannot be None")


class ChatMemberLeft(ChatMember):
"""
Expand Down
17 changes: 16 additions & 1 deletion src/telegram/_chatpermissions.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class ChatPermissions(TelegramObject):
:attr:`can_change_info`, :attr:`can_invite_users`, :attr:`can_pin_messages`,
:attr:`can_send_audios`, :attr:`can_send_documents`, :attr:`can_send_photos`,
:attr:`can_send_videos`, :attr:`can_send_video_notes`, :attr:`can_send_voice_notes`,
:attr:`can_manage_topics` and :attr:`can_edit_tag` are equal.
:attr:`can_manage_topics`, :attr:`can_edit_tag`, and :attr:`can_react_to_messages` are equal.

.. versionchanged:: 20.0
:attr:`can_manage_topics` is considered as well when comparing objects of
Expand All @@ -50,6 +50,9 @@ class ChatPermissions(TelegramObject):
.. versionchanged:: 22.7
:attr:`can_edit_tag` is considered as well when comparing objects of
this type in terms of equality.
.. versionchanged:: NEXT.VERSION
:attr:`can_react_to_messages` is considered as well when comparing objects of
this type in terms of equality.


Note:
Expand Down Expand Up @@ -100,6 +103,10 @@ class ChatPermissions(TelegramObject):
tag.

.. versionadded:: 22.7
can_react_to_messages (:obj:`bool`, optional): :obj:`True`, if the user is allowed to react
to messages. If omitted, defaults to the value of :attr:`can_send_messages`.

.. versionadded:: NEXT.VERSION

Attributes:
can_send_messages (:obj:`bool`): Optional. :obj:`True`, if the user is allowed to send text
Expand Down Expand Up @@ -145,6 +152,10 @@ class ChatPermissions(TelegramObject):
tag.

.. versionadded:: 22.7
can_react_to_messages (:obj:`bool`): Optional. :obj:`True`, if the user is allowed to react
to messages. If omitted, defaults to the value of :attr:`can_send_messages`.

.. versionadded:: NEXT.VERSION

"""

Expand All @@ -155,6 +166,7 @@ class ChatPermissions(TelegramObject):
"can_invite_users",
"can_manage_topics",
"can_pin_messages",
"can_react_to_messages",
"can_send_audios",
"can_send_documents",
"can_send_messages",
Expand Down Expand Up @@ -183,6 +195,7 @@ def __init__(
can_send_video_notes: bool | None = None,
can_send_voice_notes: bool | None = None,
can_edit_tag: bool | None = None,
can_react_to_messages: bool | None = None,
*,
api_kwargs: JSONDict | None = None,
):
Expand All @@ -203,6 +216,7 @@ def __init__(
self.can_send_video_notes: bool | None = can_send_video_notes
self.can_send_voice_notes: bool | None = can_send_voice_notes
self.can_edit_tag: bool | None = can_edit_tag
self.can_react_to_messages: bool | None = can_react_to_messages

self._id_attrs = (
self.can_send_messages,
Expand All @@ -220,6 +234,7 @@ def __init__(
self.can_send_video_notes,
self.can_send_voice_notes,
self.can_edit_tag,
self.can_react_to_messages,
)

self._freeze()
Expand Down
Loading
Loading