mirror of
				https://github.com/LonamiWebs/Telethon.git
				synced 2025-11-04 01:47:27 +03:00 
			
		
		
		
	add a bunch more readthedocs from wiki
This commit is contained in:
		
							parent
							
								
									34e7ae026e
								
							
						
					
					
						commit
						f6ec7e47a7
					
				
							
								
								
									
										59
									
								
								readthedocs/extra/advanced-usage/bots.rst
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								readthedocs/extra/advanced-usage/bots.rst
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,59 @@
 | 
			
		|||
======
 | 
			
		||||
Bots
 | 
			
		||||
======
 | 
			
		||||
 | 
			
		||||
Talking to Inline Bots
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
You can query an inline bot, such as `@VoteBot`__
 | 
			
		||||
(note, *query*, not *interact* with a voting message), by making use of
 | 
			
		||||
the `GetInlineBotResultsRequest`__ request:
 | 
			
		||||
 | 
			
		||||
    .. code-block:: python
 | 
			
		||||
 | 
			
		||||
        from telethon.tl.functions.messages import GetInlineBotResultsRequest
 | 
			
		||||
 | 
			
		||||
        bot_results = client(GetInlineBotResultsRequest(
 | 
			
		||||
            bot, user_or_chat, 'query', ''
 | 
			
		||||
        ))
 | 
			
		||||
 | 
			
		||||
And you can select any of their results by using
 | 
			
		||||
`SendInlineBotResultRequest`__:
 | 
			
		||||
 | 
			
		||||
    .. code-block:: python
 | 
			
		||||
 | 
			
		||||
        from telethon.tl.functions.messages import SendInlineBotResultRequest
 | 
			
		||||
 | 
			
		||||
        client(SendInlineBotResultRequest(
 | 
			
		||||
            get_input_peer(user_or_chat),
 | 
			
		||||
            obtained_query_id,
 | 
			
		||||
            obtained_str_id
 | 
			
		||||
        ))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Talking to Bots with special reply markup
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
To interact with a message that has a special reply markup, such as
 | 
			
		||||
`@VoteBot`__ polls, you would use
 | 
			
		||||
`GetBotCallbackAnswerRequest`__:
 | 
			
		||||
 | 
			
		||||
    .. code-block:: python
 | 
			
		||||
 | 
			
		||||
        from telethon.tl.functions.messages import GetBotCallbackAnswerRequest
 | 
			
		||||
 | 
			
		||||
        client(GetBotCallbackAnswerRequest(
 | 
			
		||||
            user_or_chat,
 | 
			
		||||
            msg.id,
 | 
			
		||||
            data=msg.reply_markup.rows[wanted_row].buttons[wanted_button].data
 | 
			
		||||
        ))
 | 
			
		||||
 | 
			
		||||
It’s a bit verbose, but it has all the information you would need to
 | 
			
		||||
show it visually (button rows, and buttons within each row, each with
 | 
			
		||||
its own data).
 | 
			
		||||
 | 
			
		||||
__ https://t.me/vote
 | 
			
		||||
__ https://lonamiwebs.github.io/Telethon/methods/messages/get_inline_bot_results.html
 | 
			
		||||
__ https://lonamiwebs.github.io/Telethon/methods/messages/send_inline_bot_result.html
 | 
			
		||||
__ https://lonamiwebs.github.io/Telethon/methods/messages/get_bot_callback_answer.html
 | 
			
		||||
__ https://t.me/vote
 | 
			
		||||
| 
						 | 
				
			
			@ -2,6 +2,10 @@
 | 
			
		|||
Signing In
 | 
			
		||||
=========================
 | 
			
		||||
 | 
			
		||||
.. note::
 | 
			
		||||
    Make sure you have gone through :ref:`prelude` already!
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Two Factor Authorization (2FA)
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										323
									
								
								readthedocs/extra/advanced-usage/users-and-chats.rst
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										323
									
								
								readthedocs/extra/advanced-usage/users-and-chats.rst
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,323 @@
 | 
			
		|||
=========================
 | 
			
		||||
Users and Chats
 | 
			
		||||
=========================
 | 
			
		||||
 | 
			
		||||
.. note::
 | 
			
		||||
    Make sure you have gone through :ref:`prelude` already!
 | 
			
		||||
 | 
			
		||||
.. contents::
 | 
			
		||||
 | 
			
		||||
.. _retrieving-an-entity:
 | 
			
		||||
 | 
			
		||||
Retrieving an entity (user or group)
 | 
			
		||||
**************************************
 | 
			
		||||
An “entity” is used to refer to either an `User`__ or a `Chat`__
 | 
			
		||||
(which includes a `Channel`__). The most straightforward way to get
 | 
			
		||||
an entity is to use ``TelegramClient.get_entity()``. This method accepts
 | 
			
		||||
either a string, which can be a username, phone number or `t.me`__-like
 | 
			
		||||
link, or an integer that will be the ID of an **user**. You can use it
 | 
			
		||||
like so:
 | 
			
		||||
 | 
			
		||||
    .. code-block:: python
 | 
			
		||||
 | 
			
		||||
        # all of these work
 | 
			
		||||
        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)
 | 
			
		||||
 | 
			
		||||
For the last one to work, the library must have “seen” the user at least
 | 
			
		||||
once. The library will “see” the user as long as any request contains
 | 
			
		||||
them, so if you’ve called ``.get_dialogs()`` for instance, and your
 | 
			
		||||
friend was there, the library will know about them. For more, read about
 | 
			
		||||
the :ref:`sessions`.
 | 
			
		||||
 | 
			
		||||
If you want to get a channel or chat by ID, you need to specify that
 | 
			
		||||
