/* Custom Modules - Usage : [ ] within the file's init(), define BotActions & Load them into the ModulesManager [ ] Define Execution Bodies for these BotActions [ ] Afterwards, add the following to parent modules.rs file - mod <modulename>; - within init(), <modulename>::init(mgr).await */ const OF_CMD_CHANNEL:Channel = Channel(String::new()); use std::sync::Arc; use chrono::{TimeZone,Local}; use twitch_irc::message::ReplyToMessage; use crate::core::bot_actions::ExecBodyParams; use crate::core::botinstance::Channel; use crate::core::botlog; use casual_logger::Log; use crate::core::bot_actions::actions_util; use crate::core::botmodules::{BotActionTrait, BotCommand, BotModule, ModulesManager}; use crate::core::identity::UserRole::*; pub async fn init(mgr: Arc<ModulesManager>) { // 1. Define the BotAction let botc1 = BotCommand { module: BotModule(String::from("experiments002")), command: String::from("say"), // command call name alias: vec![ "s".to_string(), ], // String of alternative names exec_body: actions_util::asyncbox(sayout), help: String::from("Test Command tester"), required_roles: vec![ BotAdmin, // Mod(OF_CMD_CHANNEL), VIP(OF_CMD_CHANNEL), ], }; // 2. Add the BotAction to ModulesManager botc1.add_to_modmgr(Arc::clone(&mgr)).await; // If enabling by defauling at instance level , uncomment the following // mgr.set_instance_enabled(BotModule(String::from("experiments002"))).await; } async fn sayout(params : ExecBodyParams) { /* usage : <target channel> <message> */ let reply_parent = if let Some(Some(reply)) = params.msg.source.tags.0.get("reply-parent-msg-body") { Some(reply) } else { None } ; let reply_parent_ts = if let Some(Some(replyts)) = params.msg.source.tags.0.get("tmi-sent-ts") { let a: i64 = replyts.parse().unwrap(); let b = Local.timestamp_millis_opt(a).unwrap(); Some(b.format("%m-%d %H:%M")) } else { None } ; // [x] Unwraps arguments from message let argrslt = if let Some((_,str1)) = params.msg.message_text.split_once(' ') { if reply_parent.is_none() { if let Some((channelstr,msgstr)) = str1.split_once(' ') { Some((channelstr,msgstr)) } else { None } } else if let Some((_,str2)) = str1.split_once(' ') { if let Some((channelstr,msgstr)) = str2.split_once(' ') { Some((channelstr,msgstr)) } else { None } } else { None } } else { None }; match argrslt { Some((trgchnl,outmsg)) => { let bot = Arc::clone(¶ms.bot); let botlock = bot.read().await; // [x] Validate first if trgchnl exists botlog::trace( &format!("[TRACE] Evaluated status of {} : {:?}", trgchnl.to_string().clone(),botlock.botmgrs.chat.client.get_channel_status(trgchnl.to_string().clone()).await), Some("Chat > send_botmsg".to_string()), None, ); /* 1. If a Reply , [ ] Get Parent Content message - reply_parent [ ] Get Parent Chatter - reply_parent_usr [ ] Get Parent Channel - msg.channel_login -> Share this first then [ ] Get Reply Message (that triggered bot command) - msgstr [ ] Get Reply Sender - msg.sender.name [ ] Get Target Channel - trgchnl 2. If not a reply [ ] Get Reply Message (that triggered bot command) - msgstr [ ] Get Reply Sender - msg.sender.name [ ] Get Target Channel - trgchnl */ // reply_parent_ts let newoutmsg = if let Some(srcmsg) = reply_parent { format!("{} {} @ {} : {}", reply_parent_ts.unwrap(), params.msg.sender.name, params.msg.channel_login, srcmsg) } else { format!("in {} - {} : {}", params.msg.channel_login, params.msg.sender.name, outmsg) }; botlock .botmgrs .chat .say( trgchnl.to_string(), newoutmsg.to_string(), params.clone(), ).await; }, None => { botlog::debug( "sayout had issues trying to parse arguments", Some("experiment002 > sayout".to_string()), Some(¶ms.msg), ); let bot = Arc::clone(¶ms.bot); let botlock = bot.read().await; // uses chat.say_in_reply_to() for the bot controls for messages botlock .botmgrs .chat .say_in_reply_to( Channel(params.clone().msg.channel_login().to_string()), params.clone().msg.message_id().to_string(), String::from("Invalid arguments"), params.clone() ).await; }, } Log::flush(); }