or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

advanced-features.mdapplication-framework.mdbot-api.mdfiles.mdfilters.mdhandlers.mdindex.mdkeyboards.mdtelegram-types.md

filters.mddocs/

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

```