0
# Event System
1
2
Real-time update handling with event decorators, filters, and handlers for messages, edits, deletions, and other Telegram updates in Telethon.
3
4
## Capabilities
5
6
### Event Handler Registration
7
8
Register and manage event handlers for real-time updates.
9
10
```python { .api }
11
def on(self, event):
12
"""
13
Decorator to register event handlers.
14
15
Parameters:
16
- event: Event class or instance (NewMessage, MessageEdited, etc.)
17
18
Usage:
19
@client.on(events.NewMessage)
20
async def handler(event):
21
await event.respond('Hello!')
22
"""
23
24
def add_event_handler(
25
self,
26
callback,
27
event=None
28
):
29
"""
30
Add an event handler function.
31
32
Parameters:
33
- callback: Async function to handle events
34
- event: Event filter (None for all events)
35
36
Usage:
37
async def my_handler(event):
38
print(f"Got event: {event}")
39
40
client.add_event_handler(my_handler, events.NewMessage)
41
"""
42
43
def remove_event_handler(
44
self,
45
callback,
46
event=None
47
) -> int:
48
"""
49
Remove an event handler.
50
51
Parameters:
52
- callback: Handler function to remove
53
- event: Specific event type to remove (None for all)
54
55
Returns:
56
int: Number of handlers removed
57
"""
58
59
def list_event_handlers(self) -> List[Tuple[Callable, EventBuilder]]:
60
"""
61
List all registered event handlers.
62
63
Returns:
64
List of (callback, event) tuples
65
"""
66
```
67
68
### Event Loop Management
69
70
Control the event loop and update processing.
71
72
```python { .api }
73
def run_until_disconnected(self):
74
"""
75
Run the client until disconnected.
76
77
Blocks the current thread and processes events.
78
Use in synchronous code or as final call in async main().
79
80
Usage:
81
client.start()
82
client.run_until_disconnected()
83
"""
84
85
async def catch_up(self):
86
"""
87
Catch up on missed updates since last connection.
88
89
Processes updates that occurred while client was offline.
90
Requires catch_up=True in client constructor.
91
"""
92
93
async def set_receive_updates(self, receive_updates: bool):
94
"""
95
Enable or disable receiving updates.
96
97
Parameters:
98
- receive_updates: Whether to process updates
99
"""
100
```
101
102
### Message Events
103
104
Handle new, edited, and deleted messages.
105
106
```python { .api }
107
class NewMessage:
108
"""
109
Event for new incoming messages.
110
111
Attributes:
112
- message: The new message object
113
- chat: Chat where message was sent
114
- sender: User who sent the message
115
"""
116
def __init__(
117
self,
118
chats=None,
119
*,
120
blacklist_chats: bool = False,
121
func=None,
122
pattern=None,
123
from_users=None,
124
forwards=None,
125
incoming: bool = None,
126
outgoing: bool = None
127
):
128
"""
129
Filter for new messages.
130
131
Parameters:
132
- chats: Specific chats to monitor (None for all)
133
- blacklist_chats: Exclude instead of include specified chats
134
- func: Custom filter function
135
- pattern: Regex pattern to match message text
136
- from_users: Only messages from these users
137
- forwards: Include forwarded messages
138
- incoming: Only incoming messages
139
- outgoing: Only outgoing messages
140
"""
141
142
class MessageEdited:
143
"""
144
Event for message edits.
145
146
Attributes same as NewMessage.
147
"""
148
def __init__(self, **kwargs):
149
"""Parameters same as NewMessage."""
150
151
class MessageDeleted:
152
"""
153
Event for message deletions.
154
155
Attributes:
156
- deleted_ids: List of deleted message IDs
157
- peer: Chat where messages were deleted
158
"""
159
def __init__(self, chats=None, *, blacklist_chats: bool = False):
160
"""
161
Filter for message deletions.
162
163
Parameters:
164
- chats: Specific chats to monitor
165
- blacklist_chats: Exclude specified chats
166
"""
167
168
class MessageRead:
169
"""
170
Event for message read status changes.
171
172
Attributes:
173
- message_ids: IDs of messages marked as read
174
- peer: Chat where messages were read
175
- max_id: Highest message ID read
176
"""
177
def __init__(self, chats=None, *, blacklist_chats: bool = False):
178
"""Parameters same as MessageDeleted."""
179
```
180
181
### Interactive Events
182
183
Handle button clicks and inline queries.
184
185
```python { .api }
186
class CallbackQuery:
187
"""
188
Event for inline button clicks.
189
190
Attributes:
191
- query: The callback query object
192
- data: Button callback data
193
- message: Message containing the button
194
- sender: User who clicked the button
195
"""
196
def __init__(
197
self,
198
chats=None,
199
*,
200
blacklist_chats: bool = False,
201
func=None,
202
data=None,
203
pattern=None
204
):
205
"""
206
Filter for callback queries.
207
208
Parameters:
209
- chats: Specific chats to monitor
210
- blacklist_chats: Exclude specified chats
211
- func: Custom filter function
212
- data: Specific callback data to match
213
- pattern: Regex pattern for callback data
214
"""
215
216
class InlineQuery:
217
"""
218
Event for inline bot queries.
219
220
Attributes:
221
- query: The inline query object
222
- text: Query text from user
223
- user: User making the query
224
- offset: Pagination offset
225
"""
226
def __init__(
227
self,
228
*,
229
users=None,
230
blacklist_users: bool = False,
231
func=None,
232
pattern=None
233
):
234
"""
235
Filter for inline queries.
236
237
Parameters:
238
- users: Specific users to monitor
239
- blacklist_users: Exclude specified users
240
- func: Custom filter function
241
- pattern: Regex pattern for query text
242
"""
243
```
244
245
### Chat Activity Events
246
247
Monitor chat actions and user status changes.
248
249
```python { .api }
250
class ChatAction:
251
"""
252
Event for chat actions (typing, online status, etc.).
253
254
Attributes:
255
- action: The specific action (typing, online, etc.)
256
- user: User performing the action
257
- chat: Chat where action occurred
258
"""
259
def __init__(
260
self,
261
chats=None,
262
*,
263
blacklist_chats: bool = False,
264
func=None
265
):
266
"""
267
Filter for chat actions.
268
269
Parameters:
270
- chats: Specific chats to monitor
271
- blacklist_chats: Exclude specified chats
272
- func: Custom filter function
273
"""
274
275
class UserUpdate:
276
"""
277
Event for user status changes (online, offline, etc.).
278
279
Attributes:
280
- user: User whose status changed
281
- status: New user status
282
"""
283
def __init__(
284
self,
285
*,
286
users=None,
287
blacklist_users: bool = False,
288
func=None
289
):
290
"""
291
Filter for user updates.
292
293
Parameters:
294
- users: Specific users to monitor
295
- blacklist_users: Exclude specified users
296
- func: Custom filter function
297
"""
298
```
299
300
### Album Events
301
302
Handle grouped media messages.
303
304
```python { .api }
305
class Album:
306
"""
307
Event for grouped media messages (albums).
308
309
Attributes:
310
- messages: List of messages in the album
311
- grouped_id: Album group identifier
312
"""
313
def __init__(
314
self,
315
chats=None,
316
*,
317
blacklist_chats: bool = False,
318
func=None
319
):
320
"""
321
Filter for album messages.
322
323
Parameters same as NewMessage.
324
"""
325
```
326
327
### Raw Events
328
329
Handle low-level Telegram updates.
330
331
```python { .api }
332
class Raw:
333
"""
334
Event for raw Telegram updates.
335
336
Provides access to unprocessed updates from Telegram.
337
338
Attributes:
339
- update: Raw update object from Telegram
340
"""
341
def __init__(
342
self,
343
*,
344
types=None,
345
func=None
346
):
347
"""
348
Filter for raw updates.
349
350
Parameters:
351
- types: Specific update types to handle
352
- func: Custom filter function
353
"""
354
```
355
356
### Event Control
357
358
Control event propagation and handling.
359
360
```python { .api }
361
class StopPropagation(Exception):
362
"""
363
Exception to stop processing further event handlers.
364
365
Raise this in an event handler to prevent other handlers
366
from processing the same event.
367
368
Usage:
369
@client.on(events.NewMessage)
370
async def first_handler(event):
371
if event.text.startswith('/stop'):
372
await event.respond('Stopping here!')
373
raise StopPropagation
374
375
@client.on(events.NewMessage)
376
async def second_handler(event):
377
# This won't run if first handler raises StopPropagation
378
await event.respond('This might not be sent')
379
"""
380
```
381
382
### Standalone Event Registration
383
384
Register events without a client instance.
385
386
```python { .api }
387
def register(event=None):
388
"""
389
Decorator to register event handlers without a client.
390
391
Parameters:
392
- event: Event class or instance
393
394
Usage:
395
@events.register(events.NewMessage)
396
async def handler(event):
397
await event.respond('Hello!')
398
399
# Later, add to client:
400
client.add_event_handler(handler)
401
"""
402
403
def unregister(callback, event=None):
404
"""
405
Remove registered event handlers.
406
407
Parameters:
408
- callback: Handler function to remove
409
- event: Specific event type (None for all)
410
411
Returns:
412
int: Number of handlers removed
413
"""
414
415
def is_handler(callback) -> bool:
416
"""
417
Check if a function is registered as an event handler.
418
419
Parameters:
420
- callback: Function to check
421
422
Returns:
423
bool: True if registered as handler
424
"""
425
426
def list(callback) -> List:
427
"""
428
List event builders registered to a callback.
429
430
Parameters:
431
- callback: Handler function
432
433
Returns:
434
List of event builders
435
"""
436
```
437
438
## Usage Examples
439
440
### Basic Event Handling
441
442
```python
443
import asyncio
444
import re
445
from telethon import TelegramClient, events
446
447
async def basic_events():
448
client = TelegramClient('session', api_id, api_hash)
449
450
# Simple message handler
451
@client.on(events.NewMessage)
452
async def message_handler(event):
453
print(f"New message: {event.text}")
454
await event.respond(f"You said: {event.text}")
455
456
# Pattern-based handler
457
@client.on(events.NewMessage(pattern=r'/start'))
458
async def start_handler(event):
459
await event.respond('Hello! I am a bot.')
460
461
# Handler for specific chats
462
@client.on(events.NewMessage(chats=['username', 'chat_id']))
463
async def chat_handler(event):
464
await event.respond('Message in monitored chat!')
465
466
await client.start()
467
await client.run_until_disconnected()
468
469
asyncio.run(basic_events())
470
```
471
472
### Advanced Message Filtering
473
474
```python
475
import re
476
from telethon import events
477
478
async def advanced_filtering():
479
client = TelegramClient('session', api_id, api_hash)
480
481
# Command pattern matching
482
@client.on(events.NewMessage(pattern=r'/echo (.+)'))
483
async def echo_command(event):
484
text_to_echo = event.pattern_match.group(1)
485
await event.respond(f"Echo: {text_to_echo}")
486
487
# Custom filter function
488
def is_admin_message(event):
489
return event.sender_id in [admin_id_1, admin_id_2]
490
491
@client.on(events.NewMessage(func=is_admin_message))
492
async def admin_handler(event):
493
await event.respond("Admin command received!")
494
495
# Multiple conditions
496
@client.on(events.NewMessage(
497
chats=[group_chat_id],
498
from_users=[specific_user_id],
499
incoming=True
500
))
501
async def specific_handler(event):
502
await event.respond("Message from specific user in group!")
503
504
# Forwarded messages only
505
@client.on(events.NewMessage(forwards=True))
506
async def forward_handler(event):
507
await event.respond("This is a forwarded message!")
508
509
await client.start()
510
await client.run_until_disconnected()
511
```
512
513
### Interactive Events
514
515
```python
516
from telethon import Button, events
517
518
async def interactive_events():
519
client = TelegramClient('session', api_id, api_hash)
520
521
# Send message with buttons
522
@client.on(events.NewMessage(pattern='/menu'))
523
async def menu_handler(event):
524
buttons = [
525
[Button.inline('Option 1', b'opt1')],
526
[Button.inline('Option 2', b'opt2')],
527
[Button.inline('Help', b'help')]
528
]
529
await event.respond('Choose an option:', buttons=buttons)
530
531
# Handle button clicks
532
@client.on(events.CallbackQuery(data=b'opt1'))
533
async def option1_handler(event):
534
await event.answer('You chose Option 1!')
535
await event.edit('Option 1 selected ✓')
536
537
@client.on(events.CallbackQuery(data=b'opt2'))
538
async def option2_handler(event):
539
await event.answer('You chose Option 2!')
540
await event.edit('Option 2 selected ✓')
541
542
@client.on(events.CallbackQuery(data=b'help'))
543
async def help_handler(event):
544
await event.answer('This is help text!', alert=True)
545
546
# Pattern matching for callback data
547
@client.on(events.CallbackQuery(pattern=rb'user_(\d+)'))
548
async def user_callback(event):
549
user_id = int(event.pattern_match.group(1))
550
await event.answer(f'User ID: {user_id}')
551
552
await client.start()
553
await client.run_until_disconnected()
554
```
555
556
### Event Lifecycle Management
557
558
```python
559
async def event_lifecycle():
560
client = TelegramClient('session', api_id, api_hash)
561
562
# Handler with stop propagation
563
@client.on(events.NewMessage(pattern='/stop'))
564
async def stop_handler(event):
565
await event.respond('Stopping here!')
566
raise events.StopPropagation
567
568
@client.on(events.NewMessage)
569
async def catch_all_handler(event):
570
# This won't run for /stop messages
571
await event.respond('Catch-all handler')
572
573
# Dynamic handler addition
574
async def dynamic_handler(event):
575
await event.respond('Dynamic handler!')
576
577
# Add handler programmatically
578
client.add_event_handler(
579
dynamic_handler,
580
events.NewMessage(pattern='/dynamic')
581
)
582
583
# Remove handler after some time
584
await asyncio.sleep(60) # Wait 1 minute
585
removed = client.remove_event_handler(dynamic_handler)
586
print(f"Removed {removed} handlers")
587
588
# List all handlers
589
handlers = client.list_event_handlers()
590
print(f"Active handlers: {len(handlers)}")
591
592
await client.start()
593
await client.run_until_disconnected()
594
```
595
596
### Album and Media Events
597
598
```python
599
async def media_events():
600
client = TelegramClient('session', api_id, api_hash)
601
602
# Handle grouped media (albums)
603
@client.on(events.Album)
604
async def album_handler(event):
605
await event.respond(
606
f'Received album with {len(event.messages)} items!'
607
)
608
609
# Process each item in album
610
for message in event.messages:
611
if message.photo:
612
print(f"Photo in album: {message.id}")
613
elif message.video:
614
print(f"Video in album: {message.id}")
615
616
# Handle message edits
617
@client.on(events.MessageEdited)
618
async def edit_handler(event):
619
await event.respond(f'Message {event.id} was edited!')
620
621
# Handle message deletions
622
@client.on(events.MessageDeleted)
623
async def delete_handler(event):
624
print(f'Messages deleted: {event.deleted_ids}')
625
# Note: Can't respond to deleted messages
626
627
# Handle read status
628
@client.on(events.MessageRead)
629
async def read_handler(event):
630
print(f'Messages read up to ID: {event.max_id}')
631
632
await client.start()
633
await client.run_until_disconnected()
634
```
635
636
### Chat Activity Monitoring
637
638
```python
639
async def activity_monitoring():
640
client = TelegramClient('session', api_id, api_hash)
641
642
# Monitor typing indicators
643
@client.on(events.ChatAction)
644
async def typing_handler(event):
645
if hasattr(event.action, 'typing') and event.action.typing:
646
user = await event.get_user()
647
print(f'{user.first_name} is typing...')
648
649
# Monitor user status changes
650
@client.on(events.UserUpdate)
651
async def status_handler(event):
652
user = await event.get_user()
653
status = event.status
654
655
if hasattr(status, 'online') and status.online:
656
print(f'{user.first_name} came online')
657
elif hasattr(status, 'offline'):
658
print(f'{user.first_name} went offline')
659
660
await client.start()
661
await client.run_until_disconnected()
662
```
663
664
### Raw Event Handling
665
666
```python
667
from telethon.tl.types import UpdateNewMessage, UpdateMessageEdited
668
669
async def raw_events():
670
client = TelegramClient('session', api_id, api_hash)
671
672
# Handle specific raw update types
673
@client.on(events.Raw(types=[UpdateNewMessage]))
674
async def raw_message_handler(event):
675
update = event.update
676
message = update.message
677
print(f"Raw message: {message.message}")
678
679
# Handle all raw updates
680
@client.on(events.Raw)
681
async def all_updates_handler(event):
682
update_type = type(event.update).__name__
683
print(f"Received update: {update_type}")
684
685
await client.start()
686
await client.run_until_disconnected()
687
```
688
689
## Types
690
691
```python { .api }
692
from typing import Union, List, Optional, Callable, Pattern, Any
693
import re
694
from telethon.tl import types
695
from telethon import custom
696
697
EventHandler = Callable[[Any], None]
698
FilterFunction = Callable[[Any], bool]
699
PatternType = Union[str, Pattern[str], Pattern[bytes]]
700
EntityFilter = Union[int, str, List[Union[int, str]]]
701
702
class EventBuilder:
703
"""Base class for event filters"""
704
705
class EventCommon:
706
"""Common event attributes and methods"""
707
client: TelegramClient
708
original_update: types.Updates
709
710
async def get_chat(self):
711
"""Get the chat where the event occurred"""
712
713
async def get_sender(self):
714
"""Get the user who triggered the event"""
715
716
async def get_input_chat(self):
717
"""Get InputPeer for the chat"""
718
719
async def get_input_sender(self):
720
"""Get InputPeer for the sender"""
721
```