Update docstrings to have consistent style

This commit is contained in:
Lonami Exo 2019-05-20 11:38:26 +02:00
parent 4b74d16438
commit 7c1c040d50
15 changed files with 501 additions and 295 deletions

View File

@ -127,13 +127,6 @@ class AccountMethods(UserMethods):
them. In other words, returns the current client modified so that them. In other words, returns the current client modified so that
requests are done as a takeout: requests are done as a takeout:
>>> from telethon.sync import TelegramClient
>>>
>>> with TelegramClient(...) as client:
>>> with client.takeout() as takeout:
>>> client.get_messages('me') # normal call
>>> takeout.get_messages('me') # wrapped through takeout
Some of the calls made through the takeout session will have lower Some of the calls made through the takeout session will have lower
flood limits. This is useful if you want to export the data from flood limits. This is useful if you want to export the data from
conversations or mass-download media, since the rate limits will conversations or mass-download media, since the rate limits will
@ -159,7 +152,7 @@ class AccountMethods(UserMethods):
preserved for future usage as `client.session.takeout_id preserved for future usage as `client.session.takeout_id
<telethon.sessions.abstract.Session.takeout_id>`. <telethon.sessions.abstract.Session.takeout_id>`.
Args: Arguments
finalize (`bool`): finalize (`bool`):
Whether the takeout session should be finalized upon Whether the takeout session should be finalized upon
exit or not. exit or not.
@ -191,14 +184,16 @@ class AccountMethods(UserMethods):
The maximum file size, in bytes, that you plan The maximum file size, in bytes, that you plan
to download for each message with media. to download for each message with media.
Example: Example
.. code-block:: python .. code-block:: python
from telethon import errors from telethon import errors
try: try:
with client.takeout() as takeout: with client.takeout() as takeout:
client.get_messages('me') # normal call
takeout.get_messages('me') # wrapped through takeout (less limits)
for message in takeout.iter_messages(chat, wait_time=0): for message in takeout.iter_messages(chat, wait_time=0):
... # Do something with the message ... # Do something with the message
@ -228,12 +223,17 @@ class AccountMethods(UserMethods):
""" """
Finishes the current takeout session. Finishes the current takeout session.
Args: Arguments
success (`bool`): success (`bool`):
Whether the takeout completed successfully or not. Whether the takeout completed successfully or not.
Returns: Returns
``True`` if the operation was successful, ``False`` otherwise. ``True`` if the operation was successful, ``False`` otherwise.
Example
.. code-block:: python
client.end_takeout(success=False)
""" """
try: try:
async with _TakeoutClient(True, self, None) as takeout: async with _TakeoutClient(True, self, None) as takeout:

View File

@ -44,7 +44,7 @@ class AuthMethods(MessageParseMethods, UserMethods):
coroutine that you should await on your own code; otherwise coroutine that you should await on your own code; otherwise
the loop is ran until said coroutine completes. the loop is ran until said coroutine completes.
Args: Arguments
phone (`str` | `int` | `callable`): phone (`str` | `int` | `callable`):
The phone (or callable without arguments to get it) The phone (or callable without arguments to get it)
to which the code will be sent. If a bot-token-like to which the code will be sent. If a bot-token-like
@ -81,11 +81,11 @@ class AuthMethods(MessageParseMethods, UserMethods):
How many times the code/password callback should be How many times the code/password callback should be
retried or switching between signing in and signing up. retried or switching between signing in and signing up.
Returns: Returns
This `TelegramClient`, so initialization This `TelegramClient`, so initialization
can be chained with ``.start()``. can be chained with ``.start()``.
Example: Example
.. code-block:: python .. code-block:: python
client = TelegramClient('anon', api_id, api_hash) client = TelegramClient('anon', api_id, api_hash)
@ -271,7 +271,7 @@ class AuthMethods(MessageParseMethods, UserMethods):
This method will send the code if it's not provided. This method will send the code if it's not provided.
Args: Arguments
phone (`str` | `int`): phone (`str` | `int`):
The phone to send the code to if no code was provided, The phone to send the code to if no code was provided,
or to override the phone that was previously used with or to override the phone that was previously used with
@ -295,9 +295,18 @@ class AuthMethods(MessageParseMethods, UserMethods):
The hash returned by `send_code_request`. This can be left as The hash returned by `send_code_request`. This can be left as
``None`` to use the last hash known for the phone to be used. ``None`` to use the last hash known for the phone to be used.
Returns: Returns
The signed in user, or the information about The signed in user, or the information about
:meth:`send_code_request`. :meth:`send_code_request`.
Example
.. code-block:: python
phone = '+34 123 123 123'
client.sign_in(phone) # send code
code = input('enter code: ')
client.sign_in(phone, code)
""" """
me = await self.get_me() me = await self.get_me()
if me: if me:
@ -351,7 +360,7 @@ class AuthMethods(MessageParseMethods, UserMethods):
will be banned otherwise.** See https://telegram.org/tos will be banned otherwise.** See https://telegram.org/tos
and https://core.telegram.org/api/terms. and https://core.telegram.org/api/terms.
Args: Arguments
code (`str` | `int`): code (`str` | `int`):
The code sent by Telegram The code sent by Telegram
@ -369,8 +378,17 @@ class AuthMethods(MessageParseMethods, UserMethods):
The hash returned by `send_code_request`. This can be left as The hash returned by `send_code_request`. This can be left as
``None`` to use the last hash known for the phone to be used. ``None`` to use the last hash known for the phone to be used.
Returns: Returns
The new created :tl:`User`. The new created :tl:`User`.
Example
.. code-block:: python
phone = '+34 123 123 123'
client.send_code_request(phone)
code = input('enter code: ')
client.sign_up(code, first_name='Anna', last_name='Banana')
""" """
me = await self.get_me() me = await self.get_me()
if me: if me:
@ -421,15 +439,27 @@ class AuthMethods(MessageParseMethods, UserMethods):
""" """
Sends the Telegram code needed to login to the given phone number. Sends the Telegram code needed to login to the given phone number.
Args: Arguments
phone (`str` | `int`): phone (`str` | `int`):
The phone to which the code will be sent. The phone to which the code will be sent.
force_sms (`bool`, optional): force_sms (`bool`, optional):
Whether to force sending as SMS. Whether to force sending as SMS.
Returns: Returns
An instance of :tl:`SentCode`. An instance of :tl:`SentCode`.
Example
.. code-block:: python
phone = '+34 123 123 123'
sent = client.send_code_request(phone)
print(sent)
if sent.phone_registered:
print('This phone has an existing account registered')
else:
print('This phone does not have an account registered')
""" """
result = None result = None
phone = utils.parse_phone(phone) or self._phone phone = utils.parse_phone(phone) or self._phone
@ -461,11 +491,10 @@ class AuthMethods(MessageParseMethods, UserMethods):
""" """
Logs out Telegram and deletes the current ``*.session`` file. Logs out Telegram and deletes the current ``*.session`` file.
Returns: Returns
``True`` if the operation was successful. ``True`` if the operation was successful.
Example: Example
.. code-block:: python .. code-block:: python
# Note: you will need to login again! # Note: you will need to login again!
@ -504,6 +533,7 @@ class AuthMethods(MessageParseMethods, UserMethods):
Has no effect if both current and new password are omitted. Has no effect if both current and new password are omitted.
Arguments
current_password (`str`, optional): current_password (`str`, optional):
The current password, to authorize changing to ``new_password``. The current password, to authorize changing to ``new_password``.
Must be set if changing existing 2FA settings. Must be set if changing existing 2FA settings.
@ -533,8 +563,17 @@ class AuthMethods(MessageParseMethods, UserMethods):
If the callback returns an invalid code, it will raise If the callback returns an invalid code, it will raise
``CodeInvalidError``. ``CodeInvalidError``.
Returns: Returns
``True`` if successful, ``False`` otherwise. ``True`` if successful, ``False`` otherwise.
Example
.. code-block:: python
# Setting a password for your account which didn't have
client.edit_2fa(new_password='I_<3_Telethon')
# Removing the password
client.edit_2fa(current_password='I_<3_Telethon')
""" """
if new_password is None and current_password is None: if new_password is None and current_password is None:
return False return False