they are a channel or a chat. The library can’t infer what they are by
 | 
			
		||||
just their ID (unless the ID is marked, but this is only done
 | 
			
		||||
internally), so you need to wrap the ID around a `Peer`__ object:
 | 
			
		||||
 | 
			
		||||
    .. code-block:: python
 | 
			
		||||
 | 
			
		||||
        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))
 | 
			
		||||
 | 
			
		||||
**Note** that most requests don’t ask for an ``User``, or a ``Chat``,
 | 
			
		||||
but rather for ``InputUser``, ``InputChat``, and so on. If this is the
 | 
			
		||||
case, you should prefer ``.get_input_entity()`` over ``.get_entity()``,
 | 
			
		||||
as it will be immediate if you provide an ID (whereas ``.get_entity()``
 | 
			
		||||
may need to find who the entity is first).
 | 
			
		||||
 | 
			
		||||
Via your open “chats” (dialogs)
 | 
			
		||||
-------------------------------
 | 
			
		||||
 | 
			
		||||
.. note::
 | 
			
		||||
    Please read here: :ref:`retrieving-all-dialogs`.
 | 
			
		||||
 | 
			
		||||
Via ResolveUsernameRequest
 | 
			
		||||
--------------------------
 | 
			
		||||
 | 
			
		||||
This is the request used by ``.get_entity`` internally, but you can also
 | 
			
		||||
use it by hand:
 | 
			
		||||
 | 
			
		||||
.. code-block:: python
 | 
			
		||||
 | 
			
		||||
    from telethon.tl.functions.contacts import ResolveUsernameRequest
 | 
			
		||||
 | 
			
		||||
    result = client(ResolveUsernameRequest('username'))
 | 
			
		||||
    found_chats = result.chats
 | 
			
		||||
    found_users = result.users
 | 
			
		||||
    # result.peer may be a PeerUser, PeerChat or PeerChannel
 | 
			
		||||
 | 
			
		||||
See `Peer`__ for more information about this result.
 | 
			
		||||
 | 
			
		||||
Via MessageFwdHeader
 | 
			
		||||
--------------------
 | 
			
		||||
 | 
			
		||||
If all you have is a `MessageFwdHeader`__ after you retrieved a bunch
 | 
			
		||||
of messages, this gives you access to the ``from_id`` (if forwarded from
 | 
			
		||||
an user) and ``channel_id`` (if forwarded from a channel). Invoking
 | 
			
		||||
`GetMessagesRequest`__ also returns a list of ``chats`` and
 | 
			
		||||
``users``, and you can find the desired entity there:
 | 
			
		||||
 | 
			
		||||
    .. code-block:: python
 | 
			
		||||
 | 
			
		||||
        # Logic to retrieve messages with `GetMessagesRequest´
 | 
			
		||||
        messages = foo()
 | 
			
		||||
        fwd_header = bar()
 | 
			
		||||
 | 
			
		||||
        user = next(u for u in messages.users if u.id == fwd_header.from_id)
 | 
			
		||||
        channel = next(c for c in messages.chats if c.id == fwd_header.channel_id)
 | 
			
		||||
 | 
			
		||||
Or you can just call ``.get_entity()`` with the ID, as you should have
 | 
			
		||||
seen that user or channel before. A call to ``GetMessagesRequest`` may
 | 
			
		||||
still be neeed.
 | 
			
		||||
 | 
			
		||||
Via GetContactsRequest
 | 
			
		||||
----------------------
 | 
			
		||||
 | 
			
		||||
The library will call this for you if you pass a phone number to
 | 
			
		||||
``.get_entity``, but again, it can be done manually. If the user you
 | 
			
		||||
want to talk to is a contact, you can use `GetContactsRequest`__:
 | 
			
		||||
 | 
			
		||||
    .. code-block:: python
 | 
			
		||||
 | 
			
		||||
        from telethon.tl.functions.contacts import GetContactsRequest
 | 
			
		||||
        from telethon.tl.types.contacts import Contacts
 | 
			
		||||
 | 
			
		||||
        contacts = client(GetContactsRequest(0))
 | 
			
		||||
        if isinstance(contacts, Contacts):
 | 
			
		||||
            users = contacts.users
 | 
			
		||||
            contacts = contacts.contacts
 | 
			
		||||
 | 
			
		||||
__ https://lonamiwebs.github.io/Telethon/types/user.html
 | 
			
		||||
__ https://lonamiwebs.github.io/Telethon/types/chat.html
 | 
			
		||||
__ https://lonamiwebs.github.io/Telethon/constructors/channel.html
 | 
			
		||||
__ https://t.me
 | 
			
		||||
__ https://lonamiwebs.github.io/Telethon/types/peer.html
 | 
			
		||||
__ https://lonamiwebs.github.io/Telethon/types/peer.html
 | 
			
		||||
__ https://lonamiwebs.github.io/Telethon/constructors/message_fwd_header.html
 | 
			
		||||
__ https://lonamiwebs.github.io/Telethon/methods/messages/get_messages.html
 | 
			
		||||
__ https://lonamiwebs.github.io/Telethon/methods/contacts/get_contacts.html
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
.. _retrieving-all-dialogs:
 | 
			
		||||
 | 
			
		||||
Retrieving all dialogs
 | 
			
		||||
***********************
 | 
			
		||||
 | 
			
		||||
There are several ``offset_xyz=`` parameters that have no effect at all,
 | 
			
		||||
but there's not much one can do since this is something the server should handle.
 | 
			
		||||
Currently, the only way to get all dialogs
 | 
			
		||||
