{"id":13478507,"url":"https://github.com/teloxide/teloxide","last_synced_at":"2025-05-14T21:02:03.224Z","repository":{"id":37029498,"uuid":"205705227","full_name":"teloxide/teloxide","owner":"teloxide","description":"🤖 An elegant Telegram bots framework for Rust","archived":false,"fork":false,"pushed_at":"2025-05-05T08:57:02.000Z","size":12187,"stargazers_count":3571,"open_issues_count":63,"forks_count":258,"subscribers_count":32,"default_branch":"master","last_synced_at":"2025-05-07T20:28:52.978Z","etag":null,"topics":["rust","telegram","telegram-bot-api","telegram-bot-framework","teloxide"],"latest_commit_sha":null,"homepage":"https://docs.rs/teloxide/latest/teloxide/","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/teloxide.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2019-09-01T16:46:32.000Z","updated_at":"2025-05-06T23:03:01.000Z","dependencies_parsed_at":"2024-02-02T12:39:22.317Z","dependency_job_id":"8fff67b2-c061-44c3-bdcc-c46f9cdb584f","html_url":"https://github.com/teloxide/teloxide","commit_stats":{"total_commits":3238,"total_committers":92,"mean_commits":35.19565217391305,"dds":0.5849289684990735,"last_synced_commit":"9876587d930e3bb3a6d99058bed2a07730bdbb67"},"previous_names":[],"tags_count":40,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/teloxide%2Fteloxide","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/teloxide%2Fteloxide/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/teloxide%2Fteloxide/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/teloxide%2Fteloxide/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/teloxide","download_url":"https://codeload.github.com/teloxide/teloxide/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253909365,"owners_count":21982689,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["rust","telegram","telegram-bot-api","telegram-bot-framework","teloxide"],"created_at":"2024-07-31T16:01:58.006Z","updated_at":"2025-05-14T21:02:03.125Z","avatar_url":"https://github.com/teloxide.png","language":"Rust","readme":"\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\"https://github.com/teloxide/teloxide/blob/master/media/teloxide-logo.png?raw=true\" width=\"250\"/\u003e\n  \u003ch1\u003e\u003ccode\u003eteloxide\u003c/code\u003e\u003c/h1\u003e\n  \u003ca href=\"https://docs.rs/teloxide/\"\u003e\n    \u003cimg src=\"https://docs.rs/teloxide/badge.svg\"\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://github.com/teloxide/teloxide/actions\"\u003e\n    \u003cimg src=\"https://github.com/teloxide/teloxide/workflows/Continuous%20integration/badge.svg\"\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://crates.io/crates/teloxide\"\u003e\n    \u003cimg src=\"https://img.shields.io/crates/v/teloxide.svg\"\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://core.telegram.org/bots/api\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/API%20coverage-Up%20to%207.5%20(inclusively)-green.svg\"\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://t.me/teloxide\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/support-t.me%2Fteloxide-blueviolet\"\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://devpod.sh/open#https://github.com/teloxide/teloxide\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/Open_in-DevPod-blueviolet\"\u003e\n  \u003c/a\u003e\n\n  A full-featured framework that empowers you to easily build [Telegram bots](https://telegram.org/blog/bot-revolution) using [Rust](https://www.rust-lang.org/). It handles all the difficult stuff so you can focus only on your business logic.\n\u003c/div\u003e\n\n## Highlights\n\n - **Declarative design.** `teloxide` is based upon [`dptree`], a functional [chain of responsibility] pattern that allows you to express pipelines of message processing in a highly declarative and extensible style.\n\n[`dptree`]: https://github.com/teloxide/dptree\n[chain of responsibility]: https://en.wikipedia.org/wiki/Chain-of-responsibility_pattern\n\n - **Feature-rich.** You can use both long polling and webhooks, configure an underlying HTTPS client, set a custom URL of a Telegram API server, do graceful shutdown, and much more.\n\n - **Simple dialogues.** Our dialogues subsystem is simple and easy-to-use, and, furthermore, is agnostic of how/where dialogues are stored. For example, you can just replace a one line to achieve [persistence]. Out-of-the-box storages include [Redis] and [Sqlite].\n\n[persistence]: https://en.wikipedia.org/wiki/Persistence_(computer_science)\n[Redis]: https://redis.io/\n[Sqlite]: https://www.sqlite.org\n\n - **Strongly typed commands.** Define bot commands as an `enum` and `teloxide` will parse them automatically — just like JSON structures in [`serde-json`] and command-line arguments in [`structopt`].\n\n[`structopt`]: https://github.com/TeXitoi/structopt\n[`serde-json`]: https://github.com/serde-rs/json\n\n## Setting up your environment\n\n 1. [Download Rust](http://rustup.rs/).\n 2. Create a new bot using [@Botfather](https://t.me/botfather) to get a token in the format `123456789:blablabla`.\n 3. Initialise the `TELOXIDE_TOKEN` environmental variable to your token:\n```bash\n# Unix-like\n$ export TELOXIDE_TOKEN=\u003cYour token here\u003e\n\n# Windows command line\n$ set TELOXIDE_TOKEN=\u003cYour token here\u003e\n\n# Windows PowerShell\n$ $env:TELOXIDE_TOKEN=\u003cYour token here\u003e\n```\n\n 4. Make sure that your Rust compiler is up to date (`teloxide` currently requires rustc at least version 1.80):\n```bash\n# If you're using stable\n$ rustup update stable\n$ rustup override set stable\n\n# If you're using nightly\n$ rustup update nightly\n$ rustup override set nightly\n```\n\n 5. Run `cargo new my_bot`, enter the directory and put these lines into your `Cargo.toml`:\n```toml\n[dependencies]\nteloxide = { version = \"0.15.0\", features = [\"macros\"] }\nlog = \"0.4\"\npretty_env_logger = \"0.5\"\ntokio = { version =  \"1.8\", features = [\"rt-multi-thread\", \"macros\"] }\n```\n\n_Note: if there is functionality in master that is not released yet, you can pull the Git repository as follows:_\n\n```toml\nteloxide = { git = \"https://github.com/teloxide/teloxide.git\", features = [\"macros\"] }\n```\n\n## API overview\n\n### The dices bot\n\nThis bot replies with a dice to each received message:\n\n[[`examples/throw_dice.rs`](crates/teloxide/examples/throw_dice.rs)]\n\n```rust,no_run\nuse teloxide::prelude::*;\n\n#[tokio::main]\nasync fn main() {\n    pretty_env_logger::init();\n    log::info!(\"Starting throw dice bot...\");\n\n    let bot = Bot::from_env();\n\n    teloxide::repl(bot, |bot: Bot, msg: Message| async move {\n        bot.send_dice(msg.chat.id).await?;\n        Ok(())\n    })\n    .await;\n}\n```\n\n\u003cdiv align=\"center\"\u003e\n    \u003cimg src=\"https://github.com/teloxide/teloxide/blob/master/media/throw-dice.gif?raw=true\" width=\"420\" /\u003e\n\u003c/div\u003e\n\n### Commands\n\nCommands are strongly typed and defined declaratively, similar to how we define CLI using [structopt] and JSON structures in [serde-json]. The following bot accepts these commands:\n\n - `/username \u003cyour username\u003e`\n - `/usernameandage \u003cyour username\u003e \u003cyour age\u003e`\n - `/help`\n\n[structopt]: https://docs.rs/structopt/0.3.9/structopt/\n[serde-json]: https://github.com/serde-rs/json\n\n[[`examples/command.rs`](crates/teloxide/examples/command.rs)]\n\n```rust,no_run\nuse teloxide::{prelude::*, utils::command::BotCommands};\n\n#[tokio::main]\nasync fn main() {\n    pretty_env_logger::init();\n    log::info!(\"Starting command bot...\");\n\n    let bot = Bot::from_env();\n\n    Command::repl(bot, answer).await;\n}\n\n#[derive(BotCommands, Clone)]\n#[command(rename_rule = \"lowercase\", description = \"These commands are supported:\")]\nenum Command {\n    #[command(description = \"display this text.\")]\n    Help,\n    #[command(description = \"handle a username.\")]\n    Username(String),\n    #[command(description = \"handle a username and an age.\", parse_with = \"split\")]\n    UsernameAndAge { username: String, age: u8 },\n}\n\nasync fn answer(bot: Bot, msg: Message, cmd: Command) -\u003e ResponseResult\u003c()\u003e {\n    match cmd {\n        Command::Help =\u003e bot.send_message(msg.chat.id, Command::descriptions().to_string()).await?,\n        Command::Username(username) =\u003e {\n            bot.send_message(msg.chat.id, format!(\"Your username is @{username}.\")).await?\n        }\n        Command::UsernameAndAge { username, age } =\u003e {\n            bot.send_message(msg.chat.id, format!(\"Your username is @{username} and age is {age}.\"))\n                .await?\n        }\n    };\n\n    Ok(())\n}\n```\n\n\u003cdiv align=\"center\"\u003e\n    \u003cimg src=\"https://github.com/teloxide/teloxide/blob/master/media/command.gif?raw=true\" width=\"420\" /\u003e\n\u003c/div\u003e\n\n### Dialogues management\n\nA dialogue is typically described by an enumeration where each variant is one possible state of the dialogue. There are also _state handler functions_, which may turn a dialogue from one state to another, thereby forming an [FSM].\n\n[FSM]: https://en.wikipedia.org/wiki/Finite-state_machine\n\nBelow is a bot that asks you three questions and then sends the answers back to you:\n\n[[`examples/dialogue.rs`](crates/teloxide/examples/dialogue.rs)]\n\n```rust,ignore\nuse teloxide::{dispatching::dialogue::InMemStorage, prelude::*};\n\ntype MyDialogue = Dialogue\u003cState, InMemStorage\u003cState\u003e\u003e;\ntype HandlerResult = Result\u003c(), Box\u003cdyn std::error::Error + Send + Sync\u003e\u003e;\n\n#[derive(Clone, Default)]\npub enum State {\n    #[default]\n    Start,\n    ReceiveFullName,\n    ReceiveAge {\n        full_name: String,\n    },\n    ReceiveLocation {\n        full_name: String,\n        age: u8,\n    },\n}\n\n#[tokio::main]\nasync fn main() {\n    pretty_env_logger::init();\n    log::info!(\"Starting dialogue bot...\");\n\n    let bot = Bot::from_env();\n\n    Dispatcher::builder(\n        bot,\n        Update::filter_message()\n            .enter_dialogue::\u003cMessage, InMemStorage\u003cState\u003e, State\u003e()\n            .branch(dptree::case![State::Start].endpoint(start))\n            .branch(dptree::case![State::ReceiveFullName].endpoint(receive_full_name))\n            .branch(dptree::case![State::ReceiveAge { full_name }].endpoint(receive_age))\n            .branch(\n                dptree::case![State::ReceiveLocation { full_name, age }].endpoint(receive_location),\n            ),\n    )\n    .dependencies(dptree::deps![InMemStorage::\u003cState\u003e::new()])\n    .enable_ctrlc_handler()\n    .build()\n    .dispatch()\n    .await;\n}\n\nasync fn start(bot: Bot, dialogue: MyDialogue, msg: Message) -\u003e HandlerResult {\n    bot.send_message(msg.chat.id, \"Let's start! What's your full name?\").await?;\n    dialogue.update(State::ReceiveFullName).await?;\n    Ok(())\n}\n\nasync fn receive_full_name(bot: Bot, dialogue: MyDialogue, msg: Message) -\u003e HandlerResult {\n    match msg.text() {\n        Some(text) =\u003e {\n            bot.send_message(msg.chat.id, \"How old are you?\").await?;\n            dialogue.update(State::ReceiveAge { full_name: text.into() }).await?;\n        }\n        None =\u003e {\n            bot.send_message(msg.chat.id, \"Send me plain text.\").await?;\n        }\n    }\n\n    Ok(())\n}\n\nasync fn receive_age(\n    bot: Bot,\n    dialogue: MyDialogue,\n    full_name: String, // Available from `State::ReceiveAge`.\n    msg: Message,\n) -\u003e HandlerResult {\n    match msg.text().map(|text| text.parse::\u003cu8\u003e()) {\n        Some(Ok(age)) =\u003e {\n            bot.send_message(msg.chat.id, \"What's your location?\").await?;\n            dialogue.update(State::ReceiveLocation { full_name, age }).await?;\n        }\n        _ =\u003e {\n            bot.send_message(msg.chat.id, \"Send me a number.\").await?;\n        }\n    }\n\n    Ok(())\n}\n\nasync fn receive_location(\n    bot: Bot,\n    dialogue: MyDialogue,\n    (full_name, age): (String, u8), // Available from `State::ReceiveLocation`.\n    msg: Message,\n) -\u003e HandlerResult {\n    match msg.text() {\n        Some(location) =\u003e {\n            let report = format!(\"Full name: {full_name}\\nAge: {age}\\nLocation: {location}\");\n            bot.send_message(msg.chat.id, report).await?;\n            dialogue.exit().await?;\n        }\n        None =\u003e {\n            bot.send_message(msg.chat.id, \"Send me plain text.\").await?;\n        }\n    }\n\n    Ok(())\n}\n```\n\n\u003cdiv align=\"center\"\u003e\n    \u003cimg src=\"https://github.com/teloxide/teloxide/blob/master/media/dialogue.gif?raw=true\" width=\"420\" /\u003e\n\u003c/div\u003e\n\n[More examples \u003e\u003e](crates/teloxide/examples/)\n\n## Testing\n\nThe community has made a crate called [`teloxide_tests`](https://github.com/LasterAlex/teloxide_tests) for testing `teloxide` bots.\n\n[See some testing examples \u003e\u003e](https://github.com/LasterAlex/teloxide_tests/tree/master/examples)\n\n## Tutorials\n\n - [_\"Migrating my family finance bot from Python to Rust (teloxide) because I am tired of exceptions (part 1)\"_](https://web.archive.org/web/20230130112018/https://trkohler.com/posts/i-migrated-my-family-finance-bot-from-python-to-rust-because-i-am-tired-of-exceptions/) by Troy Köhler.\n - [_\"Migrating my family finance bot from Python to Rust (teloxide) [part 2]\"_](https://web.archive.org/web/20240529200929/https://trkohler.com/posts/migrating-my-family-finance-bot-from-python-to-rust-teloxide-part-2/) by Troy Köhler.\n\n## FAQ\n\n**Q: Where I can ask questions?**\n\nA:\n\n - [Issues] is a good place for well-formed questions about the library design, enhancements, and bug reports.\n - [GitHub Discussions] is a place where you can ask us for help in a less formal manner.\n - If you need quick help in real-time, you should ask a question in [our official Telegram group].\n\n[Issues]: https://github.com/teloxide/teloxide/issues\n[our official Telegram group]: https://t.me/teloxide\n[GitHub Discussions]: https://github.com/teloxide/teloxide/discussions\n\n**Q: Do you support the Telegram API for clients?**\n\nA: No, only the bots API.\n\n**Q: Can I use webhooks?**\n\nA: You can! `teloxide` has a built-in support for webhooks in `dispatching::update_listeners::webhooks` module. See how it's used in [`examples/ngrok_ping_pong_bot.rs`](crates/teloxide/examples/ngrok_ping_pong.rs) and [`examples/heroku_ping_pong_bot.rs`](crates/teloxide/examples/heroku_ping_pong.rs).\n\n**Q: Can I handle both callback queries and messages within a single dialogue?**\n\nA: Yes, see [`examples/purchase.rs`](crates/teloxide/examples/purchase.rs).\n\n**Q: How can I organize complex logic?**\n\nA: You can use [`CommonVoiceBot`] as an example of a bot with a nested dialogue structure distributed across different files.\n\n[`CommonVoiceBot`]: https://gitlab.com/alenpaulvarghese/commonvoicebot\n\n**Q: Where can I find a WebApp example?**\n\nA: Check out [@TheAwiteb]'s [WebApp `teloxide` example].\n\n[@TheAwiteb]: https://github.com/TheAwiteb\n[WebApp `teloxide` example]: https://gist.github.com/TheAwiteb/8d809b34b619b01e64453bb31dbd8bf4\n\n## Community bots\n\nFeel free to propose your own bot to our collection!\n\n - [`raine/tgreddit`](https://github.com/raine/tgreddit) — A bot that sends the top posts of your favorite subreddits to Telegram.\n - [`magnickolas/remindee-bot`](https://github.com/magnickolas/remindee-bot) — Telegram bot for managing reminders.\n - [`WaffleLapkin/crate_upd_bot`](https://github.com/WaffleLapkin/crate_upd_bot) — A bot that notifies about crate updates.\n - [`mattrighetti/GroupActivityBot`](https://github.com/mattrighetti/group-activity-bot-rs) — Telegram bot that keeps track of user activity in groups.\n - [`alenpaul2001/AurSearchBot`](https://gitlab.com/alenpaul2001/aursearchbot) — Telegram bot for searching in Arch User Repository (AUR).\n - [`ArtHome12/vzmuinebot`](https://github.com/ArtHome12/vzmuinebot) — Telegram bot for food menu navigate.\n - [`studiedlist/EddieBot`](https://gitlab.com/studiedlist/eddie-bot) — Chatting bot with several entertainment features.\n - [`modos189/tg_blackbox_bot`](https://gitlab.com/modos189/tg_blackbox_bot) — Anonymous feedback for your Telegram project.\n - [`0xNima/spacecraft`](https://github.com/0xNima/spacecraft) — Yet another telegram bot to downloading Twitter spaces.\n - [`0xNima/Twideo`](https://github.com/0xNima/Twideo) — Simple Telegram Bot for downloading videos from Twitter via their links.\n - [`mattrighetti/libgen-bot-rs`](https://github.com/mattrighetti/libgen-bot-rs) — Telegram bot to interface with libgen.\n - [`zamazan4ik/npaperbot-telegram`](https://github.com/zamazan4ik/npaperbot-telegram) — Telegram bot for searching via C++ proposals.\n - [`studentenherz/dlebot`](https://github.com/studentenherz/dlebot) — A bot to query definitions of words from the Spanish Language Dictionary.\n - [`fr0staman/fr0staman_bot`](https://github.com/fr0staman/fr0staman_bot) — Feature rich Telegram game-like bot with pigs 🐽.\n - [`franciscofigueira/transferBot`](https://github.com/franciscofigueira/transferBot) — Telegram bot that notifies of crypto token transfers.\n\nSee [2500+ other public repositories using `teloxide` \u003e\u003e](https://github.com/teloxide/teloxide/network/dependents)\n\n## Contributing\n\nSee [`CONRIBUTING.md`](CONTRIBUTING.md).\n","funding_links":[],"categories":["Rust","Telegram Libraries","Libraries"],"sub_categories":["Rust","Web programming"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fteloxide%2Fteloxide","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fteloxide%2Fteloxide","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fteloxide%2Fteloxide/lists"}