View File

@ -19,10 +19,7 @@ class BotMethods(UserMethods):
""" """
Makes an inline query to the specified bot (e.g. ``@vote New Poll``). Makes an inline query to the specified bot (e.g. ``@vote New Poll``).
>>> client = ... Arguments
>>> client.inline_query('vote', 'My New Poll')
Args:
bot (`entity`): bot (`entity`):
The bot entity to which the inline query should be made. The bot entity to which the inline query should be made.
@ -36,12 +33,11 @@ class BotMethods(UserMethods):
The geo point location information to send to the bot The geo point location information to send to the bot
for localised results. Available under some bots. for localised results. Available under some bots.
Returns: Returns
A list of `custom.InlineResult A list of `custom.InlineResult
<telethon.tl.custom.inlineresult.InlineResult>`. <telethon.tl.custom.inlineresult.InlineResult>`.
Example: Example
.. code-block:: python .. code-block:: python
# Make an inline query to @like # Make an inline query to @like

View File

@ -24,6 +24,22 @@ class ButtonMethods(UpdateMethods):
the markup very often. Otherwise, it is not necessary. the markup very often. Otherwise, it is not necessary.
This method is **not** asynchronous (don't use ``await`` on it). This method is **not** asynchronous (don't use ``await`` on it).
Arguments
buttons (`hints.MarkupLike`):
The button, list of buttons, array of buttons or markup
to convert into a markup.
inline_only (`bool`, optional):
Whether the buttons **must** be inline buttons only or not.
Example
.. code-block:: python
from telethon import Button
markup = client.build_reply_markup(Button.inline('hi'))
client.send_message('click me', buttons=markup)
""" """
if buttons is None: if buttons is None:
return None return None

View File

@ -289,7 +289,7 @@ class ChatMethods(UserMethods):
""" """
Iterator over the participants belonging to the specified chat. Iterator over the participants belonging to the specified chat.
Args: Arguments
entity (`entity`): entity (`entity`):
The entity from which to retrieve the participants list. The entity from which to retrieve the participants list.
@ -323,14 +323,13 @@ class ChatMethods(UserMethods):
This has no effect if a ``filter`` is given. This has no effect if a ``filter`` is given.
Yields: Yields
The :tl:`User` objects returned by :tl:`GetParticipantsRequest` The :tl:`User` objects returned by :tl:`GetParticipantsRequest`
with an additional ``.participant`` attribute which is the with an additional ``.participant`` attribute which is the
matched :tl:`ChannelParticipant` type for channels/megagroups matched :tl:`ChannelParticipant` type for channels/megagroups
or :tl:`ChatParticipants` for normal chats. or :tl:`ChatParticipants` for normal chats.
Example: Example
.. code-block:: python .. code-block:: python
# Show all user IDs in a chat # Show all user IDs in a chat
@ -362,6 +361,16 @@ class ChatMethods(UserMethods):
""" """
Same as `iter_participants()`, but returns a Same as `iter_participants()`, but returns a
`TotalList <telethon.helpers.TotalList>` instead. `TotalList <telethon.helpers.TotalList>` instead.
Example
.. code-block:: python
users = client.get_participants(chat)
print(users[0].first_name)
for user in users:
if user.username is not None:
print(user.username)
""" """
return await self.iter_participants(*args, **kwargs).collect() return await self.iter_participants(*args, **kwargs).collect()
@ -397,7 +406,7 @@ class ChatMethods(UserMethods):
*all* event types will be returned. If at least one of them is *all* event types will be returned. If at least one of them is
``True``, only those that are true will be returned. ``True``, only those that are true will be returned.
Args: Arguments
entity (`entity`): entity (`entity`):
The channel entity from which to get its admin log. The channel entity from which to get its admin log.
@ -472,22 +481,15 @@ class ChatMethods(UserMethods):
delete (`bool`): delete (`bool`):
If ``True``, events of message deletions will be returned. If ``True``, events of message deletions will be returned.
Yields: Yields
Instances of `telethon.tl.custom.adminlogevent.AdminLogEvent`. Instances of `telethon.tl.custom.adminlogevent.AdminLogEvent`.
Example: Example
.. code-block:: python .. code-block:: python
for event in client.iter_admin_log(channel): for event in client.iter_admin_log(channel):
if event.changed_title: if event.changed_title:
print('The title changed from', event.old, 'to', event.new) print('The title changed from', event.old, 'to', event.new)
# Get a list of deleted message events which said "heck"
events = client.get_admin_log(channel, search='heck', delete=True)
# Print the old message before it was deleted
print(events[0].old)
""" """
return _AdminLogIter( return _AdminLogIter(
self, self,
@ -519,6 +521,15 @@ class ChatMethods(UserMethods):
**kwargs) -> 'hints.TotalList': **kwargs) -> 'hints.TotalList':
""" """
Same as `iter_admin_log()`, but returns a ``list`` instead. Same as `iter_admin_log()`, but returns a ``list`` instead.
Example
.. code-block:: python
# Get a list of deleted message events which said "heck"
events = client.get_admin_log(channel, search='heck', delete=True)
# Print the old message before it was deleted
print(events[0].old)
""" """
return await self.iter_admin_log(*args, **kwargs).collect() return await self.iter_admin_log(*args, **kwargs).collect()
@ -533,22 +544,14 @@ class ChatMethods(UserMethods):
Returns a context-manager object to represent a "chat action". Returns a context-manager object to represent a "chat action".
Chat actions indicate things like "user is typing", "user is Chat actions indicate things like "user is typing", "user is
uploading a photo", etc. Normal usage is as follows: uploading a photo", etc.
.. code-block:: python
async with client.action(chat, 'typing'):
await asyncio.sleep(2) # type for 2 seconds
await client.send_message(chat, 'Hello world! I type slow ^^')
If the action is ``'cancel'``, you should just ``await`` the result, If the action is ``'cancel'``, you should just ``await`` the result,
since it makes no sense to use a context-manager for it: since it makes no sense to use a context-manager for it.
.. code-block:: python See the example below for intended usage.
await client.action(chat, 'cancel') Arguments
Args:
entity (`entity`): entity (`entity`):
The entity where the action should be showed in. The entity where the action should be showed in.
@ -587,10 +590,23 @@ class ChatMethods(UserMethods):
you don't want progress to be shown when it has already you don't want progress to be shown when it has already
completed. completed.
If you are uploading a file, you may do Returns
``progress_callback=chat.progress`` to update the progress of Either a context-manager object or a coroutine.
the action. Some clients don't care about this progress, though,
so it's mostly not needed, but still available. Example
.. code-block:: python
# Type for 2 seconds, then send a message
async with client.action(chat, 'typing'):
await asyncio.sleep(2)
await client.send_message(chat, 'Hello world! I type slow ^^')
# Cancel any previous action
await client.action(chat, 'cancel')
# Upload a document, showing its progress (most clients ignore this)
async with client.action(chat, 'document') as action:
client.send_file(chat, zip_file, progress_callback=action.progress)
""" """
if isinstance(action, str): if isinstance(action, str):
try: try:

View File

