0
# Handlers
1
2
Handlers process specific types of updates from Telegram. The library provides comprehensive handlers for all update types, with filtering capabilities and conversation management.
3
4
## Capabilities
5
6
### Base Handler
7
8
Foundation for all handler types with filtering and callback execution.
9
10
```python { .api }
11
class BaseHandler:
12
def __init__(self, callback: callable, block: bool = True): ...
13
14
def check_update(self, update: Update) -> bool | object: ...
15
async def handle_update(self, update: Update, application: 'Application', check_result: object, context: CallbackContext) -> object: ...
16
17
callback: callable
18
block: bool
19
```
20
21
### Message Handlers
22
23
Handle text messages, media, and other message types with comprehensive filtering.
24
25
```python { .api }
26
class MessageHandler(BaseHandler):
27
def __init__(
28
self,
29
filters: BaseFilter,
30
callback: callable,
31
block: bool = True
32
): ...
33
34
filters: BaseFilter
35
36
class CommandHandler(BaseHandler):
37
def __init__(
38
self,
39
command: str | list[str],
40
callback: callable,
41
filters: BaseFilter = None,
42
block: bool = True
43
): ...
44
45
command: str | frozenset[str]
46
filters: BaseFilter | None
47
```
48
49
Usage examples:
50
51
```python
52
from telegram.ext import MessageHandler, CommandHandler, filters
53
54
# Handle text messages
55
async def echo(update, context):
56
await update.message.reply_text(update.message.text)
57
58
text_handler = MessageHandler(filters.TEXT & ~filters.COMMAND, echo)
59
60
# Handle commands
61
async def start(update, context):
62
await update.message.reply_text("Welcome!")
63
64
start_handler = CommandHandler("start", start)
65
66
# Command with arguments
67
async def help_command(update, context):
68
command_args = context.args # List of arguments after command
69
if command_args:
70
await update.message.reply_text(f"Help for: {' '.join(command_args)}")
71
else:
72
await update.message.reply_text("General help")
73
74
help_handler = CommandHandler("help", help_command)
75
76
# Handle multiple commands
77
multi_handler = CommandHandler(["info", "about"], info_callback)
78
```
79
80
### Callback Query Handler
81
82
Handle callback queries from inline keyboard button presses.
83
84
```python { .api }
85
class CallbackQueryHandler(BaseHandler):
86
def __init__(
87
self,
88
callback: callable,
89
pattern: str | re.Pattern = None,
90
block: bool = True
91
): ...
92
93
pattern: str | re.Pattern | None
94
```
95
96
Usage example:
97
98
```python
99
from telegram.ext import CallbackQueryHandler
100
import re
101
102
async def button_callback(update, context):
103
query = update.callback_query
104
await query.answer() # Acknowledge the callback
105
106
if query.data == "option_1":
107
await query.edit_message_text("You chose option 1")
108
elif query.data == "option_2":
109
await query.edit_message_text("You chose option 2")
110
111
# Handle specific callback data
112
button_handler = CallbackQueryHandler(button_callback, pattern="^option_")
113
114
# Handle all callback queries
115
all_callbacks = CallbackQueryHandler(button_callback)
116
```
117
118
### Inline Query Handler
119
120
Handle inline queries when users type @bot_username in any chat.
121
122
```python { .api }
123
class InlineQueryHandler(BaseHandler):
124
def __init__(
125
self,
126
callback: callable,
127
pattern: str | re.Pattern = None,
128
block: bool = True,
129
chat_types: list[str] = None
130
): ...
131
132
pattern: str | re.Pattern | None
133
chat_types: list[str] | None
134
```
135
136
Usage example:
137
138
```python
139
from telegram.ext import InlineQueryHandler
140
from telegram import InlineQueryResultArticle, InputTextMessageContent
141
142
async def inline_query(update, context):
143
query = update.inline_query.query
144
145
if not query:
146
return
147
148
results = [
149
InlineQueryResultArticle(
150
id="1",
151
title=f"Result for '{query}'",
152
input_message_content=InputTextMessageContent(f"You searched for: {query}")
153
)
154
]
155
156
await update.inline_query.answer(results, cache_time=0)
157
158
inline_handler = InlineQueryHandler(inline_query)
159
```
160
161
### Conversation Handler
162
163
Manage multi-step conversations with state tracking.
164
165
```python { .api }
166
class ConversationHandler(BaseHandler):
167
def __init__(
168
self,
169
entry_points: list[BaseHandler],
170
states: dict[object, list[BaseHandler]],
171
fallbacks: list[BaseHandler],
172
allow_reentry: bool = False,
173
per_chat: bool = True,
174
per_user: bool = True,
175
per_message: bool = False,
176
conversation_timeout: float = None,
177
name: str = None,
178
persistent: bool = False,
179
map_to_parent: dict = None,
180
block: bool = True
181
): ...
182
183
END: int = -1
184
TIMEOUT: int = -2
185
WAITING: int = -3
186
187
entry_points: list[BaseHandler]
188
states: dict[object, list[BaseHandler]]
189
fallbacks: list[BaseHandler]
190
```
191
192
Usage example:
193
194
```python
195
from telegram.ext import ConversationHandler, CommandHandler, MessageHandler, filters
196
197
# Conversation states
198
CHOOSING, TYPING_REPLY = range(2)
199
200
async def start_conv(update, context):
201
await update.message.reply_text("What's your name?")
202
return TYPING_REPLY
203
204
async def received_name(update, context):
205
user_data = context.user_data
206
user_data['name'] = update.message.text
207
await update.message.reply_text(f"Nice to meet you, {update.message.text}!")
208
return ConversationHandler.END
209
210
async def cancel(update, context):
211
await update.message.reply_text("Conversation cancelled.")
212
return ConversationHandler.END
213
214
# Create conversation handler
215
conv_handler = ConversationHandler(
216
entry_points=[CommandHandler('start', start_conv)],
217
states={
218
TYPING_REPLY: [MessageHandler(filters.TEXT & ~filters.COMMAND, received_name)],
219
},
220
fallbacks=[CommandHandler('cancel', cancel)],
221
)
222
```
223
224
### Specialized Handlers
225
226
Handlers for specific Telegram features and update types.
227
228
```python { .api }
229
class PollHandler(BaseHandler):
230
def __init__(self, callback: callable, block: bool = True): ...
231
232
class PollAnswerHandler(BaseHandler):
233
def __init__(self, callback: callable, block: bool = True): ...
234
235
class ChatMemberHandler(BaseHandler):
236
def __init__(self, callback: callable, chat_member_types: int = None, block: bool = True): ...
237
238
MY_CHAT_MEMBER: int = 1
239
CHAT_MEMBER: int = 2
240
ANY_CHAT_MEMBER: int = -1
241
242
class ChatJoinRequestHandler(BaseHandler):
243
def __init__(self, callback: callable, block: bool = True): ...
244
245
class ChosenInlineResultHandler(BaseHandler):
246
def __init__(self, callback: callable, pattern: str | re.Pattern = None, block: bool = True): ...
247
248
class ShippingQueryHandler(BaseHandler):
249
def __init__(self, callback: callable, block: bool = True): ...
250
251
class PreCheckoutQueryHandler(BaseHandler):
252
def __init__(self, callback: callable, block: bool = True): ...
253
254
class BusinessConnectionHandler(BaseHandler):
255
def __init__(self, callback: callable, block: bool = True): ...
256
257
class BusinessMessagesDeletedHandler(BaseHandler):
258
def __init__(self, callback: callable, block: bool = True): ...
259
260
class MessageReactionHandler(BaseHandler):
261
def __init__(self, callback: callable, block: bool = True): ...
262
263
class ChatBoostHandler(BaseHandler):
264
def __init__(self, callback: callable, block: bool = True): ...
265
266
class PaidMediaPurchasedHandler(BaseHandler):
267
def __init__(self, callback: callable, block: bool = True): ...
268
```
269
270
### String Handlers
271
272
Handle string-based updates for non-Telegram sources.
273
274
```python { .api }
275
class StringCommandHandler(BaseHandler):
276
def __init__(
277
self,
278
command: str,
279
callback: callable,
280
block: bool = True
281
): ...
282
283
class StringRegexHandler(BaseHandler):
284
def __init__(
285
self,
286
pattern: str | re.Pattern,
287
callback: callable,
288
block: bool = True
289
): ...
290
```
291
292
### Type Handler
293
294
Handle updates based on their type.
295
296
```python { .api }
297
class TypeHandler(BaseHandler):
298
def __init__(
299
self,
300
type: type,
301
callback: callable,
302
strict: bool = False,
303
block: bool = True
304
): ...
305
306
type: type
307
strict: bool
308
```
309
310
Usage example:
311
312
```python
313
from telegram.ext import TypeHandler
314
from telegram import Document
315
316
async def handle_document(update, context):
317
document = update.message.document
318
await update.message.reply_text(f"Received document: {document.file_name}")
319
320
# Handle any update containing a Document
321
doc_handler = TypeHandler(Document, handle_document)
322
```
323
324
### Prefix Handler
325
326
Handle messages that start with specific prefixes.
327
328
```python { .api }
329
class PrefixHandler(BaseHandler):
330
def __init__(
331
self,
332
prefix: str | list[str],
333
command: str | list[str],
334
callback: callable,
335
filters: BaseFilter = None,
336
block: bool = True
337
): ...
338
339
prefix: frozenset[str]
340
command: frozenset[str]
341
filters: BaseFilter | None
342
```
343
344
Usage example:
345
346
```python
347
from telegram.ext import PrefixHandler
348
349
async def custom_command(update, context):
350
command = context.matches[0].group(1) # The command part
351
await update.message.reply_text(f"Custom command: {command}")
352
353
# Handle messages like "!help", "!info", "#status"
354
prefix_handler = PrefixHandler(['!', '#'], ['help', 'info', 'status'], custom_command)
355
```
356
357
## Handler Groups and Priority
358
359
```python
360
# Handlers are processed in groups (lower numbers first)
361
application.add_handler(urgent_handler, group=0) # Processed first
362
application.add_handler(normal_handler, group=1) # Processed second
363
application.add_handler(fallback_handler, group=2) # Processed last
364
365
# Within a group, handlers are processed in order of addition
366
# First matching handler stops processing (unless handler returns None)
367
```
368
369
## Handler Patterns
370
371
### Pattern Matching in Handlers
372
373
```python
374
# Callback queries with regex patterns
375
async def pattern_callback(update, context):
376
match = context.match # The regex match object
377
data = match.group(1) # Extract captured groups
378
await update.callback_query.answer(f"Matched: {data}")
379
380
pattern_handler = CallbackQueryHandler(pattern_callback, pattern=r"^action_(.+)$")
381
382
# Inline queries with patterns
383
inline_pattern = InlineQueryHandler(inline_callback, pattern=r"^search (.+)")
384
```
385
386
### Error Handling in Handlers
387
388
```python
389
async def safe_handler(update, context):
390
try:
391
# Handler logic
392
await risky_operation()
393
except Exception as e:
394
await update.message.reply_text("An error occurred!")
395
# Re-raise to trigger error handlers if needed
396
raise
397
398
# Global error handling
399
async def error_handler(update, context):
400
print(f"Error: {context.error}")
401
402
application.add_error_handler(error_handler)
403
```
404
405
## Types
406
407
```python { .api }
408
from typing import Any, Pattern, Union, List, Dict, Optional, Callable
409
import re
410
411
BaseFilter = Any # Defined in filters module
412
```