use matrix_sdk::ruma::OwnedRoomOrAliasId;
use matrix_sdk::ruma::events::room::member::StrippedRoomMemberEvent;
use tokio::time::{
Duration,
sleep,
};
use crate::prelude::*;
use crate::utils;
#[derive(Debug, Deserialize)]
#[serde(default)]
#[doc(hidden)]
pub struct Config {
enabled: bool,
}
impl Default for Config {
fn default() -> Self { Self { enabled: true } }
}
#[doc(hidden)]
pub fn load(bot: Rdzobot) {
if !bot.config().module.autojoin.enabled {
return;
}
bot.add_command(LeaveCommand::command(), on_cmd_leave);
bot.add_event_handler(on_invite);
}
#[derive(clap::Parser)]
#[command(name = "!leave")]
#[command(about = "Causes the bot to leave this or specified room [owner only]")]
struct LeaveCommand {
room: Option<OwnedRoomOrAliasId>,
}
async fn on_cmd_leave(
mut arg_matches: clap::ArgMatches,
event: OriginalSyncRoomMessageEvent,
client: Client,
room: Room,
bot: Rdzobot,
) -> anyhow::Result<()> {
let args = LeaveCommand::from_arg_matches_mut(&mut arg_matches).unwrap();
let room_to_leave =
match utils::resolve_room_alias_with_default(client, args.room, Some(&room)).await {
Ok(Some(r)) => r,
Ok(None) => unreachable!(),
Err(err) => {
tracing::debug!("no room to leave: {:?}", err);
nie_zesraj_się(&event, &room).await?;
return Ok(());
}
};
if bot.config().owner.as_ref().is_some_and(|owner| &event.sender == owner) {
tracing::warn!(
"leaving room {}{}",
room_to_leave.room_id(),
if let Some(name) = room_to_leave.cached_display_name() {
format!(" ({name})")
} else {
"".to_string()
},
);
room_to_leave.leave().await?;
} else {
tracing::debug!("refusing to leave, not the owner");
nie_zesraj_się(&event, &room).await?;
}
Ok(())
}
async fn on_invite(event: StrippedRoomMemberEvent, client: Client, room: Room) {
if event.state_key != client.user_id().unwrap() {
return;
}
tokio::spawn(async move {
tracing::warn!("joining room {}", room.room_id());
let mut delay = 2;
while let Err(err) = room.join().await {
if delay > 3600 {
tracing::error!("failed to join room {}", room.room_id());
break;
}
tracing::info!(
"failed to join room {} ({err:?}), retrying in {delay} s",
room.room_id(),
);
sleep(Duration::from_secs(delay)).await;
delay *= 2;
}
tracing::warn!("joined room {}", room.room_id());
});
}