Skip to main content

Crate ferogram

Crate ferogram 

Source
Expand description

A native, elegant MTProto framework for Rust.

ferogram talks to Telegram directly over MTProto, no Bot API proxy, and handles auth for both bots and user accounts from the same client builder. You get a dispatcher with composable filters, FSM for multi-step conversations, CDN downloads, middleware, MTProxy support, and a raw client.invoke() escape hatch for anything not wrapped yet.

Still in development but already covers major use cases for production. Check the CHANGELOG before upgrading.

§Quick start: bot

use ferogram::{Client, update::Update};

const API_ID: i32 = 0; // from https://my.telegram.org
const API_HASH: &str = ""; // from https://my.telegram.org

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let (client, _) = Client::quick_connect("bot.session", API_ID, API_HASH).await?;

    let mut stream = client.stream_updates();
    while let Some(upd) = stream.next().await {
        if let Update::NewMessage(msg) = upd {
            if !msg.outgoing() {
                msg.reply(msg.text().unwrap_or_default()).await.ok();
            }
        }
    }
    Ok(())
}

§Quick start: user account

use ferogram::Client;

const API_ID: i32 = 0; // from https://my.telegram.org
const API_HASH: &str = ""; // from https://my.telegram.org

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let (client, _) = Client::quick_connect("my.session", API_ID, API_HASH).await?;

    client.send_message("me", "Hello from ferogram!").await?;
    Ok(())
}

§Dispatcher and filters

use ferogram::filters::{Dispatcher, command, private, text_contains};

let mut dp = Dispatcher::new();

dp.on_message(command("start"), |msg| async move {
    msg.reply("Hello!").await.ok();
});

dp.on_message(private() & text_contains("help"), |msg| async move {
    msg.reply("Type /start to begin.").await.ok();
});

while let Some(upd) = stream.next().await {
    dp.dispatch(upd).await;
}

Filters compose with &, |, !. Built-ins: command, private, group, channel, text, media, photo, forwarded, reply, album, regex, and more.

§FSM

use std::sync::Arc;

#[derive(FsmState, Clone, Debug, PartialEq)]
enum Form { Name, Age }

dp.with_state_storage(Arc::new(MemoryStorage::new()));

dp.on_message_fsm(text(), Form::Name, |msg, state| async move {
    state.set_data("name", msg.text().unwrap()).await.ok();
    state.transition(Form::Age).await.ok();
    msg.reply("How old are you?").await.ok();
});

§Raw API

If something isn’t wrapped yet, you can call any TL function directly (the current layer is exposed as tl::LAYER):

use ferogram::tl;

let req = tl::functions::messages::SendMessage {
    peer: peer.into(),
    message: "Hello!".into(),
    random_id: ferogram::random_i64_pub(),
    ..Default::default()
};
client.invoke(&req).await?;

§Session backends

Binary file by default. Switch to SQLite, libSQL, or a base64 string with a feature flag. Bring your own backend by implementing SessionBackend.

// Portable string session, useful for serverless or env-var setups
let s = client.export_session_string().await?;
let (client, _) = Client::builder().session_string(s).connect().await?;

// SQLite (feature: sqlite-session)
Client::builder().session_backend(Arc::new(SqliteBackend::open("s.db")?));

// libSQL, local file or in-memory (feature: libsql-session)
Client::builder().session_backend(Arc::new(LibSqlBackend::open_local("s.db")?));

// Remote Turso, or a local file kept synced with one (feature: libsql-remote-session)
Client::builder().session_backend(Arc::new(LibSqlBackend::open_remote(url, token)?));
Client::builder().session_backend(Arc::new(LibSqlBackend::open_replica("s.db", url, token)?));

§Cargo feature flags

Everything below is off by default; the default build is just login, raw RPC (client.invoke()), and updates.