(open chats, conversations, etc.) is by using the ``offset_date``:
 | 
			
		||||
 | 
			
		||||
    .. code-block:: python
 | 
			
		||||
 | 
			
		||||
        from telethon.tl.functions.messages import GetDialogsRequest
 | 
			
		||||
        from telethon.tl.types import InputPeerEmpty
 | 
			
		||||
        from time import sleep
 | 
			
		||||
 | 
			
		||||
        dialogs = []
 | 
			
		||||
        users = []
 | 
			
		||||
        chats = []
 | 
			
		||||
 | 
			
		||||
        last_date = None
 | 
			
		||||
        chunk_size = 20
 | 
			
		||||
        while True:
 | 
			
		||||
            result = client(GetDialogsRequest(
 | 
			
		||||
                         offset_date=last_date,
 | 
			
		||||
                         offset_id=0,
 | 
			
		||||
                         offset_peer=InputPeerEmpty(),
 | 
			
		||||
                         limit=chunk_size
 | 
			
		||||
                     ))
 | 
			
		||||
            dialogs.extend(result.dialogs)
 | 
			
		||||
            users.extend(result.users)
 | 
			
		||||
            chats.extend(result.chats)
 | 
			
		||||
            if not result.messages:
 | 
			
		||||
                break
 | 
			
		||||
            last_date = min(msg.date for msg in result.messages)
 | 
			
		||||
            sleep(2)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Joining a chat or channel
 | 
			
		||||
*******************************
 | 
			
		||||
 | 
			
		||||
Note that `Chat`__\ s are normal groups, and `Channel`__\ s are a
 | 
			
		||||
special form of `Chat`__\ s,
 | 
			
		||||
which can also be super-groups if their ``megagroup`` member is
 | 
			
		||||
``True``.
 | 
			
		||||
 | 
			
		||||
Joining a public channel
 | 
			
		||||
------------------------
 | 
			
		||||
 | 
			
		||||
Once you have the :ref:`entity <retrieving-an-entity>`
 | 
			
		||||
of the channel you want to join to, you can
 | 
			
		||||
make use of the `JoinChannelRequest`__ to join such channel:
 | 
			
		||||
 | 
			
		||||
    .. code-block:: python
 | 
			
		||||
 | 
			
		||||
        from telethon.tl.functions.channels import JoinChannelRequest
 | 
			
		||||
        client(JoinChannelRequest(channel))
 | 
			
		||||
 | 
			
		||||
        # In the same way, you can also leave such channel
 | 
			
		||||
        from telethon.tl.functions.channels import LeaveChannelRequest
 | 
			
		||||
        client(LeaveChannelRequest(input_channel))
 | 
			
		||||
 | 
			
		||||
For more on channels, check the `channels namespace`__.
 | 
			
		||||
 | 
			
		||||
Joining a private chat or channel
 | 
			
		||||
---------------------------------
 | 
			
		||||
 | 
			
		||||
If all you have is a link like this one:
 | 
			
		||||
``https://t.me/joinchat/AAAAAFFszQPyPEZ7wgxLtd``, you already have
 | 
			
		||||
enough information to join! The part after the
 | 
			
		||||
``https://t.me/joinchat/``, this is, ``AAAAAFFszQPyPEZ7wgxLtd`` on this
 | 
			
		||||
example, is the ``hash`` of the chat or channel. Now you can use
 | 
			
		||||
`ImportChatInviteRequest`__ as follows:
 | 
			
		||||
 | 
			
		||||
    .. -block:: python
 | 
			
		||||
 | 
			
		||||
        from telethon.tl.functions.messages import ImportChatInviteRequest
 | 
			
		||||
        updates = client(ImportChatInviteRequest('AAAAAEHbEkejzxUjAUCfYg'))
 | 
			
		||||
 | 
			
		||||
Adding someone else to such chat or channel
 | 
			
		||||
-------------------------------------------
 | 
			
		||||
 | 
			
		||||
If you don’t want to add yourself, maybe because you’re already in, you
 | 
			
		||||
can always add someone else with the `AddChatUserRequest`__, which
 | 
			
		||||
use is very straightforward:
 | 
			
		||||
 | 
			
		||||
    .. code-block:: python
 | 
			
		||||
 | 
			
		||||
        from telethon.tl.functions.messages import AddChatUserRequest
 | 
			
		||||
 | 
			
		||||
        client(AddChatUserRequest(
 | 
			
		||||
            chat_id,
 | 
			
		||||
            user_to_add,
 | 
			
		||||
            fwd_limit=10  # allow the user to see the 10 last messages
 | 
			
		||||
        ))
 | 
			
		||||
 | 
			
		||||
Checking a link without joining
 | 
			
		||||
-------------------------------
 | 
			
		||||
 | 
			
		||||
If you don’t need to join but rather check whether it’s a group or a
 | 
			
		||||
channel, you can use the `CheckChatInviteRequest`__, which takes in
 | 
			
		||||
the `hash`__ of said channel or group.
 | 
			
		||||
 | 
			
		||||
__ https://lonamiwebs.github.io/Telethon/constructors/chat.html
 | 
			
		||||
__ https://lonamiwebs.github.io/Telethon/constructors/channel.html
 | 
			
		||||
__ https://lonamiwebs.github.io/Telethon/types/chat.html
 | 
			
		||||
__ https://lonamiwebs.github.io/Telethon/methods/channels/join_channel.html
 | 
			
		||||
__ https://lonamiwebs.github.io/Telethon/methods/channels/index.html
 | 
			
		||||
__ https://lonamiwebs.github.io/Telethon/methods/messages/import_chat_invite.html
 | 
			
		||||
