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