Skip to content

tgapis/ferogram

 
 

ferogram

Async Rust library for the Telegram MTProto protocol. Developed by Ankit Chaubey.

Crates.io docs.rs License TL Layer Telegram Chat Telegram Channel

Note

Pre-production: APIs may change between minor versions. See CHANGELOG before upgrading.


Crates

Most users only need ferogram.

Crate Description
ferogram High-level async client: auth, messaging, media, bots
ferogram-session Session persistence types and storage backends
ferogram-parsers Telegram Markdown and HTML entity parsers
ferogram-tl-types Layer types, functions, enums (definitions)
ferogram-mtproto MTProto session, DH exchange, framing, transports
ferogram-crypto AES-IGE, RSA, SHA, Diffie-Hellman, auth key derivation
ferogram-tl-gen Build-time code generator from the TL AST
ferogram-tl-parser Parses .tl schema into an AST

Installation

[dependencies]
ferogram = "0.3.0"
tokio        = { version = "1", features = ["full"] }

Get your api_id and api_hash from my.telegram.org.

Optional features:

ferogram = { version = "0.3.0", features = ["sqlite-session"] }  # SQLite session
ferogram = { version = "0.3.0", features = ["libsql-session"] }  # libsql / Turso
ferogram = { version = "0.3.0", features = ["html"] }            # HTML parser
ferogram = { version = "0.3.0", features = ["html5ever"] }       # html5ever parser

ferogram re-exports ferogram_tl_types as ferogram::tl.


Quick Start Bot

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

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let (client, _shutdown) = Client::builder()
        .api_id(std::env::var("API_ID")?.parse()?)
        .api_hash(std::env::var("API_HASH")?)
        .session("bot.session")
        .connect()
        .await?;

    client.bot_sign_in(&std::env::var("BOT_TOKEN")?).await?;
    client.save_session().await?;

    let mut stream = client.stream_updates();
    while let Some(upd) = stream.next().await {
        if let Update::NewMessage(msg) = upd {
            if !msg.outgoing() {
                if let Some(peer) = msg.peer_id() {
                    client.send_message_to_peer(peer.clone(), msg.text().unwrap_or("")).await?;
                }
            }
        }
    }
    Ok(())
}

Quick Start User

use ferogram::{Client, SignInError};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let (client, _shutdown) = Client::builder()
        .api_id(12345)
        .api_hash("your_api_hash")
        .session("my.session")
        .connect()
        .await?;

    if !client.is_authorized().await? {
        let token = client.request_login_code("+1234567890").await?;
        let code  = read_line();

        match client.sign_in(&token, &code).await {
            Ok(name) => println!("Welcome, {name}!"),
            Err(SignInError::PasswordRequired(t)) => {
                client.check_password(*t, "my_2fa_password").await?;
            }
            Err(e) => return Err(e.into()),
        }
        client.save_session().await?;
    }

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

Session Backends

Backend Flag Notes
BinaryFileBackend default Single-process bots, scripts
InMemoryBackend default Tests, ephemeral tasks
StringSessionBackend default Serverless, env-var storage
SqliteBackend sqlite-session Multi-session local apps
LibSqlBackend libsql-session Turso / distributed storage
Custom - Implement SessionBackend
let s = client.export_session_string().await?;
let (client, _) = Client::builder().session_string(s).connect().await?;

Raw API

Every Telegram API method is accessible via client.invoke():

use ferogram::tl;

let req = tl::functions::bots::SetBotCommands {
    scope: tl::enums::BotCommandScope::Default(tl::types::BotCommandScopeDefault {}),
    lang_code: "en".into(),
    commands: vec![
        tl::enums::BotCommand::BotCommand(tl::types::BotCommand {
            command:     "start".into(),
            description: "Start the bot".into(),
        }),
    ],
};
client.invoke(&req).await?;

// Target a specific DC
client.invoke_on_dc(2, &req).await?;

Tests

cargo test --workspace
cargo test --workspace --all-features

Integration tests in ferogram/tests/integration.rs use InMemoryBackend and don't need real credentials.


Community


Contributing

Read CONTRIBUTING.md before opening a PR. Run cargo test --workspace and cargo clippy --workspace locally. Security issues: see SECURITY.md.


Author

Developed by Ankit Chaubey out of curiosity to explore.

ferogram is developed as part of exploration, learning, and experimentation with the Telegram MTProto protocol. Use it at your own risk. Its future and stability are not yet guaranteed.


Thanks

Thanks to Lonami and the grammers project for early learning and inspiration in understanding MTProto structure.

Thanks to Telegram Desktop and TDLib for serving as references when implementing MTProto behavior.


License

Licensed under either of, at your option:

Unless you explicitly state otherwise, any contribution submitted for inclusion shall be dual-licensed as above, without any additional terms or conditions.


Telegram Terms of Service

Ensure your usage complies with Telegram's Terms of Service and API Terms of Service. Misuse of the Telegram API, including spam, mass scraping, or automation of normal user accounts, may result in account limitations or permanent bans.

About

Async Rust implementation of the Telegram MTProto protocol for building Telegram clients.

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages

  • Rust 100.0%