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:
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:
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:
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.
@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:
async def my_event_handler(event):
if 'hello' in event.raw_text:
await 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.
Note
Event handlers must be async def
. After all,
Telethon is an asynchronous library based on asyncio
,
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?
@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.
@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
, 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:
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.