diff --git a/examples/command_bot.rs b/examples/command_bot.rs index 2f2213e5..20bbf7a1 100644 --- a/examples/command_bot.rs +++ b/examples/command_bot.rs @@ -8,13 +8,13 @@ use matrix_sdk::{ events::room::message::{MessageEvent, MessageEventContent, TextMessageEventContent}, AsyncClient, AsyncClientConfig, EventEmitter, Room, SyncSettings, }; -use tokio::sync::{Mutex, RwLock}; +use tokio::sync::RwLock; use url::Url; struct CommandBot { /// This clone of the `AsyncClient` will send requests to the server, /// while the other keeps us in sync with the server using `sync_forever`. - client: Mutex, + client: AsyncClient, /// A timestamp so we only respond to messages sent after the bot is running. start_time: UInt, } @@ -24,7 +24,7 @@ impl CommandBot { let now = SystemTime::now(); let timestamp = now.duration_since(UNIX_EPOCH).unwrap().as_millis(); Self { - client: Mutex::new(client), + client, start_time: UInt::new(timestamp as u64).unwrap(), } } @@ -57,8 +57,6 @@ impl EventEmitter for CommandBot { println!("sending"); self.client - .lock() - .await // send our message to the room we found the "!party" command in // the last parameter is an optional Uuid which we don't care about. .room_send(&room_id, content, None) @@ -82,10 +80,6 @@ async fn login_and_sync( let homeserver_url = Url::parse(&homeserver_url)?; // create a new AsyncClient with the given homeserver url and config let mut client = AsyncClient::new_with_config(homeserver_url, None, client_config).unwrap(); - // add our CommandBot to be notified of incoming messages - client - .add_event_emitter(Box::new(CommandBot::new(client.clone()))) - .await; client .login( @@ -98,6 +92,14 @@ async fn login_and_sync( println!("logged in as {}", username); + // initial sync to set up state and so our bot doesn't respond to old messages + client.sync(SyncSettings::default()).await.unwrap(); + // add our CommandBot to be notified of incoming messages, we do this after the initial + // sync to avoid responding to messages before the bot was running. + client + .add_event_emitter(Box::new(CommandBot::new(client.clone()))) + .await; + // this keeps state from the server streaming in to CommandBot via the EventEmitter trait client.sync_forever(SyncSettings::new(), |_| async {}).await; diff --git a/src/async_client.rs b/src/async_client.rs index 86a9e139..5e298a8b 100644 --- a/src/async_client.rs +++ b/src/async_client.rs @@ -318,7 +318,7 @@ impl AsyncClient { /// only if the client also holds the encryption keys for this device. #[instrument(skip(password))] pub async fn login + std::fmt::Debug>( - &mut self, + &self, user: S, password: S, device_id: Option, @@ -368,7 +368,7 @@ impl AsyncClient { /// * alias - The `RoomId` or `RoomAliasId` of the room to be joined. /// An alias looks like this `#name:example.com` pub async fn join_room_by_id_or_alias( - &mut self, + &self, alias: &RoomIdOrAliasId, ) -> Result { let request = join_room_by_id_or_alias::Request { @@ -390,7 +390,7 @@ impl AsyncClient { /// /// * reason - Optional reason why the room member is being kicked out. pub async fn kick_user( - &mut self, + &self, room_id: &RoomId, user_id: &UserId, reason: Option, @@ -411,7 +411,7 @@ impl AsyncClient { /// /// * room_id - The `RoomId` of the room to leave. /// - pub async fn leave_room(&mut self, room_id: &RoomId) -> Result { + pub async fn leave_room(&self, room_id: &RoomId) -> Result { let request = leave_room::Request { room_id: room_id.clone(), }; @@ -428,7 +428,7 @@ impl AsyncClient { /// /// * user_id - The `UserId` of the user to invite to the room. pub async fn invite_user_by_id( - &mut self, + &self, room_id: &RoomId, user_id: &UserId, ) -> Result { @@ -451,7 +451,7 @@ impl AsyncClient { /// /// * invite_id - A third party id of a user to invite to the room. pub async fn invite_user_by_3pid( - &mut self, + &self, room_id: &RoomId, invite_id: &Invite3pid, ) -> Result { @@ -492,7 +492,7 @@ impl AsyncClient { /// # }); /// ``` pub async fn create_room>( - &mut self, + &self, room: R, ) -> Result { let request = room.into(); @@ -536,7 +536,7 @@ impl AsyncClient { /// # }); /// ``` pub async fn room_messages>( - &mut self, + &self, request: R, ) -> Result { let req = request.into(); @@ -549,10 +549,7 @@ impl AsyncClient { /// /// * `sync_settings` - Settings for the sync call. #[instrument] - pub async fn sync( - &mut self, - sync_settings: SyncSettings, - ) -> Result { + pub async fn sync(&self, sync_settings: SyncSettings) -> Result { let request = sync_events::Request { filter: None, since: sync_settings.token, @@ -701,7 +698,7 @@ impl AsyncClient { /// ``` #[instrument(skip(callback))] pub async fn sync_forever( - &mut self, + &self, sync_settings: SyncSettings, callback: impl Fn(sync_events::IncomingResponse) -> C + Send, ) where @@ -879,7 +876,7 @@ impl AsyncClient { /// }) /// ``` pub async fn room_send( - &mut self, + &self, room_id: &RoomId, #[allow(unused_mut)] mut content: MessageEventContent, txn_id: Option, @@ -894,7 +891,7 @@ impl AsyncClient { let room = client.joined_rooms.get(room_id); match room { - Some(r) => r.write().await.is_encrypted(), + Some(r) => r.read().await.is_encrypted(), None => false, } }; @@ -903,7 +900,7 @@ impl AsyncClient { let missing_sessions = { let client = self.base_client.read().await; let room = client.joined_rooms.get(room_id); - let room = room.as_ref().unwrap().write().await; + let room = room.as_ref().unwrap().read().await; let users = room.members.keys(); self.base_client .read() diff --git a/src/base_client.rs b/src/base_client.rs index 686f8c15..33a0314f 100644 --- a/src/base_client.rs +++ b/src/base_client.rs @@ -811,7 +811,7 @@ mod test { .with_body_from_file("tests/data/sync.json") .create(); - let mut client = AsyncClient::new(homeserver, Some(session)).unwrap(); + let client = AsyncClient::new(homeserver, Some(session)).unwrap(); let sync_settings = SyncSettings::new().timeout(Duration::from_millis(3000)); diff --git a/src/models/room.rs b/src/models/room.rs index b0f1b735..9701d04a 100644 --- a/src/models/room.rs +++ b/src/models/room.rs @@ -417,7 +417,7 @@ mod test { .with_body_from_file("tests/data/sync.json") .create(); - let mut client = AsyncClient::new(homeserver, Some(session)).unwrap(); + let client = AsyncClient::new(homeserver, Some(session)).unwrap(); let sync_settings = SyncSettings::new().timeout(Duration::from_millis(3000)); diff --git a/src/request_builder.rs b/src/request_builder.rs index 42f088f5..795e8534 100644 --- a/src/request_builder.rs +++ b/src/request_builder.rs @@ -341,7 +341,7 @@ mod test { .room_alias_name("room_alias") .topic("room topic") .visibility(Visibility::Private); - let mut cli = AsyncClient::new(homeserver, Some(session)).unwrap(); + let cli = AsyncClient::new(homeserver, Some(session)).unwrap(); assert!(cli.create_room(builder).await.is_ok()); } @@ -373,7 +373,7 @@ mod test { // TODO this makes ruma error `Err(IntoHttp(IntoHttpError(Query(Custom("unsupported value")))))`?? // .filter(RoomEventFilter::default()); - let mut cli = AsyncClient::new(homeserver, Some(session)).unwrap(); + let cli = AsyncClient::new(homeserver, Some(session)).unwrap(); assert!(cli.room_messages(builder).await.is_ok()); } } diff --git a/tests/async_client_tests.rs b/tests/async_client_tests.rs index b2e72ff7..3c9dacdc 100644 --- a/tests/async_client_tests.rs +++ b/tests/async_client_tests.rs @@ -17,7 +17,7 @@ async fn login() { .with_body_from_file("tests/data/login_response.json") .create(); - let mut client = AsyncClient::new(homeserver, None).unwrap(); + let client = AsyncClient::new(homeserver, None).unwrap(); client .login("example", "wordpass", None, None) @@ -46,7 +46,7 @@ async fn sync() { .with_body_from_file("tests/data/sync.json") .create(); - let mut client = AsyncClient::new(homeserver, Some(session)).unwrap(); + let client = AsyncClient::new(homeserver, Some(session)).unwrap(); let sync_settings = SyncSettings::new().timeout(Duration::from_millis(3000)); @@ -75,7 +75,7 @@ async fn room_names() { .with_body_from_file("tests/data/sync.json") .create(); - let mut client = AsyncClient::new(homeserver, Some(session)).unwrap(); + let client = AsyncClient::new(homeserver, Some(session)).unwrap(); let sync_settings = SyncSettings::new().timeout(Duration::from_millis(3000));