From ad40be1870cc759e235d59ca4b8950380a1f958d Mon Sep 17 00:00:00 2001 From: Kubat <mael.martin31@gmail.com> Date: Wed, 15 Dec 2021 18:06:41 +0100 Subject: [PATCH] Clean the code + switch for reaction handler --- mgb.ini | 15 +++--- src/config.rs | 9 +++- src/matrix.rs | 146 +++++++++++++++++++++++++++----------------------- 3 files changed, 96 insertions(+), 74 deletions(-) diff --git a/mgb.ini b/mgb.ini index aee6c9b..47a6bec 100644 --- a/mgb.ini +++ b/mgb.ini @@ -1,12 +1,13 @@ [user] -id = "@some_id:matrix.org" -password = no-password -display_name = MGB-Hitagi +id=@some_id\:matrix.org +password=no-password +display_name=MGB-Hitagi [handler] -state_member = true +state_member=false +reaction=true [basic] -name = basic package -acl = any -admins = @martin2018:iiens.net +name=basic package +acl=any +admins=@some_id\:matrix.org diff --git a/src/config.rs b/src/config.rs index a2696c5..e2adb25 100644 --- a/src/config.rs +++ b/src/config.rs @@ -12,6 +12,7 @@ pub struct Config { pub user_password: String, // The true user name pub handle_state_member: bool, // Install handler for state memver changes + pub handle_reaction: bool, // Install handler for emoji reactions ini_handler: Ini, } @@ -49,6 +50,9 @@ pub fn from_file(file_name: &String) -> Result<Config, String> { let handle_state_member_str = conf .get_from_or(Some("handler"), "state_member", "true") .to_string(); + let handle_reaction_str = conf + .get_from_or(Some("handler"), "reaction", "true") + .to_string(); return match Url::parse(hs_url_str) { Err(e) => Err(e.to_string()), Ok(hs_url) => Ok(Config { @@ -64,6 +68,8 @@ pub fn from_file(file_name: &String) -> Result<Config, String> { homeserver_url: hs_url, handle_state_member: <bool as FromStr>::from_str(&handle_state_member_str) .unwrap_or(false), + handle_reaction: <bool as FromStr>::from_str(&handle_reaction_str) + .unwrap_or(false), ini_handler: conf, }), }; @@ -78,7 +84,8 @@ pub fn write_default(file_name: &String) -> Result<(), String> { .set("password", "no-password") .set("display_name", "MGB-Hitagi"); conf.with_section(Some("handler")) - .set("state_member", "true"); + .set("state_member", "false") + .set("reaction", "true"); conf.with_section(Some("basic")) .set("name", "basic package") .set("acl", "any") diff --git a/src/matrix.rs b/src/matrix.rs index 08896e4..48b7abc 100644 --- a/src/matrix.rs +++ b/src/matrix.rs @@ -81,9 +81,83 @@ async fn startup_and_log_rooms(client: &Client) { join_all(list_to_wait_for).await; } +async fn on_msg_room_event( + ev: SyncMessageEvent<MessageEventContent>, + room: Room, + __info: Option<EncryptionInfo>, +) { + let sender_id = ev.sender.clone(); + return_if!(sender_id.as_str() == room.own_user_id().as_str(), ()); + + if let (Room::Joined(joined), MessageType::Text(TextMessageEventContent { ref body, .. })) = + (room, ev.content.msgtype.clone()) + { + if body.starts_with("%") { + if let Some(stripped) = body.strip_prefix("%") { + let args = stripped.split(' ').collect::<Vec<&str>>(); + let mut res: String = format!("Command not found"); + if let Some(pkg) = GLOBAL_PKG + .lock() + .unwrap() + .iter() + .find(|x| x.has_command(&args)) + { + res = pkg.handle(&joined, &sender_id, args); + } + + let event = ev.into_full_event(joined.room_id().clone()); + let msg = AnyMessageEventContent::RoomMessage( + MessageEventContent::text_reply_html(res.clone(), res, &event), + ); + joined.send(msg, None).await.unwrap(); + } + } + }; +} + +async fn on_msg_room_reaction( + ev: SyncMessageEvent<ReactionEventContent>, + room: Room, + _: Option<EncryptionInfo>, +) { + let sender_id = ev.sender.clone(); + return_if!(sender_id.as_str() == room.own_user_id().as_str(), ()); + if let ( + Room::Joined(joined), + ReactionEventContent { + relates_to: Relation { + emoji, event_id, .. + }, + .. + }, + ) = (room, ev.content) + { + let msg_content = format!( + "Not handled reactions in room {} with event {event_id}, emoji was {emoji}", + joined.room_id() + ); + let msg = AnyMessageEventContent::RoomMessage(MessageEventContent::text_html( + msg_content.clone(), + msg_content, + )); + joined.send(msg, None).await.unwrap(); + }; +} + static GLOBAL_PKG: SyncLazy<Arc<Mutex<Vec<CmdPackage>>>> = SyncLazy::new(|| Arc::new(Mutex::new(Vec::<CmdPackage>::new()))); +macro_rules! register_handler_if_enabled { + ($client: expr, $config: expr, $handler: expr, $handler_name: expr) => {{ + if ($config) { + info!("Handle {} events", $handler_name); + ($client).register_event_handler($handler).await; + } else { + warn!("Ignore {} events", $handler_name); + } + }}; +} + pub async fn connect_and_handle(config: Config) -> Result<()> { // TODO: Refactor let pkg_commands_vec = vec![ @@ -98,65 +172,6 @@ pub async fn connect_and_handle(config: Config) -> Result<()> { }; GLOBAL_PKG.lock().unwrap().push(pkg); - let on_msg_room_reaction = |ev: SyncMessageEvent<ReactionEventContent>, - room: Room, - _: Option<EncryptionInfo>| async move { - let sender_id = ev.sender.clone(); - return_if!(sender_id.as_str() == room.own_user_id().as_str(), ()); - if let ( - Room::Joined(joined), - ReactionEventContent { - relates_to: Relation { - emoji, event_id, .. - }, - .. - }, - ) = (room, ev.content) - { - let msg_content = format!( - "Not handled reactions in room {} with event {event_id}, emoji was {emoji}", - joined.room_id() - ); - let msg = AnyMessageEventContent::RoomMessage(MessageEventContent::text_html( - msg_content.clone(), - msg_content, - )); - joined.send(msg, None).await.unwrap(); - }; - }; - - let on_msg_room_event = |ev: SyncMessageEvent<MessageEventContent>, - room: Room, - __info: Option<EncryptionInfo>| async { - let sender_id = ev.sender.clone(); - return_if!(sender_id.as_str() == room.own_user_id().as_str(), ()); - - if let (Room::Joined(joined), MessageType::Text(TextMessageEventContent { ref body, .. })) = - (room, ev.content.msgtype.clone()) - { - if body.starts_with("%") { - if let Some(stripped) = body.strip_prefix("%") { - let args = stripped.split(' ').collect::<Vec<&str>>(); - let mut res: String = format!("Command not found"); - if let Some(pkg) = GLOBAL_PKG - .lock() - .unwrap() - .iter() - .find(|x| x.has_command(&args)) - { - res = pkg.handle(&joined, &sender_id, args); - } - - let event = ev.into_full_event(joined.room_id().clone()); - let msg = AnyMessageEventContent::RoomMessage( - MessageEventContent::text_reply_html(res.clone(), res, &event), - ); - joined.send(msg, None).await.unwrap(); - } - } - }; - }; - let alice = UserId::try_from(config.user_name)?; let client = Client::new(config.homeserver_url)?; @@ -171,14 +186,13 @@ pub async fn connect_and_handle(config: Config) -> Result<()> { info!("Logged as: {}", alice); client.sync_once(SyncSettings::default()).await?; - startup_and_log_rooms(&client).await; - if config.handle_state_member { - info!("Handle state member events"); - client.register_event_handler(on_state_member).await; - } else { - warn!("Ignore state member events"); - } + register_handler_if_enabled!( + client, + config.handle_state_member, + on_state_member, + "state member" + ); client.register_event_handler(on_msg_room_event).await; client.register_event_handler(on_msg_room_reaction).await; -- GitLab