sent
An async MTProto client library for Telegram — speaks the raw protocol, supports both user accounts and bots, and exposes an event-driven Python API.
The Bot API is a comfortable abstraction until you need something it doesn’t expose. Then you’re at MTProto — Telegram’s actual wire protocol, with its own crypto handshake, session model, and RPC layer. sent implements that from the bottom up and puts an ergonomic async API on top, for user accounts as well as bots.
What it does
- Async MTProto 2.0 — encryption, session handling, and RPC with
RpcResult/MsgContainerunpacking - Every login path — phone + code, SRP-based 2FA, bot token, and QR login
- Event system —
NewMessage,MessageDeleted,MessageRead,CallbackQuery,ChatAction,UserUpdate, andAlbum - A friendly surface —
send_message,send_file,get_dialogs,iter_messages, and aconversation()helper for prompt-and-await flows - TL layer 225, auto-generated from the current Telegram schema
- Pluggable sessions — SQLite with an entity cache,
StringSession, or in-memory - Transports — TCP abridged, intermediate, and full, with SOCKS5 proxy support
client = TelegramClient("echo_bot", API_ID, API_HASH)
@client.on(events.NewMessage)
async def handler(event):
await event.reply(event.text)
await client.start(bot_token=BOT_TOKEN)
await client.run_until_disconnected()
How it works
The protocol work is the project. Telegram’s schema is defined in TL, so the type layer is code-generated from the current schema rather than hand-maintained — layer bumps become a regeneration instead of a rewrite. Above that sits the transport (three TCP framings, optionally over SOCKS5), then the crypto and session layer, then RPC, and only then the part users touch.
Sessions are where a client like this earns or loses its reputation. Auth keys and cached entities persist to SQLite so a restart doesn’t mean a fresh login, and StringSession exists for environments with no writable disk — the deploy target most libraries forget. Crypto has optional native backends: sent[fast] pulls in cryptg, with pycryptodome as a fallback, and pure Python when neither is available.
Notes
Writing a protocol client teaches you how much a documented API hides. Message containers, sequence numbering, and salt rotation are all invisible from the Bot API side, and all mandatory here. It ships on PyPI as sent, with docs generated alongside the library.