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