__ https://lonamiwebs.github.io/Telethon/methods/messages/add_chat_user.html
 | 
			
		||||
__ https://lonamiwebs.github.io/Telethon/methods/messages/check_chat_invite.html
 | 
			
		||||
__ https://github.com/LonamiWebs/Telethon/wiki/Joining-a-chat-or-channel#joining-a-private-chat-or-channel
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Retrieving all chat members (channels too)
 | 
			
		||||
******************************************
 | 
			
		||||
 | 
			
		||||
In order to get all the members from a mega-group or channel, you need
 | 
			
		||||
to use `GetParticipantsRequest`__. As we can see it needs an
 | 
			
		||||
`InputChannel`__, (passing the mega-group or channel you’re going to
 | 
			
		||||
use will work), and a mandatory `ChannelParticipantsFilter`__. The
 | 
			
		||||
closest thing to “no filter” is to simply use
 | 
			
		||||
`ChannelParticipantsSearch`__ with an empty ``'q'`` string.
 | 
			
		||||
 | 
			
		||||
If we want to get *all* the members, we need to use a moving offset and
 | 
			
		||||
a fixed limit:
 | 
			
		||||
 | 
			
		||||
    .. code-block:: python
 | 
			
		||||
 | 
			
		||||
        from telethon.tl.functions.channels import GetParticipantsRequest
 | 
			
		||||
        from telethon.tl.types import ChannelParticipantsSearch
 | 
			
		||||
        from time import sleep
 | 
			
		||||
 | 
			
		||||
        offset = 0
 | 
			
		||||
        limit = 100
 | 
			
		||||
        all_participants = []
 | 
			
		||||
 | 
			
		||||
        while True:
 | 
			
		||||
            participants = client.invoke(GetParticipantsRequest(
 | 
			
		||||
                channel, ChannelParticipantsSearch(''), offset, limit
 | 
			
		||||
            ))
 | 
			
		||||
            if not participants.users:
 | 
			
		||||
                break
 | 
			
		||||
            all_participants.extend(participants.users)
 | 
			
		||||
            offset += len(participants.users)
 | 
			
		||||
            # sleep(1)  # This line seems to be optional, no guarantees!
 | 
			
		||||
 | 
			
		||||
Note that ``GetParticipantsRequest`` returns `ChannelParticipants`__,
 | 
			
		||||
which may have more information you need (like the role of the
 | 
			
		||||
participants, total count of members, etc.)
 | 
			
		||||
 | 
			
		||||
__ https://lonamiwebs.github.io/Telethon/methods/channels/get_participants.html
 | 
			
		||||
__ https://lonamiwebs.github.io/Telethon/methods/channels/get_participants.html
 | 
			
		||||
__ https://lonamiwebs.github.io/Telethon/types/channel_participants_filter.html
 | 
			
		||||
__ https://lonamiwebs.github.io/Telethon/constructors/channel_participants_search.html
 | 
			
		||||
__ https://lonamiwebs.github.io/Telethon/constructors/channels/channel_participants.html
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Recent Actions
 | 
			
		||||
********************
 | 
			
		||||
 | 
			
		||||
“Recent actions” is simply the name official applications have given to
 | 
			
		||||
the “admin log”. Simply use `GetAdminLogRequest`__ for that, and
 | 
			
		||||
you’ll get AdminLogResults.events in return which in turn has the final
 | 
			
		||||
`.action`__.
 | 
			
		||||
 | 
			
		||||
__ https://lonamiwebs.github.io/Telethon/methods/channels/get_admin_log.html
 | 
			
		||||
__ https://lonamiwebs.github.io/Telethon/types/channel_admin_log_event_action.html
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Increasing View Count in a Channel
 | 
			
		||||
****************************************
 | 
			
		||||
 | 
			
		||||
It has been asked `quite`__ `a few`__ `times`__ (really, `many`__), and
 | 
			
		||||
while I don’t understand why so many people ask this, the solution is to
 | 
			
		||||
use `GetMessagesViewsRequest`__, setting ``increment=True``:
 | 
			
		||||
 | 
			
		||||
    .. code-block:: python
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        # Obtain `channel' through dialogs or through client.get_entity() or anyhow.
 | 
			
		||||
        # Obtain `msg_ids' through `.get_message_history()` or anyhow. Must be a list.
 | 
			
		||||
 | 
			
		||||
        client(GetMessagesViewsRequest(
 | 
			
		||||
            peer=channel,
 | 
			
		||||
            id=msg_ids,
 | 
			
		||||
            increment=True
 | 
			
		||||
        ))
 | 
			
		||||
 | 
			
		||||
__ https://github.com/LonamiWebs/Telethon/issues/233
 | 
			
		||||
__ https://github.com/LonamiWebs/Telethon/issues/305
 | 
			
		||||
__ https://github.com/LonamiWebs/Telethon/issues/409
 | 
			
		||||
__ https://github.com/LonamiWebs/Telethon/issues/447
 | 
			
		||||
__ https://lonamiwebs.github.io/Telethon/methods/messages/get_messages_views.html
 | 
			
		||||
| 
						 | 
				
			
			@ -2,6 +2,10 @@
 | 
			
		|||
Working with messages
 | 
			
		||||
=========================
 | 
			
		||||
 | 
			
		||||
.. note::
 | 
			
		||||
    Make sure you have gone through :ref:`prelude` already!
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Forwarding messages
 | 
			
		||||
*******************
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,8 +1,4 @@
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
*****************
 | 
			
		||||
Examples
 | 
			
		||||
*****************
 | 
			
		||||
.. _prelude:
 | 
			
		||||
 | 
			
		||||
Prelude
 | 
			
		||||