FeatureAddsPulls in
derive#[derive(FsmState)] and other proc-macrosferogram-derive
sqlite-sessionSQLite-backed session storagerusqlite (bundled sqlite3, native build)
libsql-sessionlibSQL-backed session storage (local/embedded replica)libsql
libsql-remote-sessionRemote libSQL/Turso session storage with replicationlibsql-session + replication
serdeSerialize/Deserialize on session typesferogram-session/serde
fsmFSM dispatcher helper (dp.on_message_fsm)ferogram-fsm
parsers / htmlHTML/Markdown message parsing for rich textferogram-parsers
html5everStricter, spec-compliant HTML parsinghtml5ever
experimentalExperimental transfer APIs (resumable transfers)mp4
resilient-connectDNS-over-HTTPS + Firebase/Google config fallback for censored networksreqwest (transitively rustls/aws-lc-rs)
socks5SOCKS5 proxy support for outgoing connectionstokio-socks
metricsRPC/connection counters, histograms, gaugesmetrics
parserRe-export the TL parser for custom toolingferogram-tl-parser
codegenRe-export the TL code generator for custom toolingferogram-tl-gen
# Minimal: login, raw RPC, updates only
ferogram = { version = "0.6", default-features = false }

# A typical bot: rich text + FSM + SQLite sessions
ferogram = { version = "0.6", features = ["parsers", "fsm", "sqlite-session"] }

Note: sqlite-session and libsql-session/libsql-remote-session are mutually exclusive, both bundle a sqlite3 C source, and enabling both at once fails at link time with duplicate-symbol errors. Pick one.

§What’s covered

  • Rich Messaging: text, media, albums, polls, dice, games, reactions, scheduled messages
  • HTML & Markdown: full parse and generate support for both formats
  • Inline & Reply Keyboards: buttons, callbacks, inline mode
  • CDN: transparent CDN download handling, no extra calls needed
  • Proxy Support: SOCKS5 with optional auth
  • MTProxy: Classic, DD, and FakeTLS transports, via link or manual config
  • Transport Probing: races transports, connects via whichever is fastest
  • Concurrent Transfers: parallel uploads/downloads with pause, resume, cancel, and progress tracking
  • Resumable Transfers: checkpointed uploads/downloads that survive crashes
  • Session Backends: file, in-memory, string, SQLite, LibSQL
  • Router & Dispatcher: composable filters (&, |, !) for expressive handlers
  • FSM: type-safe finite state machine for multi-step conversations
  • Middleware: rate limiting, tracing, panic recovery
  • TgCalls: group calls, P2P calls, conference calls, screen share/presentation, audio and video
  • Raw API: full TL coverage via client.invoke()
  • Python Bindings: native performance with a clean Python API

…and more features like this throughout the codebase!

Full list in FEATURES.md. Group calls, P2P calls, and screen share are handled separately by the tgcalls crate, built on top of ferogram and the official ntgcalls bindings.

If something’s missing, feel free to open a feature request or PR. Check the contributing guidelines first.

§Community

Re-exports§