@ -117,7 +117,7 @@ class DialogMethods(UserMethods):
""" """
Iterator over the dialogs (open conversations/subscribed channels). Iterator over the dialogs (open conversations/subscribed channels).
Args: Arguments
limit (`int` | `None`): limit (`int` | `None`):
How many dialogs to be retrieved as maximum. Can be set to How many dialogs to be retrieved as maximum. Can be set to
``None`` to retrieve all dialogs. Note that this may take ``None`` to retrieve all dialogs. Note that this may take
@ -159,31 +159,15 @@ class DialogMethods(UserMethods):
archived (`bool`, optional): archived (`bool`, optional):
Alias for `folder`. If unspecified, all will be returned, Alias for `folder`. If unspecified, all will be returned,
``False`` implies ``folder=0`` and ``True`` implies ``folder=1``. ``False`` implies ``folder=0`` and ``True`` implies ``folder=1``.
Yields: Yields
Instances of `telethon.tl.custom.dialog.Dialog`. Instances of `telethon.tl.custom.dialog.Dialog`.
Example: Example
.. code-block:: python .. code-block:: python
# Get all open conversation, print the title of the first # Print all dialog IDs and the title, nicely formatted
dialogs = client.get_dialogs() for dialog in client.iter_dialogs():
first = dialogs[0] print('{:>14}: {}'.format(dialog.id, dialog.title))
print(first.title)
# Use the dialog somewhere else
client.send_message(first, 'hi')
# Get drafts
drafts = client.get_drafts()
# Getting only non-archived dialogs (both equivalent)
non_archived = client.get_dialogs(folder=0)
non_archived = client.get_dialogs(archived=False)
# Getting only archived dialogs (both equivalent)
archived = client.get_dialogs(folder=1)
non_archived = client.get_dialogs(archived=True)
""" """
if archived is not None: if archived is not None:
folder = 1 if archived else 0 folder = 1 if archived else 0
@ -202,6 +186,25 @@ class DialogMethods(UserMethods):
""" """
Same as `iter_dialogs()`, but returns a Same as `iter_dialogs()`, but returns a
`TotalList <telethon.helpers.TotalList>` instead. `TotalList <telethon.helpers.TotalList>` instead.
Example
.. code-block:: python
# Get all open conversation, print the title of the first
dialogs = client.get_dialogs()
first = dialogs[0]
print(first.title)
# Use the dialog somewhere else
client.send_message(first, 'hi')
# Getting only non-archived dialogs (both equivalent)
non_archived = client.get_dialogs(folder=0)
non_archived = client.get_dialogs(archived=False)
# Getting only archived dialogs (both equivalent)
archived = client.get_dialogs(folder=1)
non_archived = client.get_dialogs(archived=True)
""" """
return await self.iter_dialogs(*args, **kwargs).collect() return await self.iter_dialogs(*args, **kwargs).collect()
@ -213,6 +216,13 @@ class DialogMethods(UserMethods):
You can call `telethon.tl.custom.draft.Draft.set_message` You can call `telethon.tl.custom.draft.Draft.set_message`
to change the message or `telethon.tl.custom.draft.Draft.delete` to change the message or `telethon.tl.custom.draft.Draft.delete`
among other things. among other things.
Example
.. code-block:: python
# Clear all drafts
for draft in client.get_drafts():
draft.delete()
""" """
# TODO Passing a limit here makes no sense # TODO Passing a limit here makes no sense
return _DraftsIter(self, None) return _DraftsIter(self, None)
@ -220,6 +230,13 @@ class DialogMethods(UserMethods):
async def get_drafts(self: 'TelegramClient') -> 'hints.TotalList': async def get_drafts(self: 'TelegramClient') -> 'hints.TotalList':
""" """
Same as `iter_drafts()`, but returns a list instead. Same as `iter_drafts()`, but returns a list instead.
Example
.. code-block:: python
# Get drafts, print the text of the first
drafts = client.get_drafts()
print(drafts[0].text)
""" """
return await self.iter_drafts().collect() return await self.iter_drafts().collect()
@ -233,7 +250,7 @@ class DialogMethods(UserMethods):
""" """
Archives (or un-archives) one or more dialogs. Archives (or un-archives) one or more dialogs.
Args: Arguments
entity (entities): entity (entities):
The entity or list of entities to move to the desired The entity or list of entities to move to the desired
archive folder. archive folder.
@ -258,11 +275,10 @@ class DialogMethods(UserMethods):
You can only use this parameter if the other two You can only use this parameter if the other two
are not set. are not set.
Returns: Returns
The :tl:`Updates` object that the request produces. The :tl:`Updates` object that the request produces.
Example: Example
.. code-block:: python .. code-block:: python
# Archiving the first 5 dialogs # Archiving the first 5 dialogs
@ -316,7 +332,7 @@ class DialogMethods(UserMethods):
with them, but rather a way to easily send messages and await for with them, but rather a way to easily send messages and await for
responses or other reactions. Refer to its documentation for more. responses or other reactions. Refer to its documentation for more.
Args: Arguments
entity (`entity`): entity (`entity`):
The entity with which a new conversation should be opened. The entity with which a new conversation should be opened.
@ -381,11 +397,10 @@ class DialogMethods(UserMethods):
With the setting disabled, both ``msg2`` and ``msg3`` will With the setting disabled, both ``msg2`` and ``msg3`` will
be ``'Hi!'`` since one is a response and also a reply. be ``'Hi!'`` since one is a response and also a reply.
Returns: Returns
A `Conversation <telethon.tl.custom.conversation.Conversation>`. A `Conversation <telethon.tl.custom.conversation.Conversation>`.
Example: Example
.. code-block:: python .. code-block:: python
# <you> denotes outgoing messages you sent # <you> denotes outgoing messages you sent

View File

@ -30,7 +30,7 @@ class DownloadMethods(UserMethods):
""" """
Downloads the profile photo from the given user, chat or channel. Downloads the profile photo from the given user, chat or channel.
Args: Arguments
entity (`entity`): entity (`entity`):
From who the photo will be downloaded. From who the photo will be downloaded.
@ -53,14 +53,14 @@ class DownloadMethods(UserMethods):
download_big (`bool`, optional): download_big (`bool`, optional):
Whether to use the big version of the available photos. Whether to use the big version of the available photos.
Returns: Returns
``None`` if no photo was provided, or if it was Empty. On success ``None`` if no photo was provided, or if it was Empty. On success
the file path is returned since it may differ from the one given. the file path is returned since it may differ from the one given.
Example: Example
.. code-block:: python .. code-block:: python
# Download your own profile photo
path = client.download_profile_photo('me') path = client.download_profile_photo('me')
print(path) print(path)
""" """
@ -147,6 +147,9 @@ class DownloadMethods(UserMethods):
``cryptg`` (through ``pip install cryptg``) so that decrypting the ``cryptg`` (through ``pip install cryptg``) so that decrypting the
received data is done in C instead of Python (much faster). received data is done in C instead of Python (much faster).
See also `Message.download_media() <telethon.tl.custom.message.Message.download_media>`.
Arguments
message (`Message <telethon.tl.custom.message.Message>` | :tl:`Media`): message (`Message <telethon.tl.custom.message.Message>` | :tl:`Media`):
The media or message containing the media that will be downloaded. The media or message containing the media that will be downloaded.
@ -177,12 +180,11 @@ class DownloadMethods(UserMethods):
In short, use ``thumb=0`` if you want the smallest thumbnail In short, use ``thumb=0`` if you want the smallest thumbnail
and ``thumb=-1`` if you want the largest thumbnail. and ``thumb=-1`` if you want the largest thumbnail.
Returns: Returns
``None`` if no media was provided, or if it was Empty. On success ``None`` if no media was provided, or if it was Empty. On success
the file path is returned since it may differ from the one given. the file path is returned since it may differ from the one given.
Example: Example
.. code-block:: python .. code-block:: python
path = client.download_media(message) path = client.download_media(message)
@ -190,7 +192,6 @@ class DownloadMethods(UserMethods):
# or # or
path = message.download_media() path = message.download_media()
message.download_media(filename) message.download_media(filename)
""" """
# TODO This won't work for messageService # TODO This won't work for messageService
if isinstance(message, types.Message): if isinstance(message, types.Message):
@ -236,7 +237,7 @@ class DownloadMethods(UserMethods):
""" """
Low-level method to download files from their input location. Low-level method to download files from their input location.
Args: Arguments
input_location (:tl:`InputFileLocation`): input_location (:tl:`InputFileLocation`):
The file location from which the file will be downloaded. The file location from which the file will be downloaded.
See `telethon.utils.get_input_location` source for a complete See `telethon.utils.get_input_location` source for a complete
@ -265,6 +266,13 @@ class DownloadMethods(UserMethods):
dc_id (`int`, optional): dc_id (`int`, optional):
The data center the library should connect to in order The data center the library should connect to in order
to download the file. You shouldn't worry about this. to download the file. You shouldn't worry about this.
Example
.. code-block:: python
# Download a file and print its header
data = client.download_file(input_file, bytes)
print(data[:16])
""" """
if not part_size_kb: if not part_size_kb:
if not file_size: if not file_size:

