diff --git a/src/main.rs b/src/main.rs index b3cc2ae..3486347 100644 --- a/src/main.rs +++ b/src/main.rs @@ -14,28 +14,16 @@ use {log, pretty_env_logger}; use crate::jsonrpc::RpcClient; -const CHANNEL: &str = "#hackens-signal"; -const MEDIA_DIR: &str = "./www"; -const SIGNALCLI_DIR: &str = "./.config"; -const SOCKET: &str = "./socket"; -const URL_ROOT: &str = "https://hackens.org/irc-bridge/"; - #[tokio::main] async fn main() -> Result<(), String> { pretty_env_logger::init(); log::info!("Starting..."); - // TODO: load config at runtime and add consts inside - let config = Config { - nickname: Some("bottest".to_owned()), - server: Some("ulminfo.fr".to_owned()), - channels: vec![CHANNEL.to_owned()], - use_tls: Some(true), - ..Config::default() - }; + let config = Config::load("./config.toml").map_err(|e| format!("Error while loading config: {e}"))?; + check_config(&config); // Initialisation of components. TODO separate module let init_irc = async { - let mut client = Client::from_config(config).await.unwrap(); + let mut client = Client::from_config(config.clone()).await.unwrap(); client.identify().unwrap(); let sender = client.sender(); @@ -55,7 +43,7 @@ async fn main() -> Result<(), String> { let init_signal = async { log::debug!("Initializing Signal"); - let signal_client = jsonrpc::connect_unix(SOCKET) + let signal_client = jsonrpc::connect_unix(config.options.get("socket").unwrap()) .await .map_err(|e| format!("failed to connect to signal socket: {e}"))?; let signal_stream = signal_client.subscribe_receive(None).await.unwrap(); @@ -65,10 +53,11 @@ async fn main() -> Result<(), String> { let ((sender, mut stream), (mut signal_stream, signal_client)) = try_join(init_irc, init_signal).await?; let bridge = Bridge::new( - &Path::new(MEDIA_DIR), - &Path::new(SIGNALCLI_DIR), - URL_ROOT, - GROUPID, + &Path::new(config.options.get("media_dir").unwrap()), + &Path::new(config.options.get("signal_cli_dir").unwrap()), + &config.options.get("url_root").unwrap(), + &config.options.get("groupid").unwrap(), + &config.channels[0], ); // Run !! @@ -94,13 +83,13 @@ async fn handle_irc( .transpose() .map_err(|e| format!("error while retrieving messages from irc: {e}"))? { - if let Some(msg) = bridge.irc2signal(message) { + if let Some((groupid, msg)) = bridge.irc2signal(message) { log::trace!("[SIGNAL SEND] {msg}"); signal_client .send( None, vec![], - vec![String::from(GROUPID)], + vec![String::from(groupid)], false, false, msg, @@ -141,9 +130,9 @@ async fn handle_signal( } Some(Ok(val)) => { log::trace!("[SIGNAL RCV] {:?}", val); - if let Some(msg) = bridge.signal2irc(val).await { + if let Some((channel, msg)) = bridge.signal2irc(val).await { sender - .send_privmsg(CHANNEL, msg) + .send_privmsg(channel, msg) .map_err(|e| format!("error while sending to irc: {e}"))?; } } @@ -155,3 +144,14 @@ async fn handle_signal( } } } + +fn check_config(config: &Config) -> bool { + let keys = vec![ + "groupid", + "media_dir", + "signal_cli_dir", + "socket", + "url_root", + ]; + keys.into_iter().fold(config.channels.len() >= 1, |b, k| b && config.options.contains_key(k)) +} diff --git a/src/transform.rs b/src/transform.rs index 0a1e4be..fbbd8aa 100644 --- a/src/transform.rs +++ b/src/transform.rs @@ -54,6 +54,7 @@ pub struct Bridge<'a> { signalcli_dir: &'a Path, url_root: &'a str, groupid: &'a str, + irc_channel: &'a str, } impl<'a> Bridge<'a> { @@ -62,12 +63,14 @@ impl<'a> Bridge<'a> { signalcli_dir: &'a Path, url_root: &'a str, groupid: &'a str, + irc_channel: &'a str, ) -> Self { Self { media_dir, signalcli_dir, url_root, groupid, + irc_channel, } } @@ -120,7 +123,7 @@ impl<'a> Bridge<'a> { } } - pub async fn signal2irc(self: &Self, signal: Value) -> Option { + pub async fn signal2irc(self: &Self, signal: Value) -> Option<(&str, String)> { let mut result: SignalMessageBuilder = SignalMessageBuilder::default(); if let Value::Object(map) = signal { if let Some(Value::Object(envelope)) = map.get("envelope") { @@ -137,18 +140,18 @@ impl<'a> Bridge<'a> { } } } - result.build() + result.build().map(|e| (self.irc_channel, e)) } - pub fn irc2signal(self: &Self, message: Message) -> Option { + pub fn irc2signal(self: &Self, message: Message) -> Option<(&str, String)> { match (message.prefix, message.command) { (Some(Prefix::Nickname(from, _, _)), Command::PRIVMSG(_, message)) => { - return Some(format!("<{from}>: {message}")) + Some(format!("<{from}>: {message}")) } (Some(Prefix::Nickname(from, _, _)), Command::NOTICE(_, message)) => { - return Some(format!("📜 {from} {message}")) + Some(format!("📜 {from} {message}")) } - _ => return None, - } + _ => None, + }.map(|e| (self.groupid, e)) } }