or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

api-methods.mdbot-and-dispatcher.mdfilters-and-handlers.mdindex.mdstate-management.mdtypes-and-objects.mdutilities-and-enums.md

utilities-and-enums.mddocs/

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

```