---------
 | 
			
		||||
| 
						 | 
				
			
			@ -48,19 +44,5 @@ This example shows a basic usage more than enough in most cases. Even reading th
 | 
			
		|||
for the TelegramClient_ may help a lot!
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Signing In
 | 
			
		||||
--------------
 | 
			
		||||
 | 
			
		||||
.. toctree::
 | 
			
		||||
    examples-signing-in
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Working with messages
 | 
			
		||||
-----------------------
 | 
			
		||||
 | 
			
		||||
.. toctree::
 | 
			
		||||
    examples-working-with-messages
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
.. _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
 | 
			
		||||
							
								
								
									
										115
									
								
								readthedocs/extra/basic/accessing-the-full-api.rst
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										115
									
								
								readthedocs/extra/basic/accessing-the-full-api.rst
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,115 @@
 | 
			
		|||
==========================
 | 
			
		||||
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
 | 
			
		||||
							
								
								
									
										76
									
								
								readthedocs/extra/basic/creating-a-client.rst
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								readthedocs/extra/basic/creating-a-client.rst
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,76 @@
 | 
			
		|||
.. _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.
 | 
			
		||||
 | 
			
		||||
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.
 | 
			
		||||
 | 
			
		||||
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:
 | 
			
		||||
 | 
			
		||||
    .. code-block:: python
 | 
			
		||||
 | 
			
		||||
        from telethon import TelegramClient
 | 
			
		||||
 | 
			
		||||
        # Use your own values here
 | 
			
		||||
        api_id = 12345
 | 
			
		||||
        api_hash = '0123456789abcdef0123456789abcdef'
 | 
			
		||||
        phone_number = '+34600000000'
 | 
			
		||||
 | 
			
		||||
        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:
 | 
			
		||||
 | 
			
		||||
    ``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:
 | 
			
		||||
 | 
			
		||||
    ``client.is_user_authorized()  # Returns True if you can send requests``
 | 
			
		||||
 | 
			
		||||
If you're not authorized, you need to ``.sign_in()``:
 | 
			
		||||
 | 
			
		||||
    .. code-block:: python
 | 
			
		||||
 | 
			
		||||
        client.send_code_request(phone_number)
 | 
			
		||||
        myself = client.sign_in(phone_number, input('Enter code: '))
 | 
			
		||||
        # If .sign_in raises PhoneNumberUnoccupiedError, use .sign_up instead
 | 
			
		||||
        # 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!
 | 
			
		||||
 | 
			
		||||
.. note::
 | 
			
		||||
    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
 | 
			
		||||
 | 
			
		||||
            import socks
 | 
			
		||||
            client = TelegramClient('session_id',
 | 
			
		||||
                api_id=12345, api_hash='0123456789abcdef0123456789abcdef',
 | 
			
		||||
                proxy=(socks.SOCKS5, 'localhost', 4444)
 | 
			
		||||
            )
 | 
			
		||||
 | 
			
		||||
    The ``proxy=`` argument should be a tuple, a list or a dict,
 | 
			
		||||
    consisting of parameters described `here`__.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
__ https://github.com/Anorov/PySocks#installation
 | 
			
		||||
__ https://github.com/Anorov/PySocks#usage-1%3E
 | 
			
		||||
							
								
								
									
										54
									
								
								readthedocs/extra/basic/getting-started.rst
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								readthedocs/extra/basic/getting-started.rst
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,54 @@
 | 
			
		|||
.. Telethon documentation master file, created by
 | 
			
		||||
   sphinx-quickstart on Fri Nov 17 15:36:11 2017.
 | 
			
		||||
   You can adapt this file completely to your liking, but it should at least
 | 
			
		||||
   contain the root `toctree` directive.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
=================
 | 
			
		||||
Getting Started!
 | 
			
		||||
=================
 | 
			
		||||
 | 
			
		||||
Simple Installation
 | 
			
		||||
*********************
 | 
			
		||||
 | 
			
		||||
   ``pip install telethon``
 | 
			
		||||
 | 
			
		||||
**More details**: :ref:`installation`
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Creating a client
 | 
			
		||||
**************
 | 
			
		||||
 | 
			
		||||
   .. code-block:: python
 | 
			
		||||
 | 
			
		||||
       from telethon import TelegramClient
 | 
			
		||||
 | 
			
		||||
       # These example values won't work. You must get your own api_id and
 | 
			
		||||
       # api_hash from https://my.telegram.org, under API Development.
 | 
			
		||||
       api_id = 12345
 | 
			
		||||
       api_hash = '0123456789abcdef0123456789abcdef'
 | 
			
		||||
       phone = '+34600000000'
 | 
			
		||||
 | 
			
		||||
       client = TelegramClient('session_name', api_id, api_hash)
 | 
			
		||||
       client.connect()
 | 
			
		||||
 | 
			
		||||
       # If you already have a previous 'session_name.session' file, skip this.
 | 
			
		||||
       client.sign_in(phone=phone)
 | 
			
		||||
       me = client.sign_in(code=77777)  # Put whatever code you received here.
 | 
			
		||||
 | 
			
		||||
**More details**: `Click here <https://github.com/lonamiwebs/telethon/wiki/Creating-a-Client>`_
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Simple Stuff
 | 
			
		||||
**************
 | 
			
		||||
   .. code-block:: python
 | 
			
		||||
 | 
			
		||||
       print(me.stringify())
 | 
			
		||||
 | 
			
		||||
       client.send_message('username', 'Hello! Talking to you from Telethon')
 | 
			
		||||
       client.send_file('username', '/home/myself/Pictures/holidays.jpg')
 | 
			
		||||
 | 
			
		||||
       client.download_profile_photo(me)
 | 
			
		||||
       total, messages, senders = client.get_message_history('username')
 | 
			
		||||
       client.download_media(messages[0])
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										82
									
								
								readthedocs/extra/basic/installation.rst
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								readthedocs/extra/basic/installation.rst
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,82 @@
 | 
			
		|||
