summaryrefslogtreecommitdiff
path: root/src/main.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs96
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(())
}