View File

@ -38,6 +38,15 @@ class MessageParseMethods(UserMethods):
that ``assert text == unparse(*parse(text))``. that ``assert text == unparse(*parse(text))``.
See :tl:`MessageEntity` for allowed message entities. See :tl:`MessageEntity` for allowed message entities.
Example
.. code-block:: python
# Disabling default formatting
client.parse_mode = None
# Enabling HTML as the default format
client.parse_mode = 'html'
""" """
return self._parse_mode return self._parse_mode

View File

@ -319,7 +319,13 @@ class MessageMethods(UploadMethods, ButtonMethods, MessageParseMethods):
If either `search`, `filter` or `from_user` are provided, If either `search`, `filter` or `from_user` are provided,
:tl:`messages.Search` will be used instead of :tl:`messages.getHistory`. :tl:`messages.Search` will be used instead of :tl:`messages.getHistory`.
Args: .. note::
Telegram's flood wait limit for :tl:`GetHistoryRequest` seems to
be around 30 seconds per 10 requests, therefore a sleep of 1
second is the default for this limit (or above).
Arguments
entity (`entity`): entity (`entity`):
The entity from whom to retrieve the message history. The entity from whom to retrieve the message history.
@ -406,16 +412,10 @@ class MessageMethods(UploadMethods, ButtonMethods, MessageParseMethods):
You cannot use this if both `entity` and `ids` are ``None``. You cannot use this if both `entity` and `ids` are ``None``.
Yields: Yields
Instances of `telethon.tl.custom.message.Message`. Instances of `telethon.tl.custom.message.Message`.
Notes: Example
Telegram's flood wait limit for :tl:`GetHistoryRequest` seems to
be around 30 seconds per 10 requests, therefore a sleep of 1
second is the default for this limit (or above).
Example:
.. code-block:: python .. code-block:: python
# From most-recent to oldest # From most-recent to oldest
@ -439,7 +439,6 @@ class MessageMethods(UploadMethods, ButtonMethods, MessageParseMethods):
for message in client.iter_messages(chat, filter=InputMessagesFilterPhotos): for message in client.iter_messages(chat, filter=InputMessagesFilterPhotos):
print(message.photo) print(message.photo)
""" """
if ids is not None: if ids is not None:
return _IDsIter(self, limit, entity=entity, ids=ids) return _IDsIter(self, limit, entity=entity, ids=ids)
@ -476,8 +475,7 @@ class MessageMethods(UploadMethods, ButtonMethods, MessageParseMethods):
a single `Message <telethon.tl.custom.message.Message>` will be a single `Message <telethon.tl.custom.message.Message>` will be
returned for convenience instead of a list. returned for convenience instead of a list.
Example: Example
.. code-block:: python .. code-block:: python
# Get 0 photos and print the total to show how many photos there are # Get 0 photos and print the total to show how many photos there are
@ -540,8 +538,10 @@ class MessageMethods(UploadMethods, ButtonMethods, MessageParseMethods):
is also done through this method. Simply send ``'/start data'`` to is also done through this method. Simply send ``'/start data'`` to
the bot. the bot.
Args: See also `Message.respond() <telethon.tl.custom.message.Message.respond>`
and `Message.reply() <telethon.tl.custom.message.Message.reply>`.
Arguments
entity (`entity`): entity (`entity`):
To who will it be sent. To who will it be sent.
@ -596,20 +596,14 @@ class MessageMethods(UploadMethods, ButtonMethods, MessageParseMethods):
channel or not. Defaults to ``False``, which means it will channel or not. Defaults to ``False``, which means it will
notify them. Set it to ``True`` to alter this behaviour. notify them. Set it to ``True`` to alter this behaviour.
Returns: Returns
The sent `custom.Message <telethon.tl.custom.message.Message>`. The sent `custom.Message <telethon.tl.custom.message.Message>`.
Example: Example
.. code-block:: python .. code-block:: python
client.send_message('lonami', 'Thanks for the Telethon library!') # Markdown is the default
client.send_message('lonami', 'Thanks for the **Telethon** library!')
# Replies and responses
message = client.send_message('me', 'Trying out **markdown**')
message.reply('Trying replies')
message.respond('Trying responses')
# Default to another parse mode # Default to another parse mode
client.parse_mode = 'html' client.parse_mode = 'html'
@ -748,7 +742,9 @@ class MessageMethods(UploadMethods, ButtonMethods, MessageParseMethods):
(the "forwarded from" text), you should use `send_message` with (the "forwarded from" text), you should use `send_message` with
the original message instead. This will send a copy of it. the original message instead. This will send a copy of it.
Args: See also `Message.forward_to() <telethon.tl.custom.message.Message.forward_to>`.
Arguments
entity (`entity`): entity (`entity`):
To which entity the message(s) will be forwarded. To which entity the message(s) will be forwarded.
@ -777,7 +773,7 @@ class MessageMethods(UploadMethods, ButtonMethods, MessageParseMethods):
``True`` will group always (even converting separate ``True`` will group always (even converting separate
images into albums), and ``False`` will never group. images into albums), and ``False`` will never group.
Returns: Returns
The list of forwarded `telethon.tl.custom.message.Message`, The list of forwarded `telethon.tl.custom.message.Message`,
or a single one if a list wasn't provided as input. or a single one if a list wasn't provided as input.
@ -785,8 +781,7 @@ class MessageMethods(UploadMethods, ButtonMethods, MessageParseMethods):
will fail with ``MessageIdInvalidError``. If only some are will fail with ``MessageIdInvalidError``. If only some are
invalid, the list will have ``None`` instead of those messages. invalid, the list will have ``None`` instead of those messages.
Example: Example
.. code-block:: python .. code-block:: python
# a single one # a single one
@ -884,7 +879,9 @@ class MessageMethods(UploadMethods, ButtonMethods, MessageParseMethods):
""" """
Edits the given message to change its text or media. Edits the given message to change its text or media.
Args: See also `Message.edit() <telethon.tl.custom.message.Message.edit>`.
Arguments
entity (`entity` | `Message <telethon.tl.custom.message.Message>`): entity (`entity` | `Message <telethon.tl.custom.message.Message>`):
From which chat to edit the message. This can also be From which chat to edit the message. This can also be
the message to be edited, and the entity will be inferred the message to be edited, and the entity will be inferred
@ -925,38 +922,28 @@ class MessageMethods(UploadMethods, ButtonMethods, MessageParseMethods):
you have signed in as a bot. You can also pass your own you have signed in as a bot. You can also pass your own
:tl:`ReplyMarkup` here. :tl:`ReplyMarkup` here.
Examples: Returns
The edited `telethon.tl.custom.message.Message`, unless
`entity` was a :tl:`InputBotInlineMessageID` in which
case this method returns a boolean.
>>> client = ... Raises
>>> message = client.send_message('username', 'hello')
>>>
>>> client.edit_message('username', message, 'hello!')
>>> # or
>>> client.edit_message('username', message.id, 'Hello')
>>> # or
>>> client.edit_message(message, 'Hello!')
Raises:
``MessageAuthorRequiredError`` if you're not the author of the ``MessageAuthorRequiredError`` if you're not the author of the
message but tried editing it anyway. message but tried editing it anyway.
``MessageNotModifiedError`` if the contents of the message were ``MessageNotModifiedError`` if the contents of the message were
not modified at all. not modified at all.
Returns: Example
The edited `telethon.tl.custom.message.Message`, unless
`entity` was a :tl:`InputBotInlineMessageID` in which
case this method returns a boolean.
Example:
.. code-block:: python .. code-block:: python
client.edit_message(message, 'New text') message = client.send_message(chat, 'hello')
client.edit_message(chat, message, 'hello!')
# or # or
message.edit('New text') client.edit_message(chat, message.id, 'hello!!')
# or # or
client.edit_message(chat, message_id, 'New text') client.edit_message(message, 'hello!!!')
""" """
if isinstance(entity, types.InputBotInlineMessageID): if isinstance(entity, types.InputBotInlineMessageID):
text = message text = message
@ -1002,7 +989,16 @@ class MessageMethods(UploadMethods, ButtonMethods, MessageParseMethods):
""" """
Deletes the given messages, optionally "for everyone". Deletes the given messages, optionally "for everyone".
Args: See also `Message.delete() <telethon.tl.custom.message.Message.delete>`.
.. warning::
This method does **not** validate that the message IDs belong
to the chat that you passed! It's possible for the method to
delete messages from different private chats and small group
chats at once, so make sure to pass the right IDs.
Arguments
entity (`entity`): entity (`entity`):
From who the message will be deleted. This can actually From who the message will be deleted. This can actually
be ``None`` for normal chats, but **must** be present be ``None`` for normal chats, but **must** be present
@ -1025,17 +1021,14 @@ class MessageMethods(UploadMethods, ButtonMethods, MessageParseMethods):
Disabling this has no effect on channels or megagroups, Disabling this has no effect on channels or megagroups,
since it will unconditionally delete the message for everyone. since it will unconditionally delete the message for everyone.
Returns: Returns
A list of :tl:`AffectedMessages`, each item being the result A list of :tl:`AffectedMessages`, each item being the result
for the delete calls of the messages in chunks of 100 each. for the delete calls of the messages in chunks of 100 each.
Example: Example
.. code-block:: python .. code-block:: python
client.delete_messages(chat, messages) client.delete_messages(chat, messages)
# or
message.delete()
""" """
if not utils.is_list_like(message_ids): if not utils.is_list_like(message_ids):
message_ids = (message_ids,) message_ids = (message_ids,)
@ -1074,7 +1067,7 @@ class MessageMethods(UploadMethods, ButtonMethods, MessageParseMethods):
If neither message nor maximum ID are provided, all messages will be If neither message nor maximum ID are provided, all messages will be
marked as read by assuming that ``max_id = 0``. marked as read by assuming that ``max_id = 0``.
Args: Arguments
entity (`entity`): entity (`entity`):
The chat where these messages are located. The chat where these messages are located.
@ -1092,8 +1085,7 @@ class MessageMethods(UploadMethods, ButtonMethods, MessageParseMethods):
If no message is provided, this will be the only action If no message is provided, this will be the only action
taken. taken.
Example: Example
.. code-block:: python .. code-block:: python
client.send_read_acknowledge(last_message) client.send_read_acknowledge(last_message)

