atagen

matrix-rust-sdk

public
Star0
Watch0
ssh://brewery@pls.lobotomise.me:33/atagen/matrix-rust-sdk.git

Blame: examples/autojoin/src/main.rs

7ff8adafe9e4atagen2026-10-22 12:30 UTC1
use std::{env, process::exit};
7ff8adafe9e4atagen2026-10-22 12:30 UTC2
7ff8adafe9e4atagen2026-10-22 12:30 UTC3
use matrix_sdk::{
7ff8adafe9e4atagen2026-10-22 12:30 UTC4
    Client, Room, config::SyncSettings, ruma::events::room::member::StrippedRoomMemberEvent,
7ff8adafe9e4atagen2026-10-22 12:30 UTC5
};
7ff8adafe9e4atagen2026-10-22 12:30 UTC6
use tokio::time::{Duration, sleep};
7ff8adafe9e4atagen2026-10-22 12:30 UTC7
7ff8adafe9e4atagen2026-10-22 12:30 UTC8
async fn on_stripped_state_member(
7ff8adafe9e4atagen2026-10-22 12:30 UTC9
    room_member: StrippedRoomMemberEvent,
7ff8adafe9e4atagen2026-10-22 12:30 UTC10
    client: Client,
7ff8adafe9e4atagen2026-10-22 12:30 UTC11
    room: Room,
7ff8adafe9e4atagen2026-10-22 12:30 UTC12
) {
7ff8adafe9e4atagen2026-10-22 12:30 UTC13
    if room_member.state_key != client.user_id().unwrap() {
7ff8adafe9e4atagen2026-10-22 12:30 UTC14
        return;
7ff8adafe9e4atagen2026-10-22 12:30 UTC15
    }
7ff8adafe9e4atagen2026-10-22 12:30 UTC16
7ff8adafe9e4atagen2026-10-22 12:30 UTC17
    tokio::spawn(async move {
7ff8adafe9e4atagen2026-10-22 12:30 UTC18
        println!("Autojoining room {}", room.room_id());
7ff8adafe9e4atagen2026-10-22 12:30 UTC19
        let mut delay = 2;
7ff8adafe9e4atagen2026-10-22 12:30 UTC20
7ff8adafe9e4atagen2026-10-22 12:30 UTC21
        while let Err(err) = room.join().await {
7ff8adafe9e4atagen2026-10-22 12:30 UTC22
            // retry autojoin due to synapse sending invites, before the
7ff8adafe9e4atagen2026-10-22 12:30 UTC23
            // invited user can join for more information see
7ff8adafe9e4atagen2026-10-22 12:30 UTC24
            // https://github.com/matrix-org/synapse/issues/4345
7ff8adafe9e4atagen2026-10-22 12:30 UTC25
            eprintln!("Failed to join room {} ({err:?}), retrying in {delay}s", room.room_id());
7ff8adafe9e4atagen2026-10-22 12:30 UTC26
7ff8adafe9e4atagen2026-10-22 12:30 UTC27
            sleep(Duration::from_secs(delay)).await;
7ff8adafe9e4atagen2026-10-22 12:30 UTC28
            delay *= 2;
7ff8adafe9e4atagen2026-10-22 12:30 UTC29
7ff8adafe9e4atagen2026-10-22 12:30 UTC30
            if delay > 3600 {
7ff8adafe9e4atagen2026-10-22 12:30 UTC31
                eprintln!("Can't join room {} ({err:?})", room.room_id());
7ff8adafe9e4atagen2026-10-22 12:30 UTC32
                break;
7ff8adafe9e4atagen2026-10-22 12:30 UTC33
            }
7ff8adafe9e4atagen2026-10-22 12:30 UTC34
        }
7ff8adafe9e4atagen2026-10-22 12:30 UTC35
        println!("Successfully joined room {}", room.room_id());
7ff8adafe9e4atagen2026-10-22 12:30 UTC36
    });
7ff8adafe9e4atagen2026-10-22 12:30 UTC37
}
7ff8adafe9e4atagen2026-10-22 12:30 UTC38
7ff8adafe9e4atagen2026-10-22 12:30 UTC39
async fn login_and_sync(
7ff8adafe9e4atagen2026-10-22 12:30 UTC40
    homeserver_url: String,
7ff8adafe9e4atagen2026-10-22 12:30 UTC41
    username: &str,
7ff8adafe9e4atagen2026-10-22 12:30 UTC42
    password: &str,
7ff8adafe9e4atagen2026-10-22 12:30 UTC43
) -> anyhow::Result<()> {
7ff8adafe9e4atagen2026-10-22 12:30 UTC44
    // Note that when encryption is enabled, you should use a persistent store to be
7ff8adafe9e4atagen2026-10-22 12:30 UTC45
    // able to restore the session with a working encryption setup.
7ff8adafe9e4atagen2026-10-22 12:30 UTC46
    // See the `persist_session` example.
7ff8adafe9e4atagen2026-10-22 12:30 UTC47
    let client = Client::builder().homeserver_url(homeserver_url).build().await?;
7ff8adafe9e4atagen2026-10-22 12:30 UTC48
7ff8adafe9e4atagen2026-10-22 12:30 UTC49
    client
7ff8adafe9e4atagen2026-10-22 12:30 UTC50
        .matrix_auth()
7ff8adafe9e4atagen2026-10-22 12:30 UTC51
        .login_username(username, password)
7ff8adafe9e4atagen2026-10-22 12:30 UTC52
        .initial_device_display_name("autojoin bot")
7ff8adafe9e4atagen2026-10-22 12:30 UTC53
        .await?;
7ff8adafe9e4atagen2026-10-22 12:30 UTC54
7ff8adafe9e4atagen2026-10-22 12:30 UTC55
    println!("logged in as {username}");
7ff8adafe9e4atagen2026-10-22 12:30 UTC56
7ff8adafe9e4atagen2026-10-22 12:30 UTC57
    client.add_event_handler(on_stripped_state_member);
7ff8adafe9e4atagen2026-10-22 12:30 UTC58
7ff8adafe9e4atagen2026-10-22 12:30 UTC59
    client.sync(SyncSettings::default()).await?;
7ff8adafe9e4atagen2026-10-22 12:30 UTC60
7ff8adafe9e4atagen2026-10-22 12:30 UTC61
    Ok(())
7ff8adafe9e4atagen2026-10-22 12:30 UTC62
}
7ff8adafe9e4atagen2026-10-22 12:30 UTC63
7ff8adafe9e4atagen2026-10-22 12:30 UTC64
#[tokio::main]
7ff8adafe9e4atagen2026-10-22 12:30 UTC65
async fn main() -> anyhow::Result<()> {
7ff8adafe9e4atagen2026-10-22 12:30 UTC66
    tracing_subscriber::fmt::init();
7ff8adafe9e4atagen2026-10-22 12:30 UTC67
7ff8adafe9e4atagen2026-10-22 12:30 UTC68
    // parse the command line for homeserver, username and password
7ff8adafe9e4atagen2026-10-22 12:30 UTC69
    let (Some(homeserver_url), Some(username), Some(password)) =
7ff8adafe9e4atagen2026-10-22 12:30 UTC70
        (env::args().nth(1), env::args().nth(2), env::args().nth(3))
7ff8adafe9e4atagen2026-10-22 12:30 UTC71
    else {
7ff8adafe9e4atagen2026-10-22 12:30 UTC72
        eprintln!("Usage: {} <homeserver_url> <username> <password>", env::args().next().unwrap());
7ff8adafe9e4atagen2026-10-22 12:30 UTC73
        exit(1)
7ff8adafe9e4atagen2026-10-22 12:30 UTC74
    };
7ff8adafe9e4atagen2026-10-22 12:30 UTC75
7ff8adafe9e4atagen2026-10-22 12:30 UTC76
    login_and_sync(homeserver_url, &username, &password).await?;
7ff8adafe9e4atagen2026-10-22 12:30 UTC77
    Ok(())
7ff8adafe9e4atagen2026-10-22 12:30 UTC78
}