atagen

matrix-rust-sdk

public
Star0
Watch0
ssh://brewery@pls.lobotomise.me:33/atagen/matrix-rust-sdk.git
examples/autojoin/src/main.rsRust78 lines2.3 KB
1
use std::{env, process::exit};
2
3
use matrix_sdk::{
4
    Client, Room, config::SyncSettings, ruma::events::room::member::StrippedRoomMemberEvent,
5
};
6
use tokio::time::{Duration, sleep};
7
8
async fn on_stripped_state_member(
9
    room_member: StrippedRoomMemberEvent,
10
    client: Client,
11
    room: Room,
12
) {
13
    if room_member.state_key != client.user_id().unwrap() {
14
        return;
15
    }
16
17
    tokio::spawn(async move {
18
        println!("Autojoining room {}", room.room_id());
19
        let mut delay = 2;
20
21
        while let Err(err) = room.join().await {
22
            // retry autojoin due to synapse sending invites, before the
23
            // invited user can join for more information see
24
            // https://github.com/matrix-org/synapse/issues/4345
25
            eprintln!("Failed to join room {} ({err:?}), retrying in {delay}s", room.room_id());
26
27
            sleep(Duration::from_secs(delay)).await;
28
            delay *= 2;
29
30
            if delay > 3600 {
31
                eprintln!("Can't join room {} ({err:?})", room.room_id());
32
                break;
33
            }
34
        }
35
        println!("Successfully joined room {}", room.room_id());
36
    });
37
}
38
39
async fn login_and_sync(
40
    homeserver_url: String,
41
    username: &str,
42
    password: &str,
43
) -> anyhow::Result<()> {
44
    // Note that when encryption is enabled, you should use a persistent store to be
45
    // able to restore the session with a working encryption setup.
46
    // See the `persist_session` example.
47
    let client = Client::builder().homeserver_url(homeserver_url).build().await?;
48
49
    client
50
        .matrix_auth()
51
        .login_username(username, password)
52
        .initial_device_display_name("autojoin bot")
53
        .await?;
54
55
    println!("logged in as {username}");
56
57
    client.add_event_handler(on_stripped_state_member);
58
59
    client.sync(SyncSettings::default()).await?;
60
61
    Ok(())
62
}
63
64
#[tokio::main]
65
async fn main() -> anyhow::Result<()> {
66
    tracing_subscriber::fmt::init();
67
68
    // parse the command line for homeserver, username and password
69
    let (Some(homeserver_url), Some(username), Some(password)) =
70
        (env::args().nth(1), env::args().nth(2), env::args().nth(3))
71
    else {
72
        eprintln!("Usage: {} <homeserver_url> <username> <password>", env::args().next().unwrap());
73
        exit(1)
74
    };
75
76
    login_and_sync(homeserver_url, &username, &password).await?;
77
    Ok(())
78
}