2019-05-09 13:24:37 +03:00
|
|
|
=======
|
|
|
|
Updates
|
|
|
|
=======
|
|
|
|
|
|
|
|
Updates are an important topic in a messaging platform like Telegram.
|
|
|
|
After all, you want to be notified when a new message arrives, when
|
|
|
|
a member joins, when someone starts typing, etc.
|
|
|
|
For that, you can use **events**.
|
|
|
|
|
|
|
|
.. important::
|
|
|
|
|
|
|
|
It is strongly advised to enable logging when working with events,
|
|
|
|
since exceptions in event handlers are hidden by default. Please
|
|
|
|
add the following snippet to the very top of your file:
|
|
|
|
|
|
|
|
.. code-block:: python
|
|
|
|
|
|
|
|
import logging
|
|
|
|
logging.basicConfig(format='[%(levelname) 5s/%(asctime)s] %(name)s: %(message)s',
|
|
|
|
level=logging.WARNING)
|
|
|
|
|
|
|
|
|
|
|
|
Getting Started
|
|
|
|
===============
|
|
|
|
|
|
|
|
Let's start things with an example to automate replies:
|
|
|
|
|
|
|
|
.. code-block:: python
|
|
|
|
|
|
|
|
from telethon import TelegramClient, events
|
|
|
|
|
|
|
|
client = TelegramClient('anon', api_id, api_hash)
|
|
|
|
|
|
|
|
@client.on(events.NewMessage)
|
|
|
|
async def my_event_handler(event):
|
|
|
|
if 'hello' in event.raw_text:
|
|
|
|
await event.reply('hi!')
|
|
|
|
|
|
|
|
client.start()
|
|
|
|
client.run_until_disconnected()
|
|
|
|
|
|
|
|
|
|
|
|
This code isn't much, but there might be some things unclear.
|
|
|
|
Let's break it down:
|
|
|
|
|
|
|
|
.. code-block:: python
|
|
|
|
|
|
|
|
from telethon import TelegramClient, events
|
|
|
|
|
|
|
|
client = TelegramClient('anon', api_id, api_hash)
|
|
|
|
|
|
|
|
|
|
|
|
This is normal creation (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
|
|
|
|
<telethon.events.newmessage.NewMessage>` *event*,
|
|
|
|
the callback function you're about to define will be called:
|
|
|
|
|
|
|
|
.. code-block:: python
|
|
|
|
|
|
|
|
async def my_event_handler(event):
|
|
|
|
if 'hello' in event.raw_text:
|
|
|
|
await event.reply('hi!')
|
|
|
|
|
|
|
|
|
|
|
|
If a `NewMessage
|
|
|
|
<telethon.events.newmessage.NewMessage>` event occurs,
|
|
|
|
and ``'hello'`` is in the text of the message, we `reply()
|
|
|
|
<telethon.tl.custom.message.Message.reply>` to the event
|
|
|
|
with a ``'hi!'`` message.
|
|
|
|
|
|
|
|
.. note::
|
|
|
|
|
|
|
|
Event handlers **must** be ``async def``. After all,
|
2019-06-11 12:09:22 +03:00
|
|
|
Telethon is an asynchronous library based on `asyncio`,
|
2019-05-09 13:24:37 +03:00
|
|
|
which is a safer and often faster approach to threads.
|
|
|
|
|
|
|
|
You **must** ``await`` all method calls that use
|
|
|
|
network requests, which is most of them.
|
|
|
|
|
|
|
|
|
|
|
|
More Examples
|
|
|
|
=============
|
|
|
|
|
|
|
|
Replying to messages with hello is fun, but, can we do more?
|
|
|
|
|
|
|
|
.. code-block:: python
|
|
|
|
|
|
|
|
@client.on(events.NewMessage(outgoing=True, pattern=r'\.save'))
|
|
|
|
async def handler(event):
|
|
|
|
if event.is_reply:
|
|
|
|
replied = await event.get_reply_message()
|
|
|
|
sender = replied.sender
|
|
|
|
await client.download_profile_photo(sender)
|
|
|
|
await event.respond('Saved your photo {}'.format(sender.username))
|
|
|
|
|
|
|
|
We could also get replies. This event filters outgoing messages
|
|
|
|
(only those that we send will trigger the method), then we filter
|
|
|
|
by the regex ``r'\.save'``, which will match messages starting
|
|
|
|
with ``".save"``.
|
|
|
|
|
|
|
|
Inside the method, we check whether the event is replying to another message
|
|
|
|
or not. If it is, we get the reply message and the sender of that message,
|
|
|
|
and download their profile photo.
|
|
|
|
|
|
|
|
Let's delete messages which contain "heck". We don't allow swearing here.
|
|
|
|
|
|
|
|
.. code-block:: python
|
|
|
|
|
|
|
|
@client.on(events.NewMessage(pattern=r'(?i).*heck'))
|
|
|
|
async def handler(event):
|
|
|
|
await event.delete()
|
|
|
|
|
|
|
|
|
|
|
|
With the ``r'(?i).*heck'`` regex, we match case-insensitive
|
|
|
|
"heck" anywhere in the message. Regex is very powerful and you
|
|
|
|
can learn more at https://regexone.com/.
|
|
|
|
|
|
|
|
So far, we have only seen the `NewMessage
|
|
|
|
<telethon.events.newmessage.NewMessage>`, but there are many more
|
|
|
|
which will be covered later. This is only a small introduction to updates.
|
|
|
|
|
|
|
|
Entities
|
|
|
|
========
|
|
|
|
|
|
|
|
When you need the user or chat where an event occurred, you **must** use
|
|
|
|
the following methods:
|
|
|
|
|
2019-05-21 14:26:34 +03:00
|
|
|
.. code-block:: python
|
2019-05-09 13:24:37 +03:00
|
|
|
|
|
|
|
async def handler(event):
|
|
|
|
# Good
|
|
|
|
chat = await event.get_chat()
|
|
|
|
sender = await event.get_sender()
|
|
|
|
chat_id = event.chat_id
|
|
|
|
sender_id = event.sender_id
|
|
|
|
|
|
|
|
# BAD. Don't do this
|
|
|
|
chat = event.chat
|
|
|
|
sender = event.sender
|
|
|
|
chat_id = event.chat.id
|
|
|
|
sender_id = event.sender.id
|
|
|
|
|
|
|
|
Events are like messages, but don't have all the information a message has!
|
|
|
|
When you manually get a message, it will have all the information it needs.
|
|
|
|
When you receive an update about a message, it **won't** have all the
|
|
|
|
information, so you have to **use the methods**, not the properties.
|
|
|
|
|
|
|
|
Make sure you understand the code seen here before continuing!
|
|
|
|
As a rule of thumb, remember that new message events behave just
|
|
|
|
like message objects, so you can do with them everything you can
|
|
|
|
do with a message object.
|