Expand description

Support for user dialogues.

The main type is (surprise!) Dialogue. Under the hood, it is just a wrapper over Storage and a chat ID. All it does is provides convenient method for manipulating the dialogue state. Storage is where all dialogue states are stored; it can be either InMemStorage, which is a simple hash map from std::collections, or an advanced database wrapper such as SqliteStorage. In the latter case, your dialogues are persistent, meaning that you can safely restart your bot and all ongoing dialogues will remain in the database – this is a preferred method for production bots.

examples/dialogue.rs clearly demonstrates the typical usage of dialogues. Your dialogue state can be represented as an enumeration:

#[derive(Clone, Default)]
pub enum State {
    ReceiveAge {
        full_name: String,
    ReceiveLocation {
        full_name: String,
        age: u8,

Each state is associated with its respective handler: e.g., when a dialogue state is ReceiveAge, receive_age is invoked:

async fn receive_age(
    bot: Bot,
    dialogue: MyDialogue,
    full_name: String, // Available from `State::ReceiveAge`.
    msg: Message,
) -> HandlerResult {
    match msg.text().map(|text| text.parse::<u8>()) {
        Some(Ok(age)) => {
            bot.send_message(msg.chat.id, "What's your location?").await?;
            dialogue.update(State::ReceiveLocation { full_name, age }).await?;
        _ => {
            bot.send_message(msg.chat.id, "Send me a number.").await?;


Variant’s fields are passed to state handlers as single arguments like full_name: String or tuples in case of two or more variant parameters (see below). Using Dialogue::update, you can update the dialogue with a new state, in our case – State::ReceiveLocation { full_name, age }. To exit the dialogue, just call Dialogue::exit and it will be removed from the underlying storage:

async fn receive_location(
    bot: Bot,
    dialogue: MyDialogue,
    (full_name, age): (String, u8), // Available from `State::ReceiveLocation`.
    msg: Message,
) -> HandlerResult {
    match msg.text() {
        Some(location) => {
            let message =
                format!("Full name: {}\nAge: {}\nLocation: {}", full_name, age, location);
            bot.send_message(msg.chat.id, message).await?;
        None => {
            bot.send_message(msg.chat.id, "Send me a text message.").await?;



Various serializers for dialogue storages.


A handle for controlling dialogue state.
A dialogue storage based on std::collections::HashMap.
A dialogue storage based on Redis.
A persistent dialogue storage based on SQLite.
A dialogue storage wrapper which logs all actions performed on an underlying storage.


An error returned from InMemStorage.
An error returned from RedisStorage.
An error returned from SqliteStorage.


Something that may has a chat ID.
A serializer for memory storages.
A storage of dialogues.


Enters a dialogue context.

Type Definitions

A storage with an erased error type.