diff options
Diffstat (limited to 'src/main.rs')
| -rw-r--r-- | src/main.rs | 96 |
1 files changed, 79 insertions, 17 deletions
diff --git a/src/main.rs b/src/main.rs index a3b1f64..5e361cb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,32 +4,94 @@ //! Slavoj Žižek in your life, this matrix bot can help you satisfying that //! need. -use std::sync::{Arc, Mutex}; - -use matrix_bot_api::MatrixBot; +use matrix_sdk::room::Room; +use matrix_sdk::events::room::member::MemberEventContent; +use matrix_sdk::events::StrippedStateEvent; +use matrix_sdk::{async_trait, Client, ClientConfig, EventHandler, SyncSettings}; +use tokio::time::{sleep, Duration}; +use url::Url; pub mod bot_config; -pub mod command_handler; pub mod zizek_db; use bot_config::BotConfig; -use command_handler::CommandHandler; use zizek_db::ZizekDb; -fn main() +struct AutoJoinBot +{ + client: Client, +} + +impl AutoJoinBot +{ + pub fn new(client: Client) -> Self { Self { client } } +} + +#[async_trait] +impl EventHandler for AutoJoinBot { + async fn on_stripped_state_member(&self, room: Room, room_member: &StrippedStateEvent<MemberEventContent>, _: Option<MemberEventContent>){ + /* If the event does not concern the bot user, ignore it */ + if room_member.state_key != self.client.user_id().await.unwrap() { + return; + } + + if let Room::Invited(room) = room { + println!("Autojoining room {}", room.room_id()); + 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 + eprintln!( + "Failed to join room {} ({:?}), retrying in {}s", + room.room_id(), + err, + delay + ); + + sleep(Duration::from_secs(delay)).await; + delay *= 2; + + if delay > 3600 { + eprintln!("Can't join room {} ({:?})", room.room_id(), err); + break; + } + } + println!("Successfully joined room {}", room.room_id()); + } + } +} + +async fn login_and_sync(homeserver_url: &str, username: &str, password: &str) -> Result<(), matrix_sdk::Error> { + let mut config_dir = dirs::home_dir().expect("No home directory found"); + config_dir.push("zizek_bot"); + let config = ClientConfig::new().store_path(config_dir); + + + let homeserver_url = Url::parse(&homeserver_url).expect("Couldn't parse the homeserver URL"); + let client = Client::new_with_config(homeserver_url, config).unwrap(); + + client.login(username, password, None, Some("Slavoj Žižek")).await?; + println!("logged in as {}", username); + + client.set_event_handler(Box::new(AutoJoinBot::new(client.clone()))).await; + + client.sync(SyncSettings::default()).await; + + Ok(()) +} + +#[tokio::main] +async fn main() -> Result<(), matrix_sdk::Error> { + tracing_subscriber::fmt::init(); + let bot_config = BotConfig::from_config_file().expect("Unable to read bot configuration file"); - let zizek_db = Arc::new(Mutex::new( - ZizekDb::from_file("zizek_quotes.db").expect("Unable to load zizek quote database"), - )); + let zizek_db = + ZizekDb::from_file("zizek_quotes.db").expect("Unable to load zizek quote database"); - /* The command handler is the handler with the highest priority, so it gets - * registered first */ - let bot = MatrixBot::new(CommandHandler::new(zizek_db.clone())); + login_and_sync(bot_config.homeserver_url(), bot_config.username(), bot_config.password()).await?; - bot.run( - bot_config.user(), - bot_config.password(), - bot_config.homeserver_url(), - ); + Ok(()) } |