.. _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 already have the library installed, upgrade with:
 | 
			
		||||
 | 
			
		||||
    ``pip install --upgrade telethon``.
 | 
			
		||||
 | 
			
		||||
You can also install the library directly from GitHub or a fork:
 | 
			
		||||
 | 
			
		||||
   .. code-block:: python
 | 
			
		||||
 | 
			
		||||
        # pip install git+https://github.com/LonamiWebs/Telethon.git
 | 
			
		||||
        or
 | 
			
		||||
        $ git clone https://github.com/LonamiWebs/Telethon.git
 | 
			
		||||
        $ cd Telethon/
 | 
			
		||||
        # pip install -Ue .
 | 
			
		||||
 | 
			
		||||
If you don't have root access, simply pass the ``--user`` flag to the pip command.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Manual Installation
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
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``
 | 
			
		||||
 | 
			
		||||
3. Enter the cloned repository: ``cd Telethon``
 | 
			
		||||
 | 
			
		||||
4. Run the code generator: ``python3 setup.py gen_tl``
 | 
			
		||||
 | 
			
		||||
5. Done!
 | 
			
		||||
 | 
			
		||||
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!
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Sending Requests
 | 
			
		||||
*****************
 | 
			
		||||
    `Here <https://github.com/lonamiwebs/telethon/wiki/Session-Files>`__
 | 
			
		||||
 | 
			
		||||
Working with updates
 | 
			
		||||
**********************
 | 
			
		||||
    `Here <https://github.com/lonamiwebs/telethon/wiki/Working-with-Updates>`__
 | 
			
		||||
 | 
			
		||||
Accessing the full API
 | 
			
		||||
***********************
 | 
			
		||||
    `Here <https://github.com/lonamiwebs/telethon/wiki/Accessing-the-Full-API>`__
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
__ 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
 | 
			
		||||
							
								
								
									
										55
									
								
								readthedocs/extra/basic/sending-requests.rst
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								readthedocs/extra/basic/sending-requests.rst
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,55 @@
 | 
			
		|||
.. _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.
 | 
			
		||||
							
								
								
									
										48
									
								
								readthedocs/extra/basic/sessions.rst
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								readthedocs/extra/basic/sessions.rst
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,48 @@
 | 
			
		|||
.. _sessions:
 | 
			
		||||
 | 
			
		||||
==============
 | 
			
		||||
Session Files
 | 
			
		||||
==============
 | 
			
		||||
 | 
			
		||||
The first parameter you pass the 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.
 | 
			
		||||
							
								
								
									
										133
									
								
								readthedocs/extra/basic/working-with-updates.rst
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										133
									
								
								readthedocs/extra/basic/working-with-updates.rst
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,133 @@
 | 
			
		|||
====================
 | 
			
		||||
Working with Updates
 | 
			
		||||
====================
 | 
			
		||||
 | 
			
		||||
.. contents::
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
The library can run in four distinguishable modes:
 | 
			
		||||
 | 
			
		||||
- With no extra threads at all.
 | 
			
		||||
- With an extra thread that receives everything as soon as possible (default).
 | 
			
		||||
- 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.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Using multiple workers
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
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.
 | 
			
		||||
 | 
			
		||||
