0
# Filters System
1
2
Powerful filtering system for precisely targeting which updates handlers should process, with extensive built-in filters and support for custom filter creation.
3
4
## Capabilities
5
6
### Basic Filters
7
8
Core filters for common update types and content.
9
10
```python { .api }
11
class filters:
12
ALL: UpdateFilter
13
TEXT: MessageFilter
14
COMMAND: MessageFilter
15
PHOTO: MessageFilter
16
VIDEO: MessageFilter
17
VIDEO_NOTE: MessageFilter
18
VOICE: MessageFilter
19
AUDIO: MessageFilter
20
DOCUMENT: MessageFilter
21
ANIMATION: MessageFilter
22
STICKER: MessageFilter
23
LOCATION: MessageFilter
24
CONTACT: MessageFilter
25
VENUE: MessageFilter
26
POLL: MessageFilter
27
DICE: MessageFilter
28
GAME: MessageFilter
29
FORWARDED: MessageFilter
30
REPLY: MessageFilter
31
```
32
33
Usage examples:
34
35
```python
36
from telegram.ext import MessageHandler, filters
37
38
# Text messages only (excluding commands)
39
text_handler = MessageHandler(filters.TEXT & ~filters.COMMAND, handle_text)
40
41
# Photo messages
42
photo_handler = MessageHandler(filters.PHOTO, handle_photo)
43
44
# Video or video note messages
45
video_handler = MessageHandler(filters.VIDEO | filters.VIDEO_NOTE, handle_video)
46
47
# Documents that aren't photos/videos/audio
48
doc_handler = MessageHandler(
49
filters.DOCUMENT & ~(filters.PHOTO | filters.VIDEO | filters.AUDIO),
50
handle_document
51
)
52
53
# Forwarded messages
54
forward_handler = MessageHandler(filters.FORWARDED, handle_forwarded)
55
56
# Replies to other messages
57
reply_handler = MessageHandler(filters.REPLY, handle_reply)
58
```
59
60
### Chat Type Filters
61
62
Filter messages based on chat type.
63
64
```python { .api }
65
class filters:
66
class ChatType:
67
PRIVATE: MessageFilter
68
GROUP: MessageFilter
69
SUPERGROUP: MessageFilter
70
CHANNEL: MessageFilter
71
GROUPS: MessageFilter # GROUP | SUPERGROUP
72
```
73
74
Usage examples:
75
76
```python
77
# Private messages only
78
private_handler = MessageHandler(
79
filters.ChatType.PRIVATE & filters.TEXT,
80
handle_private_message
81
)
82
83
# Group messages (both regular and supergroups)
84
group_handler = MessageHandler(
85
filters.ChatType.GROUPS & filters.COMMAND,
86
handle_group_command
87
)
88
89
# Channel posts
90
channel_handler = MessageHandler(
91
filters.ChatType.CHANNEL,
92
handle_channel_post
93
)
94
```
95
96
### User and Chat Filters
97
98
Filter by specific users, chats, or user properties.
99
100
```python { .api }
101
class filters:
102
class User:
103
@staticmethod
104
def user_id(user_id: int | list[int]) -> MessageFilter: ...
105
106
@staticmethod
107
def username(username: str | list[str]) -> MessageFilter: ...
108
109
class Chat:
110
@staticmethod
111
def chat_id(chat_id: int | list[int]) -> MessageFilter: ...
112
113
@staticmethod
114
def username(username: str | list[str]) -> MessageFilter: ...
115
116
@staticmethod
117
def title(title: str | list[str]) -> MessageFilter: ...
118
119
IS_BOT: MessageFilter
120
IS_PREMIUM: MessageFilter
121
```
122
123
Usage examples:
124
125
```python
126
# Messages from specific user
127
user_filter = filters.User.user_id(123456789)
128
user_handler = MessageHandler(user_filter, handle_specific_user)
129
130
# Messages from multiple users
131
admin_users = [123456789, 987654321, 555666777]
132
admin_filter = filters.User.user_id(admin_users)
133
admin_handler = MessageHandler(admin_filter & filters.COMMAND, handle_admin_command)
134
135
# Messages from specific username
136
username_filter = filters.User.username("john_doe")
137
username_handler = MessageHandler(username_filter, handle_john)
138
139
# Messages in specific chat
140
chat_filter = filters.Chat.chat_id(-1001234567890)
141
chat_handler = MessageHandler(chat_filter, handle_specific_chat)
142
143
# Messages from bots
144
bot_filter = filters.IS_BOT
145
bot_handler = MessageHandler(bot_filter, handle_bot_message)
146
147
# Messages from premium users
148
premium_filter = filters.IS_PREMIUM
149
premium_handler = MessageHandler(premium_filter, handle_premium_user)
150
```
151
152
### Content Filters
153
154
Filter based on message content and properties.
155
156
```python { .api }
157
class filters:
158
class Text:
159
@staticmethod
160
def startswith(prefix: str | list[str], ignore_case: bool = False) -> MessageFilter: ...
161
162
@staticmethod
163
def endswith(suffix: str | list[str], ignore_case: bool = False) -> MessageFilter: ...
164
165
@staticmethod
166
def contains(substring: str | list[str], ignore_case: bool = False) -> MessageFilter: ...
167
168
class Regex:
169
@staticmethod
170
def create(pattern: str | Pattern, flags: int = 0) -> MessageFilter: ...
171
172
class Language:
173
@staticmethod
174
def language_code(lang_code: str | list[str]) -> MessageFilter: ...
175
176
HAS_MEDIA_SPOILER: MessageFilter
177
HAS_PROTECTED_CONTENT: MessageFilter
178
IS_AUTOMATIC_FORWARD: MessageFilter
179
IS_TOPIC_MESSAGE: MessageFilter
180
```
181
182
Usage examples:
183
184
```python
185
import re
186
187
# Messages starting with specific text
188
hello_filter = filters.Text.startswith("hello", ignore_case=True)
189
hello_handler = MessageHandler(hello_filter, handle_greeting)
190
191
# Messages containing keywords
192
keyword_filter = filters.Text.contains(["help", "support", "assistance"])
193
help_handler = MessageHandler(keyword_filter, handle_help_request)
194
195
# Regex pattern matching
196
email_pattern = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b'
197
email_filter = filters.Regex.create(email_pattern, re.IGNORECASE)
198
email_handler = MessageHandler(email_filter, handle_email)
199
200
# Messages from users with specific language
201
spanish_filter = filters.Language.language_code("es")
202
spanish_handler = MessageHandler(spanish_filter & filters.TEXT, handle_spanish)
203
204
# Messages with spoiler media
205
spoiler_filter = filters.HAS_MEDIA_SPOILER
206
spoiler_handler = MessageHandler(spoiler_filter, handle_spoiler_media)
207
```
208
209
### Entity Filters
210
211
Filter messages containing specific entity types.
212
213
```python { .api }
214
class filters:
215
class Entity:
216
MENTION: MessageFilter # @username
217
HASHTAG: MessageFilter # #hashtag
218
CASHTAG: MessageFilter # $CASHTAG
219
BOT_COMMAND: MessageFilter # /command
220
URL: MessageFilter # http://example.com
221
EMAIL: MessageFilter # user@example.com
222
PHONE_NUMBER: MessageFilter # +1234567890
223
BOLD: MessageFilter # **bold**
224
ITALIC: MessageFilter # *italic*
225
CODE: MessageFilter # `code`
226
PRE: MessageFilter # ```pre```
227
TEXT_LINK: MessageFilter # [text](url)
228
TEXT_MENTION: MessageFilter # @user (no username)
229
```
230
231
Usage examples:
232
233
```python
234
# Messages with mentions
235
mention_handler = MessageHandler(filters.Entity.MENTION, handle_mention)
236
237
# Messages with hashtags
238
hashtag_handler = MessageHandler(filters.Entity.HASHTAG, handle_hashtag)
239
240
# Messages with URLs
241
url_handler = MessageHandler(filters.Entity.URL, handle_url)
242
243
# Messages with email addresses
244
email_handler = MessageHandler(filters.Entity.EMAIL, handle_email)
245
246
# Messages with phone numbers
247
phone_handler = MessageHandler(filters.Entity.PHONE_NUMBER, handle_phone)
248
249
# Messages with code blocks
250
code_handler = MessageHandler(filters.Entity.CODE | filters.Entity.PRE, handle_code)
251
```
252
253
### Status Update Filters
254
255
Filter special message types and status updates.
256
257
```python { .api }
258
class filters:
259
class StatusUpdate:
260
NEW_CHAT_MEMBERS: MessageFilter
261
LEFT_CHAT_MEMBER: MessageFilter
262
NEW_CHAT_TITLE: MessageFilter
263
NEW_CHAT_PHOTO: MessageFilter
264
DELETE_CHAT_PHOTO: MessageFilter
265
GROUP_CHAT_CREATED: MessageFilter
266
SUPERGROUP_CHAT_CREATED: MessageFilter
267
CHANNEL_CHAT_CREATED: MessageFilter
268
MIGRATE_TO_CHAT_ID: MessageFilter
269
MIGRATE_FROM_CHAT_ID: MessageFilter
270
PINNED_MESSAGE: MessageFilter
271
INVOICE: MessageFilter
272
SUCCESSFUL_PAYMENT: MessageFilter
273
USERS_SHARED: MessageFilter
274
CHAT_SHARED: MessageFilter
275
CONNECTED_WEBSITE: MessageFilter
276
WRITE_ACCESS_ALLOWED: MessageFilter
277
PASSPORT_DATA: MessageFilter
278
PROXIMITY_ALERT_TRIGGERED: MessageFilter
279
VIDEO_CHAT_SCHEDULED: MessageFilter
280
VIDEO_CHAT_STARTED: MessageFilter
281
VIDEO_CHAT_ENDED: MessageFilter
282
VIDEO_CHAT_PARTICIPANTS_INVITED: MessageFilter
283
WEB_APP_DATA: MessageFilter
284
FORUM_TOPIC_CREATED: MessageFilter
285
FORUM_TOPIC_CLOSED: MessageFilter
286
FORUM_TOPIC_REOPENED: MessageFilter
287
FORUM_TOPIC_EDITED: MessageFilter
288
GENERAL_FORUM_TOPIC_HIDDEN: MessageFilter
289
GENERAL_FORUM_TOPIC_UNHIDDEN: MessageFilter
290
GIVEAWAY_CREATED: MessageFilter
291
GIVEAWAY: MessageFilter
292
GIVEAWAY_WINNERS: MessageFilter
293
GIVEAWAY_COMPLETED: MessageFilter
294
CHAT_BACKGROUND_SET: MessageFilter
295
BOOST_ADDED: MessageFilter
296
```
297
298
Usage examples:
299
300
```python
301
# New members joining
302
welcome_handler = MessageHandler(
303
filters.StatusUpdate.NEW_CHAT_MEMBERS,
304
handle_new_members
305
)
306
307
# Members leaving
308
goodbye_handler = MessageHandler(
309
filters.StatusUpdate.LEFT_CHAT_MEMBER,
310
handle_member_left
311
)
312
313
# Chat title changes
314
title_handler = MessageHandler(
315
filters.StatusUpdate.NEW_CHAT_TITLE,
316
handle_title_change
317
)
318
319
# Successful payments
320
payment_handler = MessageHandler(
321
filters.StatusUpdate.SUCCESSFUL_PAYMENT,
322
handle_payment_success
323
)
324
325
# Video chat events
326
video_chat_handler = MessageHandler(
327
filters.StatusUpdate.VIDEO_CHAT_STARTED | filters.StatusUpdate.VIDEO_CHAT_ENDED,
328
handle_video_chat_event
329
)
330
```
331
332
### Update Type Filters
333
334
Filter different types of updates beyond messages.
335
336
```python { .api }
337
class filters:
338
class UpdateType:
339
MESSAGE: UpdateFilter
340
EDITED_MESSAGE: UpdateFilter
341
CHANNEL_POST: UpdateFilter
342
EDITED_CHANNEL_POST: UpdateFilter
343
INLINE_QUERY: UpdateFilter
344
CHOSEN_INLINE_RESULT: UpdateFilter
345
CALLBACK_QUERY: UpdateFilter
346
SHIPPING_QUERY: UpdateFilter
347
PRE_CHECKOUT_QUERY: UpdateFilter
348
POLL: UpdateFilter
349
POLL_ANSWER: UpdateFilter
350
MY_CHAT_MEMBER: UpdateFilter
351
CHAT_MEMBER: UpdateFilter
352
CHAT_JOIN_REQUEST: UpdateFilter
353
CHAT_BOOST: UpdateFilter
354
REMOVED_CHAT_BOOST: UpdateFilter
355
BUSINESS_CONNECTION: UpdateFilter
356
BUSINESS_MESSAGE: UpdateFilter
357
EDITED_BUSINESS_MESSAGE: UpdateFilter
358
DELETED_BUSINESS_MESSAGES: UpdateFilter
359
MESSAGE_REACTION: UpdateFilter
360
MESSAGE_REACTION_COUNT: UpdateFilter
361
PURCHASED_PAID_MEDIA: UpdateFilter
362
```
363
364
### Custom Filters
365
366
Create custom filters for specific use cases.
367
368
```python { .api }
369
class BaseFilter:
370
def __init__(self, name: str = None, data_filter: bool = False): ...
371
372
def filter(self, message: Message) -> bool | dict: ...
373
374
def __and__(self, other: BaseFilter) -> BaseFilter: ...
375
def __or__(self, other: BaseFilter) -> BaseFilter: ...
376
def __invert__(self) -> BaseFilter: ...
377
def __xor__(self, other: BaseFilter) -> BaseFilter: ...
378
379
class MessageFilter(BaseFilter):
380
pass
381
382
class UpdateFilter(BaseFilter):
383
pass
384
```
385
386
Usage examples:
387
388
```python
389
from telegram.ext.filters import BaseFilter
390
391
# Custom filter for long messages
392
class LongMessageFilter(BaseFilter):
393
def __init__(self, min_length=100):
394
self.min_length = min_length
395
super().__init__(name=f"LongMessage({min_length})")
396
397
def filter(self, message):
398
return message.text and len(message.text) >= self.min_length
399
400
long_msg_filter = LongMessageFilter(200)
401
long_handler = MessageHandler(long_msg_filter, handle_long_message)
402
403
# Filter for specific file extensions
404
class FileExtensionFilter(BaseFilter):
405
def __init__(self, extensions):
406
self.extensions = [ext.lower() for ext in extensions]
407
super().__init__(name=f"FileExtension({extensions})")
408
409
def filter(self, message):
410
if not message.document or not message.document.file_name:
411
return False
412
413
filename = message.document.file_name.lower()
414
return any(filename.endswith(f".{ext}") for ext in self.extensions)
415
416
pdf_filter = FileExtensionFilter(["pdf"])
417
pdf_handler = MessageHandler(pdf_filter, handle_pdf)
418
419
# Filter with data extraction
420
class UrlExtractorFilter(BaseFilter):
421
def __init__(self):
422
super().__init__(name="URLExtractor", data_filter=True)
423
424
def filter(self, message):
425
if not message.entities:
426
return False
427
428
urls = []
429
for entity in message.entities:
430
if entity.type == "url":
431
url = message.text[entity.offset:entity.offset + entity.length]
432
urls.append(url)
433
434
return {"urls": urls} if urls else False
435
436
url_filter = UrlExtractorFilter()
437
438
async def handle_urls(update, context):
439
urls = context.match["urls"] # Access extracted data
440
await update.message.reply_text(f"Found URLs: {', '.join(urls)}")
441
442
url_handler = MessageHandler(url_filter, handle_urls)
443
444
# Admin filter
445
class AdminFilter(BaseFilter):
446
def __init__(self):
447
super().__init__(name="Admin")
448
449
def filter(self, message):
450
# Check if user is admin in the chat
451
return message.from_user.id in get_admin_list(message.chat.id)
452
453
admin_filter = AdminFilter()
454
admin_handler = MessageHandler(admin_filter & filters.COMMAND, handle_admin_command)
455
```
456
457
### Filter Combinations
458
459
Combine filters using logical operators.
460
461
```python
462
# AND operation - both conditions must be true
463
text_and_private = filters.TEXT & filters.ChatType.PRIVATE
464
465
# OR operation - either condition can be true
466
media_filter = filters.PHOTO | filters.VIDEO | filters.ANIMATION
467
468
# NOT operation - condition must be false
469
non_command_text = filters.TEXT & ~filters.COMMAND
470
471
# XOR operation - exactly one condition must be true
472
either_photo_or_video = filters.PHOTO ^ filters.VIDEO
473
474
# Complex combinations
475
admin_media_filter = (
476
filters.User.user_id(admin_user_ids) &
477
(filters.PHOTO | filters.VIDEO | filters.DOCUMENT) &
478
~filters.HAS_MEDIA_SPOILER
479
)
480
481
# Grouped conditions
482
content_filter = (
483
(filters.TEXT & filters.Text.contains(["urgent", "important"])) |
484
(filters.PHOTO & filters.Entity.HASHTAG) |
485
(filters.DOCUMENT & filters.Text.contains("report"))
486
)
487
```
488
489
### Performance Considerations
490
491
```python
492
# Order filters by specificity (most specific first)
493
# Good - specific user check first
494
efficient_filter = filters.User.user_id(admin_id) & filters.TEXT & filters.COMMAND
495
496
# Less efficient - broad check first
497
less_efficient = filters.TEXT & filters.COMMAND & filters.User.user_id(admin_id)
498
499
# Use built-in filters when possible (they're optimized)
500
# Good
501
builtin_filter = filters.PHOTO
502
503
# Less efficient custom equivalent
504
class PhotoFilter(BaseFilter):
505
def filter(self, message):
506
return message.photo is not None
507
508
# Cache expensive operations in custom filters
509
class ExpensiveFilter(BaseFilter):
510
def __init__(self):
511
self._cache = {}
512
super().__init__()
513
514
def filter(self, message):
515
user_id = message.from_user.id
516
if user_id not in self._cache:
517
self._cache[user_id] = expensive_check(user_id)
518
return self._cache[user_id]
519
```
520
521
## Types
522
523
```python { .api }
524
from typing import Union, List, Pattern
525
import re
526
527
FilterType = Union[BaseFilter, MessageFilter, UpdateFilter]
528
PatternType = Union[str, Pattern]
529
```