0
# Utilities and Enums
1
2
Comprehensive utility functions for deep linking, keyboard building, text formatting, token validation, and complete enumeration system for API constants. These utilities simplify common bot development tasks.
3
4
## Capabilities
5
6
### Deep Linking Utilities
7
8
Functions for creating and managing Telegram bot deep links.
9
10
```python { .api }
11
def create_start_link(bot_username: str, payload: str | None = None, encode: bool = False) -> str:
12
"""
13
Create a start link for the bot.
14
15
Parameters:
16
- bot_username: Bot username (without @)
17
- payload: Optional payload to include in the link
18
- encode: Whether to base64 encode the payload
19
20
Returns:
21
Deep link URL (t.me/bot_username?start=payload)
22
"""
23
24
def create_telegram_link(username: str, **params: str) -> str:
25
"""
26
Create telegram:// protocol links.
27
28
Parameters:
29
- username: Username or entity
30
- params: Additional URL parameters
31
32
Returns:
33
Telegram protocol link
34
"""
35
36
def encode_payload(payload: str) -> str:
37
"""
38
Encode payload for deep links using base64url encoding.
39
40
Parameters:
41
- payload: Raw payload string
42
43
Returns:
44
Base64url encoded payload
45
"""
46
47
def decode_payload(encoded_payload: str) -> str:
48
"""
49
Decode base64url encoded payload.
50
51
Parameters:
52
- encoded_payload: Base64url encoded payload
53
54
Returns:
55
Decoded payload string
56
"""
57
```
58
59
### Keyboard Builders
60
61
Utility classes for building inline and reply keyboards.
62
63
```python { .api }
64
class KeyboardBuilder:
65
"""Generic keyboard builder base class"""
66
67
def __init__(self, markup: list[list[Any]] | None = None):
68
"""
69
Initialize keyboard builder.
70
71
Parameters:
72
- markup: Optional initial markup
73
"""
74
75
def add(self, *buttons: Any) -> KeyboardBuilder:
76
"""Add buttons to the current row"""
77
78
def row(self, *buttons: Any) -> KeyboardBuilder:
79
"""Add buttons as a new row"""
80
81
def adjust(self, *sizes: int, repeat: bool = True) -> KeyboardBuilder:
82
"""
83
Adjust button layout by specifying row sizes.
84
85
Parameters:
86
- sizes: Number of buttons per row
87
- repeat: Whether to repeat the pattern
88
"""
89
90
def as_markup(self) -> Any:
91
"""Generate the final keyboard markup"""
92
93
class InlineKeyboardBuilder(KeyboardBuilder):
94
"""Builder for inline keyboards"""
95
96
def button(
97
self,
98
text: str,
99
url: str | None = None,
100
login_url: LoginUrl | None = None,
101
callback_data: str | None = None,
102
web_app: WebAppInfo | None = None,
103
switch_inline_query: str | None = None,
104
switch_inline_query_current_chat: str | None = None,
105
callback_game: CallbackGame | None = None,
106
pay: bool | None = None,
107
**kwargs: Any
108
) -> InlineKeyboardBuilder:
109
"""
110
Add an inline keyboard button.
111
112
Parameters:
113
- text: Button text
114
- url: HTTP or tg:// URL
115
- login_url: Login URL for Telegram Login
116
- callback_data: Data for callback query
117
- web_app: Web App info
118
- switch_inline_query: Switch to inline mode
119
- switch_inline_query_current_chat: Switch to inline mode in current chat
120
- callback_game: Callback game
121
- pay: Payment button
122
123
Returns:
124
Self for method chaining
125
"""
126
127
def as_markup(self) -> InlineKeyboardMarkup:
128
"""Generate InlineKeyboardMarkup"""
129
130
class ReplyKeyboardBuilder(KeyboardBuilder):
131
"""Builder for reply keyboards"""
132
133
def button(
134
self,
135
text: str,
136
request_user: KeyboardButtonRequestUser | None = None,
137
request_chat: KeyboardButtonRequestChat | None = None,
138
request_contact: bool | None = None,
139
request_location: bool | None = None,
140
request_poll: KeyboardButtonPollType | None = None,
141
web_app: WebAppInfo | None = None,
142
**kwargs: Any
143
) -> ReplyKeyboardBuilder:
144
"""
145
Add a reply keyboard button.
146
147
Parameters:
148
- text: Button text
149
- request_user: Request user sharing
150
- request_chat: Request chat sharing
151
- request_contact: Request contact sharing
152
- request_location: Request location sharing
153
- request_poll: Request poll creation
154
- web_app: Web App info
155
156
Returns:
157
Self for method chaining
158
"""
159
160
def as_markup(
161
self,
162
resize_keyboard: bool | None = None,
163
one_time_keyboard: bool | None = None,
164
input_field_placeholder: str | None = None,
165
selective: bool | None = None,
166
is_persistent: bool | None = None
167
) -> ReplyKeyboardMarkup:
168
"""
169
Generate ReplyKeyboardMarkup.
170
171
Parameters:
172
- resize_keyboard: Resize keyboard to fit
173
- one_time_keyboard: Hide keyboard after use
174
- input_field_placeholder: Placeholder text
175
- selective: Show keyboard only to specific users
176
- is_persistent: Keep keyboard visible
177
178
Returns:
179
ReplyKeyboardMarkup object
180
"""
181
```
182
183
### Text Decoration Utilities
184
185
Functions and classes for formatting text with HTML and Markdown.
186
187
```python { .api }
188
class TextDecoration:
189
"""Base class for text decorations"""
190
191
def bold(self, text: str) -> str:
192
"""Make text bold"""
193
194
def italic(self, text: str) -> str:
195
"""Make text italic"""
196
197
def code(self, text: str) -> str:
198
"""Format text as inline code"""
199
200
def pre(self, text: str, language: str | None = None) -> str:
201
"""Format text as code block"""
202
203
def link(self, text: str, url: str) -> str:
204
"""Create a link"""
205
206
def spoiler(self, text: str) -> str:
207
"""Create spoiler text"""
208
209
def strikethrough(self, text: str) -> str:
210
"""Strike through text"""
211
212
def underline(self, text: str) -> str:
213
"""Underline text"""
214
215
class HtmlDecoration(TextDecoration):
216
"""HTML text decoration"""
217
218
def bold(self, text: str) -> str:
219
"""Format: <b>text</b>"""
220
221
def italic(self, text: str) -> str:
222
"""Format: <i>text</i>"""
223
224
def code(self, text: str) -> str:
225
"""Format: <code>text</code>"""
226
227
def pre(self, text: str, language: str | None = None) -> str:
228
"""Format: <pre><code class="language">text</code></pre>"""
229
230
def link(self, text: str, url: str) -> str:
231
"""Format: <a href="url">text</a>"""
232
233
def spoiler(self, text: str) -> str:
234
"""Format: <tg-spoiler>text</tg-spoiler>"""
235
236
class MarkdownDecoration(TextDecoration):
237
"""Markdown text decoration"""
238
239
def bold(self, text: str) -> str:
240
"""Format: **text**"""
241
242
def italic(self, text: str) -> str:
243
"""Format: *text*"""
244
245
def code(self, text: str) -> str:
246
"""Format: `text`"""
247
248
def pre(self, text: str, language: str | None = None) -> str:
249
"""Format: ```language\ntext\n```"""
250
251
# Global decoration instances
252
html: HtmlDecoration
253
md: MarkdownDecoration
254
```
255
256
### Token Utilities
257
258
Functions for validating and parsing bot tokens.
259
260
```python { .api }
261
def validate_token(token: str) -> bool:
262
"""
263
Validate bot token format.
264
265
Parameters:
266
- token: Bot token to validate
267
268
Returns:
269
True if token format is valid
270
"""
271
272
def extract_bot_id(token: str) -> int:
273
"""
274
Extract bot ID from token.
275
276
Parameters:
277
- token: Bot token
278
279
Returns:
280
Bot ID as integer
281
282
Raises:
283
ValueError if token format is invalid
284
"""
285
```
286
287
### Media Group Utilities
288
289
Utilities for building and managing media groups.
290
291
```python { .api }
292
class MediaGroupBuilder:
293
"""Builder for media groups (albums)"""
294
295
def __init__(self, caption: str | None = None, parse_mode: str | None = None):
296
"""
297
Initialize media group builder.
298
299
Parameters:
300
- caption: Overall caption for the media group
301
- parse_mode: Parse mode for caption
302
"""
303
304
def add_photo(
305
self,
306
media: str | InputFile,
307
caption: str | None = None,
308
parse_mode: str | None = None,
309
caption_entities: list[MessageEntity] | None = None,
310
has_spoiler: bool | None = None
311
) -> MediaGroupBuilder:
312
"""Add photo to media group"""
313
314
def add_video(
315
self,
316
media: str | InputFile,
317
width: int | None = None,
318
height: int | None = None,
319
duration: int | None = None,
320
supports_streaming: bool | None = None,
321
thumbnail: str | InputFile | None = None,
322
caption: str | None = None,
323
parse_mode: str | None = None,
324
caption_entities: list[MessageEntity] | None = None,
325
has_spoiler: bool | None = None
326
) -> MediaGroupBuilder:
327
"""Add video to media group"""
328
329
def add_audio(
330
self,
331
media: str | InputFile,
332
thumbnail: str | InputFile | None = None,
333
caption: str | None = None,
334
parse_mode: str | None = None,
335
caption_entities: list[MessageEntity] | None = None,
336
duration: int | None = None,
337
performer: str | None = None,
338
title: str | None = None
339
) -> MediaGroupBuilder:
340
"""Add audio to media group"""
341
342
def add_document(
343
self,
344
media: str | InputFile,
345
thumbnail: str | InputFile | None = None,
346
caption: str | None = None,
347
parse_mode: str | None = None,
348
caption_entities: list[MessageEntity] | None = None,
349
disable_content_type_detection: bool | None = None
350
) -> MediaGroupBuilder:
351
"""Add document to media group"""
352
353
def build(self) -> list[InputMedia]:
354
"""Build the media group"""
355
```
356
357
### Chat Action Utilities
358
359
Utilities for managing chat actions (typing indicators).
360
361
```python { .api }
362
class ChatActionSender:
363
"""Automatic chat action sender"""
364
365
def __init__(
366
self,
367
bot: Bot,
368
chat_id: int | str,
369
action: str = "typing",
370
interval: float = 5.0
371
):
372
"""
373
Initialize chat action sender.
374
375
Parameters:
376
- bot: Bot instance
377
- chat_id: Target chat ID
378
- action: Chat action to send
379
- interval: Interval between action sends
380
"""
381
382
async def __aenter__(self) -> ChatActionSender:
383
"""Start sending chat actions"""
384
385
async def __aexit__(self, exc_type, exc_val, exc_tb) -> None:
386
"""Stop sending chat actions"""
387
```
388
389
### Link Generation Utilities
390
391
Additional utilities for generating various types of links.
392
393
```python { .api }
394
def create_tg_link(entity: str, **params: str) -> str:
395
"""
396
Create tg:// protocol links.
397
398
Parameters:
399
- entity: Target entity (username, chat_id, etc.)
400
- params: Additional parameters
401
402
Returns:
403
Telegram protocol link
404
"""
405
```
406
407
## Enumerations
408
409
### Core Enums
410
411
Fundamental enumerations for Telegram API constants.
412
413
```python { .api }
414
class ChatType(str, Enum):
415
"""Chat types"""
416
PRIVATE = "private"
417
GROUP = "group"
418
SUPERGROUP = "supergroup"
419
CHANNEL = "channel"
420
421
class ChatAction(str, Enum):
422
"""Chat actions (typing indicators)"""
423
TYPING = "typing"
424
UPLOAD_PHOTO = "upload_photo"
425
RECORD_VIDEO = "record_video"
426
UPLOAD_VIDEO = "upload_video"
427
RECORD_VOICE = "record_voice"
428
UPLOAD_VOICE = "upload_voice"
429
UPLOAD_DOCUMENT = "upload_document"
430
CHOOSE_STICKER = "choose_sticker"
431
FIND_LOCATION = "find_location"
432
RECORD_VIDEO_NOTE = "record_video_note"
433
UPLOAD_VIDEO_NOTE = "upload_video_note"
434
435
class ParseMode(str, Enum):
436
"""Text parsing modes"""
437
HTML = "HTML"
438
MARKDOWN = "Markdown"
439
MARKDOWN_V2 = "MarkdownV2"
440
441
class ContentType(str, Enum):
442
"""Message content types"""
443
TEXT = "text"
444
AUDIO = "audio"
445
DOCUMENT = "document"
446
ANIMATION = "animation"
447
GAME = "game"
448
PHOTO = "photo"
449
STICKER = "sticker"
450
VIDEO = "video"
451
VIDEO_NOTE = "video_note"
452
VOICE = "voice"
453
CONTACT = "contact"
454
DICE = "dice"
455
POLL = "poll"
456
VENUE = "venue"
457
LOCATION = "location"
458
NEW_CHAT_MEMBERS = "new_chat_members"
459
LEFT_CHAT_MEMBER = "left_chat_member"
460
INVOICE = "invoice"
461
SUCCESSFUL_PAYMENT = "successful_payment"
462
CONNECTED_WEBSITE = "connected_website"
463
MIGRATE_TO_CHAT_ID = "migrate_to_chat_id"
464
MIGRATE_FROM_CHAT_ID = "migrate_from_chat_id"
465
PINNED_MESSAGE = "pinned_message"
466
NEW_CHAT_TITLE = "new_chat_title"
467
NEW_CHAT_PHOTO = "new_chat_photo"
468
DELETE_CHAT_PHOTO = "delete_chat_photo"
469
GROUP_CHAT_CREATED = "group_chat_created"
470
SUPERGROUP_CHAT_CREATED = "supergroup_chat_created"
471
CHANNEL_CHAT_CREATED = "channel_chat_created"
472
MESSAGE_AUTO_DELETE_TIMER_CHANGED = "message_auto_delete_timer_changed"
473
WEB_APP_DATA = "web_app_data"
474
475
class UpdateType(str, Enum):
476
"""Update types"""
477
MESSAGE = "message"
478
EDITED_MESSAGE = "edited_message"
479
CHANNEL_POST = "channel_post"
480
EDITED_CHANNEL_POST = "edited_channel_post"
481
INLINE_QUERY = "inline_query"
482
CHOSEN_INLINE_RESULT = "chosen_inline_result"
483
CALLBACK_QUERY = "callback_query"
484
SHIPPING_QUERY = "shipping_query"
485
PRE_CHECKOUT_QUERY = "pre_checkout_query"
486
POLL = "poll"
487
POLL_ANSWER = "poll_answer"
488
MY_CHAT_MEMBER = "my_chat_member"
489
CHAT_MEMBER = "chat_member"
490
CHAT_JOIN_REQUEST = "chat_join_request"
491
```
492
493
### Message Entity Enums
494
495
Enumerations for message formatting and entities.
496
497
```python { .api }
498
class MessageEntityType(str, Enum):
499
"""Message entity types"""
500
MENTION = "mention" # @username
501
HASHTAG = "hashtag" # #hashtag
502
CASHTAG = "cashtag" # $USD
503
BOT_COMMAND = "bot_command" # /start
504
URL = "url" # https://telegram.org
505
EMAIL = "email" # user@example.com
506
PHONE_NUMBER = "phone_number" # +1-123-456-7890
507
BOLD = "bold" # Bold text
508
ITALIC = "italic" # Italic text
509
UNDERLINE = "underline" # Underlined text
510
STRIKETHROUGH = "strikethrough" # Strikethrough text
511
SPOILER = "spoiler" # Spoiler text
512
CODE = "code" # Inline code
513
PRE = "pre" # Code block
514
TEXT_LINK = "text_link" # Clickable text URLs
515
TEXT_MENTION = "text_mention" # Users without usernames
516
CUSTOM_EMOJI = "custom_emoji" # Custom emoji
517
518
class PollType(str, Enum):
519
"""Poll types"""
520
REGULAR = "regular"
521
QUIZ = "quiz"
522
523
class DiceEmoji(str, Enum):
524
"""Dice emoji types"""
525
DICE = "π²" # 1-6
526
DARTS = "π―" # 1-6
527
BASKETBALL = "π" # 1-5
528
FOOTBALL = "β½" # 1-5
529
BOWLING = "π³" # 1-6
530
SLOT_MACHINE = "π°" # 1-64
531
```
532
533
### User and Chat Management Enums
534
535
Enumerations for user and chat management.
536
537
```python { .api }
538
class ChatMemberStatus(str, Enum):
539
"""Chat member statuses"""
540
CREATOR = "creator"
541
ADMINISTRATOR = "administrator"
542
MEMBER = "member"
543
RESTRICTED = "restricted"
544
LEFT = "left"
545
KICKED = "kicked"
546
547
class BotCommandScopeType(str, Enum):
548
"""Bot command scope types"""
549
DEFAULT = "default"
550
ALL_PRIVATE_CHATS = "all_private_chats"
551
ALL_GROUP_CHATS = "all_group_chats"
552
ALL_CHAT_ADMINISTRATORS = "all_chat_administrators"
553
CHAT = "chat"
554
CHAT_ADMINISTRATORS = "chat_administrators"
555
CHAT_MEMBER = "chat_member"
556
```
557
558
### Media and Sticker Enums
559
560
Enumerations for media and sticker handling.
561
562
```python { .api }
563
class StickerFormat(str, Enum):
564
"""Sticker formats"""
565
STATIC = "static"
566
ANIMATED = "animated"
567
VIDEO = "video"
568
569
class StickerType(str, Enum):
570
"""Sticker types"""
571
REGULAR = "regular"
572
MASK = "mask"
573
CUSTOM_EMOJI = "custom_emoji"
574
575
class InputMediaType(str, Enum):
576
"""Input media types"""
577
PHOTO = "photo"
578
VIDEO = "video"
579
ANIMATION = "animation"
580
AUDIO = "audio"
581
DOCUMENT = "document"
582
```
583
584
### Inline Query Enums
585
586
Enumerations for inline query handling.
587
588
```python { .api }
589
class InlineQueryResultType(str, Enum):
590
"""Inline query result types"""
591
ARTICLE = "article"
592
PHOTO = "photo"
593
GIF = "gif"
594
MPEG4_GIF = "mpeg4_gif"
595
VIDEO = "video"
596
AUDIO = "audio"
597
VOICE = "voice"
598
DOCUMENT = "document"
599
LOCATION = "location"
600
VENUE = "venue"
601
CONTACT = "contact"
602
GAME = "game"
603
STICKER = "sticker"
604
```
605
606
## Usage Examples
607
608
### Building Keyboards
609
610
```python
611
from aiogram.utils.keyboard import InlineKeyboardBuilder, ReplyKeyboardBuilder
612
613
# Inline keyboard with multiple buttons
614
builder = InlineKeyboardBuilder()
615
builder.button(text="Button 1", callback_data="btn1")
616
builder.button(text="Button 2", callback_data="btn2")
617
builder.button(text="Button 3", callback_data="btn3")
618
builder.button(text="Button 4", callback_data="btn4")
619
620
# Adjust layout: 2 buttons per row, then 1, then repeat pattern
621
builder.adjust(2, 1)
622
623
keyboard = builder.as_markup()
624
625
# Reply keyboard with special buttons
626
reply_builder = ReplyKeyboardBuilder()
627
reply_builder.button(text="π Share Contact", request_contact=True)
628
reply_builder.button(text="π Share Location", request_location=True)
629
reply_builder.button(text="Regular Button")
630
reply_builder.adjust(2, 1)
631
632
reply_keyboard = reply_builder.as_markup(
633
resize_keyboard=True,
634
one_time_keyboard=True
635
)
636
```
637
638
### Text Formatting
639
640
```python
641
from aiogram.utils.text_decorations import html_decoration as html
642
from aiogram.utils.text_decorations import markdown_decoration as md
643
644
# HTML formatting
645
text = (
646
f"{html.bold('Welcome!')} to our bot.\n"
647
f"Visit our {html.link('website', 'https://example.com')}\n"
648
f"Use {html.code('/start')} to begin\n"
649
f"{html.spoiler('Secret message')}"
650
)
651
652
# Markdown formatting
653
text = (
654
f"{md.bold('Welcome!')} to our bot.\n"
655
f"Visit our {md.link('website', 'https://example.com')}\n"
656
f"Use {md.code('/start')} to begin"
657
)
658
659
await message.answer(text, parse_mode="HTML")
660
```
661
662
### Deep Linking
663
664
```python
665
from aiogram.utils.deep_linking import create_start_link, encode_payload, decode_payload
666
667
# Create simple start link
668
link = create_start_link("mybot", "welcome")
669
# Result: https://t.me/mybot?start=welcome
670
671
# Create encoded start link
672
payload = "user_id=123&source=website"
673
encoded = encode_payload(payload)
674
link = create_start_link("mybot", encoded)
675
676
# In handler, decode the payload
677
@router.message(CommandStart(deep_link=True))
678
async def handle_start_link(message: Message, command: CommandObject):
679
if command.args:
680
try:
681
decoded = decode_payload(command.args)
682
# Parse the decoded payload
683
params = dict(param.split('=') for param in decoded.split('&'))
684
user_id = params.get('user_id')
685
source = params.get('source')
686
687
await message.answer(f"Welcome! Referred by user {user_id} from {source}")
688
except Exception:
689
await message.answer("Invalid referral link")
690
```
691
692
### Media Groups
693
694
```python
695
from aiogram.utils.media_group import MediaGroupBuilder
696
from aiogram.types import FSInputFile
697
698
# Build media group
699
media_builder = MediaGroupBuilder(caption="Photo album")
700
media_builder.add_photo(FSInputFile("photo1.jpg"), caption="First photo")
701
media_builder.add_photo(FSInputFile("photo2.jpg"))
702
media_builder.add_video(FSInputFile("video.mp4"), caption="Video")
703
704
media_group = media_builder.build()
705
await bot.send_media_group(chat_id, media_group)
706
```
707
708
### Chat Actions
709
710
```python
711
from aiogram.utils.chat_action import ChatActionSender
712
713
# Automatic typing indicator
714
async with ChatActionSender(bot, chat_id, "typing"):
715
# Simulate long operation
716
await asyncio.sleep(3)
717
await bot.send_message(chat_id, "Operation completed!")
718
719
# Custom action and interval
720
async with ChatActionSender(bot, chat_id, "upload_photo", interval=3.0):
721
# Process and upload photo
722
await process_image()
723
await bot.send_photo(chat_id, photo)
724
```
725
726
### Using Enums
727
728
```python
729
from aiogram.enums import ChatType, ContentType, ParseMode
730
731
@router.message(F.chat.type == ChatType.PRIVATE)
732
async def private_only(message: Message):
733
await message.answer("This works only in private chats")
734
735
@router.message(F.content_type == ContentType.PHOTO)
736
async def handle_photo(message: Message):
737
await message.answer("Nice photo!")
738
739
# Send message with specific parse mode
740
await bot.send_message(
741
chat_id,
742
"<b>Bold text</b>",
743
parse_mode=ParseMode.HTML
744
)
745
746
# Check update type
747
if update.message:
748
update_type = UpdateType.MESSAGE
749
elif update.callback_query:
750
update_type = UpdateType.CALLBACK_QUERY
751
```
752
753
### Token Validation
754
755
```python
756
from aiogram.utils.token import validate_token, extract_bot_id
757
758
token = "123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11"
759
760
if validate_token(token):
761
bot_id = extract_bot_id(token)
762
print(f"Valid token for bot ID: {bot_id}")
763
bot = Bot(token=token)
764
else:
765
print("Invalid token format")
766
```