The next thing you want to do is to add a method that will be called when an `Update`__ arrives:
 | 
			
		||||
 | 
			
		||||
    .. code-block:: python
 | 
			
		||||
 | 
			
		||||
        def callback(update):
 | 
			
		||||
            print('I received', update)
 | 
			
		||||
 | 
			
		||||
        client.add_update_handler(callback)
 | 
			
		||||
        # 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:
 | 
			
		||||
 | 
			
		||||
    .. code-block:: python
 | 
			
		||||
 | 
			
		||||
        from telethon.tl.types import UpdateShortMessage, PeerUser
 | 
			
		||||
 | 
			
		||||
        def replier(update):
 | 
			
		||||
            if isinstance(update, UpdateShortMessage) and not update.out:
 | 
			
		||||
                client.send_message(PeerUser(update.user_id), update.message[::-1])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        client.add_update_handler(replier)
 | 
			
		||||
        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.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
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:
 | 
			
		||||
 | 
			
		||||
    .. code-block:: python
 | 
			
		||||
 | 
			
		||||
        while True:
 | 
			
		||||
            try:
 | 
			
		||||
                update = client.updates.poll()
 | 
			
		||||
                if not update:
 | 
			
		||||
                    continue
 | 
			
		||||
 | 
			
		||||
                print('I received', update)
 | 
			
		||||
            except KeyboardInterrupt:
 | 
			
		||||
                break
 | 
			
		||||
 | 
			
		||||
        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``.
 | 
			
		||||
 | 
			
		||||
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.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
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:
 | 
			
		||||
 | 
			
		||||
    .. code-block:: python
 | 
			
		||||
 | 
			
		||||
        client = TelegramClient(
 | 
			
		||||
            ...
 | 
			
		||||
            spawn_read_thread=False
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
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`__.
 | 
			
		||||
 | 
			
		||||
As a complete example:
 | 
			
		||||
 | 
			
		||||
    .. code-block:: python
 | 
			
		||||
 | 
			
		||||
        def callback(update):
 | 
			
		||||
            print('I received', update)
 | 
			
		||||
 | 
			
		||||
        client = TelegramClient('session', api_id, api_hash,
 | 
			
		||||
                                update_workers=1, spawn_read_thread=False)
 | 
			
		||||
 | 
			
		||||
        client.connect()
 | 
			
		||||
        client.add_update_handler(callback)
 | 
			
		||||
        client.idle()  # ends with Ctrl+C
 | 
			
		||||
        client.disconnect()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
__ 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
 | 
			
		||||
| 
						 | 
				
			
			@ -1,103 +0,0 @@
 | 
			
		|||
.. Telethon documentation master file, created by
 | 
			
		||||
   sphinx-quickstart on Fri Nov 17 15:36:11 2017.
 | 
			
		||||
   You can adapt this file completely to your liking, but it should at least
 | 
			
		||||
   contain the root `toctree` directive.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
=================
 | 
			
		||||
Getting Started!
 | 
			
		||||
=================
 | 
			
		||||
 | 
			
		||||
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 already have the library installed, upgrade with:
 | 
			
		||||
 | 
			
		||||
    ``pip install --upgrade telethon``.
 | 
			
		||||
 | 
			
		||||
You can also install the library directly from GitHub or a fork:
 | 
			
		||||
 | 
			
		||||
   .. code-block:: python
 | 
			
		||||
 | 
			
		||||
        # pip install git+https://github.com/LonamiWebs/Telethon.git
 | 
			
		||||
        or
 | 
			
		||||
        $ git clone https://github.com/LonamiWebs/Telethon.git
 | 
			
		||||
        $ cd Telethon/
 | 
			
		||||
        # pip install -Ue .
 | 
			
		||||
 | 
			
		||||
If you don't have root access, simply pass the ``--user`` flag to the pip command.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
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.
 | 
			
		||||
 | 
			
		||||
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.
 | 
			
		||||
 | 
			
		||||
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:
 | 
			
		||||
 | 
			
		||||
   .. code-block:: python
 | 
			
		||||
 | 
			
		||||
       from telethon import TelegramClient
 | 
			
		||||
 | 
			
		||||
       # These example values won't work. You must get your own api_id and
 | 
			
		||||
       # api_hash from https://my.telegram.org, under API Development.
 | 
			
		||||
       api_id = 12345
 | 
			
		||||
       api_hash = '0123456789abcdef0123456789abcdef'
 | 
			
		||||
       phone = '+34600000000'
 | 
			
		||||
 | 
			
		||||
       client = TelegramClient('session_name', api_id, api_hash)
 | 
			
		||||
       client.connect()
 | 
			
		||||
 | 
			
		||||
       # If you already have a previous 'session_name.session' file, skip this.
 | 
			
		||||
       client.sign_in(phone=phone)
 | 
			
		||||
       me = client.sign_in(code=77777)  # Put whatever code you received here.
 | 
			
		||||
 | 
			
		||||
**More details**: `Click here <https://github.com/lonamiwebs/telethon/wiki/Creating-a-Client>`_
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Simple Stuff
 | 
			
		||||
**************
 | 
			
		||||
   .. code-block:: python
 | 
			
		||||
 | 
			
		||||
       print(me.stringify())
 | 
			
		||||
 | 
			
		||||
       client.send_message('username', 'Hello! Talking to you from Telethon')
 | 
			
		||||
       client.send_file('username', '/home/myself/Pictures/holidays.jpg')
 | 
			
		||||
 | 
			
		||||
       client.download_profile_photo(me)
 | 
			
		||||
       total, messages, senders = client.get_message_history('username')
 | 
			
		||||
       client.download_media(messages[0])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Diving In
 | 
			
		||||
**************
 | 
			
		||||
 | 
			
		||||
.. note:: More info in our Wiki!
 | 
			
		||||
 | 
			
		||||
Sending Requests
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
    `Here <https://github.com/lonamiwebs/telethon/wiki/Session-Files>`__
 | 
			
		||||
 | 
			
		||||
Working with updates
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
    `Here <https://github.com/lonamiwebs/telethon/wiki/Working-with-Updates>`__
 | 
			
		||||
 | 
			
		||||
Accessing the full API
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
    `Here <https://github.com/lonamiwebs/telethon/wiki/Accessing-the-Full-API>`__
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,26 @@
 | 
			
		|||
=========================================
 | 
			
		||||
Deleted, Limited or Deactivated Accounts
 | 
			
		||||
=========================================
 | 
			
		||||
 | 
			
		||||
If you're from Iran or Russian, we have bad news for you.
 | 
			
		||||
Telegram is much more likely to ban these numbers,
 | 
			
		||||
as they are often used to spam other accounts,
 | 
			
		||||
likely through the use of libraries like this one.
 | 
			
		||||
The best advice we can give you is to not abuse the API,
 | 
			
		||||
like calling many requests really quickly,
 | 
			
		||||
and to sign up with these phones through an official application.
 | 
			
		||||
 | 
			
		||||
Telegram may also ban virtual (VoIP) phone numbers,
 | 
			
		||||
as again, they're likely to be used for spam.
 | 
			
		||||
 | 
			
		||||
If you want to check if your account has been limited,
 | 
			
		||||
simply send a private message to `@SpamBot`__ through Telegram itself.
 | 
			
		||||
You should notice this by getting errors like ``PeerFloodError``,
 | 
			
		||||
which means you're limited, for instance,
 | 
			
		||||
when sending a message to some accounts but not others.
 | 
			
		||||
 | 
			
		||||
For more discussion, please see `issue 297`__.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
__ https://t.me/SpamBot
 | 
			
		||||
__ https://github.com/LonamiWebs/Telethon/issues/297
 | 
			
		||||
							
								
								
									
										24
									
								
								readthedocs/extra/troubleshooting/enable-logging.rst
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								readthedocs/extra/troubleshooting/enable-logging.rst
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,24 @@
 | 
			
		|||
================
 | 
			
		||||
Enable Logging
 | 
			
		||||
================
 | 
			
		||||
 | 
			
		||||
Telethon makes use of the `logging`__ module, and you can enable it as follows:
 | 
			
		||||
 | 
			
		||||
    .. code-block:: python
 | 
			
		||||
 | 
			
		||||
        import logging
 | 
			
		||||
        logging.basicConfig(level=logging.DEBUG)
 | 
			
		||||
 | 
			
		||||
You can also use it in your own project very easily:
 | 
			
		||||
 | 
			
		||||
    .. code-block:: python
 | 
			
		||||
 | 
			
		||||
        import logging
 | 
			
		||||
        logger = logging.getLogger(__name__)
 | 
			
		||||
 | 
			
		||||
        logger.debug('Debug messages')
 | 
			
		||||
        logger.info('Useful information')
 | 
			
		||||
        logger.warning('This is a warning!')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
__ https://docs.python.org/3/library/logging.html
 | 
			
		||||
							
								
								
									
										27
									
								
								readthedocs/extra/troubleshooting/rpc-errors.rst
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								readthedocs/extra/troubleshooting/rpc-errors.rst
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,27 @@
 | 
			
		|||
==========
 | 
			
		||||
RPC Errors
 | 
			
		||||
==========
 | 
			
		||||
 | 
			
		||||
RPC stands for Remote Procedure Call, and when Telethon raises an
 | 
			
		||||
``RPCError``, it’s most likely because you have invoked some of the API
 | 
			
		||||
methods incorrectly (wrong parameters, wrong permissions, or even
 | 
			
		||||
something went wrong on Telegram’s server). The most common are:
 | 
			
		||||
 | 
			
		||||
-  ``FloodError`` (420), the same request was repeated many times. Must
 | 
			
		||||
   wait ``.seconds``.
 | 
			
		||||
-  ``SessionPasswordNeededError``, if you have setup two-steps
 | 
			
		||||
   verification on Telegram.
 | 
			
		||||
-  ``CdnFileTamperedError``, if the media you were trying to download
 | 
			
		||||
   from a CDN has been altered.
 | 
			
		||||
-  ``ChatAdminRequiredError``, you don’t have permissions to perform
 | 
			
		||||
   said operation on a chat or channel. Try avoiding filters, i.e. when
 | 
			
		||||
   searching messages.
 | 
			
		||||
 | 
			
		||||
The generic classes for different error codes are: \* ``InvalidDCError``
 | 
			
		||||
(303), the request must be repeated on another DC. \*
 | 
			
		||||
``BadRequestError`` (400), the request contained errors. \*
 | 
			
		||||
``UnauthorizedError`` (401), the user is not authorized yet. \*
 | 
			
		||||
``ForbiddenError`` (403), privacy violation error. \* ``NotFoundError``
 | 
			
		||||
(404), make sure you’re invoking ``Request``\ ’s!
 | 
			
		||||
 | 
			
		||||
If the error is not recognised, it will only be an ``RPCError``.
 | 
			
		||||
| 
						 | 
				
			
			@ -10,24 +10,49 @@ Pure Python 3 Telegram client library. Official Site `here <https://lonamiwebs.g
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
****************
 | 
			
		||||
Getting Started
 | 
			
		||||
****************
 | 
			
		||||
.. _installation-and-usage:
 | 
			
		||||
 | 
			
		||||
.. toctree::
 | 
			
		||||
   extra/getting_started
 | 
			
		||||
   :maxdepth: 2
 | 
			
		||||
   :caption: Installation and Simple Usage
 | 
			
		||||
 | 
			
		||||
   extra/basic/getting-started
 | 
			
		||||
   extra/basic/installation
 | 
			
		||||
   extra/basic/creating-a-client
 | 
			
		||||
   extra/basic/sessions
 | 
			
		||||
   extra/basic/sending-requests
 | 
			
		||||
   extra/basic/working-with-updates
 | 
			
		||||
   extra/basic/accessing-the-full-api
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
***************
 | 
			
		||||
Examples
 | 
			
		||||
***************
 | 
			
		||||
.. _Advanced-usage:
 | 
			
		||||
 | 
			
		||||
.. toctree::
 | 
			
		||||
   extra/examples
 | 
			
		||||
   :maxdepth: 2
 | 
			
		||||
   :caption: Advanced Usage
 | 
			
		||||
 | 
			
		||||
   extra/advanced
 | 
			
		||||
   extra/advanced-usage/signing-in
 | 
			
		||||
   extra/advanced-usage/working-with-messages
 | 
			
		||||
   extra/advanced-usage/users-and-chats
 | 
			
		||||
   extra/advanced-usage/bots
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
***************
 | 
			
		||||
Modules
 | 
			
		||||
***************
 | 
			
		||||
.. _Troubleshooting:
 | 
			
		||||
 | 
			
		||||
.. toctree::
 | 
			
		||||
   :maxdepth: 2
 | 
			
		||||
   :caption: Troubleshooting
 | 
			
		||||
 | 
			
		||||
   extra/troubleshooting/enable-logging
 | 
			
		||||
   extra/troubleshooting/deleted-limited-or-deactivated-accounts
 | 
			
		||||
   extra/troubleshooting/rpc-errors
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
.. toctree::
 | 
			
		||||
   :caption: Telethon modules
 | 
			
		||||
 | 
			
		||||
   telethon
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue
	
	Block a user