7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 1 | #![recursion_limit = "256"] |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 2 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 3 | use anyhow::Result; |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 4 | use clap::Parser; |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 5 | use futures_util::StreamExt; |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 6 | use matrix_sdk::{Client, config::SyncSettings, ruma::OwnedRoomId}; |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 7 | use matrix_sdk_ui::timeline::RoomExt; |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 8 | use url::Url; |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 9 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 10 | #[derive(Parser, Debug)] |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 11 | struct Cli { |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 12 | /// The homeserver to connect to. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 13 | #[clap(value_parser)] |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 14 | homeserver: Url, |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 15 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 16 | /// The user name that should be used for the login. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 17 | #[clap(value_parser)] |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 18 | user_name: String, |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 19 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 20 | /// The password that should be used for the login. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 21 | #[clap(value_parser)] |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 22 | password: String, |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 23 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 24 | /// Set the proxy that should be used for the connection. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 25 | #[clap(short, long)] |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 26 | proxy: Option<Url>, |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 27 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 28 | /// Enable verbose logging output. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 29 | #[clap(short, long, action)] |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 30 | verbose: bool, |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 31 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 32 | /// The room id that we should listen for the, |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 33 | #[clap(value_parser)] |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 34 | room_id: OwnedRoomId, |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 35 | } |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 36 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 37 | async fn login(cli: Cli) -> Result<Client> { |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 38 | // Note that when encryption is enabled, you should use a persistent store to be |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 39 | // able to restore the session with a working encryption setup. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 40 | // See the `persist_session` example. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 41 | let mut builder = Client::builder().homeserver_url(cli.homeserver); |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 42 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 43 | if let Some(proxy) = cli.proxy { |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 44 | builder = builder.proxy(proxy); |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 45 | } |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 46 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 47 | let client = builder.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(&cli.user_name, &cli.password) |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 52 | .initial_device_display_name("rust-sdk") |
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 | Ok(client) |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 56 | } |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 57 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 58 | #[tokio::main] |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 59 | async fn main() -> Result<()> { |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 60 | tracing_subscriber::fmt::init(); |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 61 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 62 | let cli = Cli::parse(); |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 63 | let room_id = cli.room_id.clone(); |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 64 | let client = login(cli).await?; |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 65 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 66 | let sync_settings = SyncSettings::default(); |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 67 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 68 | // Wait for the first sync response |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 69 | println!("Wait for the first sync"); |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 70 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 71 | client.sync_once(sync_settings.clone()).await?; |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 72 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 73 | // Get the timeline stream and listen to it. |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 74 | let room = client.get_room(&room_id).unwrap(); |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 75 | let timeline = room.timeline().await.unwrap(); |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 76 | let (timeline_items, mut timeline_stream) = timeline.subscribe().await; |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 77 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 78 | println!("Initial timeline items: {timeline_items:#?}"); |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 79 | tokio::spawn(async move { |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 80 | while let Some(diffs) = timeline_stream.next().await { |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 81 | println!("Received timeline diffs: {diffs:#?}"); |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 82 | } |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 83 | }); |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 84 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 85 | // Sync forever |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 86 | client.sync(sync_settings).await?; |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 87 | |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 88 | Ok(()) |
7ff8adafe9e4 | atagen | 2026-10-22 12:30 UTC | 89 | } |