mirror of
https://github.com/LonamiWebs/Telethon.git
synced 2024-11-25 02:43:45 +03:00
Use custom type for Keyboard and rename filter type (#4436)
This commit is contained in:
parent
ee3248c3a4
commit
babeba46d3
|
@ -23,7 +23,7 @@ from ...session import (
|
||||||
)
|
)
|
||||||
from ...tl import Request, abcs
|
from ...tl import Request, abcs
|
||||||
from ..events import Event
|
from ..events import Event
|
||||||
from ..events.filters import Filter
|
from ..events.filters import FilterType
|
||||||
from ..types import (
|
from ..types import (
|
||||||
AdminRight,
|
AdminRight,
|
||||||
AlbumBuilder,
|
AlbumBuilder,
|
||||||
|
@ -36,6 +36,7 @@ from ..types import (
|
||||||
Group,
|
Group,
|
||||||
InFileLike,
|
InFileLike,
|
||||||
InlineResult,
|
InlineResult,
|
||||||
|
KeyboardType,
|
||||||
LoginToken,
|
LoginToken,
|
||||||
Message,
|
Message,
|
||||||
OutFileLike,
|
OutFileLike,
|
||||||
|
@ -45,7 +46,6 @@ from ..types import (
|
||||||
RecentAction,
|
RecentAction,
|
||||||
User,
|
User,
|
||||||
)
|
)
|
||||||
from ..types import buttons as btns
|
|
||||||
from .auth import (
|
from .auth import (
|
||||||
bot_sign_in,
|
bot_sign_in,
|
||||||
check_password,
|
check_password,
|
||||||
|
@ -216,6 +216,7 @@ class Client:
|
||||||
datacenter: Optional[DataCenter] = None,
|
datacenter: Optional[DataCenter] = None,
|
||||||
connector: Optional[Connector] = None,
|
connector: Optional[Connector] = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
|
assert isinstance(__package__, str)
|
||||||
base_logger = logger or logging.getLogger(__package__[: __package__.index(".")])
|
base_logger = logger or logging.getLogger(__package__[: __package__.index(".")])
|
||||||
|
|
||||||
self._sender: Optional[Sender] = None
|
self._sender: Optional[Sender] = None
|
||||||
|
@ -251,12 +252,13 @@ class Client:
|
||||||
self._message_box = MessageBox(base_logger=base_logger)
|
self._message_box = MessageBox(base_logger=base_logger)
|
||||||
self._chat_hashes = ChatHashCache(None)
|
self._chat_hashes = ChatHashCache(None)
|
||||||
self._last_update_limit_warn: Optional[float] = None
|
self._last_update_limit_warn: Optional[float] = None
|
||||||
self._updates: asyncio.Queue[
|
self._updates: asyncio.Queue[tuple[abcs.Update, dict[int, Peer]]] = (
|
||||||
tuple[abcs.Update, dict[int, Peer]]
|
asyncio.Queue(maxsize=self._config.update_queue_limit or 0)
|
||||||
] = asyncio.Queue(maxsize=self._config.update_queue_limit or 0)
|
)
|
||||||
self._dispatcher: Optional[asyncio.Task[None]] = None
|
self._dispatcher: Optional[asyncio.Task[None]] = None
|
||||||
self._handlers: dict[
|
self._handlers: dict[
|
||||||
Type[Event], list[tuple[Callable[[Any], Awaitable[Any]], Optional[Filter]]]
|
Type[Event],
|
||||||
|
list[tuple[Callable[[Any], Awaitable[Any]], Optional[FilterType]]],
|
||||||
] = {}
|
] = {}
|
||||||
self._check_all_handlers = check_all_handlers
|
self._check_all_handlers = check_all_handlers
|
||||||
|
|
||||||
|
@ -270,7 +272,7 @@ class Client:
|
||||||
handler: Callable[[AnyEvent], Awaitable[Any]],
|
handler: Callable[[AnyEvent], Awaitable[Any]],
|
||||||
/,
|
/,
|
||||||
event_cls: Type[AnyEvent],
|
event_cls: Type[AnyEvent],
|
||||||
filter: Optional[Filter] = None,
|
filter: Optional[FilterType] = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""
|
"""
|
||||||
Register a callable to be invoked when the provided event type occurs.
|
Register a callable to be invoked when the provided event type occurs.
|
||||||
|
@ -571,7 +573,7 @@ class Client:
|
||||||
markdown: Optional[str] = None,
|
markdown: Optional[str] = None,
|
||||||
html: Optional[str] = None,
|
html: Optional[str] = None,
|
||||||
link_preview: bool = False,
|
link_preview: bool = False,
|
||||||
buttons: Optional[list[btns.Button] | list[list[btns.Button]]] = None,
|
keyboard: Optional[KeyboardType] = None,
|
||||||
) -> Message:
|
) -> Message:
|
||||||
"""
|
"""
|
||||||
Edit a message.
|
Edit a message.
|
||||||
|
@ -586,10 +588,10 @@ class Client:
|
||||||
:param markdown: See :ref:`formatting`.
|
:param markdown: See :ref:`formatting`.
|
||||||
:param html: See :ref:`formatting`.
|
:param html: See :ref:`formatting`.
|
||||||
:param link_preview: See :ref:`formatting`.
|
:param link_preview: See :ref:`formatting`.
|
||||||
:param buttons:
|
:param keyboard:
|
||||||
The buttons to use for the message.
|
The keyboard to use for the message.
|
||||||
|
|
||||||
Only bot accounts can send buttons.
|
Only bot accounts can send keyboard.
|
||||||
|
|
||||||
:return: The edited message.
|
:return: The edited message.
|
||||||
|
|
||||||
|
@ -615,7 +617,7 @@ class Client:
|
||||||
markdown=markdown,
|
markdown=markdown,
|
||||||
html=html,
|
html=html,
|
||||||
link_preview=link_preview,
|
link_preview=link_preview,
|
||||||
buttons=buttons,
|
keyboard=keyboard,
|
||||||
)
|
)
|
||||||
|
|
||||||
async def forward_messages(
|
async def forward_messages(
|
||||||
|
@ -759,7 +761,7 @@ class Client:
|
||||||
|
|
||||||
def get_handler_filter(
|
def get_handler_filter(
|
||||||
self, handler: Callable[[AnyEvent], Awaitable[Any]], /
|
self, handler: Callable[[AnyEvent], Awaitable[Any]], /
|
||||||
) -> Optional[Filter]:
|
) -> Optional[FilterType]:
|
||||||
"""
|
"""
|
||||||
Get the filter associated to the given event handler.
|
Get the filter associated to the given event handler.
|
||||||
|
|
||||||
|
@ -1034,7 +1036,7 @@ class Client:
|
||||||
return await is_authorized(self)
|
return await is_authorized(self)
|
||||||
|
|
||||||
def on(
|
def on(
|
||||||
self, event_cls: Type[AnyEvent], /, filter: Optional[Filter] = None
|
self, event_cls: Type[AnyEvent], /, filter: Optional[FilterType] = None
|
||||||
) -> Callable[
|
) -> Callable[
|
||||||
[Callable[[AnyEvent], Awaitable[Any]]], Callable[[AnyEvent], Awaitable[Any]]
|
[Callable[[AnyEvent], Awaitable[Any]]], Callable[[AnyEvent], Awaitable[Any]]
|
||||||
]:
|
]:
|
||||||
|
@ -1393,7 +1395,7 @@ class Client:
|
||||||
caption_markdown: Optional[str] = None,
|
caption_markdown: Optional[str] = None,
|
||||||
caption_html: Optional[str] = None,
|
caption_html: Optional[str] = None,
|
||||||
reply_to: Optional[int] = None,
|
reply_to: Optional[int] = None,
|
||||||
buttons: Optional[list[btns.Button] | list[list[btns.Button]]] = None,
|
keyboard: Optional[KeyboardType] = None,
|
||||||
) -> Message:
|
) -> Message:
|
||||||
"""
|
"""
|
||||||
Send an audio file.
|
Send an audio file.
|
||||||
|
@ -1437,7 +1439,7 @@ class Client:
|
||||||
caption_markdown=caption_markdown,
|
caption_markdown=caption_markdown,
|
||||||
caption_html=caption_html,
|
caption_html=caption_html,
|
||||||
reply_to=reply_to,
|
reply_to=reply_to,
|
||||||
buttons=buttons,
|
keyboard=keyboard,
|
||||||
)
|
)
|
||||||
|
|
||||||
async def send_file(
|
async def send_file(
|
||||||
|
@ -1466,7 +1468,7 @@ class Client:
|
||||||
caption_markdown: Optional[str] = None,
|
caption_markdown: Optional[str] = None,
|
||||||
caption_html: Optional[str] = None,
|
caption_html: Optional[str] = None,
|
||||||
reply_to: Optional[int] = None,
|
reply_to: Optional[int] = None,
|
||||||
buttons: Optional[list[btns.Button] | list[list[btns.Button]]],
|
keyboard: Optional[KeyboardType],
|
||||||
) -> Message:
|
) -> Message:
|
||||||
"""
|
"""
|
||||||
Send any type of file with any amount of attributes.
|
Send any type of file with any amount of attributes.
|
||||||
|
@ -1620,7 +1622,7 @@ class Client:
|
||||||
caption_markdown=caption_markdown,
|
caption_markdown=caption_markdown,
|
||||||
caption_html=caption_html,
|
caption_html=caption_html,
|
||||||
reply_to=reply_to,
|
reply_to=reply_to,
|
||||||
buttons=buttons,
|
keyboard=keyboard,
|
||||||
)
|
)
|
||||||
|
|
||||||
async def send_message(
|
async def send_message(
|
||||||
|
@ -1633,7 +1635,7 @@ class Client:
|
||||||
html: Optional[str] = None,
|
html: Optional[str] = None,
|
||||||
link_preview: bool = False,
|
link_preview: bool = False,
|
||||||
reply_to: Optional[int] = None,
|
reply_to: Optional[int] = None,
|
||||||
buttons: Optional[list[btns.Button] | list[list[btns.Button]]] = None,
|
keyboard: Optional[KeyboardType] = None,
|
||||||
) -> Message:
|
) -> Message:
|
||||||
"""
|
"""
|
||||||
Send a message.
|
Send a message.
|
||||||
|
@ -1649,10 +1651,10 @@ class Client:
|
||||||
:param reply_to:
|
:param reply_to:
|
||||||
The message identifier of the message to reply to.
|
The message identifier of the message to reply to.
|
||||||
|
|
||||||
:param buttons:
|
:param keyboard:
|
||||||
The buttons to use for the message.
|
The keyboard to use for the message.
|
||||||
|
|
||||||
Only bot accounts can send buttons.
|
Only bot accounts can send keyboard.
|
||||||
|
|
||||||
.. rubric:: Example
|
.. rubric:: Example
|
||||||
|
|
||||||
|
@ -1668,7 +1670,7 @@ class Client:
|
||||||
html=html,
|
html=html,
|
||||||
link_preview=link_preview,
|
link_preview=link_preview,
|
||||||
reply_to=reply_to,
|
reply_to=reply_to,
|
||||||
buttons=buttons,
|
keyboard=keyboard,
|
||||||
)
|
)
|
||||||
|
|
||||||
async def send_photo(
|
async def send_photo(
|
||||||
|
@ -1687,7 +1689,7 @@ class Client:
|
||||||
caption_markdown: Optional[str] = None,
|
caption_markdown: Optional[str] = None,
|
||||||
caption_html: Optional[str] = None,
|
caption_html: Optional[str] = None,
|
||||||
reply_to: Optional[int] = None,
|
reply_to: Optional[int] = None,
|
||||||
buttons: Optional[list[btns.Button] | list[list[btns.Button]]] = None,
|
keyboard: Optional[KeyboardType] = None,
|
||||||
) -> Message:
|
) -> Message:
|
||||||
"""
|
"""
|
||||||
Send a photo file.
|
Send a photo file.
|
||||||
|
@ -1733,7 +1735,7 @@ class Client:
|
||||||
caption_markdown=caption_markdown,
|
caption_markdown=caption_markdown,
|
||||||
caption_html=caption_html,
|
caption_html=caption_html,
|
||||||
reply_to=reply_to,
|
reply_to=reply_to,
|
||||||
buttons=buttons,
|
keyboard=keyboard,
|
||||||
)
|
)
|
||||||
|
|
||||||
async def send_video(
|
async def send_video(
|
||||||
|
@ -1755,7 +1757,7 @@ class Client:
|
||||||
caption_markdown: Optional[str] = None,
|
caption_markdown: Optional[str] = None,
|
||||||
caption_html: Optional[str] = None,
|
caption_html: Optional[str] = None,
|
||||||
reply_to: Optional[int] = None,
|
reply_to: Optional[int] = None,
|
||||||
buttons: Optional[list[btns.Button] | list[list[btns.Button]]],
|
keyboard: Optional[KeyboardType],
|
||||||
) -> Message:
|
) -> Message:
|
||||||
"""
|
"""
|
||||||
Send a video file.
|
Send a video file.
|
||||||
|
@ -1802,7 +1804,7 @@ class Client:
|
||||||
caption_markdown=caption_markdown,
|
caption_markdown=caption_markdown,
|
||||||
caption_html=caption_html,
|
caption_html=caption_html,
|
||||||
reply_to=reply_to,
|
reply_to=reply_to,
|
||||||
buttons=buttons,
|
keyboard=keyboard,
|
||||||
)
|
)
|
||||||
|
|
||||||
async def set_chat_default_restrictions(
|
async def set_chat_default_restrictions(
|
||||||
|
@ -1851,7 +1853,7 @@ class Client:
|
||||||
self,
|
self,
|
||||||
handler: Callable[[AnyEvent], Awaitable[Any]],
|
handler: Callable[[AnyEvent], Awaitable[Any]],
|
||||||
/,
|
/,
|
||||||
filter: Optional[Filter] = None,
|
filter: Optional[FilterType] = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""
|
"""
|
||||||
Set the filter to use for the given event handler.
|
Set the filter to use for the given event handler.
|
||||||
|
|
|
@ -13,13 +13,11 @@ from ..types import (
|
||||||
AsyncList,
|
AsyncList,
|
||||||
File,
|
File,
|
||||||
InFileLike,
|
InFileLike,
|
||||||
|
KeyboardType,
|
||||||
Message,
|
Message,
|
||||||
OutFileLike,
|
OutFileLike,
|
||||||
OutWrapper,
|
OutWrapper,
|
||||||
Peer,
|
Peer,
|
||||||
)
|
|
||||||
from ..types import buttons as btns
|
|
||||||
from ..types import (
|
|
||||||
expand_stripped_size,
|
expand_stripped_size,
|
||||||
generate_random_id,
|
generate_random_id,
|
||||||
parse_message,
|
parse_message,
|
||||||
|
@ -59,7 +57,7 @@ async def send_photo(
|
||||||
caption_markdown: Optional[str] = None,
|
caption_markdown: Optional[str] = None,
|
||||||
caption_html: Optional[str] = None,
|
caption_html: Optional[str] = None,
|
||||||
reply_to: Optional[int] = None,
|
reply_to: Optional[int] = None,
|
||||||
buttons: Optional[list[btns.Button] | list[list[btns.Button]]] = None,
|
keyboard: Optional[KeyboardType] = None,
|
||||||
) -> Message:
|
) -> Message:
|
||||||
return await send_file(
|
return await send_file(
|
||||||
self,
|
self,
|
||||||
|
@ -79,7 +77,7 @@ async def send_photo(
|
||||||
caption_markdown=caption_markdown,
|
caption_markdown=caption_markdown,
|
||||||
caption_html=caption_html,
|
caption_html=caption_html,
|
||||||
reply_to=reply_to,
|
reply_to=reply_to,
|
||||||
buttons=buttons,
|
keyboard=keyboard,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -100,7 +98,7 @@ async def send_audio(
|
||||||
caption_markdown: Optional[str] = None,
|
caption_markdown: Optional[str] = None,
|
||||||
caption_html: Optional[str] = None,
|
caption_html: Optional[str] = None,
|
||||||
reply_to: Optional[int] = None,
|
reply_to: Optional[int] = None,
|
||||||
buttons: Optional[list[btns.Button] | list[list[btns.Button]]] = None,
|
keyboard: Optional[KeyboardType] = None,
|
||||||
) -> Message:
|
) -> Message:
|
||||||
return await send_file(
|
return await send_file(
|
||||||
self,
|
self,
|
||||||
|
@ -117,7 +115,7 @@ async def send_audio(
|
||||||
caption_markdown=caption_markdown,
|
caption_markdown=caption_markdown,
|
||||||
caption_html=caption_html,
|
caption_html=caption_html,
|
||||||
reply_to=reply_to,
|
reply_to=reply_to,
|
||||||
buttons=buttons,
|
keyboard=keyboard,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -140,7 +138,7 @@ async def send_video(
|
||||||
caption_markdown: Optional[str] = None,
|
caption_markdown: Optional[str] = None,
|
||||||
caption_html: Optional[str] = None,
|
caption_html: Optional[str] = None,
|
||||||
reply_to: Optional[int] = None,
|
reply_to: Optional[int] = None,
|
||||||
buttons: Optional[list[btns.Button] | list[list[btns.Button]]],
|
keyboard: Optional[KeyboardType],
|
||||||
) -> Message:
|
) -> Message:
|
||||||
return await send_file(
|
return await send_file(
|
||||||
self,
|
self,
|
||||||
|
@ -159,7 +157,7 @@ async def send_video(
|
||||||
caption_markdown=caption_markdown,
|
caption_markdown=caption_markdown,
|
||||||
caption_html=caption_html,
|
caption_html=caption_html,
|
||||||
reply_to=reply_to,
|
reply_to=reply_to,
|
||||||
buttons=buttons,
|
keyboard=keyboard,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -189,7 +187,7 @@ async def send_file(
|
||||||
caption_markdown: Optional[str] = None,
|
caption_markdown: Optional[str] = None,
|
||||||
caption_html: Optional[str] = None,
|
caption_html: Optional[str] = None,
|
||||||
reply_to: Optional[int] = None,
|
reply_to: Optional[int] = None,
|
||||||
buttons: Optional[list[btns.Button] | list[list[btns.Button]]],
|
keyboard: Optional[KeyboardType],
|
||||||
) -> Message:
|
) -> Message:
|
||||||
message, entities = parse_message(
|
message, entities = parse_message(
|
||||||
text=caption, markdown=caption_markdown, html=caption_html, allow_empty=True
|
text=caption, markdown=caption_markdown, html=caption_html, allow_empty=True
|
||||||
|
@ -198,7 +196,7 @@ async def send_file(
|
||||||
# Re-send existing file.
|
# Re-send existing file.
|
||||||
if isinstance(file, File):
|
if isinstance(file, File):
|
||||||
return await do_send_file(
|
return await do_send_file(
|
||||||
self, chat, file._input_media, message, entities, reply_to, buttons
|
self, chat, file._input_media, message, entities, reply_to, keyboard
|
||||||
)
|
)
|
||||||
|
|
||||||
# URLs are handled early as they can't use any other attributes either.
|
# URLs are handled early as they can't use any other attributes either.
|
||||||
|
@ -222,7 +220,7 @@ async def send_file(
|
||||||
spoiler=False, url=file, ttl_seconds=None
|
spoiler=False, url=file, ttl_seconds=None
|
||||||
)
|
)
|
||||||
return await do_send_file(
|
return await do_send_file(
|
||||||
self, chat, input_media, message, entities, reply_to, buttons
|
self, chat, input_media, message, entities, reply_to, keyboard
|
||||||
)
|
)
|
||||||
|
|
||||||
input_file, name = await upload(self, file, size, name)
|
input_file, name = await upload(self, file, size, name)
|
||||||
|
@ -288,7 +286,7 @@ async def send_file(
|
||||||
)
|
)
|
||||||
|
|
||||||
return await do_send_file(
|
return await do_send_file(
|
||||||
self, chat, input_media, message, entities, reply_to, buttons
|
self, chat, input_media, message, entities, reply_to, keyboard
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -299,7 +297,7 @@ async def do_send_file(
|
||||||
message: str,
|
message: str,
|
||||||
entities: Optional[list[abcs.MessageEntity]],
|
entities: Optional[list[abcs.MessageEntity]],
|
||||||
reply_to: Optional[int],
|
reply_to: Optional[int],
|
||||||
buttons: Optional[list[btns.Button] | list[list[btns.Button]]],
|
keyboard: Optional[KeyboardType],
|
||||||
) -> Message:
|
) -> Message:
|
||||||
random_id = generate_random_id()
|
random_id = generate_random_id()
|
||||||
return client._build_message_map(
|
return client._build_message_map(
|
||||||
|
@ -319,7 +317,7 @@ async def do_send_file(
|
||||||
media=input_media,
|
media=input_media,
|
||||||
message=message,
|
message=message,
|
||||||
random_id=random_id,
|
random_id=random_id,
|
||||||
reply_markup=btns.build_keyboard(buttons),
|
reply_markup=keyboard._raw if keyboard else None,
|
||||||
entities=entities,
|
entities=entities,
|
||||||
schedule_date=None,
|
schedule_date=None,
|
||||||
send_as=None,
|
send_as=None,
|
||||||
|
|
|
@ -6,9 +6,16 @@ from typing import TYPE_CHECKING, Literal, Optional, Self
|
||||||
|
|
||||||
from ...session import ChannelRef, PeerRef
|
from ...session import ChannelRef, PeerRef
|
||||||
from ...tl import abcs, functions, types
|
from ...tl import abcs, functions, types
|
||||||
from ..types import AsyncList, Message, Peer, build_chat_map
|
from ..types import (
|
||||||
from ..types import buttons as btns
|
AsyncList,
|
||||||
from ..types import generate_random_id, parse_message, peer_id
|
KeyboardType,
|
||||||
|
Message,
|
||||||
|
Peer,
|
||||||
|
build_chat_map,
|
||||||
|
generate_random_id,
|
||||||
|
parse_message,
|
||||||
|
peer_id,
|
||||||
|
)
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from .client import Client
|
from .client import Client
|
||||||
|
@ -24,7 +31,7 @@ async def send_message(
|
||||||
html: Optional[str] = None,
|
html: Optional[str] = None,
|
||||||
link_preview: bool = False,
|
link_preview: bool = False,
|
||||||
reply_to: Optional[int] = None,
|
reply_to: Optional[int] = None,
|
||||||
buttons: Optional[list[btns.Button] | list[list[btns.Button]]] = None,
|
keyboard: Optional[KeyboardType] = None,
|
||||||
) -> Message:
|
) -> Message:
|
||||||
random_id = generate_random_id()
|
random_id = generate_random_id()
|
||||||
|
|
||||||
|
@ -71,7 +78,7 @@ async def send_message(
|
||||||
),
|
),
|
||||||
message=message,
|
message=message,
|
||||||
random_id=random_id,
|
random_id=random_id,
|
||||||
reply_markup=btns.build_keyboard(buttons),
|
reply_markup=keyboard._raw if keyboard else None,
|
||||||
entities=entities,
|
entities=entities,
|
||||||
schedule_date=None,
|
schedule_date=None,
|
||||||
send_as=None,
|
send_as=None,
|
||||||
|
@ -121,7 +128,7 @@ async def edit_message(
|
||||||
markdown: Optional[str] = None,
|
markdown: Optional[str] = None,
|
||||||
html: Optional[str] = None,
|
html: Optional[str] = None,
|
||||||
link_preview: bool = False,
|
link_preview: bool = False,
|
||||||
buttons: Optional[list[btns.Button] | list[list[btns.Button]]] = None,
|
keyboard: Optional[KeyboardType] = None,
|
||||||
) -> Message:
|
) -> Message:
|
||||||
message, entities = parse_message(
|
message, entities = parse_message(
|
||||||
text=text, markdown=markdown, html=html, allow_empty=False
|
text=text, markdown=markdown, html=html, allow_empty=False
|
||||||
|
@ -134,7 +141,7 @@ async def edit_message(
|
||||||
id=message_id,
|
id=message_id,
|
||||||
message=message,
|
message=message,
|
||||||
media=None,
|
media=None,
|
||||||
reply_markup=btns.build_keyboard(buttons),
|
reply_markup=keyboard._raw if keyboard else None,
|
||||||
entities=entities,
|
entities=entities,
|
||||||
schedule_date=None,
|
schedule_date=None,
|
||||||
)
|
)
|
||||||
|
|
|
@ -9,7 +9,7 @@ from ...session import Gap
|
||||||
from ...tl import abcs
|
from ...tl import abcs
|
||||||
from ..events import Continue
|
from ..events import Continue
|
||||||
from ..events import Event as EventBase
|
from ..events import Event as EventBase
|
||||||
from ..events.filters import Filter
|
from ..events.filters import FilterType
|
||||||
from ..types import build_chat_map
|
from ..types import build_chat_map
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
|
@ -21,7 +21,7 @@ UPDATE_LIMIT_EXCEEDED_LOG_COOLDOWN = 300
|
||||||
|
|
||||||
|
|
||||||
def on(
|
def on(
|
||||||
self: Client, event_cls: Type[Event], /, filter: Optional[Filter] = None
|
self: Client, event_cls: Type[Event], /, filter: Optional[FilterType] = None
|
||||||
) -> Callable[[Callable[[Event], Awaitable[Any]]], Callable[[Event], Awaitable[Any]]]:
|
) -> Callable[[Callable[[Event], Awaitable[Any]]], Callable[[Event], Awaitable[Any]]]:
|
||||||
def wrapper(
|
def wrapper(
|
||||||
handler: Callable[[Event], Awaitable[Any]],
|
handler: Callable[[Event], Awaitable[Any]],
|
||||||
|
@ -37,7 +37,7 @@ def add_event_handler(
|
||||||
handler: Callable[[Event], Awaitable[Any]],
|
handler: Callable[[Event], Awaitable[Any]],
|
||||||
/,
|
/,
|
||||||
event_cls: Type[Event],
|
event_cls: Type[Event],
|
||||||
filter: Optional[Filter] = None,
|
filter: Optional[FilterType] = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
self._handlers.setdefault(event_cls, []).append((handler, filter))
|
self._handlers.setdefault(event_cls, []).append((handler, filter))
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ def remove_event_handler(
|
||||||
|
|
||||||
def get_handler_filter(
|
def get_handler_filter(
|
||||||
self: Client, handler: Callable[[Event], Awaitable[Any]], /
|
self: Client, handler: Callable[[Event], Awaitable[Any]], /
|
||||||
) -> Optional[Filter]:
|
) -> Optional[FilterType]:
|
||||||
for handlers in self._handlers.values():
|
for handlers in self._handlers.values():
|
||||||
for h, f in handlers:
|
for h, f in handlers:
|
||||||
if h == handler:
|
if h == handler:
|
||||||
|
@ -67,7 +67,7 @@ def set_handler_filter(
|
||||||
self: Client,
|
self: Client,
|
||||||
handler: Callable[[Event], Awaitable[Any]],
|
handler: Callable[[Event], Awaitable[Any]],
|
||||||
/,
|
/,
|
||||||
filter: Optional[Filter] = None,
|
filter: Optional[FilterType] = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
for handlers in self._handlers.values():
|
for handlers in self._handlers.values():
|
||||||
for i, (h, _) in enumerate(handlers):
|
for i, (h, _) in enumerate(handlers):
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
from .callback import Data
|
from .callback import Data
|
||||||
from .combinators import All, Any, Filter, Not
|
from .combinators import All, Any, FilterType, Not
|
||||||
from .common import Chats, ChatType, Senders
|
from .common import Chats, ChatType, Senders
|
||||||
from .messages import Command, Forward, Incoming, Media, Outgoing, Reply, Text
|
from .messages import Command, Forward, Incoming, Media, Outgoing, Reply, Text
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
"All",
|
"All",
|
||||||
"Any",
|
"Any",
|
||||||
"Filter",
|
"FilterType",
|
||||||
"Not",
|
"Not",
|
||||||
"Chats",
|
"Chats",
|
||||||
"ChatType",
|
"ChatType",
|
||||||
|
|
|
@ -6,7 +6,7 @@ from typing import Awaitable, TypeAlias
|
||||||
|
|
||||||
from ..event import Event
|
from ..event import Event
|
||||||
|
|
||||||
Filter: TypeAlias = Callable[[Event], bool | Awaitable[bool]]
|
FilterType: TypeAlias = Callable[[Event], bool | Awaitable[bool]]
|
||||||
|
|
||||||
|
|
||||||
class Combinable(abc.ABC):
|
class Combinable(abc.ABC):
|
||||||
|
@ -22,7 +22,7 @@ class Combinable(abc.ABC):
|
||||||
Multiple ``~`` will toggle between using :class:`Not` and not using it.
|
Multiple ``~`` will toggle between using :class:`Not` and not using it.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __or__(self, other: typing.Any) -> Filter:
|
def __or__(self, other: typing.Any) -> FilterType:
|
||||||
if not callable(other):
|
if not callable(other):
|
||||||
return NotImplemented
|
return NotImplemented
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ class Combinable(abc.ABC):
|
||||||
rhs = other.filters if isinstance(other, Any) else (other,)
|
rhs = other.filters if isinstance(other, Any) else (other,)
|
||||||
return Any(*lhs, *rhs) # type: ignore [arg-type]
|
return Any(*lhs, *rhs) # type: ignore [arg-type]
|
||||||
|
|
||||||
def __and__(self, other: typing.Any) -> Filter:
|
def __and__(self, other: typing.Any) -> FilterType:
|
||||||
if not callable(other):
|
if not callable(other):
|
||||||
return NotImplemented
|
return NotImplemented
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ class Combinable(abc.ABC):
|
||||||
rhs = other.filters if isinstance(other, All) else (other,)
|
rhs = other.filters if isinstance(other, All) else (other,)
|
||||||
return All(*lhs, *rhs) # type: ignore [arg-type]
|
return All(*lhs, *rhs) # type: ignore [arg-type]
|
||||||
|
|
||||||
def __invert__(self) -> Filter:
|
def __invert__(self) -> FilterType:
|
||||||
return self.filter if isinstance(self, Not) else Not(self) # type: ignore [return-value]
|
return self.filter if isinstance(self, Not) else Not(self) # type: ignore [return-value]
|
||||||
|
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
|
@ -72,11 +72,13 @@ class Any(Combinable):
|
||||||
|
|
||||||
__slots__ = ("_filters",)
|
__slots__ = ("_filters",)
|
||||||
|
|
||||||
def __init__(self, filter1: Filter, filter2: Filter, *filters: Filter) -> None:
|
def __init__(
|
||||||
|
self, filter1: FilterType, filter2: FilterType, *filters: FilterType
|
||||||
|
) -> None:
|
||||||
self._filters = (filter1, filter2, *filters)
|
self._filters = (filter1, filter2, *filters)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def filters(self) -> tuple[Filter, ...]:
|
def filters(self) -> tuple[FilterType, ...]:
|
||||||
"""
|
"""
|
||||||
The filters being checked, in order.
|
The filters being checked, in order.
|
||||||
"""
|
"""
|
||||||
|
@ -116,11 +118,13 @@ class All(Combinable):
|
||||||
|
|
||||||
__slots__ = ("_filters",)
|
__slots__ = ("_filters",)
|
||||||
|
|
||||||
def __init__(self, filter1: Filter, filter2: Filter, *filters: Filter) -> None:
|
def __init__(
|
||||||
|
self, filter1: FilterType, filter2: FilterType, *filters: FilterType
|
||||||
|
) -> None:
|
||||||
self._filters = (filter1, filter2, *filters)
|
self._filters = (filter1, filter2, *filters)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def filters(self) -> tuple[Filter, ...]:
|
def filters(self) -> tuple[FilterType, ...]:
|
||||||
"""
|
"""
|
||||||
The filters being checked, in order.
|
The filters being checked, in order.
|
||||||
"""
|
"""
|
||||||
|
@ -158,11 +162,11 @@ class Not(Combinable):
|
||||||
|
|
||||||
__slots__ = ("_filter",)
|
__slots__ = ("_filter",)
|
||||||
|
|
||||||
def __init__(self, filter: Filter) -> None:
|
def __init__(self, filter: FilterType) -> None:
|
||||||
self._filter = filter
|
self._filter = filter
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def filter(self) -> Filter:
|
def filter(self) -> FilterType:
|
||||||
"""
|
"""
|
||||||
The filter being negated.
|
The filter being negated.
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -14,6 +14,7 @@ from .file import (
|
||||||
try_get_url_path,
|
try_get_url_path,
|
||||||
)
|
)
|
||||||
from .inline_result import InlineResult
|
from .inline_result import InlineResult
|
||||||
|
from .keyboard import InlineKeyboard, Keyboard, KeyboardType
|
||||||
from .login_token import LoginToken
|
from .login_token import LoginToken
|
||||||
from .message import (
|
from .message import (
|
||||||
Message,
|
Message,
|
||||||
|
@ -60,4 +61,7 @@ __all__ = [
|
||||||
"Participant",
|
"Participant",
|
||||||
"PasswordToken",
|
"PasswordToken",
|
||||||
"RecentAction",
|
"RecentAction",
|
||||||
|
"Keyboard",
|
||||||
|
"InlineKeyboard",
|
||||||
|
"KeyboardType",
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import weakref
|
import weakref
|
||||||
from typing import TYPE_CHECKING, Optional
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
from ....tl import abcs, types
|
from ....tl import abcs, types
|
||||||
from .button import Button
|
from .button import Button
|
||||||
|
@ -18,45 +18,6 @@ if TYPE_CHECKING:
|
||||||
from ..message import Message
|
from ..message import Message
|
||||||
|
|
||||||
|
|
||||||
def as_concrete_row(row: abcs.KeyboardButtonRow) -> types.KeyboardButtonRow:
|
|
||||||
assert isinstance(row, types.KeyboardButtonRow)
|
|
||||||
return row
|
|
||||||
|
|
||||||
|
|
||||||
def build_keyboard(
|
|
||||||
btns: Optional[list[Button] | list[list[Button]]],
|
|
||||||
) -> Optional[abcs.ReplyMarkup]:
|
|
||||||
# list[button] -> list[list[button]]
|
|
||||||
# This does allow for "invalid" inputs (mixing lists and non-lists), but that's acceptable.
|
|
||||||
buttons_lists_iter = (
|
|
||||||
button if isinstance(button, list) else [button] for button in (btns or [])
|
|
||||||
)
|
|
||||||
# Remove empty rows (also making it easy to check if all-empty).
|
|
||||||
buttons_lists = [bs for bs in buttons_lists_iter if bs]
|
|
||||||
|
|
||||||
if not buttons_lists:
|
|
||||||
return None
|
|
||||||
|
|
||||||
rows: list[abcs.KeyboardButtonRow] = [
|
|
||||||
types.KeyboardButtonRow(buttons=[btn._raw for btn in btns])
|
|
||||||
for btns in buttons_lists
|
|
||||||
]
|
|
||||||
|
|
||||||
# Guaranteed to have at least one, first one used to check if it's inline.
|
|
||||||
# If the user mixed inline with non-inline, Telegram will complain.
|
|
||||||
if isinstance(buttons_lists[0][0], InlineButton):
|
|
||||||
return types.ReplyInlineMarkup(rows=rows)
|
|
||||||
else:
|
|
||||||
return types.ReplyKeyboardMarkup(
|
|
||||||
resize=False,
|
|
||||||
single_use=False,
|
|
||||||
selective=False,
|
|
||||||
persistent=False,
|
|
||||||
rows=rows,
|
|
||||||
placeholder=None,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def create_button(message: Message, raw: abcs.KeyboardButton) -> Button:
|
def create_button(message: Message, raw: abcs.KeyboardButton) -> Button:
|
||||||
"""
|
"""
|
||||||
Create a custom button from a Telegram button.
|
Create a custom button from a Telegram button.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import weakref
|
import weakref
|
||||||
from typing import TYPE_CHECKING, Optional
|
from typing import TYPE_CHECKING, Optional, TypeAlias
|
||||||
|
|
||||||
from ....tl import types
|
from ....tl import types
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ if TYPE_CHECKING:
|
||||||
from ..message import Message
|
from ..message import Message
|
||||||
|
|
||||||
|
|
||||||
ButtonTypes = (
|
RawButtonType: TypeAlias = (
|
||||||
types.KeyboardButton
|
types.KeyboardButton
|
||||||
| types.KeyboardButtonUrl
|
| types.KeyboardButtonUrl
|
||||||
| types.KeyboardButtonCallback
|
| types.KeyboardButtonCallback
|
||||||
|
@ -53,7 +53,7 @@ class Button:
|
||||||
f"Can't instantiate abstract class {self.__class__.__name__}"
|
f"Can't instantiate abstract class {self.__class__.__name__}"
|
||||||
)
|
)
|
||||||
|
|
||||||
self._raw: ButtonTypes = types.KeyboardButton(text=text)
|
self._raw: RawButtonType = types.KeyboardButton(text=text)
|
||||||
self._msg: Optional[weakref.ReferenceType[Message]] = None
|
self._msg: Optional[weakref.ReferenceType[Message]] = None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|
53
client/src/telethon/_impl/client/types/keyboard.py
Normal file
53
client/src/telethon/_impl/client/types/keyboard.py
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
from typing import Optional, TypeAlias
|
||||||
|
|
||||||
|
from ...tl import abcs, types
|
||||||
|
from .buttons.button import Button
|
||||||
|
|
||||||
|
|
||||||
|
def _build_keyboard_rows(
|
||||||
|
btns: list[Button] | list[list[Button]],
|
||||||
|
) -> list[abcs.KeyboardButtonRow]:
|
||||||
|
# list[button] -> list[list[button]]
|
||||||
|
# This does allow for "invalid" inputs (mixing lists and non-lists), but that's acceptable.
|
||||||
|
buttons_lists_iter = [
|
||||||
|
button if isinstance(button, list) else [button] for button in (btns or [])
|
||||||
|
]
|
||||||
|
# Remove empty rows (also making it easy to check if all-empty).
|
||||||
|
buttons_lists = [bs for bs in buttons_lists_iter if bs]
|
||||||
|
|
||||||
|
return [
|
||||||
|
types.KeyboardButtonRow(buttons=[btn._raw for btn in btns])
|
||||||
|
for btns in buttons_lists
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class Keyboard:
|
||||||
|
__slots__ = ("_raw",)
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
buttons: list[Button] | list[list[Button]],
|
||||||
|
resize: bool,
|
||||||
|
single_use: bool,
|
||||||
|
selective: bool,
|
||||||
|
persistent: bool,
|
||||||
|
placeholder: Optional[str],
|
||||||
|
) -> None:
|
||||||
|
self._raw = types.ReplyKeyboardMarkup(
|
||||||
|
resize=resize,
|
||||||
|
single_use=single_use,
|
||||||
|
selective=selective,
|
||||||
|
persistent=persistent,
|
||||||
|
rows=_build_keyboard_rows(buttons),
|
||||||
|
placeholder=placeholder,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class InlineKeyboard:
|
||||||
|
__slots__ = ("_raw",)
|
||||||
|
|
||||||
|
def __init__(self, buttons: list[Button] | list[list[Button]]) -> None:
|
||||||
|
self._raw = types.ReplyInlineMarkup(rows=_build_keyboard_rows(buttons))
|
||||||
|
|
||||||
|
|
||||||
|
KeyboardType: TypeAlias = Keyboard | InlineKeyboard
|
|
@ -2,7 +2,7 @@ from __future__ import annotations
|
||||||
|
|
||||||
import datetime
|
import datetime
|
||||||
import time
|
import time
|
||||||
from typing import TYPE_CHECKING, Any, Optional, Self, Sequence
|
from typing import TYPE_CHECKING, Any, Optional, Self, Sequence, cast
|
||||||
|
|
||||||
from ...session import PeerRef
|
from ...session import PeerRef
|
||||||
from ...tl import abcs, types
|
from ...tl import abcs, types
|
||||||
|
@ -12,8 +12,9 @@ from ..parsers import (
|
||||||
parse_html_message,
|
parse_html_message,
|
||||||
parse_markdown_message,
|
parse_markdown_message,
|
||||||
)
|
)
|
||||||
from .buttons import Button, as_concrete_row, create_button
|
from .buttons import Button, create_button
|
||||||
from .file import File
|
from .file import File
|
||||||
|
from .keyboard import KeyboardType
|
||||||
from .meta import NoPublicConstructor
|
from .meta import NoPublicConstructor
|
||||||
from .peer import Peer, expand_peer, peer_id
|
from .peer import Peer, expand_peer, peer_id
|
||||||
|
|
||||||
|
@ -333,7 +334,7 @@ class Message(metaclass=NoPublicConstructor):
|
||||||
markdown: Optional[str] = None,
|
markdown: Optional[str] = None,
|
||||||
html: Optional[str] = None,
|
html: Optional[str] = None,
|
||||||
link_preview: bool = False,
|
link_preview: bool = False,
|
||||||
buttons: Optional[list[Button] | list[list[Button]]] = None,
|
keyboard: Optional[KeyboardType] = None,
|
||||||
) -> Message:
|
) -> Message:
|
||||||
"""
|
"""
|
||||||
Alias for :meth:`telethon.Client.send_message`.
|
Alias for :meth:`telethon.Client.send_message`.
|
||||||
|
@ -342,7 +343,7 @@ class Message(metaclass=NoPublicConstructor):
|
||||||
:param markdown: See :ref:`formatting`.
|
:param markdown: See :ref:`formatting`.
|
||||||
:param html: See :ref:`formatting`.
|
:param html: See :ref:`formatting`.
|
||||||
:param link_preview: See :meth:`~telethon.Client.send_message`.
|
:param link_preview: See :meth:`~telethon.Client.send_message`.
|
||||||
:param buttons: See :meth:`~telethon.Client.send_message`.
|
:param keyboard: See :meth:`~telethon.Client.send_message`.
|
||||||
"""
|
"""
|
||||||
return await self._client.send_message(
|
return await self._client.send_message(
|
||||||
self.chat,
|
self.chat,
|
||||||
|
@ -350,7 +351,7 @@ class Message(metaclass=NoPublicConstructor):
|
||||||
markdown=markdown,
|
markdown=markdown,
|
||||||
html=html,
|
html=html,
|
||||||
link_preview=link_preview,
|
link_preview=link_preview,
|
||||||
buttons=buttons,
|
keyboard=keyboard,
|
||||||
)
|
)
|
||||||
|
|
||||||
async def reply(
|
async def reply(
|
||||||
|
@ -360,7 +361,7 @@ class Message(metaclass=NoPublicConstructor):
|
||||||
markdown: Optional[str] = None,
|
markdown: Optional[str] = None,
|
||||||
html: Optional[str] = None,
|
html: Optional[str] = None,
|
||||||
link_preview: bool = False,
|
link_preview: bool = False,
|
||||||
buttons: Optional[list[Button] | list[list[Button]]] = None,
|
keyboard: Optional[KeyboardType] = None,
|
||||||
) -> Message:
|
) -> Message:
|
||||||
"""
|
"""
|
||||||
Alias for :meth:`telethon.Client.send_message` with the ``reply_to`` parameter set to this message.
|
Alias for :meth:`telethon.Client.send_message` with the ``reply_to`` parameter set to this message.
|
||||||
|
@ -369,7 +370,7 @@ class Message(metaclass=NoPublicConstructor):
|
||||||
:param markdown: See :ref:`formatting`.
|
:param markdown: See :ref:`formatting`.
|
||||||
:param html: See :ref:`formatting`.
|
:param html: See :ref:`formatting`.
|
||||||
:param link_preview: See :meth:`~telethon.Client.send_message`.
|
:param link_preview: See :meth:`~telethon.Client.send_message`.
|
||||||
:param buttons: See :meth:`~telethon.Client.send_message`.
|
:param keyboard: See :meth:`~telethon.Client.send_message`.
|
||||||
"""
|
"""
|
||||||
return await self._client.send_message(
|
return await self._client.send_message(
|
||||||
self.chat,
|
self.chat,
|
||||||
|
@ -378,7 +379,7 @@ class Message(metaclass=NoPublicConstructor):
|
||||||
html=html,
|
html=html,
|
||||||
link_preview=link_preview,
|
link_preview=link_preview,
|
||||||
reply_to=self.id,
|
reply_to=self.id,
|
||||||
buttons=buttons,
|
keyboard=keyboard,
|
||||||
)
|
)
|
||||||
|
|
||||||
async def delete(self, *, revoke: bool = True) -> None:
|
async def delete(self, *, revoke: bool = True) -> None:
|
||||||
|
@ -395,7 +396,7 @@ class Message(metaclass=NoPublicConstructor):
|
||||||
markdown: Optional[str] = None,
|
markdown: Optional[str] = None,
|
||||||
html: Optional[str] = None,
|
html: Optional[str] = None,
|
||||||
link_preview: bool = False,
|
link_preview: bool = False,
|
||||||
buttons: Optional[list[Button] | list[list[Button]]] = None,
|
keyboard: Optional[KeyboardType] = None,
|
||||||
) -> Message:
|
) -> Message:
|
||||||
"""
|
"""
|
||||||
Alias for :meth:`telethon.Client.edit_message`.
|
Alias for :meth:`telethon.Client.edit_message`.
|
||||||
|
@ -404,7 +405,7 @@ class Message(metaclass=NoPublicConstructor):
|
||||||
:param markdown: See :ref:`formatting`.
|
:param markdown: See :ref:`formatting`.
|
||||||
:param html: See :ref:`formatting`.
|
:param html: See :ref:`formatting`.
|
||||||
:param link_preview: See :meth:`~telethon.Client.send_message`.
|
:param link_preview: See :meth:`~telethon.Client.send_message`.
|
||||||
:param buttons: See :meth:`~telethon.Client.send_message`.
|
:param keyboard: See :meth:`~telethon.Client.send_message`.
|
||||||
"""
|
"""
|
||||||
return await self._client.edit_message(
|
return await self._client.edit_message(
|
||||||
self.chat,
|
self.chat,
|
||||||
|
@ -413,7 +414,7 @@ class Message(metaclass=NoPublicConstructor):
|
||||||
markdown=markdown,
|
markdown=markdown,
|
||||||
html=html,
|
html=html,
|
||||||
link_preview=link_preview,
|
link_preview=link_preview,
|
||||||
buttons=buttons,
|
keyboard=keyboard,
|
||||||
)
|
)
|
||||||
|
|
||||||
async def forward(self, target: Peer | PeerRef) -> Message:
|
async def forward(self, target: Peer | PeerRef) -> Message:
|
||||||
|
@ -476,8 +477,11 @@ class Message(metaclass=NoPublicConstructor):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
return [
|
return [
|
||||||
[create_button(self, button) for button in row.buttons]
|
[
|
||||||
for row in map(as_concrete_row, markup.rows)
|
create_button(self, button)
|
||||||
|
for button in cast(types.KeyboardButtonRow, row).buttons
|
||||||
|
]
|
||||||
|
for row in markup.rows
|
||||||
]
|
]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|
|
@ -7,6 +7,7 @@ When the return value is :data:`True`, the associated :mod:`~telethon.events` ha
|
||||||
|
|
||||||
The :doc:`/concepts/updates` concept to learn to combine filters or define your own.
|
The :doc:`/concepts/updates` concept to learn to combine filters or define your own.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from .._impl.client.events.filters import (
|
from .._impl.client.events.filters import (
|
||||||
All,
|
All,
|
||||||
Any,
|
Any,
|
||||||
|
@ -14,7 +15,7 @@ from .._impl.client.events.filters import (
|
||||||
ChatType,
|
ChatType,
|
||||||
Command,
|
Command,
|
||||||
Data,
|
Data,
|
||||||
Filter,
|
FilterType,
|
||||||
Forward,
|
Forward,
|
||||||
Incoming,
|
Incoming,
|
||||||
Media,
|
Media,
|
||||||
|
@ -31,7 +32,7 @@ __all__ = [
|
||||||
"Chats",
|
"Chats",
|
||||||
"ChatType",
|
"ChatType",
|
||||||
"Command",
|
"Command",
|
||||||
"Filter",
|
"FilterType",
|
||||||
"Forward",
|
"Forward",
|
||||||
"Incoming",
|
"Incoming",
|
||||||
"Media",
|
"Media",
|
||||||
|
|
|
@ -13,7 +13,9 @@ from .._impl.client.types import (
|
||||||
Draft,
|
Draft,
|
||||||
File,
|
File,
|
||||||
Group,
|
Group,
|
||||||
|
InlineKeyboard,
|
||||||
InlineResult,
|
InlineResult,
|
||||||
|
Keyboard,
|
||||||
LoginToken,
|
LoginToken,
|
||||||
Message,
|
Message,
|
||||||
Participant,
|
Participant,
|
||||||
|
@ -37,7 +39,9 @@ __all__ = [
|
||||||
"Draft",
|
"Draft",
|
||||||
"File",
|
"File",
|
||||||
"Group",
|
"Group",
|
||||||
|
"InlineKeyboard",
|
||||||
"InlineResult",
|
"InlineResult",
|
||||||
|
"Keyboard",
|
||||||
"LoginToken",
|
"LoginToken",
|
||||||
"Message",
|
"Message",
|
||||||
"Participant",
|
"Participant",
|
||||||
|
|
Loading…
Reference in New Issue
Block a user