mirror of
https://github.com/LonamiWebs/Telethon.git
synced 2025-01-24 16:24:15 +03:00
Document most methods and classes
This commit is contained in:
parent
569ff3d372
commit
604d95a807
|
@ -11,6 +11,9 @@ Glossary
|
|||
|
||||
.. seealso:: The :doc:`../concepts/chats` concept.
|
||||
|
||||
yourself
|
||||
The logged-in account, whether that represents a bot or a user with a phone number.
|
||||
|
||||
Raw API
|
||||
Functions and types under ``telethon._tl`` that enable access to all of Telegram's API.
|
||||
|
||||
|
|
|
@ -128,11 +128,8 @@ async def sign_in(
|
|||
|
||||
|
||||
async def interactive_login(self: Client) -> User:
|
||||
try:
|
||||
return await self.get_me()
|
||||
except RpcError as e:
|
||||
if e.code != 401:
|
||||
raise
|
||||
if me := await self.get_me():
|
||||
return me
|
||||
|
||||
phone_or_token = ""
|
||||
while not re.match(r"\+?[\s()]*\d", phone_or_token):
|
||||
|
|
|
@ -11,6 +11,10 @@ if TYPE_CHECKING:
|
|||
|
||||
|
||||
class InlineResults(metaclass=NoPublicConstructor):
|
||||
"""
|
||||
:final:
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
client: Client,
|
||||
|
@ -119,7 +123,7 @@ class InlineResult(metaclass=NoPublicConstructor):
|
|||
|
||||
|
||||
async def inline_query(
|
||||
self: Client, bot: ChatLike, query: str, *, chat: Optional[ChatLike] = None
|
||||
self: Client, bot: ChatLike, query: str = "", *, chat: Optional[ChatLike] = None
|
||||
) -> AsyncIterator[InlineResult]:
|
||||
packed_bot = await self._resolve_to_packed(bot)
|
||||
packed_chat = await self._resolve_to_packed(chat) if chat else None
|
||||
|
|
|
@ -107,6 +107,59 @@ T = TypeVar("T")
|
|||
|
||||
|
||||
class Client:
|
||||
"""
|
||||
A client capable of connecting to Telegram and sending requests.
|
||||
|
||||
This is the "entry point" of the library.
|
||||
|
||||
This class can be used as an asynchronous context manager to automatically :meth:`connect` and :meth:`disconnect`:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
async with Client(session, api_id, api_hash) as client:
|
||||
... # automatically connect()-ed
|
||||
|
||||
... # after exiting the block, disconnect() was automatically called
|
||||
|
||||
:param session:
|
||||
A name or path to a ``.session`` file, or a different storage.
|
||||
|
||||
:param api_id:
|
||||
The API ID. See :doc:`/basic/signing-in` to learn how to obtain it.
|
||||
|
||||
:param api_hash:
|
||||
The API hash. See :doc:`/basic/signing-in` to learn how to obtain it.
|
||||
|
||||
:param device_model:
|
||||
Device model.
|
||||
|
||||
:param system_version:
|
||||
System version.
|
||||
|
||||
:param app_version:
|
||||
Application version.
|
||||
|
||||
:param system_lang_code:
|
||||
ISO 639-1 language code of the system's language.
|
||||
|
||||
:param lang_code:
|
||||
ISO 639-1 language code of the application's language.
|
||||
|
||||
:param catch_up:
|
||||
Whether to "catch up" on updates that occured while the client was not connected.
|
||||
|
||||
:param server_addr:
|
||||
Override the server address ``'ip:port'`` pair to connect to.
|
||||
Useful to connect to one of Telegram's test servers.
|
||||
|
||||
:param flood_sleep_threshold:
|
||||
Maximum amount of time, in seconds, to automatically sleep before retrying a request.
|
||||
This sleeping occurs when ``FLOOD_WAIT`` :class:`~telethon.RpcError` is raised by Telegram.
|
||||
|
||||
:param update_queue_limit:
|
||||
Maximum amount of updates to keep in memory before dropping them.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
session: Optional[Union[str, Path, Storage]],
|
||||
|
@ -152,17 +205,114 @@ class Client:
|
|||
event_cls: Type[Event],
|
||||
filter: Optional[Filter] = None,
|
||||
) -> None:
|
||||
"""
|
||||
Register a callable to be invoked when the provided event type occurs.
|
||||
|
||||
:param handler:
|
||||
The callable to invoke when an event occurs.
|
||||
This is often just a function object.
|
||||
|
||||
:param event_cls:
|
||||
The event type to bind to the handler.
|
||||
When Telegram sends an update corresponding to this type,
|
||||
*handler* is called with an instance of this event type as the only argument.
|
||||
|
||||
:param filter:
|
||||
Filter function to call with the event before calling *handler*.
|
||||
If it returns `False`, *handler* will not be called.
|
||||
See the :mod:`~telethon.events.filters` module to learn more.
|
||||
|
||||
.. rubric:: Example
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
async def my_print_handler(event):
|
||||
print(event.chat.full_name, event.text)
|
||||
|
||||
# Register a handler to be called on new messages
|
||||
client.add_event_handler(my_print_handler, events.NewMessage)
|
||||
|
||||
# Register a handler to be called on new messages if they contain "hello" or "/start"
|
||||
from telethon.events import filters
|
||||
|
||||
client.add_event_handler(
|
||||
my_print_handler,
|
||||
events.NewMessage,
|
||||
filters.Any(filters.Text(r'hello'), filters.Command('/start')),
|
||||
)
|
||||
|
||||
.. seealso::
|
||||
|
||||
:meth:`on`, used to register handlers with the decorator syntax.
|
||||
"""
|
||||
add_event_handler(self, handler, event_cls, filter)
|
||||
|
||||
async def bot_sign_in(self, token: str) -> User:
|
||||
"""
|
||||
Sign in to a bot account.
|
||||
|
||||
:param token:
|
||||
The bot token obtained from `@BotFather <https://t.me/BotFather>`_.
|
||||
It's a string composed of digits, a colon, and characters from the base-64 alphabet.
|
||||
|
||||
:return: The bot user corresponding to :term:`yourself`.
|
||||
|
||||
.. rubric:: Example
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
await client.bot_sign_in('12345:abc67DEF89ghi')
|
||||
|
||||
.. seealso::
|
||||
|
||||
:meth:`request_login_code`, used to sign in as a user instead.
|
||||
"""
|
||||
return await bot_sign_in(self, token)
|
||||
|
||||
async def check_password(
|
||||
self, token: PasswordToken, password: Union[str, bytes]
|
||||
) -> User:
|
||||
"""
|
||||
Check the two-factor-authentication (2FA) password.
|
||||
If it is correct, completes the login.
|
||||
|
||||
:param token:
|
||||
The return value from :meth:`sign_in`.
|
||||
|
||||
:param password:
|
||||
The 2FA password.
|
||||
|
||||
:return: The user corresponding to :term:`yourself`.
|
||||
|
||||
.. rubric:: Example
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from telethon.types import PasswordToken
|
||||
|
||||
login_token = await client.request_login_code('+1 23 456')
|
||||
password_token = await client.sign_in(login_token, input('code: '))
|
||||
assert isinstance(password_token, PasswordToken)
|
||||
|
||||
user = await client.check_password(password_token, '1-L0V3+T3l3th0n')
|
||||
|
||||
.. seealso::
|
||||
|
||||
:meth:`request_login_code` and :meth:`sign_in`
|
||||
"""
|
||||
return await check_password(self, token, password)
|
||||
|
||||
async def connect(self) -> None:
|
||||
"""
|
||||
Connect to the Telegram servers.
|
||||
|
||||
.. rubric:: Example
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
await client.connect()
|
||||
# success!
|
||||
"""
|
||||
await connect(self)
|
||||
|
||||
async def delete_dialog(self) -> None:
|
||||
|
@ -171,17 +321,84 @@ class Client:
|
|||
async def delete_messages(
|
||||
self, chat: ChatLike, message_ids: List[int], *, revoke: bool = True
|
||||
) -> int:
|
||||
"""
|
||||
Delete messages.
|
||||
|
||||
:param chat:
|
||||
The :term:`chat` where the messages are.
|
||||
|
||||
.. warning::
|
||||
|
||||
When deleting messages from private conversations or small groups,
|
||||
this parameter is ignored. This means the *message_ids* may delete
|
||||
messages in different chats.
|
||||
|
||||
:param message_ids:
|
||||
The list of message identifiers to delete.
|
||||
|
||||
:param revoke:
|
||||
When set to :data:`True`, the message will be deleted for everyone that is part of *chat*.
|
||||
Otherwise, the message will only be deleted for :term:`yourself`.
|
||||
|
||||
:return: The amount of messages that were deleted.
|
||||
|
||||
.. rubric:: Example
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
# Delete two messages from chat for yourself
|
||||
await client.delete_messages(
|
||||
chat,
|
||||
[187481, 187482],
|
||||
revoke=False,
|
||||
)
|
||||
|
||||
.. seealso::
|
||||
|
||||
:meth:`telethon.types.Message.delete`
|
||||
"""
|
||||
return await delete_messages(self, chat, message_ids, revoke=revoke)
|
||||
|
||||
async def disconnect(self) -> None:
|
||||
"""
|
||||
Disconnect from the Telegram servers.
|
||||
|
||||
This call will only fail if saving the :term:`session` fails.
|
||||
|
||||
.. rubric:: Example
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
await client.disconnect()
|
||||
# success!
|
||||
"""
|
||||
await disconnect(self)
|
||||
|
||||
async def download(self, media: MediaLike, file: OutFileLike) -> None:
|
||||
"""
|
||||
Download a file.
|
||||
|
||||
This is simply a more convenient method to `iter_download`,
|
||||
as it will handle dealing with the file chunks and writes by itself.
|
||||
:param media:
|
||||
The media to download.
|
||||
This will often come from :attr:`telethon.types.Message.file`.
|
||||
|
||||
:param file:
|
||||
The output file path or :term:`file-like object`.
|
||||
|
||||
.. rubric:: Example
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
if photo := message.photo:
|
||||
await client.download(photo, 'picture.jpg')
|
||||
|
||||
if video := message.video:
|
||||
with open('video.mp4, 'wb') as file:
|
||||
await client.download(video, file)
|
||||
|
||||
.. seealso::
|
||||
|
||||
:meth:`iter_download`, for fine-grained control over the download.
|
||||
"""
|
||||
await download(self, media, file)
|
||||
|
||||
|
@ -195,6 +412,33 @@ class Client:
|
|||
html: Optional[str] = None,
|
||||
link_preview: Optional[bool] = None,
|
||||
) -> Message:
|
||||
"""
|
||||
Edit a message.
|
||||
|
||||
:param chat:
|
||||
The :term:`chat` where the message to edit is.
|
||||
|
||||
:param message_id:
|
||||
The identifier of the message to edit.
|
||||
|
||||
The rest of parameters behave the same as they do in `send_message` or `send_file`.
|
||||
|
||||
:return: The edited message.
|
||||
|
||||
.. rubric:: Example
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
# Edit message to have text without formatting
|
||||
await client.edit_message(chat, msg_id, text='New text')
|
||||
|
||||
# Remove the link preview without changing the text
|
||||
await client.edit_message(chat, msg_id, link_preview=False)
|
||||
|
||||
.. seealso::
|
||||
|
||||
:meth:`telethon.types.Message.edit`
|
||||
"""
|
||||
return await edit_message(
|
||||
self,
|
||||
chat,
|
||||
|
@ -208,9 +452,50 @@ class Client:
|
|||
async def forward_messages(
|
||||
self, target: ChatLike, message_ids: List[int], source: ChatLike
|
||||
) -> List[Message]:
|
||||
"""
|
||||
Forward messages from one :term:`chat` to another.
|
||||
|
||||
:param target:
|
||||
The :term:`chat` where the messages will be forwarded to.
|
||||
|
||||
:param message_ids:
|
||||
The list of message identifiers to forward.
|
||||
|
||||
:param source:
|
||||
The source :term:`chat` where the messages to forward exist.
|
||||
|
||||
:return: The forwarded messages.
|
||||
|
||||
.. rubric:: Example
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
# Forward two messages from chat to the destination
|
||||
await client.forward_messages(
|
||||
destination,
|
||||
[187481, 187482],
|
||||
chat,
|
||||
)
|
||||
|
||||
.. seealso::
|
||||
|
||||
:meth:`telethon.types.Message.forward_to`
|
||||
"""
|
||||
return await forward_messages(self, target, message_ids, source)
|
||||
|
||||
async def get_contacts(self) -> AsyncList[User]:
|
||||
"""
|
||||
Get the users in your contact list.
|
||||
|
||||
:return: Your contacts.
|
||||
|
||||
.. rubric:: Example
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
async for user in client.get_contacts():
|
||||
print(user.full_name, user.id)
|
||||
"""
|
||||
return await get_contacts(self)
|
||||
|
||||
def get_dialogs(self) -> None:
|
||||
|
@ -219,9 +504,51 @@ class Client:
|
|||
def get_handler_filter(
|
||||
self, handler: Callable[[Event], Awaitable[Any]]
|
||||
) -> Optional[Filter]:
|
||||
"""
|
||||
Get the filter associated to the given event handler.
|
||||
|
||||
:param handler:
|
||||
The callable that was previously added as an event handler.
|
||||
|
||||
:return:
|
||||
The filter, if *handler* was actually registered and had a filter.
|
||||
|
||||
.. rubric:: Example
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from telethon.events import filters
|
||||
|
||||
# Get the current filter...
|
||||
filt = client.get_handler_filter(my_handler)
|
||||
|
||||
# ...and "append" a new filter that also must match.
|
||||
client.set_handler_filter(my_handler, filters.All(filt, filt.Text(r'test')))
|
||||
"""
|
||||
return get_handler_filter(self, handler)
|
||||
|
||||
async def get_me(self) -> User:
|
||||
async def get_me(self) -> Optional[User]:
|
||||
"""
|
||||
Get information about :term:`yourself`.
|
||||
|
||||
:return:
|
||||
The user associated with the logged-in account, or :data:`None` if the client is not authorized.
|
||||
|
||||
.. rubric:: Example
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
me = await client.get_me()
|
||||
assert me is not None, "not logged in!"
|
||||
|
||||
if me.bot:
|
||||
print('I am a bot')
|
||||
|
||||
print('My name is', me.full_name)
|
||||
|
||||
if me.phone:
|
||||
print('My phone number is', me.phone)
|
||||
"""
|
||||
return await get_me(self)
|
||||
|
||||
def get_messages(
|
||||
|
@ -232,6 +559,40 @@ class Client:
|
|||
offset_id: Optional[int] = None,
|
||||
offset_date: Optional[datetime.datetime] = None,
|
||||
) -> AsyncList[Message]:
|
||||
"""
|
||||
Get the message history from a :term:`chat`.
|
||||
|
||||
Edit a message.
|
||||
|
||||
:param chat:
|
||||
The :term:`chat` where the message to edit is.
|
||||
|
||||
:param limit:
|
||||
How many messages to fetch at most.
|
||||
|
||||
:param offset_id:
|
||||
Start getting messages with an identifier lower than this one.
|
||||
This means only messages older than the message with ``id = offset_id`` will be fetched.
|
||||
|
||||
:param offset_date:
|
||||
Start getting messages with a date lower than this one.
|
||||
This means only messages sent before *offset_date* will be fetched.
|
||||
|
||||
:return: The message history.
|
||||
|
||||
.. rubric:: Example
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
# Get the last message in a chat
|
||||
last_message = (await client.get_messages(chat, 1))[0]
|
||||
|
||||
# Print all messages before 2023 as HTML
|
||||
from datetime import datetime
|
||||
|
||||
async for message in client.get_messages(chat, offset_date=datetime(2023, 1, 1)):
|
||||
print(message.sender.full_name, ':', message.html_text)
|
||||
"""
|
||||
return get_messages(
|
||||
self, chat, limit, offset_id=offset_id, offset_date=offset_date
|
||||
)
|
||||
|
@ -245,14 +606,70 @@ class Client:
|
|||
get_participants(self)
|
||||
|
||||
async def inline_query(
|
||||
self, bot: ChatLike, query: str, *, chat: Optional[ChatLike] = None
|
||||
self, bot: ChatLike, query: str = "", *, chat: Optional[ChatLike] = None
|
||||
) -> AsyncIterator[InlineResult]:
|
||||
"""
|
||||
Perform a *@bot inline query*.
|
||||
|
||||
It's known as inline because clients with a GUI display the results *inline*,
|
||||
after typing on the message input textbox, without sending any message.
|
||||
|
||||
:param bot:
|
||||
The bot to sent the query string to.
|
||||
|
||||
:param query:
|
||||
The query string to send to the bot.
|
||||
|
||||
:param chat:
|
||||
Where the query is being made and will be sent.
|
||||
Some bots display different results based on the type of chat.
|
||||
|
||||
:return: The query results returned by the bot.
|
||||
|
||||
.. rubric:: Example
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
i = 0
|
||||
|
||||
# This is equivalent to typing "@bot songs" in an official client
|
||||
async for result in client.inline_query(bot, 'songs'):
|
||||
if 'keyword' in result.title:
|
||||
await result.send(chat)
|
||||
break
|
||||
|
||||
i += 1
|
||||
if i == 10:
|
||||
break # did not find 'keyword' in the first few results
|
||||
"""
|
||||
return await inline_query(self, bot, query, chat=chat)
|
||||
|
||||
async def interactive_login(self) -> User:
|
||||
"""
|
||||
Begin an interactive login if needed.
|
||||
If the account was already logged-in, this method simply returns :term:`yourself`.
|
||||
|
||||
:return: The user corresponding to :term:`yourself`.
|
||||
|
||||
.. rubric:: Example
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
me = await client.interactive_login()
|
||||
print('Logged in as:', me.full_name)
|
||||
|
||||
.. seealso::
|
||||
|
||||
In-depth explanation for :doc:`/basic/signing-in`.
|
||||
"""
|
||||
return await interactive_login(self)
|
||||
|
||||
async def is_authorized(self) -> bool:
|
||||
"""
|
||||
Check whether the client instance is authorized (i.e. logged-in).
|
||||
|
||||
:return: :data:`True` if the client instance has signed-in.
|
||||
"""
|
||||
return await is_authorized(self)
|
||||
|
||||
async def iter_download(self) -> None:
|
||||
|
@ -263,18 +680,137 @@ class Client:
|
|||
) -> Callable[
|
||||
[Callable[[Event], Awaitable[Any]]], Callable[[Event], Awaitable[Any]]
|
||||
]:
|
||||
"""
|
||||
Register the decorated function to be invoked when the provided event type occurs.
|
||||
|
||||
:param event_cls:
|
||||
The event type to bind to the handler.
|
||||
When Telegram sends an update corresponding to this type,
|
||||
the decorated function is called with an instance of this event type as the only argument.
|
||||
|
||||
:param filter:
|
||||
Filter function to call with the event before calling *handler*.
|
||||
If it returns `False`, *handler* will not be called.
|
||||
See the :mod:`~telethon.events.filters` module to learn more.
|
||||
|
||||
:return: The decorator.
|
||||
|
||||
.. rubric:: Example
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
# Register a handler to be called on new messages
|
||||
@client.on(events.NewMessage)
|
||||
async def my_print_handler(event):
|
||||
print(event.chat.full_name, event.text)
|
||||
|
||||
# Register a handler to be called on new messages if they contain "hello" or "/start"
|
||||
from telethon.events.filters import Any, Text, Command
|
||||
|
||||
@client.on(events.NewMessage, Any(Text(r'hello'), Command('/start')))
|
||||
async def my_other_print_handler(event):
|
||||
print(event.chat.full_name, event.text)
|
||||
|
||||
.. seealso::
|
||||
|
||||
:meth:`add_event_handler`, used to register existing functions as event handlers.
|
||||
"""
|
||||
return on(self, event_cls, filter)
|
||||
|
||||
async def pin_message(self, chat: ChatLike, message_id: int) -> Message:
|
||||
"""
|
||||
Pin a message to be at the top.
|
||||
|
||||
:param chat:
|
||||
The :term:`chat` where the message to pin is.
|
||||
|
||||
:param message_id:
|
||||
The identifier of the message to pin.
|
||||
|
||||
:return: The service message announcing the pin.
|
||||
|
||||
.. rubric:: Example
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
# Pin a message, then delete the service message
|
||||
message = await client.pin_message(chat, 187481)
|
||||
await message.delete()
|
||||
"""
|
||||
return await pin_message(self, chat, message_id)
|
||||
|
||||
def remove_event_handler(self, handler: Callable[[Event], Awaitable[Any]]) -> None:
|
||||
"""
|
||||
Remove the handler as a function to be called when events occur.
|
||||
This is simply the opposite of :meth:`add_event_handler`.
|
||||
Does nothing if the handler was not actually registered.
|
||||
|
||||
:param handler:
|
||||
The callable to stop invoking when events occur.
|
||||
|
||||
.. rubric:: Example
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
# Register a handler that removes itself when it receives 'stop'
|
||||
@client.on(events.NewMessage)
|
||||
async def my_handler(event):
|
||||
if 'stop' in event.text:
|
||||
client.remove_event_handler(my_handler)
|
||||
else:
|
||||
print('still going!')
|
||||
|
||||
.. seealso::
|
||||
|
||||
:meth:`add_event_handler`, used to register existing functions as event handlers.
|
||||
"""
|
||||
remove_event_handler(self, handler)
|
||||
|
||||
async def request_login_code(self, phone: str) -> LoginToken:
|
||||
"""
|
||||
Request Telegram to send a login code to the provided phone number.
|
||||
This is simply the opposite of :meth:`add_event_handler`.
|
||||
Does nothing if the handler was not actually registered.
|
||||
|
||||
:param phone:
|
||||
The phone number string, in international format.
|
||||
The plus-sign ``+`` can be kept in the string.
|
||||
|
||||
:return: Information about the sent code.
|
||||
|
||||
.. rubric:: Example
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
login_token = await client.request_login_code('+1 23 456...')
|
||||
print(login_token.timeout, 'seconds before code expires')
|
||||
|
||||
.. seealso::
|
||||
|
||||
:meth:`sign_in`, to complete the login procedure.
|
||||
"""
|
||||
return await request_login_code(self, phone)
|
||||
|
||||
async def resolve_to_packed(self, chat: ChatLike) -> PackedChat:
|
||||
"""
|
||||
Resolve a :term:`chat` and return a compact, reusable reference to it.
|
||||
|
||||
:param chat:
|
||||
The :term:`chat` to resolve.
|
||||
|
||||
:return: An efficient, reusable version of the input.
|
||||
|
||||
.. rubric:: Example
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
friend = await client.resolve_to_packed('@cat')
|
||||
# Now you can use `friend` to get or send messages, files...
|
||||
|
||||
.. seealso::
|
||||
|
||||
In-depth explanation for :doc:`/concepts/chats`.
|
||||
"""
|
||||
return await resolve_to_packed(self, chat)
|
||||
|
||||
async def resolve_username(self) -> Chat:
|
||||
|
@ -291,6 +827,30 @@ class Client:
|
|||
offset_id: Optional[int] = None,
|
||||
offset_date: Optional[datetime.datetime] = None,
|
||||
) -> AsyncList[Message]:
|
||||
"""
|
||||
Perform a global message search.
|
||||
This is used to search messages in no particular chat (i.e. everywhere possible).
|
||||
|
||||
:param chat:
|
||||
The :term:`chat` where the message to edit is.
|
||||
|
||||
:param limit:
|
||||
How many messages to fetch at most.
|
||||
|
||||
:param query:
|
||||
Text query to use for fuzzy matching messages.
|
||||
The rules for how "fuzzy" works are an implementation detail of the server.
|
||||
|
||||
:param offset_id:
|
||||
Start getting messages with an identifier lower than this one.
|
||||
This means only messages older than the message with ``id = offset_id`` will be fetched.
|
||||
|
||||
:param offset_date:
|
||||
Start getting messages with a date lower than this one.
|
||||
This means only messages sent before *offset_date* will be fetched.
|
||||
|
||||
:return: The found messages.
|
||||
"""
|
||||
return search_all_messages(
|
||||
self, limit, query=query, offset_id=offset_id, offset_date=offset_date
|
||||
)
|
||||
|
@ -304,6 +864,29 @@ class Client:
|
|||
offset_id: Optional[int] = None,
|
||||
offset_date: Optional[datetime.datetime] = None,
|
||||
) -> AsyncList[Message]:
|
||||
"""
|
||||
Search messages in a chat.
|
||||
|
||||
:param chat:
|
||||
The :term:`chat` where messages will be searched.
|
||||
|
||||
:param limit:
|
||||
How many messages to fetch at most.
|
||||
|
||||
:param query:
|
||||
Text query to use for fuzzy matching messages.
|
||||
The rules for how "fuzzy" works are an implementation detail of the server.
|
||||
|
||||
:param offset_id:
|
||||
Start getting messages with an identifier lower than this one.
|
||||
This means only messages older than the message with ``id = offset_id`` will be fetched.
|
||||
|
||||
:param offset_date:
|
||||
Start getting messages with a date lower than this one.
|
||||
This means only messages sent before *offset_date* will be fetched.
|
||||
|
||||
:return: The found messages.
|
||||
"""
|
||||
return search_messages(
|
||||
self, chat, limit, query=query, offset_id=offset_id, offset_date=offset_date
|
||||
)
|
||||
|
@ -325,8 +908,16 @@ class Client:
|
|||
"""
|
||||
Send an audio file.
|
||||
|
||||
Unlike `send_file`, this method will attempt to guess the values for
|
||||
Unlike :meth:`send_file`, this method will attempt to guess the values for
|
||||
duration, title and performer if they are not provided.
|
||||
|
||||
:param chat:
|
||||
The :term:`chat` where the message will be sent to.
|
||||
|
||||
:param path:
|
||||
A local file path or :class:`~telethon.types.File` to send.
|
||||
|
||||
The rest of parameters behave the same as they do in :meth:`send_file`.
|
||||
"""
|
||||
return await send_audio(
|
||||
self,
|
||||
|
@ -372,15 +963,32 @@ class Client:
|
|||
"""
|
||||
Send any type of file with any amount of attributes.
|
||||
|
||||
This method will not attempt to guess any of the file metadata such as
|
||||
width, duration, title, etc. If you want to let the library attempt to
|
||||
guess the file metadata, use the type-specific methods to send media:
|
||||
This method will *not* attempt to guess any of the file metadata such as width, duration, title, etc.
|
||||
If you want to let the library attempt to guess the file metadata, use the type-specific methods to send media:
|
||||
`send_photo`, `send_audio` or `send_file`.
|
||||
|
||||
Unlike `send_photo`, image files will be sent as documents by default.
|
||||
|
||||
The parameters are used to construct a `File`. See the documentation
|
||||
for `File.new` to learn what they do and when they are in effect.
|
||||
:param chat:
|
||||
The :term:`chat` where the message will be sent to.
|
||||
|
||||
:param path:
|
||||
A local file path or :class:`~telethon.types.File` to send.
|
||||
|
||||
:param caption:
|
||||
Caption text to display under the media, with no formatting.
|
||||
|
||||
:param caption_markdown:
|
||||
Caption text to display under the media, parsed as markdown.
|
||||
|
||||
:param caption_html:
|
||||
Caption text to display under the media, parsed as HTML.
|
||||
|
||||
The rest of parameters are passed to :meth:`telethon.types.File.new`
|
||||
if *path* isn't a :class:`~telethon.types.File`.
|
||||
See the documentation of :meth:`~telethon.types.File.new` to learn what they do.
|
||||
|
||||
Note that only one *caption* parameter can be provided.
|
||||
"""
|
||||
return await send_file(
|
||||
self,
|
||||
|
@ -418,6 +1026,23 @@ class Client:
|
|||
html: Optional[str] = None,
|
||||
link_preview: Optional[bool] = None,
|
||||
) -> Message:
|
||||
"""
|
||||
Send a message.
|
||||
|
||||
:param chat:
|
||||
The :term:`chat` where the message will be sent to.
|
||||
|
||||
:param text:
|
||||
Message text, with no formatting.
|
||||
|
||||
:param text_markdown:
|
||||
Message text, parsed as markdown.
|
||||
|
||||
:param text_html:
|
||||
Message text, parsed as HTML.
|
||||
|
||||
Note that exactly one *text* parameter must be provided.
|
||||
"""
|
||||
return await send_message(
|
||||
self,
|
||||
chat,
|
||||
|
@ -443,16 +1068,20 @@ class Client:
|
|||
"""
|
||||
Send a photo file.
|
||||
|
||||
Exactly one of path, url or file must be specified.
|
||||
A `File` can also be used as the second parameter.
|
||||
|
||||
By default, the server will be allowed to `compress` the image.
|
||||
Only compressed images can be displayed as photos in applications.
|
||||
Images that cannot be compressed will be sent as file documents,
|
||||
with a thumbnail if possible.
|
||||
If *compress* is set to :data:`False`, the image will be sent as a file document.
|
||||
|
||||
Unlike `send_file`, this method will attempt to guess the values for
|
||||
width and height if they are not provided and the can't be compressed.
|
||||
width and height if they are not provided.
|
||||
|
||||
:param chat:
|
||||
The :term:`chat` where the message will be sent to.
|
||||
|
||||
:param path:
|
||||
A local file path or :class:`~telethon.types.File` to send.
|
||||
|
||||
The rest of parameters behave the same as they do in :meth:`send_file`.
|
||||
"""
|
||||
return await send_photo(
|
||||
self,
|
||||
|
@ -487,6 +1116,14 @@ class Client:
|
|||
|
||||
Unlike `send_file`, this method will attempt to guess the values for
|
||||
duration, width and height if they are not provided.
|
||||
|
||||
:param chat:
|
||||
The :term:`chat` where the message will be sent to.
|
||||
|
||||
:param path:
|
||||
A local file path or :class:`~telethon.types.File` to send.
|
||||
|
||||
The rest of parameters behave the same as they do in :meth:`send_file`.
|
||||
"""
|
||||
return await send_video(
|
||||
self,
|
||||
|
@ -508,17 +1145,89 @@ class Client:
|
|||
handler: Callable[[Event], Awaitable[Any]],
|
||||
filter: Optional[Filter] = None,
|
||||
) -> None:
|
||||
"""
|
||||
Set the filter to use for the given event handler.
|
||||
|
||||
:param handler:
|
||||
The callable that was previously added as an event handler.
|
||||
|
||||
:param filter:
|
||||
The filter to use for *handler*, or :data:`None` to remove the old filter.
|
||||
|
||||
.. rubric:: Example
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from telethon.events import filters
|
||||
|
||||
# Change the filter to handle '/stop'
|
||||
client.set_handler_filter(my_handler, filters.Command('/stop'))
|
||||
|
||||
# Remove the filter
|
||||
client.set_handler_filter(my_handler, None)
|
||||
"""
|
||||
set_handler_filter(self, handler, filter)
|
||||
|
||||
async def sign_in(self, token: LoginToken, code: str) -> Union[User, PasswordToken]:
|
||||
"""
|
||||
Sign in to a user account.
|
||||
|
||||
:param token:
|
||||
The login token returned from :meth:`request_login_code`.
|
||||
|
||||
:return:
|
||||
The user corresponding to :term:`yourself`, or a password token if the account has 2FA enabled.
|
||||
|
||||
.. rubric:: Example
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from telethon.types import PasswordToken
|
||||
|
||||
login_token = await client.request_login_code('+1 23 456')
|
||||
user_or_token = await client.sign_in(login_token, input('code: '))
|
||||
|
||||
if isinstance(password_token, PasswordToken):
|
||||
user = await client.check_password(password_token, '1-L0V3+T3l3th0n')
|
||||
|
||||
.. seealso::
|
||||
|
||||
:meth:`check_password`, the next step if the account has 2FA enabled.
|
||||
"""
|
||||
return await sign_in(self, token, code)
|
||||
|
||||
async def sign_out(self) -> None:
|
||||
"""
|
||||
Sign out, revoking the authorization of the current :term:`session`.
|
||||
|
||||
.. rubric:: Example
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
await client.sign_out() # turn off the lights
|
||||
await client.disconnect() # shut the door
|
||||
"""
|
||||
await sign_out(self)
|
||||
|
||||
async def unpin_message(
|
||||
self, chat: ChatLike, message_id: Union[int, Literal["all"]]
|
||||
) -> None:
|
||||
"""
|
||||
Unpin one or all messages from the top.
|
||||
|
||||
:param chat:
|
||||
The :term:`chat` where the message pinned message is.
|
||||
|
||||
:param message_id:
|
||||
The identifier of the message to unpin, or ``'all'`` to unpin them all.
|
||||
|
||||
.. rubric:: Example
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
# Unpin all messages
|
||||
await client.unpin_message(chat, 'all')
|
||||
"""
|
||||
await unpin_message(self, chat, message_id)
|
||||
|
||||
# ---
|
||||
|
|
|
@ -39,6 +39,12 @@ def default_system_version() -> str:
|
|||
|
||||
@dataclass
|
||||
class Config:
|
||||
"""
|
||||
Configuration used by the :class:`telethon.Client`.
|
||||
|
||||
See the parameters of :class:`~telethon.Client` for an explanation of the fields.
|
||||
"""
|
||||
|
||||
session: Session
|
||||
api_id: int
|
||||
api_hash: str
|
||||
|
|
|
@ -10,7 +10,7 @@ if TYPE_CHECKING:
|
|||
from .client import Client
|
||||
|
||||
|
||||
async def get_me(self: Client) -> User:
|
||||
async def get_me(self: Client) -> Optional[User]:
|
||||
self
|
||||
raise NotImplementedError
|
||||
|
||||
|
|
|
@ -11,6 +11,10 @@ if TYPE_CHECKING:
|
|||
|
||||
|
||||
class Event(metaclass=NoPublicConstructor):
|
||||
"""
|
||||
The base type of all events.
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
@abc.abstractmethod
|
||||
def _try_from_update(cls, client: Client, update: abcs.Update) -> Optional[Self]:
|
||||
|
|
|
@ -6,7 +6,7 @@ from .common import Filter
|
|||
|
||||
class Any:
|
||||
"""
|
||||
Combine multiple filters, returning `True` if any of the filters pass.
|
||||
Combine multiple filters, returning :data:`True` if any of the filters pass.
|
||||
"""
|
||||
|
||||
__slots__ = ("_filters",)
|
||||
|
@ -27,7 +27,7 @@ class Any:
|
|||
|
||||
class All:
|
||||
"""
|
||||
Combine multiple filters, returning `True` if all of the filters pass.
|
||||
Combine multiple filters, returning :data:`True` if all of the filters pass.
|
||||
"""
|
||||
|
||||
__slots__ = ("_filters",)
|
||||
|
@ -48,8 +48,7 @@ class All:
|
|||
|
||||
class Not:
|
||||
"""
|
||||
Negate the output of a single filter, returning `True` if the nested
|
||||
filter does *not* pass.
|
||||
Negate the output of a single filter, returning :data:`True` if the nested filter does *not* pass.
|
||||
"""
|
||||
|
||||
__slots__ = ("_filter",)
|
||||
|
|
|
@ -7,7 +7,7 @@ Filter = Callable[[Event], bool]
|
|||
|
||||
class Chats:
|
||||
"""
|
||||
Filter by `event.chat.id`.
|
||||
Filter by ``event.chat.id``, if the event has a chat.
|
||||
"""
|
||||
|
||||
__slots__ = ("_chats",)
|
||||
|
@ -31,7 +31,7 @@ class Chats:
|
|||
|
||||
class Senders:
|
||||
"""
|
||||
Filter by `event.sender.id`.
|
||||
Filter by ``event.sender.id``, if the event has a sender.
|
||||
"""
|
||||
|
||||
__slots__ = ("_senders",)
|
||||
|
|
|
@ -6,10 +6,10 @@ from ..event import Event
|
|||
|
||||
class Text:
|
||||
"""
|
||||
Filter by `event.text` using a *regular expression* pattern.
|
||||
Filter by ``event.text`` using a *regular expression* pattern.
|
||||
|
||||
The pattern is searched on the text anywhere, not matched at the start.
|
||||
Use the `'^'` anchor if you want to match the text from the start.
|
||||
Use the ``'^'`` anchor if you want to match the text from the start.
|
||||
|
||||
The match, if any, is discarded. If you need to access captured groups,
|
||||
you need to manually perform the check inside the handler instead.
|
||||
|
@ -27,12 +27,12 @@ class Text:
|
|||
|
||||
class Command:
|
||||
"""
|
||||
Filter by `event.text` to make sure the first word matches the command or
|
||||
Filter by ``event.text`` to make sure the first word matches the command or
|
||||
the command + '@' + username, using the username of the logged-in account.
|
||||
|
||||
For example, if the logged-in account has an username of "bot", then the
|
||||
filter `Command('/help')` will match both "/help" and "/help@bot", but not
|
||||
"/list" or "/help@other".
|
||||
filter ``Command('/help')`` will match both ``"/help"`` and ``"/help@bot"``, but not
|
||||
``"/list"`` or ``"/help@other"``.
|
||||
|
||||
Note that the leading forward-slash is not automatically added,
|
||||
which allows for using a different prefix or no prefix at all.
|
||||
|
@ -49,11 +49,11 @@ class Command:
|
|||
|
||||
class Incoming:
|
||||
"""
|
||||
Filter by `event.incoming`, that is, messages sent from others to the
|
||||
Filter by ``event.incoming``, that is, messages sent from others to the
|
||||
logged-in account.
|
||||
|
||||
This is not a reliable way to check that the update was not produced by
|
||||
the logged-in account.
|
||||
the logged-in account in broadcast channels.
|
||||
"""
|
||||
|
||||
__slots__ = ()
|
||||
|
@ -64,11 +64,11 @@ class Incoming:
|
|||
|
||||
class Outgoing:
|
||||
"""
|
||||
Filter by `event.outgoing`, that is, messages sent from others to the
|
||||
Filter by ``event.outgoing``, that is, messages sent from others to the
|
||||
logged-in account.
|
||||
|
||||
This is not a reliable way to check that the update was not produced by
|
||||
the logged-in account.
|
||||
the logged-in account in broadcast channels.
|
||||
"""
|
||||
|
||||
__slots__ = ()
|
||||
|
@ -79,7 +79,7 @@ class Outgoing:
|
|||
|
||||
class Forward:
|
||||
"""
|
||||
Filter by `event.forward`.
|
||||
Filter by ``event.forward``.
|
||||
"""
|
||||
|
||||
__slots__ = ()
|
||||
|
@ -90,7 +90,7 @@ class Forward:
|
|||
|
||||
class Reply:
|
||||
"""
|
||||
Filter by `event.reply`.
|
||||
Filter by ``event.reply``.
|
||||
"""
|
||||
|
||||
__slots__ = ()
|
||||
|
|
|
@ -15,6 +15,16 @@ if TYPE_CHECKING:
|
|||
|
||||
|
||||
class NewMessage(Event, Message):
|
||||
"""
|
||||
Occurs when a new message is sent or received.
|
||||
|
||||
.. warning::
|
||||
|
||||
Messages sent with the :class:`~telethon.Client` are also caught,
|
||||
so be careful not to enter infinite loops!
|
||||
This is true for all event types, including edits.
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def _try_from_update(cls, client: Client, update: abcs.Update) -> Optional[Self]:
|
||||
if isinstance(update, (types.UpdateNewMessage, types.UpdateNewChannelMessage)):
|
||||
|
@ -29,18 +39,30 @@ class NewMessage(Event, Message):
|
|||
|
||||
|
||||
class MessageEdited(Event):
|
||||
"""
|
||||
Occurs when a new message is sent or received.
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def _try_from_update(cls, client: Client, update: abcs.Update) -> Optional[Self]:
|
||||
raise NotImplementedError()
|
||||
|
||||
|
||||
class MessageDeleted(Event):
|
||||
"""
|
||||
Occurs when one or more messages are deleted.
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def _try_from_update(cls, client: Client, update: abcs.Update) -> Optional[Self]:
|
||||
raise NotImplementedError()
|
||||
|
||||
|
||||
class MessageRead(Event):
|
||||
"""
|
||||
Occurs both when your messages are read by others, and when you read messages.
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def _try_from_update(cls, client: Client, update: abcs.Update) -> Optional[Self]:
|
||||
raise NotImplementedError()
|
||||
|
|
|
@ -10,12 +10,24 @@ if TYPE_CHECKING:
|
|||
|
||||
|
||||
class CallbackQuery(Event):
|
||||
"""
|
||||
Occurs when an inline button was pressed.
|
||||
|
||||
Only bot accounts can receive this event.
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def _try_from_update(cls, client: Client, update: abcs.Update) -> Optional[Self]:
|
||||
raise NotImplementedError()
|
||||
|
||||
|
||||
class InlineQuery(Event):
|
||||
"""
|
||||
Occurs when users type ``@bot query`` in their chat box.
|
||||
|
||||
Only bot accounts can receive this event.
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def _try_from_update(cls, client: Client, update: abcs.Update) -> Optional[Self]:
|
||||
raise NotImplementedError()
|
||||
|
|
|
@ -21,6 +21,7 @@ class AsyncList(abc.ABC, Generic[T]):
|
|||
The `len()` of the asynchronous list will be the "total count" reported
|
||||
by the server. It does not necessarily reflect how many items will
|
||||
actually be returned. This count can change as more items are fetched.
|
||||
Note that this method cannot be awaited.
|
||||
"""
|
||||
|
||||
def __init__(self) -> None:
|
||||
|
|
|
@ -6,6 +6,10 @@ from ..meta import NoPublicConstructor
|
|||
|
||||
|
||||
class Channel(metaclass=NoPublicConstructor):
|
||||
"""
|
||||
A broadcast channel.
|
||||
"""
|
||||
|
||||
__slots__ = ("_raw",)
|
||||
|
||||
def __init__(
|
||||
|
@ -45,6 +49,10 @@ class Channel(metaclass=NoPublicConstructor):
|
|||
def title(self) -> str:
|
||||
return getattr(self._raw, "title", None) or ""
|
||||
|
||||
@property
|
||||
def full_name(self) -> str:
|
||||
return self.title
|
||||
|
||||
@property
|
||||
def username(self) -> Optional[str]:
|
||||
return getattr(self._raw, "username", None)
|
||||
|
|
|
@ -6,6 +6,10 @@ from ..meta import NoPublicConstructor
|
|||
|
||||
|
||||
class Group(metaclass=NoPublicConstructor):
|
||||
"""
|
||||
A small group or supergroup.
|
||||
"""
|
||||
|
||||
__slots__ = ("_raw",)
|
||||
|
||||
def __init__(
|
||||
|
@ -49,6 +53,10 @@ class Group(metaclass=NoPublicConstructor):
|
|||
def title(self) -> str:
|
||||
return getattr(self._raw, "title", None) or ""
|
||||
|
||||
@property
|
||||
def full_name(self) -> str:
|
||||
return self.title
|
||||
|
||||
@property
|
||||
def username(self) -> Optional[str]:
|
||||
return getattr(self._raw, "username", None)
|
||||
|
|
|
@ -6,6 +6,10 @@ from ..meta import NoPublicConstructor
|
|||
|
||||
|
||||
class RestrictionReason(metaclass=NoPublicConstructor):
|
||||
"""
|
||||
A restriction reason for :class:`telethon.types.User`.
|
||||
"""
|
||||
|
||||
__slots__ = ("_raw",)
|
||||
|
||||
def __init__(self, raw: types.RestrictionReason) -> None:
|
||||
|
@ -30,6 +34,10 @@ class RestrictionReason(metaclass=NoPublicConstructor):
|
|||
|
||||
|
||||
class User(metaclass=NoPublicConstructor):
|
||||
"""
|
||||
A user, representing either a bot account or an account created with a phone number.
|
||||
"""
|
||||
|
||||
__slots__ = ("_raw",)
|
||||
|
||||
def __init__(self, raw: types.User) -> None:
|
||||
|
|
|
@ -34,8 +34,8 @@ MediaLike = object
|
|||
|
||||
class InFileLike(Protocol):
|
||||
"""
|
||||
[File-like object](https://docs.python.org/3/glossary.html#term-file-like-object)
|
||||
used for input only, where the `read` method can be `async`.
|
||||
A :term:`file-like object` used for input only.
|
||||
The :meth:`read` method can be :keyword:`async`.
|
||||
"""
|
||||
|
||||
def read(self, n: int) -> Union[bytes, Coroutine[Any, Any, bytes]]:
|
||||
|
@ -44,8 +44,8 @@ class InFileLike(Protocol):
|
|||
|
||||
class OutFileLike(Protocol):
|
||||
"""
|
||||
[File-like object](https://docs.python.org/3/glossary.html#term-file-like-object)
|
||||
used for output only, where the `write` method can be `async`.
|
||||
A :term:`file-like object` used for output only.
|
||||
The :meth:`write` method can be :keyword:`async`.
|
||||
"""
|
||||
|
||||
def write(self, data: bytes) -> Union[Any, Coroutine[Any, Any, Any]]:
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
from typing import Self
|
||||
from typing import Optional, Self
|
||||
|
||||
from ...tl import types
|
||||
from .meta import NoPublicConstructor
|
||||
|
||||
|
||||
class LoginToken(metaclass=NoPublicConstructor):
|
||||
"""
|
||||
Result of requesting a login code via :meth:`telethon.Client.request_login_code`.
|
||||
"""
|
||||
|
||||
__slots__ = ("_code", "_phone")
|
||||
|
||||
def __init__(self, code: types.auth.SentCode, phone: str) -> None:
|
||||
|
@ -14,3 +18,7 @@ class LoginToken(metaclass=NoPublicConstructor):
|
|||
@classmethod
|
||||
def _new(cls, code: types.auth.SentCode, phone: str) -> Self:
|
||||
return cls._create(code, phone)
|
||||
|
||||
@property
|
||||
def timeout(self) -> Optional[int]:
|
||||
return self._code.timeout
|
||||
|
|
|
@ -8,6 +8,10 @@ from .meta import NoPublicConstructor
|
|||
|
||||
|
||||
class Message(metaclass=NoPublicConstructor):
|
||||
"""
|
||||
A sent message.
|
||||
"""
|
||||
|
||||
__slots__ = ("_raw",)
|
||||
|
||||
def __init__(self, message: abcs.Message) -> None:
|
||||
|
@ -28,6 +32,14 @@ class Message(metaclass=NoPublicConstructor):
|
|||
def text(self) -> Optional[str]:
|
||||
return getattr(self._raw, "message", None)
|
||||
|
||||
@property
|
||||
def html_text(self) -> Optional[str]:
|
||||
raise NotImplementedError
|
||||
|
||||
@property
|
||||
def markdown_text(self) -> Optional[str]:
|
||||
raise NotImplementedError
|
||||
|
||||
@property
|
||||
def date(self) -> Optional[datetime.datetime]:
|
||||
date = getattr(self._raw, "date", None)
|
||||
|
@ -80,3 +92,16 @@ class Message(metaclass=NoPublicConstructor):
|
|||
)
|
||||
else None
|
||||
)
|
||||
|
||||
@property
|
||||
def file(self) -> Optional[File]:
|
||||
return self._file()
|
||||
|
||||
async def delete(self) -> None:
|
||||
raise NotImplementedError
|
||||
|
||||
async def edit(self) -> None:
|
||||
raise NotImplementedError
|
||||
|
||||
async def forward_to(self) -> None:
|
||||
raise NotImplementedError
|
||||
|
|
|
@ -5,6 +5,10 @@ from .meta import NoPublicConstructor
|
|||
|
||||
|
||||
class PasswordToken(metaclass=NoPublicConstructor):
|
||||
"""
|
||||
Result of attempting to :meth:`~telethon.Client.sign_in` to a 2FA-protected account.
|
||||
"""
|
||||
|
||||
__slots__ = ("_password",)
|
||||
|
||||
def __init__(self, password: types.account.Password) -> None:
|
||||
|
|
|
@ -9,6 +9,17 @@ MsgId = NewType("MsgId", int)
|
|||
|
||||
|
||||
class RpcError(ValueError):
|
||||
"""
|
||||
A Remote Procedure Call Error.
|
||||
|
||||
Only occurs when the answer to a request sent to Telegram is not the expected result.
|
||||
The library will never construct instances of this error by itself.
|
||||
|
||||
.. seealso::
|
||||
|
||||
:doc:`/concepts/errors`
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
|
|
|
@ -6,6 +6,10 @@ from ...tl import abcs, types
|
|||
|
||||
|
||||
class PackedType(Enum):
|
||||
"""
|
||||
The type of a :class:`PackedChat`.
|
||||
"""
|
||||
|
||||
# bits: zero, has-access-hash, channel, broadcast, group, chat, user, bot
|
||||
USER = 0b0000_0010
|
||||
BOT = 0b0000_0011
|
||||
|
@ -16,6 +20,16 @@ class PackedType(Enum):
|
|||
|
||||
|
||||
class PackedChat:
|
||||
"""
|
||||
A compact representation of a :term:`chat`.
|
||||
|
||||
You can reuse it as many times as you want.
|
||||
|
||||
.. seealso::
|
||||
|
||||
:doc:`/concepts/chats`
|
||||
"""
|
||||
|
||||
__slots__ = ("ty", "id", "access_hash")
|
||||
|
||||
def __init__(self, ty: PackedType, id: int, access_hash: Optional[int]) -> None:
|
||||
|
|
|
@ -3,6 +3,14 @@ from typing import Any, Dict, List, Optional, Self
|
|||
|
||||
|
||||
class DataCenter:
|
||||
"""
|
||||
Data-center information.
|
||||
|
||||
:var id: The DC identifier.
|
||||
:var addr: The server address of the DC, in ``'ip:port'`` format.
|
||||
:var auth: Authentication key to encrypt communication with.
|
||||
"""
|
||||
|
||||
__slots__ = ("id", "addr", "auth")
|
||||
|
||||
def __init__(self, *, id: int, addr: str, auth: Optional[bytes]) -> None:
|
||||
|
@ -12,6 +20,14 @@ class DataCenter:
|
|||
|
||||
|
||||
class User:
|
||||
"""
|
||||
Information about the logged-in user.
|
||||
|
||||
:var id: User identifier.
|
||||
:var dc: Data-center identifier of the user's "home" DC.
|
||||
:var bot: :data:`True` if the user is from a bot account.
|
||||
"""
|
||||
|
||||
__slots__ = ("id", "dc", "bot")
|
||||
|
||||
def __init__(self, *, id: int, dc: int, bot: bool) -> None:
|
||||
|
@ -21,6 +37,13 @@ class User:
|
|||
|
||||
|
||||
class ChannelState:
|
||||
"""
|
||||
Update state for a channel.
|
||||
|
||||
:var id: The channel identifier.
|
||||
:var pts: The channel's partial sequence number.
|
||||
"""
|
||||
|
||||
__slots__ = ("id", "pts")
|
||||
|
||||
def __init__(self, *, id: int, pts: int) -> None:
|
||||
|
@ -29,6 +52,16 @@ class ChannelState:
|
|||
|
||||
|
||||
class UpdateState:
|
||||
"""
|
||||
Update state for an account.
|
||||
|
||||
:var pts: The primary partial sequence number.
|
||||
:var qts: The secondary partial sequence number.
|
||||
:var date: Date of the latest update sequence.
|
||||
:var seq: The sequence number.
|
||||
:var channels: Update state for channels.
|
||||
"""
|
||||
|
||||
__slots__ = (
|
||||
"pts",
|
||||
"qts",
|
||||
|
@ -55,9 +88,9 @@ class UpdateState:
|
|||
|
||||
class Session:
|
||||
"""
|
||||
A Telethon session.
|
||||
A Telethon :term:`session`.
|
||||
|
||||
A `Session` instance contains the required information to login into your
|
||||
A session instance contains the required information to login into your
|
||||
Telegram account. **Never** give the saved session file to anyone else or
|
||||
make it public.
|
||||
|
||||
|
|
|
@ -15,9 +15,9 @@ class SqliteSession(Storage):
|
|||
|
||||
SQLite is a reliable way to persist data to disk and offers file locking.
|
||||
|
||||
Paths without extension will have '.session' appended to them.
|
||||
Paths without extension will have ``'.session'`` appended to them.
|
||||
This is by convention, and to make it harder to commit session files to
|
||||
an VCS by accident (adding `*.session` to `.gitignore` will catch them).
|
||||
an VCS by accident (adding ``*.session`` to ``.gitignore`` will catch them).
|
||||
"""
|
||||
|
||||
def __init__(self, file: Union[str, Path]):
|
||||
|
|
|
@ -5,6 +5,10 @@ from ..session import Session
|
|||
|
||||
|
||||
class Storage(abc.ABC):
|
||||
"""
|
||||
Interface declaring the required methods of a :term:`session` storage.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
async def load(self) -> Optional[Session]:
|
||||
"""
|
||||
|
@ -27,4 +31,6 @@ class Storage(abc.ABC):
|
|||
Delete the saved `Session`.
|
||||
|
||||
This method is called by the library post `log_out`.
|
||||
|
||||
Note that both :meth:`load` and :meth:`save` may still be called after.
|
||||
"""
|
||||
|
|
|
@ -1,3 +1,12 @@
|
|||
"""
|
||||
Filters are functions that accept a single parameter, an :class:`~telethon.events.Event` instance, and return a :class:`bool`.
|
||||
|
||||
When the return value is :data:`True`, the associated :mod:`~telethon.events` handler will be invoked.
|
||||
|
||||
.. seealso::
|
||||
|
||||
The :doc:`/concepts/updates` concept to learn to combine filters or define your own.
|
||||
"""
|
||||
from .._impl.client.events.filters import (
|
||||
All,
|
||||
Any,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
from ._impl.client.client import Config, InlineResult, InlineResults
|
||||
from ._impl.client.client import Config, InlineResult
|
||||
from ._impl.client.types import (
|
||||
AsyncList,
|
||||
Channel,
|
||||
|
@ -20,7 +20,6 @@ from ._impl.session import PackedChat, PackedType
|
|||
__all__ = [
|
||||
"Config",
|
||||
"InlineResult",
|
||||
"InlineResults",
|
||||
"AsyncList",
|
||||
"Channel",
|
||||
"Chat",
|
||||
|
|
|
@ -18,7 +18,7 @@ def main() -> None:
|
|||
run("isort", ".", "-c", "--profile", "black", "--gitignore")
|
||||
or run("black", ".", "--check", "--extend-exclude", BLACK_IGNORE)
|
||||
or run("mypy", "--strict", ".")
|
||||
or run("sphinx", "-nW", "client/doc", tmp_dir)
|
||||
or run("sphinx", "-M", "dummy", "client/doc", tmp_dir, "-n", "-W")
|
||||
or run("pytest", ".", "-m", "not net")
|
||||
)
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user