Modern and fully asynchronous framework for Telegram Bot API
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Complete type system covering all Telegram objects including messages, users, chats, keyboards, media, payments, and inline queries. Over 319 classes with full type safety and automatic serialization/deserialization.
Fundamental Telegram objects that form the basis of the Bot API.
class TelegramObject:
"""Base class for all Telegram objects with automatic serialization"""
pass
class Update(TelegramObject):
"""Represents an incoming update containing events"""
update_id: int
message: Message | None
edited_message: Message | None
channel_post: Message | None
edited_channel_post: Message | None
business_connection: BusinessConnection | None
business_message: Message | None
edited_business_message: Message | None
deleted_business_messages: BusinessMessagesDeleted | None
message_reaction: MessageReactionUpdated | None
message_reaction_count: MessageReactionCountUpdated | None
inline_query: InlineQuery | None
chosen_inline_result: ChosenInlineResult | None
callback_query: CallbackQuery | None
shipping_query: ShippingQuery | None
pre_checkout_query: PreCheckoutQuery | None
purchased_paid_media: PaidMediaPurchased | None
poll: Poll | None
poll_answer: PollAnswer | None
my_chat_member: ChatMemberUpdated | None
chat_member: ChatMemberUpdated | None
chat_join_request: ChatJoinRequest | None
chat_boost: ChatBoostUpdated | None
removed_chat_boost: ChatBoostRemoved | None
class User(TelegramObject):
"""Represents a Telegram user or bot"""
id: int
is_bot: bool
first_name: str
last_name: str | None
username: str | None
language_code: str | None
is_premium: bool | None
added_to_attachment_menu: bool | None
can_join_groups: bool | None
can_read_all_group_messages: bool | None
supports_inline_queries: bool | None
class Chat(TelegramObject):
"""Represents a chat (private, group, supergroup, or channel)"""
id: int
type: str # "private", "group", "supergroup", "channel"
title: str | None
username: str | None
first_name: str | None
last_name: str | None
is_forum: bool | None
description: str | None
invite_link: str | None
pinned_message: Message | None
permissions: ChatPermissions | None
slow_mode_delay: int | None
message_auto_delete_time: int | None
has_protected_content: bool | None
sticker_set_name: str | None
can_set_sticker_set: bool | None
linked_chat_id: int | None
location: ChatLocation | NoneMessage-related objects including content, entities, and replies.
class Message(TelegramObject):
"""Represents a message"""
message_id: int
message_thread_id: int | None
from_user: User | None
sender_chat: Chat | None
date: datetime.datetime
chat: Chat
forward_from: User | None
forward_from_chat: Chat | None
forward_from_message_id: int | None
forward_signature: str | None
forward_sender_name: str | None
forward_date: datetime.datetime | None
is_topic_message: bool | None
is_automatic_forward: bool | None
reply_to_message: Message | None
via_bot: User | None
edit_date: datetime.datetime | None
has_protected_content: bool | None
media_group_id: str | None
author_signature: str | None
text: str | None
entities: list[MessageEntity] | None
animation: Animation | None
audio: Audio | None
document: Document | None
photo: list[PhotoSize] | None
sticker: Sticker | None
story: Story | None
video: Video | None
video_note: VideoNote | None
voice: Voice | None
caption: str | None
caption_entities: list[MessageEntity] | None
has_media_spoiler: bool | None
contact: Contact | None
dice: Dice | None
game: Game | None
poll: Poll | None
venue: Venue | None
location: Location | None
new_chat_members: list[User] | None
left_chat_member: User | None
new_chat_title: str | None
new_chat_photo: list[PhotoSize] | None
delete_chat_photo: bool | None
group_chat_created: bool | None
supergroup_chat_created: bool | None
channel_chat_created: bool | None
message_auto_delete_timer_changed: MessageAutoDeleteTimerChanged | None
migrate_to_chat_id: int | None
migrate_from_chat_id: int | None
pinned_message: Message | None
invoice: Invoice | None
successful_payment: SuccessfulPayment | None
connected_website: str | None
write_access_allowed: WriteAccessAllowed | None
passport_data: PassportData | None
proximity_alert_triggered: ProximityAlertTriggered | None
forum_topic_created: ForumTopicCreated | None
forum_topic_edited: ForumTopicEdited | None
forum_topic_closed: ForumTopicClosed | None
forum_topic_reopened: ForumTopicReopened | None
general_forum_topic_hidden: GeneralForumTopicHidden | None
general_forum_topic_unhidden: GeneralForumTopicUnhidden | None
video_chat_scheduled: VideoChatScheduled | None
video_chat_started: VideoChatStarted | None
video_chat_ended: VideoChatEnded | None
video_chat_participants_invited: VideoChatParticipantsInvited | None
web_app_data: WebAppData | None
reply_markup: InlineKeyboardMarkup | None
async def answer(self, text: str, **kwargs) -> Message:
"""Reply to this message"""
async def reply(self, text: str, **kwargs) -> Message:
"""Reply to this message (alias for answer)"""
async def edit_text(self, text: str, **kwargs) -> Message | bool:
"""Edit this message's text"""
async def delete(self) -> bool:
"""Delete this message"""
async def forward(self, chat_id: int | str) -> Message:
"""Forward this message to another chat"""
async def copy(self, chat_id: int | str, **kwargs) -> MessageId:
"""Copy this message to another chat"""
class MessageEntity(TelegramObject):
"""Represents one special entity in a text message"""
type: str # "mention", "hashtag", "cashtag", "bot_command", "url", etc.
offset: int
length: int
url: str | None
user: User | None
language: str | None
custom_emoji_id: str | NoneObjects representing various media types and files.
class PhotoSize(TelegramObject):
"""Represents one size of a photo or a file/sticker thumbnail"""
file_id: str
file_unique_id: str
width: int
height: int
file_size: int | None
class Audio(TelegramObject):
"""Represents an audio file"""
file_id: str
file_unique_id: str
duration: int
performer: str | None
title: str | None
file_name: str | None
mime_type: str | None
file_size: int | None
thumbnail: PhotoSize | None
class Document(TelegramObject):
"""Represents a general file"""
file_id: str
file_unique_id: str
thumbnail: PhotoSize | None
file_name: str | None
mime_type: str | None
file_size: int | None
class Video(TelegramObject):
"""Represents a video file"""
file_id: str
file_unique_id: str
width: int
height: int
duration: int
thumbnail: PhotoSize | None
file_name: str | None
mime_type: str | None
file_size: int | None
class Animation(TelegramObject):
"""Represents an animation file (GIF or H.264/MPEG-4 AVC video without sound)"""
file_id: str
file_unique_id: str
width: int
height: int
duration: int
thumbnail: PhotoSize | None
file_name: str | None
mime_type: str | None
file_size: int | None
class Voice(TelegramObject):
"""Represents a voice note"""
file_id: str
file_unique_id: str
duration: int
mime_type: str | None
file_size: int | None
class VideoNote(TelegramObject):
"""Represents a video message"""
file_id: str
file_unique_id: str
length: int
duration: int
thumbnail: PhotoSize | None
file_size: int | NoneTypes for handling file uploads and media input.
class InputFile:
"""Base class for input files"""
pass
class FSInputFile(InputFile):
"""Input file from filesystem"""
def __init__(self, path: str | Path, filename: str | None = None, chunk_size: int = 65536):
"""
Parameters:
- path: Path to the file
- filename: Custom filename (defaults to file basename)
- chunk_size: Size of chunks for reading file
"""
class BufferedInputFile(InputFile):
"""Input file from bytes in memory"""
def __init__(self, file: bytes, filename: str):
"""
Parameters:
- file: File content as bytes
- filename: Filename for the upload
"""
class URLInputFile(InputFile):
"""Input file from URL"""
def __init__(self, url: str, filename: str | None = None, chunk_size: int = 65536):
"""
Parameters:
- url: URL to download file from
- filename: Custom filename
- chunk_size: Size of chunks for downloading
"""
class InputMedia:
"""Base class for input media objects"""
type: str
media: str | InputFile
caption: str | None
parse_mode: str | None
caption_entities: list[MessageEntity] | None
class InputMediaPhoto(InputMedia):
"""Represents a photo to be sent"""
type: str = "photo"
has_spoiler: bool | None
class InputMediaVideo(InputMedia):
"""Represents a video to be sent"""
type: str = "video"
width: int | None
height: int | None
duration: int | None
supports_streaming: bool | None
has_spoiler: bool | None
thumbnail: str | InputFile | None
class InputMediaAnimation(InputMedia):
"""Represents an animation file (GIF or H.264/MPEG-4 AVC video without sound) to be sent"""
type: str = "animation"
width: int | None
height: int | None
duration: int | None
has_spoiler: bool | None
thumbnail: str | InputFile | None
class InputMediaAudio(InputMedia):
"""Represents an audio file to be sent"""
type: str = "audio"
duration: int | None
performer: str | None
title: str | None
thumbnail: str | InputFile | None
class InputMediaDocument(InputMedia):
"""Represents a general file to be sent"""
type: str = "document"
disable_content_type_detection: bool | None
thumbnail: str | InputFile | NoneObjects for creating inline and reply keyboards.
class InlineKeyboardMarkup(TelegramObject):
"""Represents an inline keyboard"""
inline_keyboard: list[list[InlineKeyboardButton]]
class InlineKeyboardButton(TelegramObject):
"""Represents one button of an inline keyboard"""
text: str
url: str | None
login_url: LoginUrl | None
callback_data: str | None
web_app: WebAppInfo | None
switch_inline_query: str | None
switch_inline_query_current_chat: str | None
callback_game: CallbackGame | None
pay: bool | None
class ReplyKeyboardMarkup(TelegramObject):
"""Represents a custom keyboard with reply options"""
keyboard: list[list[KeyboardButton]]
is_persistent: bool | None
resize_keyboard: bool | None
one_time_keyboard: bool | None
input_field_placeholder: str | None
selective: bool | None
class KeyboardButton(TelegramObject):
"""Represents one button of the reply keyboard"""
text: str
request_user: KeyboardButtonRequestUser | None
request_chat: KeyboardButtonRequestChat | None
request_contact: bool | None
request_location: bool | None
request_poll: KeyboardButtonPollType | None
web_app: WebAppInfo | None
class ReplyKeyboardRemove(TelegramObject):
"""Removes the current custom keyboard"""
remove_keyboard: bool = True
selective: bool | None
class ForceReply(TelegramObject):
"""Forces Telegram clients to display a reply interface"""
force_reply: bool = True
input_field_placeholder: str | None
selective: bool | NoneObjects for managing chat members, permissions, and administration.
class ChatMember(TelegramObject):
"""Base class for chat members"""
status: str
user: User
class ChatMemberOwner(ChatMember):
"""Represents a chat member that owns the chat"""
status: str = "creator"
is_anonymous: bool
custom_title: str | None
class ChatMemberAdministrator(ChatMember):
"""Represents a chat member that has administrator privileges"""
status: str = "administrator"
can_be_edited: bool
can_manage_chat: bool
can_delete_messages: bool
can_manage_video_chats: bool
can_restrict_members: bool
can_promote_members: bool
can_change_info: bool
can_invite_users: bool
can_post_messages: bool | None
can_edit_messages: bool | None
can_pin_messages: bool | None
can_manage_topics: bool | None
is_anonymous: bool
custom_title: str | None
class ChatMemberMember(ChatMember):
"""Represents a chat member that has no additional privileges"""
status: str = "member"
class ChatMemberRestricted(ChatMember):
"""Represents a chat member that is under certain restrictions"""
status: str = "restricted"
is_member: bool
can_send_messages: bool
can_send_audios: bool
can_send_documents: bool
can_send_photos: bool
can_send_videos: bool
can_send_video_notes: bool
can_send_voice_notes: bool
can_send_polls: bool
can_send_other_messages: bool
can_add_web_page_previews: bool
can_change_info: bool
can_invite_users: bool
can_pin_messages: bool
can_manage_topics: bool
until_date: datetime.datetime
class ChatMemberLeft(ChatMember):
"""Represents a chat member that isn't currently a member of the chat"""
status: str = "left"
class ChatMemberBanned(ChatMember):
"""Represents a chat member that was banned in the chat"""
status: str = "kicked"
until_date: datetime.datetime
class ChatPermissions(TelegramObject):
"""Describes actions that a non-administrator user is allowed to take in a chat"""
can_send_messages: bool | None
can_send_audios: bool | None
can_send_documents: bool | None
can_send_photos: bool | None
can_send_videos: bool | None
can_send_video_notes: bool | None
can_send_voice_notes: bool | None
can_send_polls: bool | None
can_send_other_messages: bool | None
can_add_web_page_previews: bool | None
can_change_info: bool | None
can_invite_users: bool | None
can_pin_messages: bool | None
can_manage_topics: bool | None
class ChatAdministratorRights(TelegramObject):
"""Represents the rights of an administrator in a chat"""
is_anonymous: bool
can_manage_chat: bool
can_delete_messages: bool
can_manage_video_chats: bool
can_restrict_members: bool
can_promote_members: bool
can_change_info: bool
can_invite_users: bool
can_post_messages: bool | None
can_edit_messages: bool | None
can_pin_messages: bool | None
can_manage_topics: bool | NoneObjects for handling inline queries and results.
class InlineQuery(TelegramObject):
"""Represents an incoming inline query"""
id: str
from_user: User
query: str
offset: str
chat_type: str | None
location: Location | None
class CallbackQuery(TelegramObject):
"""Represents an incoming callback query from an inline keyboard button"""
id: str
from_user: User
message: Message | None
inline_message_id: str | None
chat_instance: str
data: str | None
game_short_name: str | None
async def answer(self, text: str | None = None, show_alert: bool = False, **kwargs) -> bool:
"""Answer the callback query"""
class InlineQueryResult(TelegramObject):
"""Base class for inline query results"""
type: str
id: str
class InlineQueryResultArticle(InlineQueryResult):
"""Represents a link to an article or web page"""
type: str = "article"
title: str
input_message_content: InputMessageContent
reply_markup: InlineKeyboardMarkup | None
url: str | None
hide_url: bool | None
description: str | None
thumbnail_url: str | None
thumbnail_width: int | None
thumbnail_height: int | None
class InlineQueryResultPhoto(InlineQueryResult):
"""Represents a link to a photo"""
type: str = "photo"
photo_url: str
thumbnail_url: str
photo_width: int | None
photo_height: int | None
title: str | None
description: str | None
caption: str | None
parse_mode: str | None
caption_entities: list[MessageEntity] | None
reply_markup: InlineKeyboardMarkup | None
input_message_content: InputMessageContent | NoneObjects for handling payments and invoices.
class Invoice(TelegramObject):
"""Contains basic information about an invoice"""
title: str
description: str
start_parameter: str
currency: str
total_amount: int
class LabeledPrice(TelegramObject):
"""Represents a portion of the price for goods or services"""
label: str
amount: int
class ShippingAddress(TelegramObject):
"""Represents a shipping address"""
country_code: str
state: str
city: str
street_line1: str
street_line2: str
post_code: str
class OrderInfo(TelegramObject):
"""Represents information about an order"""
name: str | None
phone_number: str | None
email: str | None
shipping_address: ShippingAddress | None
class ShippingOption(TelegramObject):
"""Represents one shipping option"""
id: str
title: str
prices: list[LabeledPrice]
class SuccessfulPayment(TelegramObject):
"""Contains basic information about a successful payment"""
currency: str
total_amount: int
invoice_payload: str
shipping_option_id: str | None
order_info: OrderInfo | None
telegram_payment_charge_id: str
provider_payment_charge_id: str
class ShippingQuery(TelegramObject):
"""Contains information about an incoming shipping query"""
id: str
from_user: User
invoice_payload: str
shipping_address: ShippingAddress
class PreCheckoutQuery(TelegramObject):
"""Contains information about an incoming pre-checkout query"""
id: str
from_user: User
currency: str
total_amount: int
invoice_payload: str
shipping_option_id: str | None
order_info: OrderInfo | NoneBusiness account integration types for connecting with Telegram Business accounts.
class BusinessConnection(TelegramObject):
"""Describes the connection of the bot with a business account"""
id: str
user: User
user_chat_id: int
date: datetime.datetime
is_enabled: bool
can_reply: bool
class BusinessMessagesDeleted(TelegramObject):
"""Messages were deleted from a connected business account"""
business_connection_id: str
chat: Chat
message_ids: list[int]
class MessageReactionUpdated(TelegramObject):
"""Change of a reaction on a message performed by a user"""
chat: Chat
message_id: int
date: datetime.datetime
old_reaction: list[ReactionType]
new_reaction: list[ReactionType]
user: User | None
actor_chat: Chat | None
class MessageReactionCountUpdated(TelegramObject):
"""Reactions to a message with anonymous reactions were changed"""
chat: Chat
message_id: int
date: datetime.datetime
reactions: list[ReactionCount]Chat boost related types for managing channel and group boosts.
class ChatBoostUpdated(TelegramObject):
"""A chat boost was added or changed"""
chat: Chat
boost: ChatBoost
class ChatBoostRemoved(TelegramObject):
"""A boost was removed from a chat"""
chat: Chat
boost_id: str
remove_date: datetime.datetime
source: ChatBoostSource
class ChatBoost(TelegramObject):
"""Contains information about a chat boost"""
boost_id: str
add_date: datetime.datetime
expiration_date: datetime.datetime
source: ChatBoostSource
class PaidMediaPurchased(TelegramObject):
"""A user purchased paid media with a non-empty payload"""
from_user: User
payload: strEnhanced message options for link previews and reply parameters.
class LinkPreviewOptions(TelegramObject):
"""Options used for link preview generation"""
is_disabled: bool | None = None
url: str | None = None
prefer_small_media: bool | None = None
prefer_large_media: bool | None = None
show_above_text: bool | None = None
class ReplyParameters(TelegramObject):
"""Describes reply parameters for the message being sent"""
message_id: int
chat_id: int | str | None = None
allow_sending_without_reply: bool | None = None
quote: str | None = None
quote_parse_mode: str | None = None
quote_entities: list[MessageEntity] | None = None
quote_position: int | None = None
class SuggestedPostParameters(TelegramObject):
"""Parameters of a suggested post to send"""
text: str | None = None
parse_mode: str | None = None
entities: list[MessageEntity] | None = None
media: list[InputMedia] | None = None
show_caption_above_media: bool | None = Nonefrom aiogram.types import Message, MessageEntity
async def handle_message(message: Message):
# Access message properties
print(f"Message ID: {message.message_id}")
print(f"From: {message.from_user.first_name if message.from_user else 'Unknown'}")
print(f"Text: {message.text}")
# Check message type
if message.photo:
print("Message contains a photo")
elif message.document:
print(f"Message contains document: {message.document.file_name}")
# Work with entities
if message.entities:
for entity in message.entities:
if entity.type == "url":
url = message.text[entity.offset:entity.offset + entity.length]
print(f"Found URL: {url}")
# Reply to message
await message.answer("Got your message!")from aiogram.types import FSInputFile, BufferedInputFile, InputMediaPhoto
# Upload from filesystem
photo = FSInputFile("path/to/photo.jpg")
await bot.send_photo(chat_id, photo)
# Upload from memory
with open("image.png", "rb") as f:
photo_bytes = f.read()
photo = BufferedInputFile(photo_bytes, filename="image.png")
await bot.send_photo(chat_id, photo)
# Media group with mixed input types
media_group = [
InputMediaPhoto(media=FSInputFile("photo1.jpg"), caption="Photo 1"),
InputMediaPhoto(media=BufferedInputFile(photo_bytes, "photo2.png"), caption="Photo 2")
]
await bot.send_media_group(chat_id, media_group)from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton, ReplyKeyboardMarkup, KeyboardButton
# Inline keyboard
inline_kb = InlineKeyboardMarkup(inline_keyboard=[
[InlineKeyboardButton(text="Button 1", callback_data="btn1")],
[InlineKeyboardButton(text="Button 2", callback_data="btn2"),
InlineKeyboardButton(text="Button 3", callback_data="btn3")]
])
# Reply keyboard
reply_kb = ReplyKeyboardMarkup(
keyboard=[
[KeyboardButton(text="Contact", request_contact=True)],
[KeyboardButton(text="Location", request_location=True)],
[KeyboardButton(text="Poll", request_poll=KeyboardButtonPollType())]
],
resize_keyboard=True,
one_time_keyboard=True
)
await message.answer("Choose an option:", reply_markup=inline_kb)Install with Tessl CLI
npx tessl i tessl/pypi-aiogram