From 8eecaff8e577546de6057d589beb820220360d72 Mon Sep 17 00:00:00 2001 From: Kubat <mael.martin31@gmail.com> Date: Fri, 24 Dec 2021 12:09:34 +0100 Subject: [PATCH] Basic reaction based command support --- src/bot.rs | 21 ++++++++++++++++----- src/cmd/mod.rs | 24 +++++++++++++++++++++--- src/cmd/package.rs | 17 ++++++++++++----- src/main.rs | 10 ++++++++-- 4 files changed, 57 insertions(+), 15 deletions(-) diff --git a/src/bot.rs b/src/bot.rs index 8b83d56..0905591 100644 --- a/src/bot.rs +++ b/src/bot.rs @@ -20,6 +20,7 @@ use matrix_sdk::{ }, UserId, }, + uuid::Uuid, Client, Result, SyncSettings, }; use std::{ @@ -109,21 +110,31 @@ async fn on_msg_room_event( 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 + let (res, emojies) = match GLOBAL_PKG .lock() .unwrap() .iter() .find(|x| x.has_command(&args)) { - res = pkg.handle(&joined, &sender_id, args); - } + Some(pkg) => { + let (res, emojies) = pkg.handle(&joined, &sender_id, args); + (res, emojies.clone()) + } + None => (format!("Command not found"), vec![]), + }; 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 msg_uuid = Uuid::new_v4(); + let send_id = joined.send(msg, Some(msg_uuid)).await.unwrap().event_id; + for emoji in emojies { + let msg_emoji = AnyMessageEventContent::Reaction(ReactionEventContent::new( + Relation::new(send_id.clone(), emoji.clone()), + )); + joined.send(msg_emoji, None).await.unwrap(); + } } } }; diff --git a/src/cmd/mod.rs b/src/cmd/mod.rs index e4da64f..3d911dd 100644 --- a/src/cmd/mod.rs +++ b/src/cmd/mod.rs @@ -20,6 +20,7 @@ pub struct Cmd { name: String, argc: u32, handler: CmdHandler, + feedback_emojies: Vec<String>, } impl Cmd { @@ -27,6 +28,10 @@ impl Cmd { (self.name == *name) && (self.argc as usize == args.len()) } + pub fn get_emojies(&self) -> &Vec<String> { + &self.feedback_emojies + } + pub fn exec(&self, args: Vec<&str>) -> String { if args.len() != self.argc as usize { error!("Arg count doesn't match"); @@ -47,7 +52,12 @@ impl Cmd { &self.name } - pub fn new_simple<F: 'static>(name: String, argc: u32, f: F) -> Cmd + pub fn new_simple<F: 'static>( + name: String, + argc: u32, + f: F, + emojies: Option<Vec<String>>, + ) -> Cmd where F: Fn(Vec<&str>) -> bool + Send + Sync, { @@ -55,10 +65,11 @@ impl Cmd { name: name, argc: argc, handler: CmdHandler::Simple(Box::new(f)), + feedback_emojies: emojies.or(Some(vec![])).unwrap(), } } - pub fn new_echo<F: 'static>(name: String, argc: u32, f: F) -> Cmd + pub fn new_echo<F: 'static>(name: String, argc: u32, f: F, emojies: Option<Vec<String>>) -> Cmd where F: Fn(Vec<&str>) -> String + Send + Sync, { @@ -66,10 +77,16 @@ impl Cmd { name: name, argc: argc, handler: CmdHandler::Echo(Box::new(f)), + feedback_emojies: emojies.or(Some(vec![])).unwrap(), } } - pub fn new_multi_echo<F: 'static>(name: String, argc: u32, f: F) -> Cmd + pub fn new_multi_echo<F: 'static>( + name: String, + argc: u32, + f: F, + emojies: Option<Vec<String>>, + ) -> Cmd where F: Fn(Vec<&str>) -> Vec<String> + Send + Sync, { @@ -77,6 +94,7 @@ impl Cmd { name: name, argc: argc, handler: CmdHandler::MultiEcho(Box::new(f)), + feedback_emojies: emojies.or(Some(vec![])).unwrap(), } } } diff --git a/src/cmd/package.rs b/src/cmd/package.rs index ce9199e..604a806 100644 --- a/src/cmd/package.rs +++ b/src/cmd/package.rs @@ -30,18 +30,25 @@ impl CmdPackage { } } - pub fn handle(&self, room: &JoinedRoom, user_id: &UserId, user_cmd: Vec<&str>) -> String { + pub fn handle( + &self, + room: &JoinedRoom, + user_id: &UserId, + user_cmd: Vec<&str>, + ) -> (String, &Vec<String>) { + static EMPTY_VEC: Vec<String> = vec![]; + match CmdAcl::action_permited(&self.admin_register, &self.acl, room, user_id) { - Err(string) => "Action not permited: ".to_string() + &string, + Err(string) => ("Action not permited: ".to_string() + &string, &EMPTY_VEC), Ok(()) => match user_cmd.split_first() { - None => "No command was passed".to_string(), + None => ("No command was passed".to_string(), &EMPTY_VEC), Some((name, args)) => match self .commands .iter() .find(|x| x.matches(name, &args.to_vec())) { - None => "Command not found".to_string(), - Some(command) => command.exec(args.to_vec()), + None => ("Command not found".to_string(), &EMPTY_VEC), + Some(command) => (command.exec(args.to_vec()), command.get_emojies()), }, }, } diff --git a/src/main.rs b/src/main.rs index 6deef15..2ce737c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -22,8 +22,14 @@ async fn main() -> matrix_sdk::Result<()> { info!("EMOJI MINUX: {}", EMOJI_MINUS); let basic_cmds = vec![ - Cmd::new_simple(format!("ping"), 0, |_x| true), - Cmd::new_echo(format!("bot_name"), 0, |_x| format!("toto")), + Cmd::new_simple(format!("ping"), 0, |_x| true, None), + Cmd::new_echo(format!("bot_name"), 0, |_x| format!("toto"), None), + Cmd::new_echo( + format!("react"), + 0, + |_| format!("React to the following"), + Some(vec![":1".to_string(), ":2".to_string()]), + ), ]; let mut bot = Bot::new(env::args().last().unwrap()); -- GitLab