Avoid using telethon.sync in the examples

This commit is contained in:
Lonami Exo 2019-08-13 23:33:39 +02:00
parent 61c0e63bbe
commit e1905d0d7a
28 changed files with 283 additions and 217 deletions

View File

@ -8,15 +8,16 @@ use these if possible.
.. code-block:: python .. code-block:: python
from telethon.sync import TelegramClient from telethon import TelegramClient
# Remember to use your own values from my.telegram.org! # Remember to use your own values from my.telegram.org!
api_id = 12345 api_id = 12345
api_hash = '0123456789abcdef0123456789abcdef' api_hash = '0123456789abcdef0123456789abcdef'
client = TelegramClient('anon', api_id, api_hash)
with TelegramClient('anon', api_id, api_hash) as client: async def main():
# Getting information about yourself # Getting information about yourself
me = client.get_me() me = await client.get_me()
# "me" is an User object. You can pretty-print # "me" is an User object. You can pretty-print
# any Telegram object with the "stringify" method: # any Telegram object with the "stringify" method:
@ -30,20 +31,20 @@ use these if possible.
print(me.phone) print(me.phone)
# You can print all the dialogs/conversations that you are part of: # You can print all the dialogs/conversations that you are part of:
for dialog in client.iter_dialogs(): async for dialog in client.iter_dialogs():
print(dialog.name, 'has ID', dialog.id) print(dialog.name, 'has ID', dialog.id)
# You can send messages to yourself... # You can send messages to yourself...
client.send_message('me', 'Hello, myself!') await client.send_message('me', 'Hello, myself!')
# ...to some chat ID # ...to some chat ID
client.send_message(-100123456, 'Hello, group!') await client.send_message(-100123456, 'Hello, group!')
# ...to your contacts # ...to your contacts
client.send_message('+34600123123', 'Hello, friend!') await client.send_message('+34600123123', 'Hello, friend!')
# ...or even to any username # ...or even to any username
client.send_message('TelethonChat', 'Hello, Telethon!') await client.send_message('TelethonChat', 'Hello, Telethon!')
# You can, of course, use markdown in your messages: # You can, of course, use markdown in your messages:
message = client.send_message( message = await client.send_message(
'me', 'me',
'This message has **bold**, `code`, __italics__ and ' 'This message has **bold**, `code`, __italics__ and '
'a [nice website](https://lonamiwebs.github.io)!', 'a [nice website](https://lonamiwebs.github.io)!',
@ -54,20 +55,23 @@ use these if possible.
print(message.raw_text) print(message.raw_text)
# You can reply to messages directly if you have a message object # You can reply to messages directly if you have a message object
message.reply('Cool!') await message.reply('Cool!')
# Or send files, songs, documents, albums... # Or send files, songs, documents, albums...
client.send_file('me', '/home/me/Pictures/holidays.jpg') await client.send_file('me', '/home/me/Pictures/holidays.jpg')
# You can print the message history of any chat: # You can print the message history of any chat:
for message in client.iter_messages('me'): async for message in client.iter_messages('me'):
print(message.id, message.text) print(message.id, message.text)
# You can download media from messages, too! # You can download media from messages, too!
# The method will return the path where the file was saved. # The method will return the path where the file was saved.
if message.photo: if message.photo:
path = message.download_media() path = await message.download_media()
print('File saved to', path) print('File saved to', path) # printed after download is done
with client:
client.loop.run_until_complete(main())
Here, we show how to sign in, get information about yourself, send Here, we show how to sign in, get information about yourself, send
@ -77,3 +81,31 @@ files.
You should make sure that you understand what the code shown here You should make sure that you understand what the code shown here
does, take note on how methods are called and used and so on before does, take note on how methods are called and used and so on before
proceeding. We will see all the available methods later on. proceeding. We will see all the available methods later on.
.. important::
Note that Telethon is an asynchronous library, and as such, you should
get used to it and learn a bit of basic `asyncio`. This will help a lot.
As a quick start, this means you generally want to write all your code
inside some ``async def`` like so:
.. code-block:: python
client = ...
async def do_something(me):
...
async def main():
# Most of your code should go here.
# You can of course make and use your own async def (do_something).
# They only need to be async if they need to await things.
me = await client.get_me()
await do_something(me)
with client:
client.loop.run_until_complete(main())
After you understand this, you may use the ``telethon.sync`` hack if you
want do so (see :ref:`compatibility-and-convenience`), but note you may
run into other issues (iPython, Anaconda, etc. have some issues with it).

View File

@ -49,7 +49,7 @@ We can finally write some code to log into our account!
.. code-block:: python .. code-block:: python
from telethon.sync import TelegramClient from telethon import TelegramClient
# Use your own values from my.telegram.org # Use your own values from my.telegram.org
api_id = 12345 api_id = 12345
@ -57,7 +57,7 @@ We can finally write some code to log into our account!
# The first parameter is the .session file name (absolute paths allowed) # The first parameter is the .session file name (absolute paths allowed)
with TelegramClient('anon', api_id, api_hash) as client: with TelegramClient('anon', api_id, api_hash) as client:
client.send_message('me', 'Hello, myself!') client.loop.run_until_complete(client.send_message('me', 'Hello, myself!'))
In the first line, we import the class name so we can create an instance In the first line, we import the class name so we can create an instance
@ -68,6 +68,16 @@ At last, we create a new `TelegramClient <telethon.client.telegramclient.Telegra
instance and call it ``client``. We can now use the client variable instance and call it ``client``. We can now use the client variable
for anything that we want, such as sending a message to ourselves. for anything that we want, such as sending a message to ourselves.
.. note::
Since Telethon is an asynchronous library, you need to ``await``
coroutine functions to have them run (or otherwise, run the loop
until they are complete). In this tiny example, we don't bother
making an ``async def main()``.
See :ref:`mastering-asyncio` to find out more.
Using a ``with`` block is the preferred way to use the library. It will Using a ``with`` block is the preferred way to use the library. It will
automatically `start() <telethon.client.auth.AuthMethods.start>` the client, automatically `start() <telethon.client.auth.AuthMethods.start>` the client,
logging or signing up if necessary. logging or signing up if necessary.

View File

@ -96,8 +96,12 @@ Instead of this:
.. code-block:: python .. code-block:: python
me = client.loop.run_until_complete(client.get_me())
print(me.username)
# or, using asyncio's default loop (it's the same)
import asyncio import asyncio
loop = asyncio.get_event_loop() loop = asyncio.get_event_loop() # == client.loop
me = loop.run_until_complete(client.get_me()) me = loop.run_until_complete(client.get_me())
print(me.username) print(me.username)

View File

@ -102,33 +102,35 @@ you're able to just do this:
.. code-block:: python .. code-block:: python
# (These examples assume you are inside an "async def")
#
# Dialogs are the "conversations you have open". # Dialogs are the "conversations you have open".
# This method returns a list of Dialog, which # This method returns a list of Dialog, which
# has the .entity attribute and other information. # has the .entity attribute and other information.
# #
# This part is IMPORTANT, because it feels the entity cache. # This part is IMPORTANT, because it feels the entity cache.
dialogs = client.get_dialogs() dialogs = await client.get_dialogs()
# All of these work and do the same. # All of these work and do the same.
lonami = client.get_entity('lonami') lonami = await client.get_entity('lonami')
lonami = client.get_entity('t.me/lonami') lonami = await client.get_entity('t.me/lonami')
lonami = client.get_entity('https://telegram.dog/lonami') lonami = await client.get_entity('https://telegram.dog/lonami')
# Other kind of entities. # Other kind of entities.
channel = client.get_entity('telegram.me/joinchat/AAAAAEkk2WdoDrB4-Q8-gg') channel = await client.get_entity('telegram.me/joinchat/AAAAAEkk2WdoDrB4-Q8-gg')
contact = client.get_entity('+34xxxxxxxxx') contact = await client.get_entity('+34xxxxxxxxx')
friend = client.get_entity(friend_id) friend = await client.get_entity(friend_id)
# Getting entities through their ID (User, Chat or Channel) # Getting entities through their ID (User, Chat or Channel)
entity = client.get_entity(some_id) entity = await client.get_entity(some_id)
# You can be more explicit about the type for said ID by wrapping # You can be more explicit about the type for said ID by wrapping
# it inside a Peer instance. This is recommended but not necessary. # it inside a Peer instance. This is recommended but not necessary.
from telethon.tl.types import PeerUser, PeerChat, PeerChannel from telethon.tl.types import PeerUser, PeerChat, PeerChannel
my_user = client.get_entity(PeerUser(some_id)) my_user = await client.get_entity(PeerUser(some_id))
my_chat = client.get_entity(PeerChat(some_id)) my_chat = await client.get_entity(PeerChat(some_id))
my_channel = client.get_entity(PeerChannel(some_id)) my_channel = await client.get_entity(PeerChannel(some_id))
.. note:: .. note::
@ -212,7 +214,7 @@ wherever needed, so you can even do things like:
.. code-block:: python .. code-block:: python
client(SendMessageRequest('username', 'hello')) await client(SendMessageRequest('username', 'hello'))
The library will call the ``.resolve()`` method of the request, which will The library will call the ``.resolve()`` method of the request, which will
resolve ``'username'`` with the appropriated :tl:`InputPeer`. Don't worry if resolve ``'username'`` with the appropriated :tl:`InputPeer`. Don't worry if
@ -258,7 +260,7 @@ That means you can do this:
message.is_private message.is_private
message.chat_id message.chat_id
message.get_chat() await message.get_chat()
# ...etc # ...etc
`SenderGetter <telethon.tl.custom.sendergetter.SenderGetter>` is similar: `SenderGetter <telethon.tl.custom.sendergetter.SenderGetter>` is similar:
@ -266,7 +268,7 @@ That means you can do this:
.. code-block:: python .. code-block:: python
message.user_id message.user_id
message.get_input_user() await message.get_input_user()
message.user message.user
# ...etc # ...etc
@ -285,22 +287,25 @@ applications"? Now do the same with the library. Use what applies:
.. code-block:: python .. code-block:: python
with client: # (These examples assume you are inside an "async def")
async with client:
# Does it have an username? Use it! # Does it have an username? Use it!
entity = client.get_entity(username) entity = await client.get_entity(username)
# Do you have a conversation open with them? Get dialogs. # Do you have a conversation open with them? Get dialogs.
client.get_dialogs() await client.get_dialogs()
# Are they participant of some group? Get them. # Are they participant of some group? Get them.
client.get_participants('TelethonChat') await client.get_participants('TelethonChat')
# Is the entity the original sender of a forwarded message? Get it. # Is the entity the original sender of a forwarded message? Get it.
client.get_messages('TelethonChat', 100) await client.get_messages('TelethonChat', 100)
# NOW you can use the ID, anywhere! # NOW you can use the ID, anywhere!
entity = client.get_entity(123456) await client.send_message(123456, 'Hi!')
client.send_message(123456, 'Hi!')
entity = await client.get_entity(123456)
print(entity)
Once the library has "seen" the entity, you can use their **integer** ID. Once the library has "seen" the entity, you can use their **integer** ID.
You can't use entities from IDs the library hasn't seen. You must make the You can't use entities from IDs the library hasn't seen. You must make the

View File

@ -19,7 +19,8 @@ available in :ref:`telethon-errors`, but some examples are:
from telethon import errors from telethon import errors
try: try:
print(client.get_messages(chat)[0].text) messages = await client.get_messages(chat)
print(messages[0].text)
except errors.FloodWaitError as e: except errors.FloodWaitError as e:
print('Have to sleep', e.seconds, 'seconds') print('Have to sleep', e.seconds, 'seconds')
time.sleep(e.seconds) time.sleep(e.seconds)

View File

@ -78,8 +78,17 @@ Or we call `client.get_input_entity()
.. code-block:: python .. code-block:: python
import telethon.sync import telethon
peer = client.get_input_entity('someone')
async def main():
peer = await client.get_input_entity('someone')
client.loop.run_until_complete(main())
.. note::
Remember that ``await`` must occur inside an ``async def``.
Every full API example assumes you already know and do this.
When you're going to invoke an API method, most require you to pass an When you're going to invoke an API method, most require you to pass an
@ -92,7 +101,7 @@ instead:
.. code-block:: python .. code-block:: python
entity = client.get_entity('someone') entity = await client.get_entity('someone')
In the later case, when you use the entity, the library will cast it to In the later case, when you use the entity, the library will cast it to
its "input" version for you. If you already have the complete user and its "input" version for you. If you already have the complete user and
@ -120,7 +129,7 @@ request we do:
.. code-block:: python .. code-block:: python
result = client(SendMessageRequest(peer, 'Hello there!')) result = await client(SendMessageRequest(peer, 'Hello there!'))
Message sent! Of course, this is only an example. There are over 250 Message sent! Of course, this is only an example. There are over 250
methods available as of layer 80, and you can use every single of them methods available as of layer 80, and you can use every single of them
@ -128,8 +137,8 @@ as you wish. Remember to use the right types! To sum up:
.. code-block:: python .. code-block:: python
result = client(SendMessageRequest( result = await client(SendMessageRequest(
client.get_input_entity('username'), 'Hello there!' await client.get_input_entity('username'), 'Hello there!'
)) ))
@ -137,9 +146,9 @@ This can further be simplified to:
.. code-block:: python .. code-block:: python
result = client(SendMessageRequest('username', 'Hello there!')) result = await client(SendMessageRequest('username', 'Hello there!'))
# Or even # Or even
result = client(SendMessageRequest(PeerChannel(id), 'Hello there!')) result = await client(SendMessageRequest(PeerChannel(id), 'Hello there!'))
.. note:: .. note::
@ -195,7 +204,7 @@ knows all requests directly:
.. code-block:: python .. code-block:: python
client([ await client([
SendMessageRequest('me', 'Hello'), SendMessageRequest('me', 'Hello'),
SendMessageRequest('me', ', '), SendMessageRequest('me', ', '),
SendMessageRequest('me', 'World'), SendMessageRequest('me', 'World'),
@ -212,7 +221,7 @@ and still access the successful results:
from telethon.errors import MultiError from telethon.errors import MultiError
try: try:
client([ await client([
SendMessageRequest('me', 'Hello'), SendMessageRequest('me', 'Hello'),
SendMessageRequest('me', ''), SendMessageRequest('me', ''),
SendMessageRequest('me', 'World') SendMessageRequest('me', 'World')

View File

@ -154,7 +154,7 @@ you can save it in a variable directly:
string = '1aaNk8EX-YRfwoRsebUkugFvht6DUPi_Q25UOCzOAqzc...' string = '1aaNk8EX-YRfwoRsebUkugFvht6DUPi_Q25UOCzOAqzc...'
with TelegramClient(StringSession(string), api_id, api_hash) as client: with TelegramClient(StringSession(string), api_id, api_hash) as client:
client.send_message('me', 'Hi') client.loop.run_until_complete(client.send_message('me', 'Hi'))
These strings are really convenient for using in places like Heroku since These strings are really convenient for using in places like Heroku since

View File

@ -8,7 +8,7 @@ does a result have? Well, the easiest thing to do is printing it:
.. code-block:: python .. code-block:: python
user = client.get_entity('Lonami') user = await client.get_entity('Lonami')
print(user) print(user)
That will show a huge **string** similar to the following: That will show a huge **string** similar to the following:

View File

@ -27,11 +27,11 @@ to, you can make use of the :tl:`JoinChannelRequest` to join such channel:
.. code-block:: python .. code-block:: python
from telethon.tl.functions.channels import JoinChannelRequest from telethon.tl.functions.channels import JoinChannelRequest
client(JoinChannelRequest(channel)) await client(JoinChannelRequest(channel))
# In the same way, you can also leave such channel # In the same way, you can also leave such channel
from telethon.tl.functions.channels import LeaveChannelRequest from telethon.tl.functions.channels import LeaveChannelRequest
client(LeaveChannelRequest(input_channel)) await client(LeaveChannelRequest(input_channel))
For more on channels, check the `channels namespace`__. For more on channels, check the `channels namespace`__.
@ -53,7 +53,7 @@ example, is the ``hash`` of the chat or channel. Now you can use
.. code-block:: python .. code-block:: python
from telethon.tl.functions.messages import ImportChatInviteRequest from telethon.tl.functions.messages import ImportChatInviteRequest
updates = client(ImportChatInviteRequest('AAAAAEHbEkejzxUjAUCfYg')) updates = await client(ImportChatInviteRequest('AAAAAEHbEkejzxUjAUCfYg'))
Adding someone else to such chat or channel Adding someone else to such chat or channel
@ -70,7 +70,7 @@ use is very straightforward, or :tl:`InviteToChannelRequest` for channels:
# Note that ``user_to_add`` is NOT the name of the parameter. # Note that ``user_to_add`` is NOT the name of the parameter.
# It's the user you want to add (``user_id=user_to_add``). # It's the user you want to add (``user_id=user_to_add``).
client(AddChatUserRequest( await client(AddChatUserRequest(
chat_id, chat_id,
user_to_add, user_to_add,
fwd_limit=10 # Allow the user to see the 10 last messages fwd_limit=10 # Allow the user to see the 10 last messages
@ -79,7 +79,7 @@ use is very straightforward, or :tl:`InviteToChannelRequest` for channels:
# For channels (which includes megagroups) # For channels (which includes megagroups)
from telethon.tl.functions.channels import InviteToChannelRequest from telethon.tl.functions.channels import InviteToChannelRequest
client(InviteToChannelRequest( await client(InviteToChannelRequest(
channel, channel,
[users_to_add] [users_to_add]
)) ))
@ -127,7 +127,7 @@ Giving or revoking admin permissions can be done with the :tl:`EditAdminRequest`
# ) # )
# Once you have a ChatAdminRights, invoke it # Once you have a ChatAdminRights, invoke it
client(EditAdminRequest(channel, user, rights)) await client(EditAdminRequest(channel, user, rights))
# User will now be able to change group info, delete other people's # User will now be able to change group info, delete other people's
# messages and pin messages. # messages and pin messages.
@ -135,7 +135,7 @@ Giving or revoking admin permissions can be done with the :tl:`EditAdminRequest`
# In a normal chat, you should do this instead: # In a normal chat, you should do this instead:
from telethon.tl.functions.messages import EditChatAdminRequest from telethon.tl.functions.messages import EditChatAdminRequest
client(EditChatAdminRequest(chat_id, user, is_admin=True)) await client(EditChatAdminRequest(chat_id, user, is_admin=True))
@ -192,7 +192,7 @@ banned rights of a user through :tl:`EditBannedRequest` and its parameter
embed_links=True embed_links=True
) )
client(EditBannedRequest(channel, user, rights)) await client(EditBannedRequest(channel, user, rights))
You can use a `datetime.datetime` object for ``until_date=``, You can use a `datetime.datetime` object for ``until_date=``,
@ -214,7 +214,7 @@ is enough:
from telethon.tl.functions.channels import EditBannedRequest from telethon.tl.functions.channels import EditBannedRequest
from telethon.tl.types import ChatBannedRights from telethon.tl.types import ChatBannedRights
client(EditBannedRequest( await client(EditBannedRequest(
channel, user, ChatBannedRights( channel, user, ChatBannedRights(
until_date=None, until_date=None,
view_messages=True view_messages=True
@ -240,7 +240,7 @@ use :tl:`GetMessagesViewsRequest`, setting ``increment=True``:
# Obtain `channel' through dialogs or through client.get_entity() or anyhow. # Obtain `channel' through dialogs or through client.get_entity() or anyhow.
# Obtain `msg_ids' through `.get_messages()` or anyhow. Must be a list. # Obtain `msg_ids' through `.get_messages()` or anyhow. Must be a list.
client(GetMessagesViewsRequest( await client(GetMessagesViewsRequest(
peer=channel, peer=channel,
id=msg_ids, id=msg_ids,
increment=True increment=True

View File

@ -21,9 +21,9 @@ you should use :tl:`GetFullUser`:
from telethon.tl.functions.users import GetFullUserRequest from telethon.tl.functions.users import GetFullUserRequest
full = client(GetFullUserRequest(user)) full = await client(GetFullUserRequest(user))
# or even # or even
full = client(GetFullUserRequest('username')) full = await client(GetFullUserRequest('username'))
bio = full.about bio = full.about
@ -41,7 +41,7 @@ request. Omitted fields won't change after invoking :tl:`UpdateProfile`:
from telethon.tl.functions.account import UpdateProfileRequest from telethon.tl.functions.account import UpdateProfileRequest
client(UpdateProfileRequest( await client(UpdateProfileRequest(
about='This is a test from Telethon' about='This is a test from Telethon'
)) ))
@ -55,7 +55,7 @@ You need to use :tl:`account.UpdateUsername`:
from telethon.tl.functions.account import UpdateUsernameRequest from telethon.tl.functions.account import UpdateUsernameRequest
client(UpdateUsernameRequest('new_username')) await client(UpdateUsernameRequest('new_username'))
Updating your profile photo Updating your profile photo
@ -69,6 +69,6 @@ through :tl:`UploadProfilePhoto`:
from telethon.tl.functions.photos import UploadProfilePhotoRequest from telethon.tl.functions.photos import UploadProfilePhotoRequest
client(UploadProfilePhotoRequest( await client(UploadProfilePhotoRequest(
client.upload_file('/path/to/some/file') client.upload_file('/path/to/some/file')
))) )))

View File

@ -24,7 +24,7 @@ send yourself the very first sticker you have:
# Get all the sticker sets this user has # Get all the sticker sets this user has
from telethon.tl.functions.messages import GetAllStickersRequest from telethon.tl.functions.messages import GetAllStickersRequest
sticker_sets = client(GetAllStickersRequest(0)) sticker_sets = await client(GetAllStickersRequest(0))
# Choose a sticker set # Choose a sticker set
from telethon.tl.functions.messages import GetStickerSetRequest from telethon.tl.functions.messages import GetStickerSetRequest
@ -32,14 +32,14 @@ send yourself the very first sticker you have:
sticker_set = sticker_sets.sets[0] sticker_set = sticker_sets.sets[0]
# Get the stickers for this sticker set # Get the stickers for this sticker set
stickers = client(GetStickerSetRequest( stickers = await client(GetStickerSetRequest(
stickerset=InputStickerSetID( stickerset=InputStickerSetID(
id=sticker_set.id, access_hash=sticker_set.access_hash id=sticker_set.id, access_hash=sticker_set.access_hash
) )
)) ))
# Stickers are nothing more than files, so send that # Stickers are nothing more than files, so send that
client.send_file('me', stickers.documents[0]) await client.send_file('me', stickers.documents[0])
.. _issues: https://github.com/LonamiWebs/Telethon/issues/215 .. _issues: https://github.com/LonamiWebs/Telethon/issues/215

View File

@ -14,15 +14,16 @@ Each mixin has its own methods, which you all can use.
.. code-block:: python .. code-block:: python
import asyncio
from telethon import TelegramClient from telethon import TelegramClient
client = TelegramClient(name, api_id, api_hash)
async def main(): async def main():
client = await TelegramClient(name, api_id, api_hash).start()
# Now you can use all client methods listed below, like for example... # Now you can use all client methods listed below, like for example...
await client.send_message('me', 'Hello to myself!') await client.send_message('me', 'Hello to myself!')
asyncio.get_event_loop().run_until_complete(main()) with client:
client.loop.run_until_complete(main())
You **don't** need to import these `AuthMethods`, `MessageMethods`, etc. You **don't** need to import these `AuthMethods`, `MessageMethods`, etc.

View File

@ -50,7 +50,7 @@ And except them as such:
.. code-block:: python .. code-block:: python
try: try:
client.send_message(chat, 'Hi') await client.send_message(chat, 'Hi')
except errors.FloodWaitError as e: except errors.FloodWaitError as e:
# e.seconds is how many seconds you have # e.seconds is how many seconds you have
# to wait before making the request again. # to wait before making the request again.
@ -98,11 +98,11 @@ This is basic Python knowledge. You should use the dot operator:
.. code-block:: python .. code-block:: python
me = client.get_me() me = await client.get_me()
print(me.username) print(me.username)
# ^ we used the dot operator to access the username attribute # ^ we used the dot operator to access the username attribute
result = client(functions.photos.GetUserPhotosRequest( result = await client(functions.photos.GetUserPhotosRequest(
user_id='me', user_id='me',
offset=0, offset=0,
max_id=0, max_id=0,

View File

@ -190,11 +190,11 @@ class AccountMethods:
from telethon import errors from telethon import errors
try: try:
with client.takeout() as takeout: async with client.takeout() as takeout:
client.get_messages('me') # normal call await client.get_messages('me') # normal call
takeout.get_messages('me') # wrapped through takeout (less limits) await takeout.get_messages('me') # wrapped through takeout (less limits)
for message in takeout.iter_messages(chat, wait_time=0): async for message in takeout.iter_messages(chat, wait_time=0):
... # Do something with the message ... # Do something with the message
except errors.TakeoutInitDelayError as e: except errors.TakeoutInitDelayError as e:
@ -233,7 +233,7 @@ class AccountMethods:
Example Example
.. code-block:: python .. code-block:: python
client.end_takeout(success=False) await 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

@ -89,10 +89,10 @@ class AuthMethods:
client = TelegramClient('anon', api_id, api_hash) client = TelegramClient('anon', api_id, api_hash)
# Starting as a bot account # Starting as a bot account
client.start(bot_token=bot_token) await client.start(bot_token=bot_token)
# Starting as an user account # Starting as an user account
client.start(phone) await client.start(phone)
# Please enter the code you received: 12345 # Please enter the code you received: 12345
# Please enter your password: ******* # Please enter your password: *******
# (You are now logged in) # (You are now logged in)
@ -306,10 +306,10 @@ class AuthMethods:
.. code-block:: python .. code-block:: python
phone = '+34 123 123 123' phone = '+34 123 123 123'
client.sign_in(phone) # send code await client.sign_in(phone) # send code
code = input('enter code: ') code = input('enter code: ')
client.sign_in(phone, code) await client.sign_in(phone, code)
""" """
me = await self.get_me() me = await self.get_me()
if me: if me:
@ -388,10 +388,10 @@ class AuthMethods:
.. code-block:: python .. code-block:: python
phone = '+34 123 123 123' phone = '+34 123 123 123'
client.send_code_request(phone) await client.send_code_request(phone)
code = input('enter code: ') code = input('enter code: ')
client.sign_up(code, first_name='Anna', last_name='Banana') await client.sign_up(code, first_name='Anna', last_name='Banana')
""" """
me = await self.get_me() me = await self.get_me()
if me: if me:
@ -456,7 +456,7 @@ class AuthMethods:
.. code-block:: python .. code-block:: python
phone = '+34 123 123 123' phone = '+34 123 123 123'
sent = client.send_code_request(phone) sent = await client.send_code_request(phone)
print(sent) print(sent)
if sent.phone_registered: if sent.phone_registered:
@ -501,7 +501,7 @@ class AuthMethods:
.. code-block:: python .. code-block:: python
# Note: you will need to login again! # Note: you will need to login again!
client.log_out() await client.log_out()
""" """
try: try:
await self(functions.auth.LogOutRequest()) await self(functions.auth.LogOutRequest())
@ -573,10 +573,10 @@ class AuthMethods:
.. code-block:: python .. code-block:: python
# Setting a password for your account which didn't have # Setting a password for your account which didn't have
client.edit_2fa(new_password='I_<3_Telethon') await client.edit_2fa(new_password='I_<3_Telethon')
# Removing the password # Removing the password
client.edit_2fa(current_password='I_<3_Telethon') await 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

@ -40,10 +40,10 @@ class BotMethods:
.. code-block:: python .. code-block:: python
# Make an inline query to @like # Make an inline query to @like
results = client.inline_query('like', 'Do you like Telethon?') results = await client.inline_query('like', 'Do you like Telethon?')
# Send the first result to some chat # Send the first result to some chat
message = results[0].click('TelethonOffTopic') message = await results[0].click('TelethonOffTopic')
""" """
bot = await self.get_input_entity(bot) bot = await self.get_input_entity(bot)
result = await self(functions.messages.GetInlineBotResultsRequest( result = await self(functions.messages.GetInlineBotResultsRequest(

View File

@ -35,7 +35,7 @@ class ButtonMethods:
from telethon import Button from telethon import Button
markup = client.build_reply_markup(Button.inline('hi')) markup = client.build_reply_markup(Button.inline('hi'))
client.send_message('click me', buttons=markup) await client.send_message('click me', buttons=markup)
""" """
if buttons is None: if buttons is None:
return None return None

View File

@ -406,16 +406,16 @@ class ChatMethods:
.. code-block:: python .. code-block:: python
# Show all user IDs in a chat # Show all user IDs in a chat
for user in client.iter_participants(chat): async for user in client.iter_participants(chat):
print(user.id) print(user.id)
# Search by name # Search by name
for user in client.iter_participants(chat, search='name'): async for user in client.iter_participants(chat, search='name'):
print(user.username) print(user.username)
# Filter by admins # Filter by admins
from telethon.tl.types import ChannelParticipantsAdmins from telethon.tl.types import ChannelParticipantsAdmins
for user in client.iter_participants(chat, filter=ChannelParticipantsAdmins): async for user in client.iter_participants(chat, filter=ChannelParticipantsAdmins):
print(user.first_name) print(user.first_name)
""" """
return _ParticipantsIter( return _ParticipantsIter(
@ -438,7 +438,7 @@ class ChatMethods:
Example Example
.. code-block:: python .. code-block:: python
users = client.get_participants(chat) users = await client.get_participants(chat)
print(users[0].first_name) print(users[0].first_name)
for user in users: for user in users:
@ -562,7 +562,7 @@ class ChatMethods:
Example Example
.. code-block:: python .. code-block:: python
for event in client.iter_admin_log(channel): async 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)
""" """
@ -601,7 +601,7 @@ class ChatMethods:
.. code-block:: python .. code-block:: python
# Get a list of deleted message events which said "heck" # Get a list of deleted message events which said "heck"
events = client.get_admin_log(channel, search='heck', delete=True) events = await client.get_admin_log(channel, search='heck', delete=True)
# Print the old message before it was deleted # Print the old message before it was deleted
print(events[0].old) print(events[0].old)
@ -643,8 +643,8 @@ class ChatMethods:
.. code-block:: python .. code-block:: python
# Download all the profile photos of some user # Download all the profile photos of some user
for photo in client.iter_profile_photos(user): async for photo in client.iter_profile_photos(user):
client.download_media(photo) await client.download_media(photo)
""" """
return _ProfilePhotoIter( return _ProfilePhotoIter(
self, self,
@ -666,10 +666,10 @@ class ChatMethods:
.. code-block:: python .. code-block:: python
# Get the photos of a channel # Get the photos of a channel
photos = client.get_profile_photos(channel) photos = await client.get_profile_photos(channel)
# Download the oldest photo # Download the oldest photo
client.download_media(photos[-1]) await client.download_media(photos[-1])
""" """
return await self.iter_profile_photos(*args, **kwargs).collect() return await self.iter_profile_photos(*args, **kwargs).collect()
@ -746,7 +746,7 @@ class ChatMethods:
# Upload a document, showing its progress (most clients ignore this) # Upload a document, showing its progress (most clients ignore this)
async with client.action(chat, 'document') as action: async with client.action(chat, 'document') as action:
client.send_file(chat, zip_file, progress_callback=action.progress) await client.send_file(chat, zip_file, progress_callback=action.progress)
""" """
if isinstance(action, str): if isinstance(action, str):
try: try:
@ -841,10 +841,10 @@ class ChatMethods:
.. code-block:: python .. code-block:: python
# Allowing `user` to pin messages in `chat` # Allowing `user` to pin messages in `chat`
client.edit_admin(chat, user, pin_messages=True) await client.edit_admin(chat, user, pin_messages=True)
# Granting all permissions except for `add_admins` # Granting all permissions except for `add_admins`
client.edit_admin(chat, user, is_admin=True, add_admins=False) await client.edit_admin(chat, user, is_admin=True, add_admins=False)
""" """
entity = await self.get_input_entity(entity) entity = await self.get_input_entity(entity)
user = await self.get_input_entity(user) user = await self.get_input_entity(user)
@ -978,15 +978,15 @@ class ChatMethods:
from datetime import timedelta from datetime import timedelta
# Banning `user` from `chat` for 1 minute # Banning `user` from `chat` for 1 minute
client.edit_permissions(chat, user, timedelta(minutes=1), await client.edit_permissions(chat, user, timedelta(minutes=1),
view_messages=False) view_messages=False)
# Banning `user` from `chat` forever # Banning `user` from `chat` forever
client.edit_permissions(chat, user, view_messages=False) await client.edit_permissions(chat, user, view_messages=False)
# Kicking someone (ban + un-ban) # Kicking someone (ban + un-ban)
client.edit_permissions(chat, user, view_messages=False) await client.edit_permissions(chat, user, view_messages=False)
client.edit_permissions(chat, user) await client.edit_permissions(chat, user)
""" """
entity = await self.get_input_entity(entity) entity = await self.get_input_entity(entity)
if not isinstance(entity, types.InputPeerChannel): if not isinstance(entity, types.InputPeerChannel):
@ -1053,10 +1053,10 @@ class ChatMethods:
.. code-block:: python .. code-block:: python
# Kick some user from some chat # Kick some user from some chat
client.kick_participant(chat, user) await client.kick_participant(chat, user)
# Leaving chat # Leaving chat
client.kick_participant(chat, 'me') await client.kick_participant(chat, 'me')
""" """
entity = await self.get_input_entity(entity) entity = await self.get_input_entity(entity)
user = await self.get_input_entity(user) user = await self.get_input_entity(user)

View File

@ -205,7 +205,7 @@ class DialogMethods:
.. code-block:: python .. code-block:: python
# Print all dialog IDs and the title, nicely formatted # Print all dialog IDs and the title, nicely formatted
for dialog in client.iter_dialogs(): async for dialog in client.iter_dialogs():
print('{:>14}: {}'.format(dialog.id, dialog.title)) print('{:>14}: {}'.format(dialog.id, dialog.title))
""" """
if archived is not None: if archived is not None:
@ -231,20 +231,20 @@ class DialogMethods:
.. code-block:: python .. code-block:: python
# Get all open conversation, print the title of the first # Get all open conversation, print the title of the first
dialogs = client.get_dialogs() dialogs = await client.get_dialogs()
first = dialogs[0] first = dialogs[0]
print(first.title) print(first.title)
# Use the dialog somewhere else # Use the dialog somewhere else
client.send_message(first, 'hi') await client.send_message(first, 'hi')
# Getting only non-archived dialogs (both equivalent) # Getting only non-archived dialogs (both equivalent)
non_archived = client.get_dialogs(folder=0) non_archived = await client.get_dialogs(folder=0)
non_archived = client.get_dialogs(archived=False) non_archived = await client.get_dialogs(archived=False)
# Getting only archived dialogs (both equivalent) # Getting only archived dialogs (both equivalent)
archived = client.get_dialogs(folder=1) archived = await client.get_dialogs(folder=1)
non_archived = client.get_dialogs(archived=True) non_archived = await client.get_dialogs(archived=True)
""" """
return await self.iter_dialogs(*args, **kwargs).collect() return await self.iter_dialogs(*args, **kwargs).collect()
@ -269,11 +269,11 @@ class DialogMethods:
.. code-block:: python .. code-block:: python
# Clear all drafts # Clear all drafts
for draft in client.get_drafts(): async for draft in client.get_drafts():
draft.delete() await draft.delete()
# Getting the drafts with 'bot1' and 'bot2' # Getting the drafts with 'bot1' and 'bot2'
for draft in client.iter_drafts(['bot1', 'bot2']): async for draft in client.iter_drafts(['bot1', 'bot2']):
print(draft.text) print(draft.text)
""" """
if entity and not utils.is_list_like(entity): if entity and not utils.is_list_like(entity):
@ -293,11 +293,11 @@ class DialogMethods:
.. code-block:: python .. code-block:: python
# Get drafts, print the text of the first # Get drafts, print the text of the first
drafts = client.get_drafts() drafts = await client.get_drafts()
print(drafts[0].text) print(drafts[0].text)
# Get the draft in your chat # Get the draft in your chat
draft = client.get_drafts('me') draft = await client.get_drafts('me')
print(drafts.text) print(drafts.text)
""" """
items = await self.iter_drafts(entity).collect() items = await self.iter_drafts(entity).collect()
@ -350,18 +350,18 @@ class DialogMethods:
.. code-block:: python .. code-block:: python
# Archiving the first 5 dialogs # Archiving the first 5 dialogs
dialogs = client.get_dialogs(5) dialogs = await client.get_dialogs(5)
client.edit_folder(dialogs, 1) await client.edit_folder(dialogs, 1)
# Un-archiving the third dialog (archiving to folder 0) # Un-archiving the third dialog (archiving to folder 0)
client.edit_folder(dialog[2], 0) await client.edit_folder(dialog[2], 0)
# Moving the first dialog to folder 0 and the second to 1 # Moving the first dialog to folder 0 and the second to 1
dialogs = client.get_dialogs(2) dialogs = await client.get_dialogs(2)
client.edit_folder(dialogs, [0, 1]) await client.edit_folder(dialogs, [0, 1])
# Un-archiving all dialogs # Un-archiving all dialogs
client.archive(unpack=1) await client.archive(unpack=1)
""" """
if (entity is None) == (unpack is None): if (entity is None) == (unpack is None):
raise ValueError('You can only set either entities or unpack, not both') raise ValueError('You can only set either entities or unpack, not both')
@ -419,11 +419,11 @@ class DialogMethods:
.. code-block:: python .. code-block:: python
# Deleting the first dialog # Deleting the first dialog
dialogs = client.get_dialogs(5) dialogs = await client.get_dialogs(5)
client.delete_dialog(dialogs[0]) await client.delete_dialog(dialogs[0])
# Leaving a channel by username # Leaving a channel by username
client.delete_dialog('username') await client.delete_dialog('username')
""" """
entity = await self.get_input_entity(entity) entity = await self.get_input_entity(entity)
if isinstance(entity, types.InputPeerChannel): if isinstance(entity, types.InputPeerChannel):

View File

@ -196,7 +196,7 @@ class DownloadMethods:
.. code-block:: python .. code-block:: python
# Download your own profile photo # Download your own profile photo
path = client.download_profile_photo('me') path = await client.download_profile_photo('me')
print(path) print(path)
""" """
# hex(crc32(x.encode('ascii'))) for x in # hex(crc32(x.encode('ascii'))) for x in
@ -322,11 +322,11 @@ class DownloadMethods:
Example Example
.. code-block:: python .. code-block:: python
path = client.download_media(message) path = await client.download_media(message)
client.download_media(message, filename) await client.download_media(message, filename)
# or # or
path = message.download_media() path = await message.download_media()
message.download_media(filename) await 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):
@ -406,7 +406,7 @@ class DownloadMethods:
.. code-block:: python .. code-block:: python
# Download a file and print its header # Download a file and print its header
data = client.download_file(input_file, bytes) data = await client.download_file(input_file, bytes)
print(data[:16]) print(data[:16])
""" """
if not part_size_kb: if not part_size_kb:
@ -531,11 +531,14 @@ class DownloadMethods:
# Streaming `media` to an output file # Streaming `media` to an output file
# After the iteration ends, the sender is cleaned up # After the iteration ends, the sender is cleaned up
with open('photo.jpg', 'wb') as fd: with open('photo.jpg', 'wb') as fd:
for chunk client.iter_download(media): async for chunk client.iter_download(media):
fd.write(chunk) fd.write(chunk)
# Fetching only the header of a file (32 bytes) # Fetching only the header of a file (32 bytes)
# You should manually close the iterator in this case. # You should manually close the iterator in this case.
#
# telethon.sync must be imported for this to work,
# and you must not be inside an "async def".
stream = client.iter_download(media, request_size=32) stream = client.iter_download(media, request_size=32)
header = next(stream) header = next(stream)
stream.close() stream.close()

View File

@ -421,24 +421,24 @@ class MessageMethods:
.. code-block:: python .. code-block:: python
# From most-recent to oldest # From most-recent to oldest
for message in client.iter_messages(chat): async for message in client.iter_messages(chat):
print(message.id, message.text) print(message.id, message.text)
# From oldest to most-recent # From oldest to most-recent
for message in client.iter_messages(chat, reverse=True): async for message in client.iter_messages(chat, reverse=True):
print(message.id, message.text) print(message.id, message.text)
# Filter by sender # Filter by sender
for message in client.iter_messages(chat, from_user='me'): async for message in client.iter_messages(chat, from_user='me'):
print(message.text) print(message.text)
# Server-side search with fuzzy text # Server-side search with fuzzy text
for message in client.iter_messages(chat, search='hello'): async for message in client.iter_messages(chat, search='hello'):
print(message.id) print(message.id)
# Filter by message type: # Filter by message type:
from telethon.tl.types import InputMessagesFilterPhotos from telethon.tl.types import InputMessagesFilterPhotos
for message in client.iter_messages(chat, filter=InputMessagesFilterPhotos): async 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:
@ -482,14 +482,14 @@ class MessageMethods:
# 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
from telethon.tl.types import InputMessagesFilterPhotos from telethon.tl.types import InputMessagesFilterPhotos
photos = client.get_messages(chat, 0, filter=InputMessagesFilterPhotos) photos = await client.get_messages(chat, 0, filter=InputMessagesFilterPhotos)
print(photos.total) print(photos.total)
# Get all the photos # Get all the photos
photos = client.get_messages(chat, None, filter=InputMessagesFilterPhotos) photos = await client.get_messages(chat, None, filter=InputMessagesFilterPhotos)
# Get messages by ID: # Get messages by ID:
message_1337 = client.get_messages(chats, ids=1337) message_1337 = await client.get_messages(chats, ids=1337)
""" """
if len(args) == 1 and 'limit' not in kwargs: if len(args) == 1 and 'limit' not in kwargs:
if 'min_id' in kwargs and 'max_id' in kwargs: if 'min_id' in kwargs and 'max_id' in kwargs:
@ -605,25 +605,25 @@ class MessageMethods:
.. code-block:: python .. code-block:: python
# Markdown is the default # Markdown is the default
client.send_message('lonami', 'Thanks for the **Telethon** library!') await client.send_message('lonami', 'Thanks for the **Telethon** library!')
# Default to another parse mode # Default to another parse mode
client.parse_mode = 'html' client.parse_mode = 'html'
client.send_message('me', 'Some <b>bold</b> and <i>italic</i> text') await client.send_message('me', 'Some <b>bold</b> and <i>italic</i> text')
client.send_message('me', 'An <a href="https://example.com">URL</a>') await client.send_message('me', 'An <a href="https://example.com">URL</a>')
# code and pre tags also work, but those break the documentation :) # code and pre tags also work, but those break the documentation :)
client.send_message('me', '<a href="tg://user?id=me">Mentions</a>') await client.send_message('me', '<a href="tg://user?id=me">Mentions</a>')
# Explicit parse mode # Explicit parse mode
# No parse mode by default # No parse mode by default
client.parse_mode = None client.parse_mode = None
# ...but here I want markdown # ...but here I want markdown
client.send_message('me', 'Hello, **world**!', parse_mode='md') await client.send_message('me', 'Hello, **world**!', parse_mode='md')
# ...and here I need HTML # ...and here I need HTML
client.send_message('me', 'Hello, <i>world</i>!', parse_mode='html') await client.send_message('me', 'Hello, <i>world</i>!', parse_mode='html')
# If you logged in as a bot account, you can send buttons # If you logged in as a bot account, you can send buttons
from telethon import events, Button from telethon import events, Button
@ -633,25 +633,25 @@ class MessageMethods:
await event.edit('Thank you for clicking {}!'.format(event.data)) await event.edit('Thank you for clicking {}!'.format(event.data))
# Single inline button # Single inline button
client.send_message(chat, 'A single button, with "clk1" as data', await client.send_message(chat, 'A single button, with "clk1" as data',
buttons=Button.inline('Click me', b'clk1')) buttons=Button.inline('Click me', b'clk1'))
# Matrix of inline buttons # Matrix of inline buttons
client.send_message(chat, 'Pick one from this grid', buttons=[ await client.send_message(chat, 'Pick one from this grid', buttons=[
[Button.inline('Left'), Button.inline('Right')], [Button.inline('Left'), Button.inline('Right')],
[Button.url('Check this site!', 'https://lonamiwebs.github.io')] [Button.url('Check this site!', 'https://lonamiwebs.github.io')]
]) ])
# Reply keyboard # Reply keyboard
client.send_message(chat, 'Welcome', buttons=[ await client.send_message(chat, 'Welcome', buttons=[
Button.text('Thanks!', resize=True, single_use=True), Button.text('Thanks!', resize=True, single_use=True),
Button.request_phone('Send phone'), Button.request_phone('Send phone'),
Button.request_location('Send location') Button.request_location('Send location')
]) ])
# Forcing replies or clearing buttons. # Forcing replies or clearing buttons.
client.send_message(chat, 'Reply to me', buttons=Button.force_reply()) await client.send_message(chat, 'Reply to me', buttons=Button.force_reply())
client.send_message(chat, 'Bye Keyboard!', buttons=Button.clear()) await client.send_message(chat, 'Bye Keyboard!', buttons=Button.clear())
""" """
if file is not None: if file is not None:
return await self.send_file( return await self.send_file(
@ -788,19 +788,19 @@ class MessageMethods:
.. code-block:: python .. code-block:: python
# a single one # a single one
client.forward_messages(chat, message) await client.forward_messages(chat, message)
# or # or
client.forward_messages(chat, message_id, from_chat) await client.forward_messages(chat, message_id, from_chat)
# or # or
message.forward_to(chat) await message.forward_to(chat)
# multiple # multiple
client.forward_messages(chat, messages) await client.forward_messages(chat, messages)
# or # or
client.forward_messages(chat, message_ids, from_chat) await client.forward_messages(chat, message_ids, from_chat)
# Forwarding as a copy # Forwarding as a copy
client.send_message(chat, message) await client.send_message(chat, message)
""" """
single = not utils.is_list_like(messages) single = not utils.is_list_like(messages)
if single: if single:
@ -945,13 +945,13 @@ class MessageMethods:
Example Example
.. code-block:: python .. code-block:: python
message = client.send_message(chat, 'hello') message = await client.send_message(chat, 'hello')
client.edit_message(chat, message, 'hello!') await client.edit_message(chat, message, 'hello!')
# or # or
client.edit_message(chat, message.id, 'hello!!') await client.edit_message(chat, message.id, 'hello!!')
# or # or
client.edit_message(message, 'hello!!!') await client.edit_message(message, 'hello!!!')
""" """
if isinstance(entity, types.InputBotInlineMessageID): if isinstance(entity, types.InputBotInlineMessageID):
text = message text = message
@ -1036,7 +1036,7 @@ class MessageMethods:
Example Example
.. code-block:: python .. code-block:: python
client.delete_messages(chat, messages) await client.delete_messages(chat, messages)
""" """
if not utils.is_list_like(message_ids): if not utils.is_list_like(message_ids):
message_ids = (message_ids,) message_ids = (message_ids,)
@ -1097,11 +1097,11 @@ class MessageMethods:
.. code-block:: python .. code-block:: python
# using a Message object # using a Message object
client.send_read_acknowledge(chat, message) await client.send_read_acknowledge(chat, message)
# ...or using the int ID of a Message # ...or using the int ID of a Message
client.send_read_acknowledge(chat, message_id) await client.send_read_acknowledge(chat, message_id)
# ...or passing a list of messages to mark as read # ...or passing a list of messages to mark as read
client.send_read_acknowledge(chat, messages) await client.send_read_acknowledge(chat, messages)
""" """
if max_id is None: if max_id is None:
if not message: if not message:
@ -1158,8 +1158,8 @@ class MessageMethods:
.. code-block:: python .. code-block:: python
# Send and pin a message to annoy everyone # Send and pin a message to annoy everyone
message = client.send_message(chat, 'Pinotifying is fun!') message = await client.send_message(chat, 'Pinotifying is fun!')
client.pin_message(chat, message, notify=True) await client.pin_message(chat, message, notify=True)
""" """
if not message: if not message:
message = 0 message = 0

View File

@ -401,7 +401,7 @@ class TelegramBaseClient(abc.ABC):
.. code-block:: python .. code-block:: python
try: try:
client.connect() await client.connect()
except OSError: except OSError:
print('Failed to connect') print('Failed to connect')
""" """
@ -451,7 +451,7 @@ class TelegramBaseClient(abc.ABC):
.. 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"
client.disconnect() await client.disconnect()
""" """
if self._loop.is_running(): if self._loop.is_running():
return self._disconnect_coro() return self._disconnect_coro()

View File

@ -59,7 +59,7 @@ class UpdateMethods:
# #
# You will still receive updates, since this prevents the # You will still receive updates, since this prevents the
# script from exiting. # script from exiting.
client.run_until_disconnected() await client.run_until_disconnected()
""" """
if self.loop.is_running(): if self.loop.is_running():
return self._run_until_disconnected() return self._run_until_disconnected()
@ -218,7 +218,7 @@ class UpdateMethods:
Example Example
.. code-block:: python .. code-block:: python
client.catch_up() await client.catch_up()
""" """
pts, date = self._state_cache[None] pts, date = self._state_cache[None]
if not pts: if not pts:

View File

@ -237,22 +237,22 @@ class UploadMethods:
.. code-block:: python .. code-block:: python
# Normal files like photos # Normal files like photos
client.send_file(chat, '/my/photos/me.jpg', caption="It's me!") await client.send_file(chat, '/my/photos/me.jpg', caption="It's me!")
# or # or
client.send_message(chat, "It's me!", file='/my/photos/me.jpg') await client.send_message(chat, "It's me!", file='/my/photos/me.jpg')
# Voice notes or round videos # Voice notes or round videos
client.send_file(chat, '/my/songs/song.mp3', voice_note=True) await client.send_file(chat, '/my/songs/song.mp3', voice_note=True)
client.send_file(chat, '/my/videos/video.mp4', video_note=True) await client.send_file(chat, '/my/videos/video.mp4', video_note=True)
# Custom thumbnails # Custom thumbnails
client.send_file(chat, '/my/documents/doc.txt', thumb='photo.jpg') await client.send_file(chat, '/my/documents/doc.txt', thumb='photo.jpg')
# Only documents # Only documents
client.send_file(chat, '/my/photos/photo.png', force_document=True) await client.send_file(chat, '/my/photos/photo.png', force_document=True)
# Albums # Albums
client.send_file(chat, [ await client.send_file(chat, [
'/my/photos/holiday1.jpg', '/my/photos/holiday1.jpg',
'/my/photos/holiday2.jpg', '/my/photos/holiday2.jpg',
'/my/drawings/portrait.png' '/my/drawings/portrait.png'
@ -467,17 +467,17 @@ class UploadMethods:
.. code-block:: python .. code-block:: python
# Photos as photo and document # Photos as photo and document
file = client.upload_file('photo.jpg') file = await client.upload_file('photo.jpg')
client.send_file(chat, file) # sends as photo await client.send_file(chat, file) # sends as photo
client.send_file(chat, file, force_document=True) # sends as document await client.send_file(chat, file, force_document=True) # sends as document
file.name = 'not a photo.jpg' file.name = 'not a photo.jpg'
client.send_file(chat, file, force_document=True) # document, new name await client.send_file(chat, file, force_document=True) # document, new name
# As song or as voice note # As song or as voice note
file = client.upload_file('song.ogg') file = await client.upload_file('song.ogg')
client.send_file(chat, file) # sends as song await client.send_file(chat, file) # sends as song
client.send_file(chat, file, voice_note=True) # sends as voice note await client.send_file(chat, file, voice_note=True) # sends as voice note
""" """
if isinstance(file, (types.InputFile, types.InputFileBig)): if isinstance(file, (types.InputFile, types.InputFileBig)):
return file # Already uploaded return file # Already uploaded

View File

@ -128,7 +128,8 @@ class UserMethods:
Example Example
.. code-block:: python .. code-block:: python
print(client.get_me().username) me = await client.get_me()
print(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
@ -154,7 +155,7 @@ class UserMethods:
Example Example
.. code-block:: python .. code-block:: python
if client.is_bot(): if await client.is_bot():
print('Beep') print('Beep')
else: else:
print('Hello') print('Hello')
@ -171,10 +172,10 @@ class UserMethods:
Example Example
.. code-block:: python .. code-block:: python
if not client.is_user_authorized(): if not await client.is_user_authorized():
client.send_code_request(phone) await client.send_code_request(phone)
code = input('enter code: ') code = input('enter code: ')
client.sign_in(phone, code) await client.sign_in(phone, code)
""" """
if self._authorized is None: if self._authorized is None:
try: try:
@ -227,20 +228,20 @@ class UserMethods:
from telethon import utils from telethon import utils
me = client.get_entity('me') me = await client.get_entity('me')
print(utils.get_display_name(me)) print(utils.get_display_name(me))
chat = client.get_input_entity('username') chat = await client.get_input_entity('username')
for message in client.iter_messages(chat): async for message in client.iter_messages(chat):
... ...
# Note that you could have used the username directly, but it's # Note that you could have used the username directly, but it's
# good to use get_input_entity if you will reuse it a lot. # good to use get_input_entity if you will reuse it a lot.
for message in client.iter_messages('username'): async for message in client.iter_messages('username'):
... ...
# Note that for this to work the phone number must be in your contacts # Note that for this to work the phone number must be in your contacts
some_id = client.get_peer_id('+34123456789') some_id = await client.get_peer_id('+34123456789')
""" """
single = not utils.is_list_like(entity) single = not utils.is_list_like(entity)
if single: if single:
@ -360,10 +361,10 @@ class UserMethods:
# If you're going to use "username" often in your code # If you're going to use "username" often in your code
# (make a lot of calls), consider getting its input entity # (make a lot of calls), consider getting its input entity
# once, and then using the "user" everywhere instead. # once, and then using the "user" everywhere instead.
user = client.get_input_entity('username') user = await client.get_input_entity('username')
# The same applies to IDs, chats or channels. # The same applies to IDs, chats or channels.
chat = client.get_input_entity(-123456789) chat = await 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:
@ -444,7 +445,7 @@ class UserMethods:
Example Example
.. code-block:: python .. code-block:: python
print(client.get_peer_id('me')) print(await 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

@ -167,7 +167,7 @@ class TotalList(list):
# Telethon returns these lists in some cases (for example, # Telethon returns these lists in some cases (for example,
# only when a chunk is returned, but the "total" count # only when a chunk is returned, but the "total" count
# is available). # is available).
result = client.get_messages(chat, limit=10) result = await client.get_messages(chat, limit=10)
print(result.total) # large number print(result.total) # large number
print(len(result)) # 10 print(len(result)) # 10

View File

@ -762,7 +762,7 @@ class Message(ChatGetter, SenderGetter, TLObject, abc.ABC):
>>> # [button1] [button2] >>> # [button1] [button2]
>>> # [ button3 ] >>> # [ button3 ]
>>> # [button4] [button5] >>> # [button4] [button5]
>>> message.click(2) # index >>> await message.click(2) # index
j (`int`): j (`int`):
Clicks the button at position (i, j), these being the Clicks the button at position (i, j), these being the
@ -772,7 +772,7 @@ class Message(ChatGetter, SenderGetter, TLObject, abc.ABC):
>>> # [button1] [button2] >>> # [button1] [button2]
>>> # [ button3 ] >>> # [ button3 ]
>>> # [button4] [button5] >>> # [button4] [button5]
>>> message.click(0, 1) # (row, column) >>> await message.click(0, 1) # (row, column)
This is equivalent to ``message.buttons[0][1].click()``. This is equivalent to ``message.buttons[0][1].click()``.
@ -799,16 +799,16 @@ class Message(ChatGetter, SenderGetter, TLObject, abc.ABC):
.. code-block:: python .. code-block:: python
# Click the first button # Click the first button
message.click(0) await message.click(0)
# Click some row/column # Click some row/column
message.click(row, column) await message.click(row, column)
# Click by text # Click by text
message.click(text='👍') await message.click(text='👍')
# Click by data # Click by data
message.click(data=b'payload') await message.click(data=b'payload')
""" """
if not self._client: if not self._client:
return return

View File

@ -1177,14 +1177,14 @@ def encode_waveform(waveform):
file = 'my.ogg' file = 'my.ogg'
# Send 'my.ogg' with a ascending-triangle waveform # Send 'my.ogg' with a ascending-triangle waveform
client.send_file(chat, file, attributes=[types.DocumentAttributeAudio( await client.send_file(chat, file, attributes=[types.DocumentAttributeAudio(
duration=7, duration=7,
voice=True, voice=True,
waveform=utils.encode_waveform(bytes(range(2 ** 5)) # 2**5 because 5-bit waveform=utils.encode_waveform(bytes(range(2 ** 5)) # 2**5 because 5-bit
)] )]
# Send 'my.ogg' with a square waveform # Send 'my.ogg' with a square waveform
client.send_file(chat, file, attributes=[types.DocumentAttributeAudio( await client.send_file(chat, file, attributes=[types.DocumentAttributeAudio(
duration=7, duration=7,
voice=True, voice=True,
waveform=utils.encode_waveform(bytes((31, 31, 15, 15, 15, 15, 31, 31)) * 4) waveform=utils.encode_waveform(bytes((31, 31, 15, 15, 15, 15, 31, 31)) * 4)