mirror of
https://github.com/LonamiWebs/Telethon.git
synced 2024-11-13 13:06:36 +03:00
189 lines
6.2 KiB
ReStructuredText
189 lines
6.2 KiB
ReStructuredText
.. _working-with-updates:
|
|
|
|
====================
|
|
Working with Updates
|
|
====================
|
|
|
|
|
|
The library comes with the :mod:`events` module. *Events* are an abstraction
|
|
over what Telegram calls `updates`__, and are meant to ease simple and common
|
|
usage when dealing with them, since there are many updates. If you're looking
|
|
for the method reference, check :ref:`telethon-events-package`, otherwise,
|
|
let's dive in!
|
|
|
|
|
|
.. note::
|
|
|
|
The library logs by default no output, and any exception that occurs
|
|
inside your handlers will be "hidden" from you to prevent the thread
|
|
from terminating (so it can still deliver events). You should enable
|
|
logging (``import logging; logging.basicConfig(level=logging.ERROR)``)
|
|
when working with events, at least the error level, to see if this is
|
|
happening so you can debug the error.
|
|
|
|
|
|
.. contents::
|
|
|
|
|
|
Getting Started
|
|
***************
|
|
|
|
.. code-block:: python
|
|
|
|
from telethon import TelegramClient, events
|
|
|
|
client = TelegramClient(..., update_workers=1, spawn_read_thread=False)
|
|
client.start()
|
|
|
|
@client.on(events.NewMessage)
|
|
def my_event_handler(event):
|
|
if 'hello' in event.raw_text:
|
|
event.reply('hi!')
|
|
|
|
client.idle()
|
|
|
|
|
|
Not much, but there might be some things unclear. What does this code do?
|
|
|
|
.. code-block:: python
|
|
|
|
from telethon import TelegramClient, events
|
|
|
|
client = TelegramClient(..., update_workers=1, spawn_read_thread=False)
|
|
client.start()
|
|
|
|
|
|
This is normal initialization (of course, pass session name, API ID and hash).
|
|
Nothing we don't know already.
|
|
|
|
.. code-block:: python
|
|
|
|
@client.on(events.NewMessage)
|
|
|
|
|
|
This Python decorator will attach itself to the ``my_event_handler``
|
|
definition, and basically means that *on* a ``NewMessage`` *event*,
|
|
the callback function you're about to define will be called:
|
|
|
|
.. code-block:: python
|
|
|
|
def my_event_handler(event):
|
|
if 'hello' in event.raw_text:
|
|
event.reply('hi!')
|
|
|
|
|
|
If a ``NewMessage`` event occurs, and ``'hello'`` is in the text of the
|
|
message, we ``reply`` to the event with a ``'hi!'`` message.
|
|
|
|
.. code-block:: python
|
|
|
|
client.idle()
|
|
|
|
|
|
Finally, this tells the client that we're done with our code, and want
|
|
to listen for all these events to occur. Of course, you might want to
|
|
do other things instead idling. For this refer to :ref:`update-modes`.
|
|
|
|
|
|
More on events
|
|
**************
|
|
|
|
The ``NewMessage`` event has much more than what was shown. You can access
|
|
the ``.sender`` of the message through that member, or even see if the message
|
|
had ``.media``, a ``.photo`` or a ``.document`` (which you could download with
|
|
for example ``client.download_media(event.photo)``.
|
|
|
|
If you don't want to ``.reply`` as a reply, you can use the ``.respond()``
|
|
method instead. Of course, there are more events such as ``ChatAction`` or
|
|
``UserUpdate``, and they're all used in the same way. Simply add the
|
|
``@client.on(events.XYZ)`` decorator on the top of your handler and you're
|
|
done! The event that will be passed always is of type ``XYZ.Event`` (for
|
|
instance, ``NewMessage.Event``), except for the ``Raw`` event which just
|
|
passes the ``Update`` object.
|
|
|
|
Note that ``.reply()`` and ``.respond()`` are just wrappers around the
|
|
``client.send_message()`` method which supports the ``file=`` parameter.
|
|
This means you can reply with a photo if you do ``client.reply(file=photo)``.
|
|
|
|
You can put the same event on many handlers, and even different events on
|
|
the same handler. You can also have a handler work on only specific chats,
|
|
for example:
|
|
|
|
|
|
.. code-block:: python
|
|
|
|
import ast
|
|
import random
|
|
|
|
|
|
# Either a single item or a list of them will work for the chats.
|
|
# You can also use the IDs, Peers, or even User/Chat/Channel objects.
|
|
@client.on(events.NewMessage(chats=('TelethonChat', 'TelethonOffTopic')))
|
|
def normal_handler(event):
|
|
if 'roll' in event.raw_text:
|
|
event.reply(str(random.randint(1, 6)))
|
|
|
|
|
|
# Similarly, you can use incoming=True for messages that you receive
|
|
@client.on(events.NewMessage(chats='TelethonOffTopic', outgoing=True))
|
|
def admin_handler(event):
|
|
if event.raw_text.startswith('eval'):
|
|
expression = event.raw_text.replace('eval', '').strip()
|
|
event.reply(str(ast.literal_eval(expression)))
|
|
|
|
|
|
You can pass one or more chats to the ``chats`` parameter (as a list or tuple),
|
|
and only events from there will be processed. You can also specify whether you
|
|
want to handle incoming or outgoing messages (those you receive or those you
|
|
send). In this example, people can say ``'roll'`` and you will reply with a
|
|
random number, while if you say ``'eval 4+4'``, you will reply with the
|
|
solution. Try it!
|
|
|
|
|
|
Events without decorators
|
|
*************************
|
|
|
|
If for any reason you can't use the ``@client.on`` syntax, don't worry.
|
|
You can call ``client.add_event_handler(callback, event)`` to achieve
|
|
the same effect.
|
|
|
|
Similar to that method, you also have :meth:`client.remove_event_handler`
|
|
and :meth:`client.list_event_handlers` which do as they names indicate.
|
|
|
|
The ``event`` type is optional in all methods and defaults to ``events.Raw``
|
|
for adding, and ``None`` when removing (so all callbacks would be removed).
|
|
|
|
|
|
Stopping propagation of Updates
|
|
*******************************
|
|
|
|
There might be cases when an event handler is supposed to be used solitary and
|
|
it makes no sense to process any other handlers in the chain. For this case,
|
|
it is possible to raise a ``StopPropagation`` exception which will cause the
|
|
propagation of the update through your handlers to stop:
|
|
|
|
.. code-block:: python
|
|
|
|
from telethon.events import StopPropagation
|
|
|
|
@client.on(events.NewMessage)
|
|
def _(event):
|
|
# ... some conditions
|
|
event.delete()
|
|
|
|
# Other handlers won't have an event to work with
|
|
raise StopPropagation
|
|
|
|
@client.on(events.NewMessage)
|
|
def _(event):
|
|
# Will never be reached, because it is the second handler
|
|
# in the chain.
|
|
pass
|
|
|
|
|
|
Remember to check :ref:`telethon-events-package` if you're looking for
|
|
the methods reference.
|
|
|
|
|
|
__ https://lonamiwebs.github.io/Telethon/types/update.html
|