Add ButtonCallback.get_message (#4250)

This commit is contained in:
apepenkov 2023-11-11 21:29:42 +03:00 committed by GitHub
parent ea65bf001e
commit 70fb266eea
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 62 additions and 3 deletions

View File

@ -1,6 +1,6 @@
from __future__ import annotations from __future__ import annotations
from typing import TYPE_CHECKING, List, Optional, Sequence from typing import TYPE_CHECKING, List, Optional, Sequence, Union
from ...mtproto import RpcError from ...mtproto import RpcError
from ...session import PackedChat, PackedType from ...session import PackedChat, PackedType
@ -117,7 +117,7 @@ async def get_chats(self: Client, chats: Sequence[ChatLike]) -> List[Chat]:
] ]
async def resolve_to_packed(client: Client, chat: ChatLike) -> PackedChat: async def resolve_to_packed(client: Client, chat: Union[ChatLike, abcs.InputPeer, abcs.Peer]) -> PackedChat:
if isinstance(chat, PackedChat): if isinstance(chat, PackedChat):
return chat return chat
@ -172,6 +172,31 @@ async def resolve_to_packed(client: Client, chat: ChatLike) -> PackedChat:
else: else:
raise RuntimeError("unexpected case") raise RuntimeError("unexpected case")
if isinstance(chat, abcs.Peer):
packed = client._chat_hashes.get(peer_id(chat))
if packed is not None:
return packed
if isinstance(chat, types.PeerUser):
return PackedChat(
ty=PackedType.USER,
id=chat.user_id,
access_hash=0,
)
elif isinstance(chat, types.PeerChat):
return PackedChat(
ty=PackedType.CHAT,
id=chat.chat_id,
access_hash=0,
)
elif isinstance(chat, types.PeerChannel):
return PackedChat(
ty=PackedType.BROADCAST,
id=chat.channel_id,
access_hash=0,
)
else:
raise RuntimeError("unexpected case")
if isinstance(chat, str): if isinstance(chat, str):
if chat.startswith("+"): if chat.startswith("+"):
resolved = await resolve_phone(client, chat) resolved = await resolve_phone(client, chat)

View File

@ -3,8 +3,10 @@ from __future__ import annotations
from typing import TYPE_CHECKING, Dict, Optional, Self from typing import TYPE_CHECKING, Dict, Optional, Self
from ...tl import abcs, functions, types from ...tl import abcs, functions, types
from ..types import Chat from ..types import Chat, Message
from .event import Event from .event import Event
from ..types.chat import peer_id
from ..client.messages import CherryPickedList
if TYPE_CHECKING: if TYPE_CHECKING:
from ..client.client import Client from ..client.client import Client
@ -69,6 +71,25 @@ class ButtonCallback(Event):
) )
) )
async def get_message(self) -> Optional[Message]:
"""
Get the :class:`~telethon.types.Message` containing the button that was clicked.
If the message is too old and is no longer accessible, :data:`None` is returned instead.
"""
pid = peer_id(self._raw.peer)
chat = self._chat_map.get(pid)
if not chat:
chat = await self._client._resolve_to_packed(pid)
lst = CherryPickedList(self._client, chat, [])
lst._ids.append(types.InputMessageCallbackQuery(id=self._raw.msg_id, query_id=self._raw.query_id))
message = (await lst)[0]
return message or None
class InlineQuery(Event): class InlineQuery(Event):
""" """

View File

@ -45,6 +45,16 @@ class Message(metaclass=NoPublicConstructor):
You can get a message from :class:`telethon.events.NewMessage`, You can get a message from :class:`telethon.events.NewMessage`,
or from methods such as :meth:`telethon.Client.get_messages`. or from methods such as :meth:`telethon.Client.get_messages`.
Empty messages can occur very rarely when fetching the message history.
In these cases, only the :attr:`id` and :attr`peer` properties are guaranteed to be present.
To determine whether a message is empty, its truthy value can be checked via :meth:`object.__bool__`:
.. code-block:: python
async for message in client.iter_messages(chat):
if not message:
print('Found empty message with ID', message.id)
""" """
def __init__( def __init__(
@ -487,6 +497,9 @@ class Message(metaclass=NoPublicConstructor):
else: else:
return False return False
def __bool__(self):
return not isinstance(self._raw, types.MessageEmpty)
def build_msg_map( def build_msg_map(
client: Client, messages: List[abcs.Message], chat_map: Dict[int, Chat] client: Client, messages: List[abcs.Message], chat_map: Dict[int, Chat]