diff --git a/src/bot_commands.rs b/src/bot_commands.rs index 9555da3..dff6424 100644 --- a/src/bot_commands.rs +++ b/src/bot_commands.rs @@ -3,6 +3,7 @@ use anyhow::Context; use file_format::FileFormat; use futures_util::pin_mut; +use futures_util::StreamExt; use image::io::Reader as ImageReader; use image::GenericImageView; use matrix_sdk::deserialized_responses::MemberEvent; @@ -32,7 +33,6 @@ use time::macros::offset; use time::Duration; use time::OffsetDateTime; use time::Weekday; -use futures_util::StreamExt; use crate::member_updates::MemberChanges; use crate::utils::avatar_http_url; @@ -168,7 +168,9 @@ async fn name_changes_command( let stream = MemberChanges::new_stream(room, event.clone()).peekable(); pin_mut!(stream); while let Some(event) = stream.next().await { - if count <= -5 { break; } + if count <= -5 { + break; + } let prev_event = stream.as_mut().peek().await; let detail = prev_event.map(|e| e.content.details()); @@ -246,7 +248,9 @@ async fn avatar_changes_command( let stream = MemberChanges::new_stream(room, event.clone()).peekable(); pin_mut!(stream); while let Some(event) = stream.next().await { - if count <= -5 { break; } + if count <= -5 { + break; + } let prev_event = stream.as_mut().peek().await; let detail = prev_event.map(|e| e.content.details()); @@ -287,7 +291,9 @@ async fn avatar_changes_command( avatar_http_url(event.content.avatar_url.as_deref(), homeserver)?; let result = format!( "{count}: Joined with avatar {}\n", - avatar_link.map(|link| link.to_string()).unwrap_or("(No avatar)".to_string()) + avatar_link + .map(|link| link.to_string()) + .unwrap_or("(No avatar)".to_string()) ); body.push_str(&result); } diff --git a/src/callbacks.rs b/src/callbacks.rs index f5b71c0..46cf04c 100644 --- a/src/callbacks.rs +++ b/src/callbacks.rs @@ -5,6 +5,7 @@ use crate::FuukaBotContext; use crate::FuukaBotError; use matrix_sdk::event_handler::Ctx; use matrix_sdk::room::Room; +use matrix_sdk::ruma::events::room::member::StrippedRoomMemberEvent; use matrix_sdk::ruma::events::room::message::sanitize::remove_plain_reply_fallback; use matrix_sdk::ruma::events::room::message::RoomMessageEventContent; use matrix_sdk::ruma::events::room::message::{ @@ -45,6 +46,31 @@ impl FuukaBotCallbacks { Ok(()) } + + pub async fn on_stripped_member(ev: StrippedRoomMemberEvent, room: Room) { + let client = room.client(); + let user_id = client.user_id().unwrap(); + if ev.state_key != user_id { + return; + } + + tokio::spawn(async move { + let room_id = room.room_id(); + tracing::info!("Autojoining room {}", room_id); + let mut delay = 2; + while let Err(e) = room.join().await { + use tokio::time::{sleep, Duration}; + tracing::warn!("Failed to join room {room_id} ({e:?}), retrying in {delay}s"); + sleep(Duration::from_secs(delay)).await; + delay *= 2; + + if delay > 3600 { + tracing::error!("Can't join room {room_id} ({e:?})"); + break; + } + } + }); + } } async fn send_error_message( diff --git a/src/utils.rs b/src/utils.rs index c9cffd8..296666a 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -73,9 +73,7 @@ pub fn make_divergence(room_hash: u32, event_id_hash: Option) -> f32 { /// Given a [nom::error::Error] and the input, returns the [RoomMessageEventContent] to send to the room pub fn nom_error_message(input: &str, e: nom::error::Error) -> RoomMessageEventContent { - let offset = input - .rfind(e.input.as_str()) - .unwrap_or(e.input.len()); + let offset = input.rfind(e.input.as_str()).unwrap_or(e.input.len()); let (prefix, suffix) = input.split_at(offset); let prefix_parts = prefix.split('\n').collect::>(); let line_number = prefix_parts.len();