Skip to content
Permalink
Browse files

Avoid using telethon.sync in the examples

  • Loading branch information...
Lonami committed Aug 13, 2019
1 parent 61c0e63 commit e1905d0d7ad3014e02bda9d5d468f669c21a7353
@@ -8,15 +8,16 @@ use these if possible.

.. code-block:: python
from telethon.sync import TelegramClient
from telethon import TelegramClient
# Remember to use your own values from my.telegram.org!
api_id = 12345
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
me = client.get_me()
me = await client.get_me()
# "me" is an User object. You can pretty-print
# any Telegram object with the "stringify" method:
@@ -30,20 +31,20 @@ use these if possible.
print(me.phone)
# 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)
# You can send messages to yourself...
client.send_message('me', 'Hello, myself!')
await client.send_message('me', 'Hello, myself!')
# ...to some chat ID
client.send_message(-100123456, 'Hello, group!')
await client.send_message(-100123456, 'Hello, group!')
# ...to your contacts
client.send_message('+34600123123', 'Hello, friend!')
await client.send_message('+34600123123', 'Hello, friend!')
# ...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:
message = client.send_message(
message = await client.send_message(
'me',
'This message has **bold**, `code`, __italics__ and '
'a [nice website](https://lonamiwebs.github.io)!',
@@ -54,20 +55,23 @@ use these if possible.
print(message.raw_text)
# 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...
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:
for message in client.iter_messages('me'):
async for message in client.iter_messages('me'):
print(message.id, message.text)
# You can download media from messages, too!
# The method will return the path where the file was saved.
if message.photo:
path = message.download_media()
print('File saved to', path)
path = await message.download_media()
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
@@ -77,3 +81,31 @@ files.
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
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).
@@ -49,15 +49,15 @@ We can finally write some code to log into our account!

.. code-block:: python
from telethon.sync import TelegramClient
from telethon import TelegramClient
# Use your own values from my.telegram.org
api_id = 12345
api_hash = '0123456789abcdef0123456789abcdef'
# The first parameter is the .session file name (absolute paths allowed)
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
@@ -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
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
automatically `start() <telethon.client.auth.AuthMethods.start>` the client,
logging or signing up if necessary.
@@ -96,8 +96,12 @@ Instead of this:

.. 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
loop = asyncio.get_event_loop()
loop = asyncio.get_event_loop() # == client.loop
me = loop.run_until_complete(client.get_me())
print(me.username)
@@ -102,33 +102,35 @@ you're able to just do this:

.. code-block:: python
# (These examples assume you are inside an "async def")
#
# Dialogs are the "conversations you have open".
# This method returns a list of Dialog, which
# has the .entity attribute and other information.
#
# 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.
lonami = client.get_entity('lonami')
lonami = client.get_entity('t.me/lonami')
lonami = client.get_entity('https://telegram.dog/lonami')
lonami = await client.get_entity('lonami')
lonami = await client.get_entity('t.me/lonami')
lonami = await client.get_entity('https://telegram.dog/lonami')
# Other kind of entities.
channel = client.get_entity('telegram.me/joinchat/AAAAAEkk2WdoDrB4-Q8-gg')
contact = client.get_entity('+34xxxxxxxxx')
friend = client.get_entity(friend_id)
channel = await client.get_entity('telegram.me/joinchat/AAAAAEkk2WdoDrB4-Q8-gg')
contact = await client.get_entity('+34xxxxxxxxx')
friend = await client.get_entity(friend_id)
# 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
# it inside a Peer instance. This is recommended but not necessary.
from telethon.tl.types import PeerUser, PeerChat, PeerChannel
my_user = client.get_entity(PeerUser(some_id))
my_chat = client.get_entity(PeerChat(some_id))
my_channel = client.get_entity(PeerChannel(some_id))
my_user = await client.get_entity(PeerUser(some_id))
my_chat = await client.get_entity(PeerChat(some_id))
my_channel = await client.get_entity(PeerChannel(some_id))
.. note::
@@ -212,7 +214,7 @@ wherever needed, so you can even do things like:

.. code-block:: python
client(SendMessageRequest('username', 'hello'))
await client(SendMessageRequest('username', 'hello'))
The library will call the ``.resolve()`` method of the request, which will
resolve ``'username'`` with the appropriated :tl:`InputPeer`. Don't worry if
@@ -258,15 +260,15 @@ That means you can do this:
message.is_private
message.chat_id
message.get_chat()
await message.get_chat()
# ...etc
`SenderGetter <telethon.tl.custom.sendergetter.SenderGetter>` is similar:

.. code-block:: python
message.user_id
message.get_input_user()
await message.get_input_user()
message.user
# ...etc
@@ -285,22 +287,25 @@ applications"? Now do the same with the library. Use what applies:

.. code-block:: python
with client:
# (These examples assume you are inside an "async def")
async with client:
# 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.
client.get_dialogs()
await client.get_dialogs()
# 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.
client.get_messages('TelethonChat', 100)
await client.get_messages('TelethonChat', 100)
# NOW you can use the ID, anywhere!
entity = client.get_entity(123456)
client.send_message(123456, 'Hi!')
await 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.
You can't use entities from IDs the library hasn't seen. You must make the
@@ -19,7 +19,8 @@ available in :ref:`telethon-errors`, but some examples are:
from telethon import errors
try:
print(client.get_messages(chat)[0].text)
messages = await client.get_messages(chat)
print(messages[0].text)
except errors.FloodWaitError as e:
print('Have to sleep', e.seconds, 'seconds')
time.sleep(e.seconds)
@@ -78,8 +78,17 @@ Or we call `client.get_input_entity()

.. code-block:: python
import telethon.sync
peer = client.get_input_entity('someone')
import telethon
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
@@ -92,7 +101,7 @@ instead:

.. 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
its "input" version for you. If you already have the complete user and
@@ -120,26 +129,26 @@ request we do:

.. 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
methods available as of layer 80, and you can use every single of them
as you wish. Remember to use the right types! To sum up:

.. code-block:: python
result = client(SendMessageRequest(
client.get_input_entity('username'), 'Hello there!'
result = await client(SendMessageRequest(
await client.get_input_entity('username'), 'Hello there!'
))
This can further be simplified to:

.. code-block:: python
result = client(SendMessageRequest('username', 'Hello there!'))
result = await client(SendMessageRequest('username', 'Hello there!'))
# Or even
result = client(SendMessageRequest(PeerChannel(id), 'Hello there!'))
result = await client(SendMessageRequest(PeerChannel(id), 'Hello there!'))
.. note::

@@ -195,7 +204,7 @@ knows all requests directly:

.. code-block:: python
client([
await client([
SendMessageRequest('me', 'Hello'),
SendMessageRequest('me', ', '),
SendMessageRequest('me', 'World'),
@@ -212,7 +221,7 @@ and still access the successful results:
from telethon.errors import MultiError
try:
client([
await client([
SendMessageRequest('me', 'Hello'),
SendMessageRequest('me', ''),
SendMessageRequest('me', 'World')
@@ -154,7 +154,7 @@ you can save it in a variable directly:
string = '1aaNk8EX-YRfwoRsebUkugFvht6DUPi_Q25UOCzOAqzc...'
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
@@ -8,7 +8,7 @@ does a result have? Well, the easiest thing to do is printing it:

.. code-block:: python
user = client.get_entity('Lonami')
user = await client.get_entity('Lonami')
print(user)
That will show a huge **string** similar to the following:

0 comments on commit e1905d0

Please sign in to comment.
You can’t perform that action at this time.