diff --git a/Cargo.lock b/Cargo.lock index 2bf97ea..48c7483 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1234,6 +1234,7 @@ dependencies = [ "reqwest", "serde_json", "tokio", + "urlencoding", ] [[package]] @@ -2704,6 +2705,12 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "urlencoding" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8db7427f936968176eaa7cdf81b7f98b980b18495ec28f1b5791ac3bfe3eea9" + [[package]] name = "uuid" version = "0.7.4" diff --git a/Cargo.toml b/Cargo.toml index 85d5518..3ec5314 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,3 +14,4 @@ miette = { version = "5.9.0", features = ["fancy"] } reqwest = { version = "0.11.18", features = ["json"] } serde_json = "1.0.99" tokio = { version = "1.29.0", features = ["full"] } +urlencoding = "2.1.2" diff --git a/src/main.rs b/src/main.rs index 453aa74..0639b72 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,8 +2,9 @@ use matrix_sdk::{ config::SyncSettings, room::Room, ruma::{ - events::room::message::{ - MessageType, OriginalSyncRoomMessageEvent, RoomMessageEventContent, + events::room::{ + member::StrippedRoomMemberEvent, + message::{MessageType, OriginalSyncRoomMessageEvent, RoomMessageEventContent}, }, OwnedUserId, }, @@ -47,25 +48,14 @@ async fn main() -> Result<()> { println!("Logged in as RIL100 bot"); - let homeserver = hs_url - .host_str() - .ok_or_else(|| return miette!("Homeserver URL does not contain a host 🤨"))? - .to_string(); - let user_id = client .user_id() - .ok_or_else(|| return miette!("Client does not have a User ID"))? + .ok_or_else(|| return miette!("Client does not have a User Id"))? .to_owned(); - client.add_event_handler(move |ev, room| { - on_room_message( - ev, - room, - username.clone(), - homeserver.clone(), - user_id.clone(), - ) - }); + client.add_event_handler(on_stripped_state_member); + + client.add_event_handler(move |ev, room| on_room_message(ev, room, user_id.clone())); let settings = SyncSettings::default().token(response.next_batch); client.sync(settings).await.into_diagnostic()?; @@ -76,8 +66,6 @@ async fn main() -> Result<()> { async fn on_room_message( event: OriginalSyncRoomMessageEvent, room: Room, - username: String, - homeserver: String, current_user: OwnedUserId, ) -> Result<()> { // Make sure room is joined @@ -89,11 +77,14 @@ async fn on_room_message( return Ok(()); }; + let user_uri = ¤t_user.matrix_to_uri().to_string(); + let user_uri = urlencoding::decode(user_uri) + .into_diagnostic()? + .into_owned(); + // Only reply to mentions if text.formatted.map_or(false, |v| { - v.body.contains(&format!( - "" - )) + v.body.contains(&format!("")) }) { // Drop the mention let query = text @@ -160,3 +151,43 @@ async fn on_room_message( Ok(()) } + +async fn on_stripped_state_member( + room_member: StrippedRoomMemberEvent, + client: Client, + room: Room, +) -> Result<()> { + if room_member.state_key + != client + .user_id() + .ok_or_else(|| return miette!("Client does not have a User Id"))? + { + return Ok(()); + } + + if let Room::Invited(room) = room { + tokio::spawn(async move { + let mut delay = 2; + + while let Err(err) = room.accept_invitation().await { + // retry autojoin due to synapse sending invites, before the + // invited user can join for more information see + // https://github.com/matrix-org/synapse/issues/4345 + miette!(format!( + "Failed to join room {} ({err:?}), retrying in {delay}s", + room.room_id() + )); + + tokio::time::sleep(tokio::time::Duration::from_secs(delay)).await; + delay *= 2; + + if delay > 3600 { + miette!(format!("Can't join room {} ({err:?})", room.room_id())); + break; + } + } + }); + } + + Ok(()) +}