View File

@ -34,7 +34,7 @@ class TelegramBaseClient(abc.ABC):
basic stuff like connecting, switching data center, etc, and basic stuff like connecting, switching data center, etc, and
leaves the `__call__` unimplemented. leaves the `__call__` unimplemented.
Args: Arguments
session (`str` | `telethon.sessions.abstract.Session`, `None`): session (`str` | `telethon.sessions.abstract.Session`, `None`):
The file name of the session file to be used if a string is The file name of the session file to be used if a string is
given (it may be a full path), or the Session instance to be given (it may be a full path), or the Session instance to be
@ -346,6 +346,18 @@ class TelegramBaseClient(abc.ABC):
def loop(self: 'TelegramClient') -> asyncio.AbstractEventLoop: def loop(self: 'TelegramClient') -> asyncio.AbstractEventLoop:
""" """
Property with the ``asyncio`` event loop used by this client. Property with the ``asyncio`` event loop used by this client.
Example
.. code-block:: python
# Download media in the background
task = client.loop_create_task(message.download_media())
# Do some work
...
# Join the task (wait for it to complete)
await task
""" """
return self._loop return self._loop
@ -353,6 +365,15 @@ class TelegramBaseClient(abc.ABC):
def disconnected(self: 'TelegramClient') -> asyncio.Future: def disconnected(self: 'TelegramClient') -> asyncio.Future:
""" """
Property with a ``Future`` that resolves upon disconnection. Property with a ``Future`` that resolves upon disconnection.
Example
.. code-block:: python
# Wait for a disconnection to occur
try:
await client.disconnected
except OSError:
print('Error on disconnect')
""" """
return self._sender.disconnected return self._sender.disconnected
@ -363,6 +384,14 @@ class TelegramBaseClient(abc.ABC):
async def connect(self: 'TelegramClient') -> None: async def connect(self: 'TelegramClient') -> None:
""" """
Connects to Telegram. Connects to Telegram.
Example
.. code-block:: python
try:
client.connect()
except OSError:
print('Failed to connect')
""" """
await self._sender.connect(self._connection( await self._sender.connect(self._connection(
self.session.server_address, self.session.server_address,
@ -385,6 +414,12 @@ class TelegramBaseClient(abc.ABC):
Returns ``True`` if the user has connected. Returns ``True`` if the user has connected.
This method is **not** asynchronous (don't use ``await`` on it). This method is **not** asynchronous (don't use ``await`` on it).
Example
.. code-block:: python
while client.is_connected():
await asyncio.sleep(1)
""" """
sender = getattr(self, '_sender', None) sender = getattr(self, '_sender', None)
return sender and sender.is_connected() return sender and sender.is_connected()
@ -397,8 +432,7 @@ class TelegramBaseClient(abc.ABC):
coroutine that you should await on your own code; otherwise coroutine that you should await on your own code; otherwise
the loop is ran until said coroutine completes. the loop is ran until said coroutine completes.
Example: Example
.. code-block:: python .. code-block:: python
# You don't need to use this if you used "with client" # You don't need to use this if you used "with client"

View File

@ -39,6 +39,15 @@ class UpdateMethods(UserMethods):
If the loop is already running, this method returns a coroutine If the loop is already running, this method returns a coroutine
that you should await on your own code. that you should await on your own code.
Example
.. code-block:: python
# Blocks the current task here until a disconnection occurs.
#
# You will still receive updates, since this prevents the
# script from exiting.
client.run_until_disconnected()
""" """
if self.loop.is_running(): if self.loop.is_running():
return self._run_until_disconnected() return self._run_until_disconnected()
@ -54,19 +63,22 @@ class UpdateMethods(UserMethods):
""" """
Decorator used to `add_event_handler` more conveniently. Decorator used to `add_event_handler` more conveniently.
>>> from telethon import TelegramClient, events
>>> client = TelegramClient(...)
>>>
>>> @client.on(events.NewMessage)
... async def handler(event):
... ...
...
>>>
Args: Arguments
event (`_EventBuilder` | `type`): event (`_EventBuilder` | `type`):
The event builder class or instance to be used, The event builder class or instance to be used,
for instance ``events.NewMessage``. for instance ``events.NewMessage``.
Example
.. code-block:: python
from telethon import TelegramClient, events
client = TelegramClient(...)
# Here we use client.on
@client.on(events.NewMessage)
async def handler(event):
...
""" """
def decorator(f): def decorator(f):
self.add_event_handler(f, event) self.add_event_handler(f, event)
@ -83,7 +95,7 @@ class UpdateMethods(UserMethods):
The callback will be called when the specified event occurs. The callback will be called when the specified event occurs.
Args: Arguments
callback (`callable`): callback (`callable`):
The callable function accepting one parameter to be used. The callable function accepting one parameter to be used.
@ -98,6 +110,17 @@ class UpdateMethods(UserMethods):
If left unspecified, `telethon.events.raw.Raw` (the If left unspecified, `telethon.events.raw.Raw` (the
:tl:`Update` objects with no further processing) will :tl:`Update` objects with no further processing) will
be passed instead. be passed instead.
Example
.. code-block:: python
from telethon import TelegramClient, events
client = TelegramClient(...)
async def handler(event):
...
client.add_event_handler(handler, events.NewMessage)
""" """
builders = events._get_handlers(callback) builders = events._get_handlers(callback)
if builders is not None: if builders is not None:
@ -121,6 +144,21 @@ class UpdateMethods(UserMethods):
If no event is given, all events for this callback are removed. If no event is given, all events for this callback are removed.
Returns how many callbacks were removed. Returns how many callbacks were removed.
Example
.. code-block:: python
@client.on(events.Raw)
@client.on(events.NewMessage)
async def handler(event):
...
# Removes only the "Raw" handling
# "handler" will still receive "events.NewMessage"
client.remove_event_handler(handler, events.Raw)
# "handler" will stop receiving anything
client.remove_event_handler(handler)
""" """
found = 0 found = 0
if event and not isinstance(event, type): if event and not isinstance(event, type):
@ -141,7 +179,19 @@ class UpdateMethods(UserMethods):
""" """
Lists all registered event handlers. Lists all registered event handlers.
Returns a list of pairs consisting of ``(callback, event)``. Returns
A list of pairs consisting of ``(callback, event)``.
Example
.. code-block:: python
@client.on(events.NewMessage(pattern='hello'))
async def on_greeting(event):
'''Greets someone'''
await event.reply('Hi')
for callback, event in client.list_event_handlers():
print(id(callback), type(event))
""" """
return [(callback, event) for event, callback in self._event_builders] return [(callback, event) for event, callback in self._event_builders]
@ -152,6 +202,11 @@ class UpdateMethods(UserMethods):
so that the updates it loads can by processed by your script. so that the updates it loads can by processed by your script.
This can also be used to forcibly fetch new updates if there are any. This can also be used to forcibly fetch new updates if there are any.
Example
.. code-block:: python
client.catch_up()
""" """
pts, date = self._state_cache[None] pts, date = self._state_cache[None]
if not pts: if not pts:

View File

@ -109,7 +109,17 @@ class UploadMethods(ButtonMethods, MessageParseMethods, UserMethods):
""" """
Sends message with the given file to the specified entity. Sends message with the given file to the specified entity.
Args: .. note::
If the ``hachoir3`` package (``hachoir`` module) is installed,
it will be used to determine metadata from audio and video files.
If the ``pillow`` package is installed and you are sending a photo,
it will be resized to fit within the maximum dimensions allowed
by Telegram to avoid ``errors.PhotoInvalidDimensionsError``. This
cannot be done if you are sending :tl:`InputFile`, however.
Arguments
entity (`entity`): entity (`entity`):
Who will receive the file. Who will receive the file.
@ -220,21 +230,11 @@ class UploadMethods(ButtonMethods, MessageParseMethods, UserMethods):
these to MP4 before sending if you want them to be streamable. these to MP4 before sending if you want them to be streamable.
Unsupported formats will result in ``VideoContentTypeError``. Unsupported formats will result in ``VideoContentTypeError``.
Notes: Returns
If the ``hachoir3`` package (``hachoir`` module) is installed,
it will be used to determine metadata from audio and video files.
If the `pillow` package is installed and you are sending a photo,
it will be resized to fit within the maximum dimensions allowed
by Telegram to avoid ``errors.PhotoInvalidDimensionsError``. This
cannot be done if you are sending :tl:`InputFile`, however.
Returns:
The `telethon.tl.custom.message.Message` (or messages) containing The `telethon.tl.custom.message.Message` (or messages) containing
the sent file, or messages if a list of them was passed. the sent file, or messages if a list of them was passed.
Example: Example
.. code-block:: python .. code-block:: python
# Normal files like photos # Normal files like photos
@ -422,7 +422,7 @@ class UploadMethods(ButtonMethods, MessageParseMethods, UserMethods):
remotely in the Telegram servers, which can be later used on. This remotely in the Telegram servers, which can be later used on. This
will **not** upload the file to your own chat or any chat at all. will **not** upload the file to your own chat or any chat at all.
Args: Arguments
file (`str` | `bytes` | `file`): file (`str` | `bytes` | `file`):
The path of the file, byte array, or stream that will be sent. The path of the file, byte array, or stream that will be sent.
Note that if a byte array or a stream is given, a filename Note that if a byte array or a stream is given, a filename
@ -449,13 +449,12 @@ class UploadMethods(ButtonMethods, MessageParseMethods, UserMethods):
A callback function accepting two parameters: A callback function accepting two parameters:
``(sent bytes, total)``. ``(sent bytes, total)``.
Returns: Returns
:tl:`InputFileBig` if the file size is larger than 10MB, :tl:`InputFileBig` if the file size is larger than 10MB,
`telethon.tl.custom.inputsizedfile.InputSizedFile` `telethon.tl.custom.inputsizedfile.InputSizedFile`
(subclass of :tl:`InputFile`) otherwise. (subclass of :tl:`InputFile`) otherwise.
Example: Example
.. code-block:: python .. code-block:: python
# Photos as photo and document # Photos as photo and document

View File

@ -108,14 +108,19 @@ class UserMethods(TelegramBaseClient):
If the user has not logged in yet, this method returns ``None``. If the user has not logged in yet, this method returns ``None``.
Args: Arguments
input_peer (`bool`, optional): input_peer (`bool`, optional):
Whether to return the :tl:`InputPeerUser` version or the normal Whether to return the :tl:`InputPeerUser` version or the normal
:tl:`User`. This can be useful if you just need to know the ID :tl:`User`. This can be useful if you just need to know the ID
of yourself. of yourself.
Returns: Returns
Your own :tl:`User`. Your own :tl:`User`.
Example
.. code-block:: python
print(client.get_me().username)
""" """
if input_peer and self._self_input_peer: if input_peer and self._self_input_peer:
return self._self_input_peer return self._self_input_peer
@ -137,6 +142,14 @@ class UserMethods(TelegramBaseClient):
async def is_bot(self: 'TelegramClient') -> bool: async def is_bot(self: 'TelegramClient') -> bool:
""" """
Return ``True`` if the signed-in user is a bot, ``False`` otherwise. Return ``True`` if the signed-in user is a bot, ``False`` otherwise.
Example
.. code-block:: python
if client.is_bot():
print('Beep')
else:
print('Hello')
""" """
if self._bot is None: if self._bot is None:
self._bot = (await self.get_me()).bot self._bot = (await self.get_me()).bot
@ -146,6 +159,14 @@ class UserMethods(TelegramBaseClient):
async def is_user_authorized(self: 'TelegramClient') -> bool: async def is_user_authorized(self: 'TelegramClient') -> bool:
""" """
Returns ``True`` if the user is authorized (i.e. has logged in). Returns ``True`` if the user is authorized (i.e. has logged in).
Example
.. code-block:: python
if not client.is_user_authorized():
client.send_code_request(phone)
code = input('enter code: ')
client.sign_in(phone, code)
""" """
if self._authorized is None: if self._authorized is None:
try: try:
@ -165,6 +186,7 @@ class UserMethods(TelegramBaseClient):
or :tl:`Channel`. You can also pass a list or iterable of entities, or :tl:`Channel`. You can also pass a list or iterable of entities,
and they will be efficiently fetched from the network. and they will be efficiently fetched from the network.
Arguments
entity (`str` | `int` | :tl:`Peer` | :tl:`InputPeer`): entity (`str` | `int` | :tl:`Peer` | :tl:`InputPeer`):
If a username is given, **the username will be resolved** making If a username is given, **the username will be resolved** making
an API call every time. Resolving usernames is an expensive an API call every time. Resolving usernames is an expensive
@ -188,12 +210,11 @@ class UserMethods(TelegramBaseClient):
If the entity can't be found, ``ValueError`` will be raised. If the entity can't be found, ``ValueError`` will be raised.
Returns: Returns
:tl:`User`, :tl:`Chat` or :tl:`Channel` corresponding to the :tl:`User`, :tl:`Chat` or :tl:`Channel` corresponding to the
input entity. A list will be returned if more than one was given. input entity. A list will be returned if more than one was given.
Example: Example
.. code-block:: python .. code-block:: python
from telethon import utils from telethon import utils
@ -284,18 +305,7 @@ class UserMethods(TelegramBaseClient):
first, but if you're going to use an entity often, consider making the first, but if you're going to use an entity often, consider making the
call: call:
>>> import asyncio Arguments
>>> rc = asyncio.get_event_loop().run_until_complete
>>>
>>> from telethon import TelegramClient
>>> client = TelegramClient(...)
>>> # If you're going to use "username" often in your code
>>> # (make a lot of calls), consider getting its input entity
>>> # once, and then using the "user" everywhere instead.
>>> user = rc(client.get_input_entity('username'))
>>> # The same applies to IDs, chats or channels.
>>> chat = rc(client.get_input_entity(-123456789))
entity (`str` | `int` | :tl:`Peer` | :tl:`InputPeer`): entity (`str` | `int` | :tl:`Peer` | :tl:`InputPeer`):
If a username or invite link is given, **the library will If a username or invite link is given, **the library will
use the cache**. This means that it's possible to be using use the cache**. This means that it's possible to be using
@ -329,12 +339,23 @@ class UserMethods(TelegramBaseClient):
If the entity can't be found, ``ValueError`` will be raised. If the entity can't be found, ``ValueError`` will be raised.
Returns: Returns
:tl:`InputPeerUser`, :tl:`InputPeerChat` or :tl:`InputPeerChannel` :tl:`InputPeerUser`, :tl:`InputPeerChat` or :tl:`InputPeerChannel`
or :tl:`InputPeerSelf` if the parameter is ``'me'`` or ``'self'``. or :tl:`InputPeerSelf` if the parameter is ``'me'`` or ``'self'``.
If you need to get the ID of yourself, you should use If you need to get the ID of yourself, you should use
`get_me` with ``input_peer=True``) instead. `get_me` with ``input_peer=True``) instead.
Example
.. code-block:: python
# If you're going to use "username" often in your code
# (make a lot of calls), consider getting its input entity
# once, and then using the "user" everywhere instead.
user = client.get_input_entity('username')
# The same applies to IDs, chats or channels.
chat = client.get_input_entity(-123456789)
""" """
# Short-circuit if the input parameter directly maps to an InputPeer # Short-circuit if the input parameter directly maps to an InputPeer
try: try:
@ -411,6 +432,11 @@ class UserMethods(TelegramBaseClient):
If ``add_mark is False``, then a positive ID will be returned If ``add_mark is False``, then a positive ID will be returned
instead. By default, bot-API style IDs (signed) are returned. instead. By default, bot-API style IDs (signed) are returned.
Example
.. code-block:: python
print(client.get_peer_id('me'))
""" """
if isinstance(peer, int): if isinstance(peer, int):
return utils.get_peer_id(peer, add_mark=add_mark) return utils.get_peer_id(peer, add_mark=add_mark)

View File

@ -185,6 +185,7 @@ PHOTO_INVALID_DIMENSIONS,400,The photo dimensions are invalid (hint: `pip instal
PHOTO_SAVE_FILE_INVALID,400,The photo you tried to send cannot be saved by Telegram. A reason may be that it exceeds 10MB. Try resizing it locally PHOTO_SAVE_FILE_INVALID,400,The photo you tried to send cannot be saved by Telegram. A reason may be that it exceeds 10MB. Try resizing it locally
PHOTO_THUMB_URL_EMPTY,400,The URL used as a thumbnail appears to be empty or has caused another HTTP error PHOTO_THUMB_URL_EMPTY,400,The URL used as a thumbnail appears to be empty or has caused another HTTP error
PIN_RESTRICTED,400,You can't pin messages in private chats with other people PIN_RESTRICTED,400,You can't pin messages in private chats with other people
POLL_OPTION_DUPLICATE,400,A duplicate option was sent in the same poll
POLL_UNSUPPORTED,400,This layer does not support polls in the issued method POLL_UNSUPPORTED,400,This layer does not support polls in the issued method
PRIVACY_KEY_INVALID,400,The privacy key is invalid PRIVACY_KEY_INVALID,400,The privacy key is invalid
PTS_CHANGE_EMPTY,500,No PTS change PTS_CHANGE_EMPTY,500,No PTS change

1 name codes description
185 PHOTO_SAVE_FILE_INVALID 400 The photo you tried to send cannot be saved by Telegram. A reason may be that it exceeds 10MB. Try resizing it locally
186 PHOTO_THUMB_URL_EMPTY 400 The URL used as a thumbnail appears to be empty or has caused another HTTP error
187 PIN_RESTRICTED 400 You can't pin messages in private chats with other people
188 POLL_OPTION_DUPLICATE 400 A duplicate option was sent in the same poll
189 POLL_UNSUPPORTED 400 This layer does not support polls in the issued method
190 PRIVACY_KEY_INVALID 400 The privacy key is invalid
191 PTS_CHANGE_EMPTY 500 No PTS change

View File

@ -234,7 +234,7 @@ messages.sendEncrypted,user,CHAT_ID_INVALID DATA_INVALID ENCRYPTION_DECLINED MSG
messages.sendEncryptedFile,user,MSG_WAIT_FAILED messages.sendEncryptedFile,user,MSG_WAIT_FAILED
messages.sendEncryptedService,user,DATA_INVALID ENCRYPTION_DECLINED MSG_WAIT_FAILED USER_IS_BLOCKED messages.sendEncryptedService,user,DATA_INVALID ENCRYPTION_DECLINED MSG_WAIT_FAILED USER_IS_BLOCKED
messages.sendInlineBotResult,user,CHAT_SEND_INLINE_FORBIDDEN CHAT_WRITE_FORBIDDEN INLINE_RESULT_EXPIRED PEER_ID_INVALID QUERY_ID_EMPTY WEBPAGE_CURL_FAILED WEBPAGE_MEDIA_EMPTY messages.sendInlineBotResult,user,CHAT_SEND_INLINE_FORBIDDEN CHAT_WRITE_FORBIDDEN INLINE_RESULT_EXPIRED PEER_ID_INVALID QUERY_ID_EMPTY WEBPAGE_CURL_FAILED WEBPAGE_MEDIA_EMPTY
messages.sendMedia,both,BOT_POLLS_DISABLED CHANNEL_INVALID CHANNEL_PRIVATE CHAT_ADMIN_REQUIRED CHAT_SEND_MEDIA_FORBIDDEN CHAT_WRITE_FORBIDDEN EXTERNAL_URL_INVALID FILE_PARTS_INVALID FILE_PART_LENGTH_INVALID INPUT_USER_DEACTIVATED MEDIA_CAPTION_TOO_LONG MEDIA_EMPTY PEER_ID_INVALID PHOTO_EXT_INVALID PHOTO_INVALID_DIMENSIONS PHOTO_SAVE_FILE_INVALID RANDOM_ID_DUPLICATE STORAGE_CHECK_FAILED Timeout USER_BANNED_IN_CHANNEL USER_IS_BLOCKED USER_IS_BOT VIDEO_CONTENT_TYPE_INVALID WEBPAGE_CURL_FAILED WEBPAGE_MEDIA_EMPTY messages.sendMedia,both,BOT_POLLS_DISABLED CHANNEL_INVALID CHANNEL_PRIVATE CHAT_ADMIN_REQUIRED CHAT_SEND_MEDIA_FORBIDDEN CHAT_WRITE_FORBIDDEN EXTERNAL_URL_INVALID FILE_PARTS_INVALID FILE_PART_LENGTH_INVALID INPUT_USER_DEACTIVATED MEDIA_CAPTION_TOO_LONG MEDIA_EMPTY PEER_ID_INVALID PHOTO_EXT_INVALID PHOTO_INVALID_DIMENSIONS PHOTO_SAVE_FILE_INVALID POLL_OPTION_DUPLICATE RANDOM_ID_DUPLICATE STORAGE_CHECK_FAILED Timeout USER_BANNED_IN_CHANNEL USER_IS_BLOCKED USER_IS_BOT VIDEO_CONTENT_TYPE_INVALID WEBPAGE_CURL_FAILED WEBPAGE_MEDIA_EMPTY
messages.sendMessage,both,AUTH_KEY_DUPLICATED BUTTON_DATA_INVALID BUTTON_TYPE_INVALID BUTTON_URL_INVALID CHANNEL_INVALID CHANNEL_PRIVATE CHAT_ADMIN_REQUIRED CHAT_ID_INVALID CHAT_RESTRICTED CHAT_WRITE_FORBIDDEN ENTITIES_TOO_LONG ENTITY_MENTION_USER_INVALID INPUT_USER_DEACTIVATED MESSAGE_EMPTY MESSAGE_TOO_LONG PEER_ID_INVALID RANDOM_ID_DUPLICATE REPLY_MARKUP_INVALID REPLY_MARKUP_TOO_LONG Timeout USER_BANNED_IN_CHANNEL USER_IS_BLOCKED USER_IS_BOT YOU_BLOCKED_USER messages.sendMessage,both,AUTH_KEY_DUPLICATED BUTTON_DATA_INVALID BUTTON_TYPE_INVALID BUTTON_URL_INVALID CHANNEL_INVALID CHANNEL_PRIVATE CHAT_ADMIN_REQUIRED CHAT_ID_INVALID CHAT_RESTRICTED CHAT_WRITE_FORBIDDEN ENTITIES_TOO_LONG ENTITY_MENTION_USER_INVALID INPUT_USER_DEACTIVATED MESSAGE_EMPTY MESSAGE_TOO_LONG PEER_ID_INVALID RANDOM_ID_DUPLICATE REPLY_MARKUP_INVALID REPLY_MARKUP_TOO_LONG Timeout USER_BANNED_IN_CHANNEL USER_IS_BLOCKED USER_IS_BOT YOU_BLOCKED_USER
messages.sendMultiMedia,both, messages.sendMultiMedia,both,
messages.sendVote,user, messages.sendVote,user,

1 method usability errors
234 messages.sendEncryptedFile user MSG_WAIT_FAILED
235 messages.sendEncryptedService user DATA_INVALID ENCRYPTION_DECLINED MSG_WAIT_FAILED USER_IS_BLOCKED
236 messages.sendInlineBotResult user CHAT_SEND_INLINE_FORBIDDEN CHAT_WRITE_FORBIDDEN INLINE_RESULT_EXPIRED PEER_ID_INVALID QUERY_ID_EMPTY WEBPAGE_CURL_FAILED WEBPAGE_MEDIA_EMPTY
237 messages.sendMedia both BOT_POLLS_DISABLED CHANNEL_INVALID CHANNEL_PRIVATE CHAT_ADMIN_REQUIRED CHAT_SEND_MEDIA_FORBIDDEN CHAT_WRITE_FORBIDDEN EXTERNAL_URL_INVALID FILE_PARTS_INVALID FILE_PART_LENGTH_INVALID INPUT_USER_DEACTIVATED MEDIA_CAPTION_TOO_LONG MEDIA_EMPTY PEER_ID_INVALID PHOTO_EXT_INVALID PHOTO_INVALID_DIMENSIONS PHOTO_SAVE_FILE_INVALID RANDOM_ID_DUPLICATE STORAGE_CHECK_FAILED Timeout USER_BANNED_IN_CHANNEL USER_IS_BLOCKED USER_IS_BOT VIDEO_CONTENT_TYPE_INVALID WEBPAGE_CURL_FAILED WEBPAGE_MEDIA_EMPTY BOT_POLLS_DISABLED CHANNEL_INVALID CHANNEL_PRIVATE CHAT_ADMIN_REQUIRED CHAT_SEND_MEDIA_FORBIDDEN CHAT_WRITE_FORBIDDEN EXTERNAL_URL_INVALID FILE_PARTS_INVALID FILE_PART_LENGTH_INVALID INPUT_USER_DEACTIVATED MEDIA_CAPTION_TOO_LONG MEDIA_EMPTY PEER_ID_INVALID PHOTO_EXT_INVALID PHOTO_INVALID_DIMENSIONS PHOTO_SAVE_FILE_INVALID POLL_OPTION_DUPLICATE RANDOM_ID_DUPLICATE STORAGE_CHECK_FAILED Timeout USER_BANNED_IN_CHANNEL USER_IS_BLOCKED USER_IS_BOT VIDEO_CONTENT_TYPE_INVALID WEBPAGE_CURL_FAILED WEBPAGE_MEDIA_EMPTY
238 messages.sendMessage both AUTH_KEY_DUPLICATED BUTTON_DATA_INVALID BUTTON_TYPE_INVALID BUTTON_URL_INVALID CHANNEL_INVALID CHANNEL_PRIVATE CHAT_ADMIN_REQUIRED CHAT_ID_INVALID CHAT_RESTRICTED CHAT_WRITE_FORBIDDEN ENTITIES_TOO_LONG ENTITY_MENTION_USER_INVALID INPUT_USER_DEACTIVATED MESSAGE_EMPTY MESSAGE_TOO_LONG PEER_ID_INVALID RANDOM_ID_DUPLICATE REPLY_MARKUP_INVALID REPLY_MARKUP_TOO_LONG Timeout USER_BANNED_IN_CHANNEL USER_IS_BLOCKED USER_IS_BOT YOU_BLOCKED_USER
239 messages.sendMultiMedia both
240 messages.sendVote user