pub use media::DownloadIter;
pub use builder::BuilderError;
pub use builder::ClientBuilder;
pub use file_info::FileInfo;
pub use file_info::detect_mime;
pub use file_info::file_info;
pub use file_info::file_info_from_path;
pub use guest_chat::GuestChatQuery;
pub use keyboard::Button;
pub use keyboard::InlineKeyboard;
pub use keyboard::ReplyKeyboard;
pub use media::Document;
pub use media::DocumentThumb;
pub use media::Downloadable;
pub use media::MediaQuality;
pub use media::Photo;
pub use media::PhotoThumb;
pub use media::ProfilePhoto;
pub use media::RawLocation;
pub use media::Sticker;
pub use media::UploadedFile;
pub use media::VideoQualityInfo;
pub use media::video_cover;
pub use participants::Participant;
pub use participants::ParticipantStatus;
pub use participants::ProfilePhotoIter;
pub use peer_ext::OptionPeerExt;
pub use peer_ext::PeerExt;
pub use peer_ref::InviteHash;
pub use peer_ref::PeerRef;
pub use poll::PollBuilder;
pub use search::GlobalSearchBuilder;
pub use search::SearchBuilder;
pub use transfer::TransferError;
pub use transfer::TransferHandle;
pub use transfer::TransferProgress;
pub use transfer_limits::TransferLimits;
pub use types::Channel;
pub use types::ChannelKind;
pub use types::Chat;
pub use types::Community;
pub use types::Group;
pub use types::MessagePage;
pub use types::User;
pub use types::UserFull;
pub use typing_guard::TypingGuard;
pub use update::BotStoppedUpdate;
pub use update::MessageReactionUpdate;
pub use update::PollVoteUpdate;
pub use update::ButtonFilter;
pub use update::Update;
pub use update::ChatActionUpdate;
pub use update::JoinRequestUpdate;
pub use update::ParticipantUpdate;
pub use update::UserStatusUpdate;
pub use update::ChatBoostUpdate;
pub use update::PreCheckoutQueryUpdate;
pub use update::ShippingQueryUpdate;
pub use update_config::OverflowStrategy;
pub use update_config::UpdateConfig;
pub use ferogram_msgbox as message_box;
pub use ferogram_tl_types as tl;
pub use ferogram_mtproto as mtproto;
pub use ferogram_crypto as crypto;
pub use ferogram_tl_parser as parser;parser
pub use ferogram_tl_gen as codegen;codegen

Modules§

authentication
MTProto authentication key generation (DH handshake steps).
builder
cdn_download
Telegram CDN DC file downloads.
conversation
dc_migration
dc_pool
file_info
File type detection and metadata extraction.
filters
fsmfsm
guest_chat
inline_iter
keyboard
macros
media
middleware
parsersparsers
participants
peer_ext
peer_ref
persist
poll
proxy
reactions
search
session_backend
socks5
string_session
Portable string-session encoding/decoding (V1/V2 binary base64 format).
transfer
Transfer progress tracking, pause/resume/cancel controls, and typed transfer errors.
transfer_limits
User-tunable transfer concurrency: how hard Ferogram is allowed to push when uploading or downloading a file.
types
typing_guard
update
update_config
Configuration for user-facing update buffering.
util

Macros§

dispatch

Structs§

