Skip to content

ankit-chaubey/ferogram

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

71 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

ferogram

Async Rust library for Telegram's MTProto protocol.

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

Built by Ankit Chaubey

I built ferogram because I kept hitting walls with other MTProto libraries. Things that should have been straightforward weren't, and I kept needing the library to behave slightly differently than it would let me. So I wrote my own.

It talks to Telegram directly over MTProto, no Bot API proxy in between. It works for both bots and user accounts from the same API and the same client builder.

The major use cases are covered: messaging, media, inline keyboards, CDN downloads, FSM for multi-step conversations, FakeTLS and MTProxy for censored networks, and a raw invoke() escape hatch for anything the high-level API doesn't wrap yet.


If you want the Bot API instead, take a look at ferobot.

The longer-term goal is to support multiple languages from the same Rust core. Python is already live as ferogram-py on PyPI, pre-built wheels, no Rust toolchain needed.

Note

ferogram is still in active development. It covers major use cases and runs in production, but the API may still shift. Check CHANGELOG before upgrading.


Getting started

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

Get api_id and api_hash from my.telegram.org. For optional feature flags (SQLite session, HTML parser, FSM derive macro) see the ferogram crate README.


Development on GitHub moves faster than crates.io. Releases are pushed to crates.io when there's a patch or a proper release, so there may be fixes and features on main that aren't published yet. If you need something from main, you can point directly to a specific commit:

ferogram = { git = "https://github.com/ankit-chaubey/ferogram", rev = "COMMIT_SHA" }

Otherwise, stable from crates.io is the safe default.


Quick start: bot

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

const API_ID: i32 = 0;
const API_HASH: &str = "";

#[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;
const API_HASH: &str = "";

#[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(())
}

Core features

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 cover command, private, group, channel, text, media, forwarded, reply, album, custom, and more.

FSM

use ferogram::{FsmState, fsm::MemoryStorage};
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();
});

Storage is swappable. Implement StateStorage to use Redis, a database, or anything else.

Raw API

When the high-level API doesn't cover something, client.invoke() takes any TL function directly:

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?;
client.invoke_on_dc(2, &req).await?;

Session backends

By default the session is a binary file on disk. Switch to SQLite, LibSQL (Turso), or a base64 string for serverless setups. You can also bring your own by implementing SessionBackend.

let s = client.export_session_string().await?;
let (client, _) = Client::builder().session_string(s).connect().await?;

What's covered

See FEATURES.md for the full list with method signatures. Runnable examples are in ferogram/examples/.

If something is missing, open a feature request or drop by t.me/FerogramChat. If the high-level API isn't enough, the raw API is always there.


Secret chats (end-to-end encrypted) are fully implemented but not published to crates.io yet. The plan is to release once there is enough community demand for it.

Voice and video calls : group audio is fully implemented, stable, and already in production use. Group video is implemented with some codec edge cases still being ironed out. P2P is partially implemented and in active development. All of this will be published as separate crates when it comes out of the workspace.


Testing

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

Community and links

Contributing

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

Acknowledgments

Big shoutout to Lonami for grammers. It was one of the most helpful references while building ferogram, and grammers and Telethon are two of my all-time favorites. Love those projects.

Protocol behavior references from Telegram Desktop and TDLib.

License

MIT OR Apache-2.0. See LICENSE-MIT and LICENSE-APACHE.

Usage must comply with Telegram's API Terms of Service.

About

⚡ High-performance Telegram MTProto framework written in Rust for building powerful Telegram clients, apps, and bots.

Topics

Resources

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages