mirror of
https://github.com/LonamiWebs/Telethon.git
synced 2025-08-08 04:52:30 +00:00
Clean up and complete RTD documentation
This commit is contained in:
@@ -1,117 +0,0 @@
|
||||
.. _accessing-the-full-api:
|
||||
|
||||
==========================
|
||||
Accessing the Full API
|
||||
==========================
|
||||
|
||||
The ``TelegramClient`` doesn’t offer a method for every single request
|
||||
the Telegram API supports. However, it’s very simple to ``.invoke()``
|
||||
any request. Whenever you need something, don’t forget to `check the
|
||||
documentation`__ and look for the `method you need`__. There you can go
|
||||
through a sorted list of everything you can do.
|
||||
|
||||
You should also refer to the documentation to see what the objects
|
||||
(constructors) Telegram returns look like. Every constructor inherits
|
||||
from a common type, and that’s the reason for this distinction.
|
||||
|
||||
Say ``client.send_message()`` didn’t exist, we could use the `search`__
|
||||
to look for “message”. There we would find `SendMessageRequest`__,
|
||||
which we can work with.
|
||||
|
||||
Every request is a Python class, and has the parameters needed for you
|
||||
to invoke it. You can also call ``help(request)`` for information on
|
||||
what input parameters it takes. Remember to “Copy import to the
|
||||
clipboard”, or your script won’t be aware of this class! Now we have:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from telethon.tl.functions.messages import SendMessageRequest
|
||||
|
||||
If you’re going to use a lot of these, you may do:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
import telethon.tl.functions as tl
|
||||
# We now have access to 'tl.messages.SendMessageRequest'
|
||||
|
||||
We see that this request must take at least two parameters, a ``peer``
|
||||
of type `InputPeer`__, and a ``message`` which is just a Python
|
||||
``str``\ ing.
|
||||
|
||||
How can we retrieve this ``InputPeer``? We have two options. We manually
|
||||
`construct one`__, for instance:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from telethon.tl.types import InputPeerUser
|
||||
|
||||
peer = InputPeerUser(user_id, user_hash)
|
||||
|
||||
Or we call ``.get_input_entity()``:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
peer = client.get_input_entity('someone')
|
||||
|
||||
When you’re going to invoke an API method, most require you to pass an
|
||||
``InputUser``, ``InputChat``, or so on, this is why using
|
||||
``.get_input_entity()`` is more straightforward (and sometimes
|
||||
immediate, if you know the ID of the user for instance). If you also
|
||||
need to have information about the whole user, use ``.get_entity()``
|
||||
instead:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
entity = 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
|
||||
want to cache its input version so the library doesn’t have to do this
|
||||
every time its used, simply call ``.get_input_peer``:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from telethon import utils
|
||||
peer = utils.get_input_user(entity)
|
||||
|
||||
After this small parenthesis about ``.get_entity`` versus
|
||||
``.get_input_entity``, we have everything we need. To ``.invoke()`` our
|
||||
request we do:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
result = client(SendMessageRequest(peer, 'Hello there!'))
|
||||
# __call__ is an alias for client.invoke(request). Both will work
|
||||
|
||||
Message sent! Of course, this is only an example.
|
||||
There are nearly 250 methods available as of layer 73,
|
||||
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!'
|
||||
))
|
||||
|
||||
|
||||
.. note::
|
||||
|
||||
Note that some requests have a "hash" parameter. This is **not** your ``api_hash``!
|
||||
It likely isn't your self-user ``.access_hash`` either.
|
||||
It's a special hash used by Telegram to only send a difference of new data
|
||||
that you don't already have with that request,
|
||||
so you can leave it to 0, and it should work (which means no hash is known yet).
|
||||
|
||||
For those requests having a "limit" parameter,
|
||||
you can often set it to zero to signify "return as many items as possible".
|
||||
This won't work for all of them though,
|
||||
for instance, in "messages.search" it will actually return 0 items.
|
||||
|
||||
|
||||
__ https://lonamiwebs.github.io/Telethon
|
||||
__ https://lonamiwebs.github.io/Telethon/methods/index.html
|
||||
__ https://lonamiwebs.github.io/Telethon/?q=message
|
||||
__ https://lonamiwebs.github.io/Telethon/methods/messages/send_message.html
|
||||
__ https://lonamiwebs.github.io/Telethon/types/input_peer.html
|
||||
__ https://lonamiwebs.github.io/Telethon/constructors/input_peer_user.html
|
@@ -1,24 +1,28 @@
|
||||
.. _creating-a-client:
|
||||
|
||||
===================
|
||||
=================
|
||||
Creating a Client
|
||||
===================
|
||||
=================
|
||||
|
||||
|
||||
Before working with Telegram's API, you need to get your own API ID and hash:
|
||||
|
||||
1. Follow `this link <https://my.telegram.org/>`_ and login with your phone number.
|
||||
1. Follow `this link <https://my.telegram.org/>`_ and login with your
|
||||
phone number.
|
||||
|
||||
2. Click under API Development tools.
|
||||
|
||||
3. A *Create new application* window will appear. Fill in your application details.
|
||||
There is no need to enter any *URL*, and only the first two fields (*App title* and *Short name*)
|
||||
can be changed later as far as I'm aware.
|
||||
3. A *Create new application* window will appear. Fill in your application
|
||||
details. There is no need to enter any *URL*, and only the first two
|
||||
fields (*App title* and *Short name*) can currently be changed later.
|
||||
|
||||
4. Click on *Create application* at the end. Remember that your **API hash is secret**
|
||||
and Telegram won't let you revoke it. Don't post it anywhere!
|
||||
4. Click on *Create application* at the end. Remember that your
|
||||
**API hash is secret** and Telegram won't let you revoke it.
|
||||
Don't post it anywhere!
|
||||
|
||||
Once that's ready, the next step is to create a ``TelegramClient``.
|
||||
This class will be your main interface with Telegram's API, and creating one is very simple:
|
||||
This class will be your main interface with Telegram's API, and creating
|
||||
one is very simple:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -31,14 +35,18 @@ This class will be your main interface with Telegram's API, and creating one is
|
||||
|
||||
client = TelegramClient('some_name', api_id, api_hash)
|
||||
|
||||
Note that ``'some_name'`` will be used to save your session (persistent information such as access key and others)
|
||||
as ``'some_name.session'`` in your disk. This is simply a JSON file which you can (but shouldn't) modify.
|
||||
|
||||
Before using the client, you must be connected to Telegram. Doing so is very easy:
|
||||
Note that ``'some_name'`` will be used to save your session (persistent
|
||||
information such as access key and others) as ``'some_name.session'`` in
|
||||
your disk. This is by default a database file using Python's ``sqlite3``.
|
||||
|
||||
Before using the client, you must be connected to Telegram.
|
||||
Doing so is very easy:
|
||||
|
||||
``client.connect() # Must return True, otherwise, try again``
|
||||
|
||||
You may or may not be authorized yet. You must be authorized before you're able to send any request:
|
||||
You may or may not be authorized yet. You must be authorized
|
||||
before you're able to send any request:
|
||||
|
||||
``client.is_user_authorized() # Returns True if you can send requests``
|
||||
|
||||
@@ -52,13 +60,25 @@ If you're not authorized, you need to ``.sign_in()``:
|
||||
# If .sign_in raises SessionPasswordNeeded error, call .sign_in(password=...)
|
||||
# You can import both exceptions from telethon.errors.
|
||||
|
||||
``myself`` is your Telegram user.
|
||||
You can view all the information about yourself by doing ``print(myself.stringify())``.
|
||||
You're now ready to use the client as you wish!
|
||||
``myself`` is your Telegram user. You can view all the information about
|
||||
yourself by doing ``print(myself.stringify())``. You're now ready to use
|
||||
the client as you wish! Remember that any object returned by the API has
|
||||
mentioned ``.stringify()`` method, and printing these might prove useful.
|
||||
|
||||
As a full example:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
client = TelegramClient('anon', api_id, api_hash)
|
||||
assert client.connect()
|
||||
if not client.is_user_authorized():
|
||||
client.send_code_request(phone_number)
|
||||
me = client.sign_in(phone_number, input('Enter code: '))
|
||||
|
||||
|
||||
.. note::
|
||||
If you want to use a **proxy**, you have to `install PySocks`__ (via pip or manual)
|
||||
and then set the appropriated parameters:
|
||||
If you want to use a **proxy**, you have to `install PySocks`__
|
||||
(via pip or manual) and then set the appropriated parameters:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -72,5 +92,58 @@ You're now ready to use the client as you wish!
|
||||
consisting of parameters described `here`__.
|
||||
|
||||
|
||||
|
||||
Two Factor Authorization (2FA)
|
||||
******************************
|
||||
|
||||
If you have Two Factor Authorization (from now on, 2FA) enabled on your
|
||||
account, calling :meth:`telethon.TelegramClient.sign_in` will raise a
|
||||
`SessionPasswordNeededError`. When this happens, just
|
||||
:meth:`telethon.TelegramClient.sign_in` again with a ``password=``:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
import getpass
|
||||
from telethon.errors import SessionPasswordNeededError
|
||||
|
||||
client.sign_in(phone)
|
||||
try:
|
||||
client.sign_in(code=input('Enter code: '))
|
||||
except SessionPasswordNeededError:
|
||||
client.sign_in(password=getpass.getpass())
|
||||
|
||||
|
||||
If you don't have 2FA enabled, but you would like to do so through Telethon,
|
||||
take as example the following code snippet:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
import os
|
||||
from hashlib import sha256
|
||||
from telethon.tl.functions import account
|
||||
from telethon.tl.types.account import PasswordInputSettings
|
||||
|
||||
new_salt = client(account.GetPasswordRequest()).new_salt
|
||||
salt = new_salt + os.urandom(8) # new random salt
|
||||
|
||||
pw = 'secret'.encode('utf-8') # type your new password here
|
||||
hint = 'hint'
|
||||
|
||||
pw_salted = salt + pw + salt
|
||||
pw_hash = sha256(pw_salted).digest()
|
||||
|
||||
result = client(account.UpdatePasswordSettingsRequest(
|
||||
current_password_hash=salt,
|
||||
new_settings=PasswordInputSettings(
|
||||
new_salt=salt,
|
||||
new_password_hash=pw_hash,
|
||||
hint=hint
|
||||
)
|
||||
))
|
||||
|
||||
Thanks to `Issue 259 <https://github.com/LonamiWebs/Telethon/issues/259>`_
|
||||
for the tip!
|
||||
|
||||
|
||||
__ https://github.com/Anorov/PySocks#installation
|
||||
__ https://github.com/Anorov/PySocks#usage-1%3E
|
||||
__ https://github.com/Anorov/PySocks#usage-1%3E
|
||||
|
87
readthedocs/extra/basic/entities.rst
Normal file
87
readthedocs/extra/basic/entities.rst
Normal file
@@ -0,0 +1,87 @@
|
||||
=========================
|
||||
Users, Chats and Channels
|
||||
=========================
|
||||
|
||||
|
||||
Introduction
|
||||
************
|
||||
|
||||
The library widely uses the concept of "entities". An entity will refer
|
||||
to any ``User``, ``Chat`` or ``Channel`` object that the API may return
|
||||
in response to certain methods, such as ``GetUsersRequest``.
|
||||
|
||||
To save bandwidth, the API also makes use of their "input" versions.
|
||||
The input version of an entity (e.g. ``InputPeerUser``, ``InputChat``,
|
||||
etc.) only contains the minimum required information that's required
|
||||
for Telegram to be able to identify who you're referring to: their ID
|
||||
and hash. This ID/hash pair is unique per user, so if you use the pair
|
||||
given by another user **or bot** it will **not** work.
|
||||
|
||||
To save *even more* bandwidth, the API also makes use of the ``Peer``
|
||||
versions, which just have an ID. This serves to identify them, but
|
||||
peers alone are not enough to use them. You need to know their hash
|
||||
before you can "use them".
|
||||
|
||||
Luckily, the library tries to simplify this mess the best it can.
|
||||
|
||||
|
||||
Getting entities
|
||||
****************
|
||||
|
||||
Through the use of the :ref:`sessions`, the library will automatically
|
||||
remember the ID and hash pair, along with some extra information, so
|
||||
you're able to just do this:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
# dialogs are the "conversations you have open"
|
||||
# this method returns a list of Dialog, which
|
||||
# have the .entity attribute and other information.
|
||||
dialogs = client.get_dialogs(limit=200)
|
||||
|
||||
# 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')
|
||||
|
||||
# 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)
|
||||
|
||||
# using peers/input peers (note that the API may return these)
|
||||
# users, chats and channels may all have the same ID, so it's
|
||||
# necessary to wrap (at least) chat and channels inside Peer.
|
||||
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))
|
||||
|
||||
|
||||
All methods in the :ref:`telegram-client` call ``.get_entity()`` to further
|
||||
save you from the hassle of doing so manually, so doing things like
|
||||
``client.send_message('lonami', 'hi!')`` is possible.
|
||||
|
||||
Every entity the library "sees" (in any response to any call) will by
|
||||
default be cached in the ``.session`` file, to avoid performing
|
||||
unnecessary API calls. If the entity cannot be found, some calls
|
||||
like ``ResolveUsernameRequest`` or ``GetContactsRequest`` may be
|
||||
made to obtain the required information.
|
||||
|
||||
|
||||
Entities vs. Input Entities
|
||||
***************************
|
||||
|
||||
As we mentioned before, API calls don't need to know the whole information
|
||||
about the entities, only their ID and hash. For this reason, another method,
|
||||
``.get_input_entity()`` is available. This will always use the cache while
|
||||
possible, making zero API calls most of the time. When a request is made,
|
||||
if you provided the full entity, e.g. an ``User``, the library will convert
|
||||
it to the required ``InputPeer`` automatically for you.
|
||||
|
||||
**You should always favour ``.get_input_entity()``** over ``.get_entity()``
|
||||
for this reason! Calling the latter will always make an API call to get
|
||||
the most recent information about said entity, but invoking requests don't
|
||||
need this information, just the ``InputPeer``. Only use ``.get_entity()``
|
||||
if you need to get actual information, like the username, name, title, etc.
|
||||
of the entity.
|
@@ -3,13 +3,13 @@
|
||||
You can adapt this file completely to your liking, but it should at least
|
||||
contain the root `toctree` directive.
|
||||
|
||||
===============
|
||||
Getting Started
|
||||
===============
|
||||
|
||||
=================
|
||||
Getting Started!
|
||||
=================
|
||||
|
||||
Simple Installation
|
||||
*********************
|
||||
*******************
|
||||
|
||||
``pip install telethon``
|
||||
|
||||
@@ -17,7 +17,7 @@ Simple Installation
|
||||
|
||||
|
||||
Creating a client
|
||||
**************
|
||||
*****************
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -39,8 +39,9 @@ Creating a client
|
||||
**More details**: :ref:`creating-a-client`
|
||||
|
||||
|
||||
Simple Stuff
|
||||
**************
|
||||
Basic Usage
|
||||
***********
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
print(me.stringify())
|
||||
@@ -52,3 +53,5 @@ Simple Stuff
|
||||
total, messages, senders = client.get_message_history('username')
|
||||
client.download_media(messages[0])
|
||||
|
||||
**More details**: :ref:`telegram-client`
|
||||
|
||||
|
@@ -1,18 +1,20 @@
|
||||
.. _installation:
|
||||
|
||||
=================
|
||||
============
|
||||
Installation
|
||||
=================
|
||||
============
|
||||
|
||||
|
||||
Automatic Installation
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
**********************
|
||||
|
||||
To install Telethon, simply do:
|
||||
|
||||
``pip install telethon``
|
||||
|
||||
If you get something like ``"SyntaxError: invalid syntax"`` or any other error while installing,
|
||||
it's probably because ``pip`` defaults to Python 2, which is not supported. Use ``pip3`` instead.
|
||||
If you get something like ``"SyntaxError: invalid syntax"`` or any other
|
||||
error while installing/importing the library, it's probably because ``pip``
|
||||
defaults to Python 2, which is not supported. Use ``pip3`` instead.
|
||||
|
||||
If you already have the library installed, upgrade with:
|
||||
|
||||
@@ -20,7 +22,7 @@ If you already have the library installed, upgrade with:
|
||||
|
||||
You can also install the library directly from GitHub or a fork:
|
||||
|
||||
.. code-block:: python
|
||||
.. code-block:: sh
|
||||
|
||||
# pip install git+https://github.com/LonamiWebs/Telethon.git
|
||||
or
|
||||
@@ -32,13 +34,15 @@ If you don't have root access, simply pass the ``--user`` flag to the pip comman
|
||||
|
||||
|
||||
Manual Installation
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
*******************
|
||||
|
||||
1. Install the required ``pyaes`` (`GitHub`__ | `PyPi`__) and ``rsa`` (`GitHub`__ | `PyPi`__) modules:
|
||||
1. Install the required ``pyaes`` (`GitHub`__ | `PyPi`__) and
|
||||
``rsa`` (`GitHub`__ | `PyPi`__) modules:
|
||||
|
||||
``sudo -H pip install pyaes rsa``
|
||||
|
||||
2. Clone Telethon's GitHub repository: ``git clone https://github.com/LonamiWebs/Telethon.git``
|
||||
2. Clone Telethon's GitHub repository:
|
||||
``git clone https://github.com/LonamiWebs/Telethon.git``
|
||||
|
||||
3. Enter the cloned repository: ``cd Telethon``
|
||||
|
||||
@@ -50,22 +54,15 @@ To generate the documentation, ``cd docs`` and then ``python3 generate.py``.
|
||||
|
||||
|
||||
Optional dependencies
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
If you're using the library under ARM (or even if you aren't),
|
||||
you may want to install ``sympy`` through ``pip`` for a substantial speed-up
|
||||
when generating the keys required to connect to Telegram
|
||||
(you can of course do this on desktop too). See `issue #199`__ for more.
|
||||
|
||||
If ``libssl`` is available on your system, it will also be used wherever encryption is needed.
|
||||
|
||||
If neither of these are available, a pure Python callback will be used instead,
|
||||
so you can still run the library wherever Python is available!
|
||||
*********************
|
||||
|
||||
If ``libssl`` is available on your system, it will be used wherever encryption
|
||||
is needed, but otherwise it will fall back to pure Python implementation so it
|
||||
will also work without it.
|
||||
|
||||
|
||||
__ https://github.com/ricmoo/pyaes
|
||||
__ https://pypi.python.org/pypi/pyaes
|
||||
__ https://github.com/sybrenstuvel/python-rsa/
|
||||
__ https://pypi.python.org/pypi/rsa/3.4.2
|
||||
__ https://github.com/LonamiWebs/Telethon/issues/199
|
||||
__ https://github.com/LonamiWebs/Telethon/issues/199
|
||||
|
@@ -1,55 +0,0 @@
|
||||
.. _sending-requests:
|
||||
|
||||
==================
|
||||
Sending Requests
|
||||
==================
|
||||
|
||||
Since we're working with Python, one must not forget that they can do ``help(client)`` or ``help(TelegramClient)``
|
||||
at any time for a more detailed description and a list of all the available methods.
|
||||
Calling ``help()`` from an interactive Python session will always list all the methods for any object, even yours!
|
||||
|
||||
Interacting with the Telegram API is done through sending **requests**,
|
||||
this is, any "method" listed on the API. There are a few methods on the ``TelegramClient`` class
|
||||
that abstract you from the need of manually importing the requests you need.
|
||||
|
||||
For instance, retrieving your own user can be done in a single line:
|
||||
|
||||
``myself = client.get_me()``
|
||||
|
||||
Internally, this method has sent a request to Telegram, who replied with the information about your own user.
|
||||
|
||||
If you want to retrieve any other user, chat or channel (channels are a special subset of chats),
|
||||
you want to retrieve their "entity". This is how the library refers to either of these:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
# The method will infer that you've passed an username
|
||||
# It also accepts phone numbers, and will get the user
|
||||
# from your contact list.
|
||||
lonami = client.get_entity('lonami')
|
||||
|
||||
Note that saving and using these entities will be more important when Accessing the Full API.
|
||||
For now, this is a good way to get information about an user or chat.
|
||||
|
||||
Other common methods for quick scripts are also available:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
# Sending a message (use an entity/username/etc)
|
||||
client.send_message('TheAyyBot', 'ayy')
|
||||
|
||||
# Sending a photo, or a file
|
||||
client.send_file(myself, '/path/to/the/file.jpg', force_document=True)
|
||||
|
||||
# Downloading someone's profile photo. File is saved to 'where'
|
||||
where = client.download_profile_photo(someone)
|
||||
|
||||
# Retrieving the message history
|
||||
total, messages, senders = client.get_message_history(someone)
|
||||
|
||||
# Downloading the media from a specific message
|
||||
# You can specify either a directory, a filename, or nothing at all
|
||||
where = client.download_media(message, '/path/to/output')
|
||||
|
||||
Remember that you can call ``.stringify()`` to any object Telegram returns to pretty print it.
|
||||
Calling ``str(result)`` does the same operation, but on a single line.
|
@@ -1,48 +0,0 @@
|
||||
.. _sessions:
|
||||
|
||||
==============
|
||||
Session Files
|
||||
==============
|
||||
|
||||
The first parameter you pass the constructor of the
|
||||
``TelegramClient`` is the ``session``, and defaults to be the session
|
||||
name (or full path). That is, if you create a ``TelegramClient('anon')``
|
||||
instance and connect, an ``anon.session`` file will be created on the
|
||||
working directory.
|
||||
|
||||
These JSON session files contain the required information to talk to the
|
||||
Telegram servers, such as to which IP the client should connect, port,
|
||||
authorization key so that messages can be encrypted, and so on.
|
||||
|
||||
These files will by default also save all the input entities that you’ve
|
||||
seen, so that you can get information about an user or channel by just
|
||||
their ID. Telegram will **not** send their ``access_hash`` required to
|
||||
retrieve more information about them, if it thinks you have already seem
|
||||
them. For this reason, the library needs to store this information
|
||||
offline.
|
||||
|
||||
The library will by default too save all the entities (users with their
|
||||
name, username, chats and so on) **in memory**, not to disk, so that you
|
||||
can quickly access them by username or phone number. This can be
|
||||
disabled too. Run ``help(client.session.entities)`` to see the available
|
||||
methods (or ``help(EntityDatabase)``).
|
||||
|
||||
If you’re not going to work without updates, or don’t need to cache the
|
||||
``access_hash`` associated with the entities’ ID, you can disable this
|
||||
by setting ``client.session.save_entities = False``.
|
||||
|
||||
If you don’t want to save the files as JSON, you can also create your
|
||||
custom ``Session`` subclass and override the ``.save()`` and ``.load()``
|
||||
methods. For example, you could save it on a database:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
class DatabaseSession(Session):
|
||||
def save():
|
||||
# serialize relevant data to the database
|
||||
|
||||
def load():
|
||||
# load relevant data to the database
|
||||
|
||||
You should read the ``session.py`` source file to know what “relevant
|
||||
data” you need to keep track of.
|
99
readthedocs/extra/basic/telegram-client.rst
Normal file
99
readthedocs/extra/basic/telegram-client.rst
Normal file
@@ -0,0 +1,99 @@
|
||||
.. _telegram-client:
|
||||
|
||||
==============
|
||||
TelegramClient
|
||||
==============
|
||||
|
||||
|
||||
Introduction
|
||||
************
|
||||
|
||||
The ``TelegramClient`` is the central class of the library, the one
|
||||
you will be using most of the time. For this reason, it's important
|
||||
to know what it offers.
|
||||
|
||||
Since we're working with Python, one must not forget that we can do
|
||||
``help(client)`` or ``help(TelegramClient)`` at any time for a more
|
||||
detailed description and a list of all the available methods. Calling
|
||||
``help()`` from an interactive Python session will always list all the
|
||||
methods for any object, even yours!
|
||||
|
||||
Interacting with the Telegram API is done through sending **requests**,
|
||||
this is, any "method" listed on the API. There are a few methods (and
|
||||
growing!) on the ``TelegramClient`` class that abstract you from the
|
||||
need of manually importing the requests you need.
|
||||
|
||||
For instance, retrieving your own user can be done in a single line:
|
||||
|
||||
``myself = client.get_me()``
|
||||
|
||||
Internally, this method has sent a request to Telegram, who replied with
|
||||
the information about your own user, and then the desired information
|
||||
was extracted from their response.
|
||||
|
||||
If you want to retrieve any other user, chat or channel (channels are a
|
||||
special subset of chats), you want to retrieve their "entity". This is
|
||||
how the library refers to either of these:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
# The method will infer that you've passed an username
|
||||
# It also accepts phone numbers, and will get the user
|
||||
# from your contact list.
|
||||
lonami = client.get_entity('lonami')
|
||||
|
||||
The so called "entities" are another important whole concept on its own,
|
||||
and you should
|
||||
Note that saving and using these entities will be more important when
|
||||
Accessing the Full API. For now, this is a good way to get information
|
||||
about an user or chat.
|
||||
|
||||
Other common methods for quick scripts are also available:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
# Sending a message (use an entity/username/etc)
|
||||
client.send_message('TheAyyBot', 'ayy')
|
||||
|
||||
# Sending a photo, or a file
|
||||
client.send_file(myself, '/path/to/the/file.jpg', force_document=True)
|
||||
|
||||
# Downloading someone's profile photo. File is saved to 'where'
|
||||
where = client.download_profile_photo(someone)
|
||||
|
||||
# Retrieving the message history
|
||||
messages = client.get_message_history(someone)
|
||||
|
||||
# Downloading the media from a specific message
|
||||
# You can specify either a directory, a filename, or nothing at all
|
||||
where = client.download_media(message, '/path/to/output')
|
||||
|
||||
# Call .disconnect() when you're done
|
||||
client.disconnect()
|
||||
|
||||
Remember that you can call ``.stringify()`` to any object Telegram returns
|
||||
to pretty print it. Calling ``str(result)`` does the same operation, but on
|
||||
a single line.
|
||||
|
||||
|
||||
Available methods
|
||||
*****************
|
||||
|
||||
This page lists all the "handy" methods available for you to use in the
|
||||
``TelegramClient`` class. These are simply wrappers around the "raw"
|
||||
Telegram API, making it much more manageable and easier to work with.
|
||||
|
||||
Please refer to :ref:`accessing-the-full-api` if these aren't enough,
|
||||
and don't be afraid to read the source code of the InteractiveTelegramClient_
|
||||
or even the TelegramClient_ itself to learn how it works.
|
||||
|
||||
|
||||
.. _InteractiveTelegramClient: https://github.com/LonamiWebs/Telethon/blob/master/telethon_examples/interactive_telegram_client.py
|
||||
.. _TelegramClient: https://github.com/LonamiWebs/Telethon/blob/master/telethon/telegram_client.py
|
||||
|
||||
|
||||
|
||||
.. automodule:: telethon.telegram_client
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
@@ -14,23 +14,24 @@ The library can run in four distinguishable modes:
|
||||
- With several worker threads that run your update handlers.
|
||||
- A mix of the above.
|
||||
|
||||
Since this section is about updates, we'll describe the simplest way to work with them.
|
||||
|
||||
.. warning::
|
||||
Remember that you should always call ``client.disconnect()`` once you're done.
|
||||
Since this section is about updates, we'll describe the simplest way to
|
||||
work with them.
|
||||
|
||||
|
||||
Using multiple workers
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
**********************
|
||||
|
||||
When you create your client, simply pass a number to the ``update_workers`` parameter:
|
||||
When you create your client, simply pass a number to the
|
||||
``update_workers`` parameter:
|
||||
|
||||
``client = TelegramClient('session', api_id, api_hash, update_workers=4)``
|
||||
|
||||
4 workers should suffice for most cases (this is also the default on `Python Telegram Bot`__).
|
||||
You can set this value to more, or even less if you need.
|
||||
4 workers should suffice for most cases (this is also the default on
|
||||
`Python Telegram Bot`__). You can set this value to more, or even less
|
||||
if you need.
|
||||
|
||||
The next thing you want to do is to add a method that will be called when an `Update`__ arrives:
|
||||
The next thing you want to do is to add a method that will be called when
|
||||
an `Update`__ arrives:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -41,7 +42,8 @@ The next thing you want to do is to add a method that will be called when an `Up
|
||||
# do more work here, or simply sleep!
|
||||
|
||||
That's it! Now let's do something more interesting.
|
||||
Every time an user talks to use, let's reply to them with the same text reversed:
|
||||
Every time an user talks to use, let's reply to them with the same
|
||||
text reversed:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -56,16 +58,18 @@ Every time an user talks to use, let's reply to them with the same text reversed
|
||||
input('Press enter to stop this!')
|
||||
client.disconnect()
|
||||
|
||||
We only ask you one thing: don't keep this running for too long, or your contacts will go mad.
|
||||
We only ask you one thing: don't keep this running for too long, or your
|
||||
contacts will go mad.
|
||||
|
||||
|
||||
Spawning no worker at all
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
*************************
|
||||
|
||||
All the workers do is loop forever and poll updates from a queue that is filled from the ``ReadThread``,
|
||||
responsible for reading every item off the network.
|
||||
If you only need a worker and the ``MainThread`` would be doing no other job,
|
||||
this is the preferred way. You can easily do the same as the workers like so:
|
||||
All the workers do is loop forever and poll updates from a queue that is
|
||||
filled from the ``ReadThread``, responsible for reading every item off
|
||||
the network. If you only need a worker and the ``MainThread`` would be
|
||||
doing no other job, this is the preferred way. You can easily do the same
|
||||
as the workers like so:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -81,24 +85,27 @@ this is the preferred way. You can easily do the same as the workers like so:
|
||||
|
||||
client.disconnect()
|
||||
|
||||
Note that ``poll`` accepts a ``timeout=`` parameter,
|
||||
and it will return ``None`` if other thread got the update before you could or if the timeout expired,
|
||||
so it's important to check ``if not update``.
|
||||
Note that ``poll`` accepts a ``timeout=`` parameter, and it will return
|
||||
``None`` if other thread got the update before you could or if the timeout
|
||||
expired, so it's important to check ``if not update``.
|
||||
|
||||
This can coexist with the rest of ``N`` workers, or you can set it to ``0`` additional workers:
|
||||
This can coexist with the rest of ``N`` workers, or you can set it to ``0``
|
||||
additional workers:
|
||||
|
||||
``client = TelegramClient('session', api_id, api_hash, update_workers=0)``
|
||||
|
||||
You **must** set it to ``0`` (or other number), as it defaults to ``None`` and there is a different.
|
||||
``None`` workers means updates won't be processed *at all*,
|
||||
so you must set it to some value (0 or greater) if you want ``client.updates.poll()`` to work.
|
||||
You **must** set it to ``0`` (or other number), as it defaults to ``None``
|
||||
and there is a different. ``None`` workers means updates won't be processed
|
||||
*at all*, so you must set it to some value (``0`` or greater) if you want
|
||||
``client.updates.poll()`` to work.
|
||||
|
||||
|
||||
Using the main thread instead the ``ReadThread``
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
************************************************
|
||||
|
||||
If you have no work to do on the ``MainThread`` and you were planning to have a ``while True: sleep(1)``,
|
||||
don't do that. Instead, don't spawn the secondary ``ReadThread`` at all like so:
|
||||
If you have no work to do on the ``MainThread`` and you were planning to have
|
||||
a ``while True: sleep(1)``, don't do that. Instead, don't spawn the secondary
|
||||
``ReadThread`` at all like so:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -111,8 +118,8 @@ And then ``.idle()`` from the ``MainThread``:
|
||||
|
||||
``client.idle()``
|
||||
|
||||
You can stop it with :kbd:`Control+C`,
|
||||
and you can configure the signals to be used in a similar fashion to `Python Telegram Bot`__.
|
||||
You can stop it with :kbd:`Control+C`, and you can configure the signals
|
||||
to be used in a similar fashion to `Python Telegram Bot`__.
|
||||
|
||||
As a complete example:
|
||||
|
||||
@@ -132,4 +139,4 @@ As a complete example:
|
||||
|
||||
__ https://python-telegram-bot.org/
|
||||
__ https://lonamiwebs.github.io/Telethon/types/update.html
|
||||
__ https://github.com/python-telegram-bot/python-telegram-bot/blob/4b3315db6feebafb94edcaa803df52bb49999ced/telegram/ext/updater.py#L460
|
||||
__ https://github.com/python-telegram-bot/python-telegram-bot/blob/4b3315db6feebafb94edcaa803df52bb49999ced/telegram/ext/updater.py#L460
|
||||
|
Reference in New Issue
Block a user