AuthKey
A Telegram authorization key (256 bytes) plus pre-computed identifiers.
AutoSleep
Automatically sleep on FLOOD_WAIT and retry once on transient I/O errors.
BinaryFileBackend
Stores the session in a compact binary file (v2 format).
CircuitBreaker
A RetryPolicy that stops retrying after threshold consecutive failures and stays silent for a cooldown window before resetting.
Client
The main Telegram client. Cheap to clone: internally Arc-wrapped.
Config
Configuration for Client::connect.
CopyOptions
Options for copying messages (forward without the “Forwarded from” attribution).
DcEntry
One entry in the DC address table.
DcFlags
Per-DC option flags.
Dialog
A Telegram dialog (chat, user, channel).
DialogCursor
Serializable snapshot of a DialogIter’s position, for resuming pagination across app restarts (e.g. a chat list the user scrolled partway through, backgrounded, and reopened later).
DialogFilterCursor
Serializable snapshot of a DialogFilterIter’s position. Get one via DialogFilterIter::cursor, resume with Client::iter_dialogs_in_filter_from.
DialogFilterIter
Cursor-based iterator over dialogs in one chat folder (DialogFilter). Created by Client::iter_dialogs_in_filter.
DialogIter
Cursor-based iterator over dialogs. Created by Client::iter_dialogs.
DialogsStream
A boxed, nameable futures::Stream over dialogs, giving access to StreamExt/TryStreamExt combinators (.map(), .take(), .try_for_each(), etc.). Created by Client::stream_dialogs.
ExperimentalFeatures
Opt-in experimental behaviours that deviate from strict Telegram spec.
ExponentialBackoff
Exponential backoff with jitter.
Finished
The final output of a successful auth key handshake.
FixedInterval
FlattenedDialogFilter
Flattened, cheap-to-query form of a tl::enums::DialogFilter.
ForwardOptions
Options for forwarding messages.
FullTransport
MTProto Full transport framing.
GetDialogsOptions
Options for crate::Client::get_dialogs. Also used by DialogIter for exclude_pinned/folder_id (via its own builder methods - limit isn’t meaningful there, DialogIter always pages at its own fixed size).
InMemoryBackend
Ephemeral in-process session: nothing persisted to disk.
InputMessage
Builder for composing outgoing messages.
IntermediateTransport
MTProto Intermediate transport framing.
InvoiceOptions
Groups all invoice parameters for crate::Client::send_invoice.
LoginToken
Token returned by crate::Client::request_login_code.
MessageIter
Cursor-based iterator over message history. Created by Client::iter_messages.
MiniAppSession
An active mini-app session returned by Client::open_mini_app.
MtProxyConfig
Decoded MTProxy configuration.
NeverRestart
NoRetries
Never retry: propagate every error immediately.
ObfuscatedStream
PaddedIntermediateTransport
MTProto Padded Intermediate transport framing.
PasswordToken
2FA challenge token returned in SignInError::PasswordRequired.
PeerCache
All fields are pub so that save_session / connect can read/write them directly, and so that advanced callers can inspect the cache.
PeerCacheStats
Caches access hashes for users and channels so every API call carries the correct hash without re-resolving peers. A snapshot of what PeerCache currently holds.
RaceLeg
One leg of a transport race: transport plus its start delay.
RetryContext
Context passed to RetryPolicy::should_retry on each failure.
RpcError
An error returned by Telegram’s servers in response to an RPC call.
SendCodeOptions
Settings forwarded to Telegram’s auth.sendCode code_settings field.
SetProfileBuilder
Builder returned by Client::set_profile.
Socks5Config
SOCKS5 proxy configuration.
SqliteBackendsqlite-session
SQLite-backed session (via rusqlite).
StringSessionBackend
Portable base64 string session backend.
UpdateStream
Asynchronous stream of crate::Updates.

Enums§

ChannelStats
Return type of Client::stats.
ErrorKind
InvocationError
The error type returned from any Client method that talks to Telegram.
LinkKind
Selects which flavour of message link crate::Client::export_message_link should produce.
MiniApp
Which kind of mini-app to open.
ObfuscatedFraming
Framing mode for ObfuscatedStream.
PeerType
Discriminates the kind of peer stored in PeerCache::username_to_peer.
QuickConnectError
Errors returned by Client::quick_connect.
SendCodeOutcome
Result of crate::Client::request_login_code.
SignInError
Errors returned by crate::Client::sign_in.
TransportKind
Which MTProto wire framing to use for a connection.
UpdateStateChange
A single update-sequence change, applied via SessionBackend::apply_update_state.

Constants§

LAYER
The API layer this code was generated from.

Traits§

ConnectionRestartPolicy
FsmStatefsm
A type that can be used as an FSM state.
Identifiable
Every generated type has a unique 32-bit constructor ID.
InvocationErrorExt
Extension trait adding .kind() and .friendly() to InvocationError.
RetryPolicy
Controls how the client reacts when an RPC call fails.
Serializable
SessionBackend
Synchronous snapshot backend: saves and loads the full session at once.

Functions§

default_transport_race
Full vs Obfuscated. Abridged/Intermediate aren’t included since they share Full’s TCP path and framing fingerprint, so they live or die with it against DPI - racing them adds load with no extra chance of success.
finish
Finalise the handshake.
random_i64_pub
Generate a random i64. Used for random_id fields in RPC requests, where Telegram only needs uniqueness, not cryptographic strength.
step1
Generate a req_pq_multi request. Returns the request + opaque state.
step2
Process ResPQ and generate req_DH_params.
step3
Process ServerDhParams into a reusable DhParamsForRetry + send the first set_client_DH_params request.

Type Aliases§

ShutdownToken
A token that can be used to gracefully shut down a Client.