summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/bot_config.rs6
-rw-r--r--src/main.rs96
2 files changed, 82 insertions, 20 deletions
diff --git a/src/bot_config.rs b/src/bot_config.rs
index 2438c40..5fd2482 100644
--- a/src/bot_config.rs
+++ b/src/bot_config.rs
@@ -6,7 +6,7 @@ use config::{Config, ConfigError, File as ConfigFile};
/// Configuration struct of a bot
pub struct BotConfig
{
- user: String,
+ username: String,
password: String,
homeserver_url: String,
}
@@ -25,14 +25,14 @@ impl BotConfig
config.merge(ConfigFile::with_name("botconfig"))?;
Ok(Self {
- user: config.get_str("user")?,
+ username: config.get_str("username")?,
password: config.get_str("password")?,
homeserver_url: config.get_str("homeserver_url")?,
})
}
/// Get the username that should be used by the bot
- pub fn user(&self) -> &String { &self.user }
+ pub fn username(&self) -> &String { &self.username }
/// Get the password the bot should use to authenticate its user
pub fn password(&self) -> &String { &self.password }
/// Get the homeserver of the bot where it should send the login data to
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(())
}