From 739f7aeeef28cb1b6ac0cb65c51057d239e4203a Mon Sep 17 00:00:00 2001
From: modulatingforce <modulatingforce@gmail.com>
Date: Fri, 31 Jan 2025 21:56:56 -0500
Subject: [PATCH] async trigger cond

---
 readme.md                           |  26 +++---
 src/bin/fun_bot.rs                  |   4 +-
 src/bin/moderator_reactor.rs        |   4 +-
 src/bin/simple_command_bot.rs       |   4 +-
 src/bin/simple_debug_listener.rs    |   4 +-
 src/bin/simple_module.rs            |   4 +-
 src/botcore/bot.rs                  |   2 +-
 src/botcore/bot_objects.rs          |  22 +++--
 src/botcore/bot_objects/command.rs  |  38 ++++++--
 src/botcore/bot_objects/listener.rs |  42 +++++++--
 src/custom_mods/guest_badge.rs      |   6 +-
 src/custom_mods/pyramid.rs          |  78 ++++++++++++++---
 src/lib.rs                          | 129 ++++++++++++++--------------
 13 files changed, 248 insertions(+), 115 deletions(-)

diff --git a/readme.md b/readme.md
index 045e712..55aa65f 100644
--- a/readme.md
+++ b/readme.md
@@ -126,12 +126,10 @@ pub async fn main() {
 
 }
 
-
 pub mod custom_mod {
-    
     use std::sync::Arc;
 
-    use forcebot_rs_v2::{asyncfn_box, Badge, Bot, Command, Module};
+    use forcebot_rs_v2::{execution_async, Badge, Bot, Command, Module};
     use twitch_irc::message::ServerMessage;
 
 
@@ -164,11 +162,12 @@ pub mod custom_mod {
         }
 
         /* 3. Set Command flags */
-        cmd.set_exec_fn(asyncfn_box(execbody));
+        cmd.set_exec_fn(execution_async(execbody));
         cmd.set_admin_only(false);
         cmd.set_min_badge(Badge::Moderator);
 
         cmd
+    }
 }
 
 ```
@@ -179,7 +178,7 @@ Bot with a simple listener that listens for all messages and prints in output
 ```rust
 use std::sync::Arc;
 
-use forcebot_rs_v2::{asyncfn_box, Bot, Listener};
+use forcebot_rs_v2::{execution_async, Bot, Listener};
 use twitch_irc::message::ServerMessage;
 
 #[tokio::main]
@@ -203,7 +202,7 @@ pub async fn main() {
     }
 
     /* 2d. Set and Store the execution body using `async_box()`  */
-    listener.set_exec_fn(asyncfn_box(execbody));
+    listener.set_exec_fn(execution_async(execbody));
 
     /* 3. Load the listener into the bot */
     bot.load_listener(listener);
@@ -220,10 +219,11 @@ pub async fn main() {
 Example listener listens for a moderator badge and reply in chat 
 
 ```rust
+
 use std::sync::Arc;
 
 use forcebot_rs_v2::Bot;
-use forcebot_rs_v2::asyncfn_box;
+use forcebot_rs_v2::execution_async;
 use forcebot_rs_v2::Listener;
 use twitch_irc::message::ServerMessage;
 
@@ -238,10 +238,11 @@ pub async fn main() {
     let mut listener = Listener::new();
 
     /* 2. Set a trigger condition function for listener */
+
     listener.set_trigger_cond_fn(
         |_:Arc<Bot>,message:ServerMessage| 
             if let ServerMessage::Privmsg(msg) = message {
-                
+                // dbg!(msg.clone());
                 for badge in msg.badges {
                     if matches!(badge, x if x.name == "moderator") {
                         // dbg!("moderator found");
@@ -262,7 +263,7 @@ pub async fn main() {
     }
 
     /* 4. Set and Store the execution body using `async_box()`  */
-    listener.set_exec_fn(asyncfn_box(execbody));
+    listener.set_exec_fn(execution_async(execbody));
 
     /* 5. Load the listener into the bot */
     bot.load_listener(listener);
@@ -273,6 +274,7 @@ pub async fn main() {
 }
 
 
+
 ```
 
 ## Simple Test Command
@@ -280,8 +282,9 @@ pub async fn main() {
 ```rust
 use std::sync::Arc;
 
+use forcebot_rs_v2::Badge;
 use forcebot_rs_v2::Bot;
-use forcebot_rs_v2::asyncfn_box;
+use forcebot_rs_v2::execution_async;
 use forcebot_rs_v2::Command;
 use twitch_irc::message::ServerMessage;
 
@@ -305,7 +308,7 @@ pub async fn main() {
     }
 
     /* 3. Set and Store the execution body using `async_box()`  */
-    cmd.set_exec_fn(asyncfn_box(execbody));
+    cmd.set_exec_fn(execution_async(execbody));
 
     /* 4. optionally, remove admin only default flag */
     cmd.set_admin_only(false);
@@ -321,6 +324,7 @@ pub async fn main() {
 
 }
 
+
 ```
 
 # Crate Rust Documentation 
diff --git a/src/bin/fun_bot.rs b/src/bin/fun_bot.rs
index 196ba05..27c67a0 100644
--- a/src/bin/fun_bot.rs
+++ b/src/bin/fun_bot.rs
@@ -41,7 +41,7 @@ pub async fn main() {
 pub mod funbot_objs {
     use std::sync::Arc;
 
-    use forcebot_rs_v2::{asyncfn_box, Badge, Bot, Command, Module};
+    use forcebot_rs_v2::{execution_async, Badge, Bot, Command, Module};
     use twitch_irc::message::ServerMessage;
 
     /// Create a Module with a loaded Command object
@@ -69,7 +69,7 @@ pub mod funbot_objs {
             Result::Err("Not Valid message type".to_string()) 
         }
 
-        cmd.set_exec_fn(asyncfn_box(execbody));
+        cmd.set_exec_fn(execution_async(execbody));
 
         cmd.set_admin_only(false);
         cmd.set_min_badge(Badge::Vip);
diff --git a/src/bin/moderator_reactor.rs b/src/bin/moderator_reactor.rs
index a7bb62c..279d204 100644
--- a/src/bin/moderator_reactor.rs
+++ b/src/bin/moderator_reactor.rs
@@ -14,7 +14,7 @@
 use std::sync::Arc;
 
 use forcebot_rs_v2::Bot;
-use forcebot_rs_v2::asyncfn_box;
+use forcebot_rs_v2::execution_async;
 use forcebot_rs_v2::Listener;
 use twitch_irc::message::ServerMessage;
 
@@ -54,7 +54,7 @@ pub async fn main() {
     }
 
     /* 4. Set and Store the execution body using `async_box()`  */
-    listener.set_exec_fn(asyncfn_box(execbody));
+    listener.set_exec_fn(execution_async(execbody));
 
     /* 5. Load the listener into the bot */
     bot.load_listener(listener);
diff --git a/src/bin/simple_command_bot.rs b/src/bin/simple_command_bot.rs
index 934ddf7..9c2f2ff 100644
--- a/src/bin/simple_command_bot.rs
+++ b/src/bin/simple_command_bot.rs
@@ -17,7 +17,7 @@ use std::sync::Arc;
 
 use forcebot_rs_v2::Badge;
 use forcebot_rs_v2::Bot;
-use forcebot_rs_v2::asyncfn_box;
+use forcebot_rs_v2::execution_async;
 use forcebot_rs_v2::Command;
 use twitch_irc::message::ServerMessage;
 
@@ -41,7 +41,7 @@ pub async fn main() {
     }
 
     /* 3. Set and Store the execution body using `async_box()`  */
-    cmd.set_exec_fn(asyncfn_box(execbody));
+    cmd.set_exec_fn(execution_async(execbody));
 
     /* 4. optionally, remove admin only default flag */
     cmd.set_admin_only(false);
diff --git a/src/bin/simple_debug_listener.rs b/src/bin/simple_debug_listener.rs
index ee129bd..791c5d0 100644
--- a/src/bin/simple_debug_listener.rs
+++ b/src/bin/simple_debug_listener.rs
@@ -12,7 +12,7 @@
 
 use std::sync::Arc;
 
-use forcebot_rs_v2::{asyncfn_box, Bot, Listener};
+use forcebot_rs_v2::{execution_async, Bot, Listener};
 use twitch_irc::message::ServerMessage;
 
 #[tokio::main]
@@ -36,7 +36,7 @@ pub async fn main() {
     }
 
     /* 2d. Set and Store the execution body using `async_box()`  */
-    listener.set_exec_fn(asyncfn_box(execbody));
+    listener.set_exec_fn(execution_async(execbody));
 
     /* 3. Load the listener into the bot */
     bot.load_listener(listener);
diff --git a/src/bin/simple_module.rs b/src/bin/simple_module.rs
index 1204e3a..f9e7bec 100644
--- a/src/bin/simple_module.rs
+++ b/src/bin/simple_module.rs
@@ -37,7 +37,7 @@ pub async fn main() {
 pub mod custom_mod {
     use std::sync::Arc;
 
-    use forcebot_rs_v2::{asyncfn_box, Badge, Bot, Command, Module};
+    use forcebot_rs_v2::{execution_async, Badge, Bot, Command, Module};
     use twitch_irc::message::ServerMessage;
 
 
@@ -70,7 +70,7 @@ pub mod custom_mod {
         }
 
         /* 3. Set Command flags */
-        cmd.set_exec_fn(asyncfn_box(execbody));
+        cmd.set_exec_fn(execution_async(execbody));
         cmd.set_admin_only(false);
         cmd.set_min_badge(Badge::Moderator);
 
diff --git a/src/botcore/bot.rs b/src/botcore/bot.rs
index 71b5cb9..e769efd 100644
--- a/src/botcore/bot.rs
+++ b/src/botcore/bot.rs
@@ -192,7 +192,7 @@ impl Bot
                         for listener in module.get_listeners() {
                         
                             let a = listener.clone();
-                            if a.cond_triggered(bot.clone(),message.clone()) {
+                            if a.cond_triggered(bot.clone(),message.clone()) && a.cond_async_triggered(bot.clone(), message.clone()).await {
                                 
                                 let _ = listener.execute_fn(bot.clone(),message.clone()).await;
                             }
diff --git a/src/botcore/bot_objects.rs b/src/botcore/bot_objects.rs
index 065e08a..cca0423 100644
--- a/src/botcore/bot_objects.rs
+++ b/src/botcore/bot_objects.rs
@@ -25,13 +25,25 @@ pub type ExecBody = Box<
     dyn Fn(Arc<Bot>,ServerMessage) -> Pin<Box<dyn Future<Output = Result<String,String>> + Send>> + Send + Sync,
 >;
 
-pub fn asyncfn_box<T>(f: fn(Arc<Bot>,ServerMessage) -> T) -> ExecBody
+pub fn execution_async<T>(f: fn(Arc<Bot>,ServerMessage) -> T) -> ExecBody
 where
     T: Future<Output = Result<String,String>> + Send + 'static,
 {
     Box::new(move |a,b| Box::pin(f(a,b)))
 }
 
+pub type TrigBody = Box<
+    dyn Fn(Arc<Bot>,ServerMessage) -> Pin<Box<dyn Future<Output = bool> + Send>> + Send + Sync,
+>;
+
+pub fn condition_async<T>(f: fn(Arc<Bot>,ServerMessage) -> T) -> TrigBody
+where
+    T: Future<Output = bool> + Send + 'static,
+{
+    Box::new(move |a,b| Box::pin(f(a,b)))
+}
+
+
 
 
 /// collection of functions to create built in objects
@@ -42,7 +54,7 @@ pub mod built_in_objects {
 
     use twitch_irc::message::ServerMessage;
 
-    use crate::{asyncfn_box, modules::Status, Badge, Bot, Command};
+    use crate::{execution_async, modules::Status, Badge, Bot, Command};
 
 
     /// create a vector of command build in objects
@@ -83,7 +95,7 @@ pub mod built_in_objects {
         }
 
         /* 3. Set and Store the execution body using `async_box()`  */
-        cmd.set_exec_fn(asyncfn_box(execbody));
+        cmd.set_exec_fn(execution_async(execbody));
 
         /* 4. optionally, remove admin only default flag */
         cmd.set_admin_only(false);
@@ -138,7 +150,7 @@ pub mod built_in_objects {
         }
 
         /* 3. Set and Store the execution body using `async_box()`  */
-        cmd.set_exec_fn(asyncfn_box(execbody));
+        cmd.set_exec_fn(execution_async(execbody));
 
         /* 4. optionally, remove admin only default flag */
         cmd.set_admin_only(false);
@@ -241,7 +253,7 @@ pub mod built_in_objects {
         }
 
         /* 3. Set and Store the execution body using `async_box()`  */
-        cmd.set_exec_fn(asyncfn_box(execbody));
+        cmd.set_exec_fn(execution_async(execbody));
 
         /* 4. optionally, remove admin only default flag */
         cmd.set_admin_only(true);
diff --git a/src/botcore/bot_objects/command.rs b/src/botcore/bot_objects/command.rs
index 0cb4249..3314347 100644
--- a/src/botcore/bot_objects/command.rs
+++ b/src/botcore/bot_objects/command.rs
@@ -2,9 +2,9 @@ use std::sync::Arc;
 
 use twitch_irc::message::{PrivmsgMessage, ServerMessage};
 
-use crate::{asyncfn_box, botcore::bot::Bot, Badge};
+use crate::{botcore::{bot::Bot, bot_objects::condition_async}, execution_async, Badge};
 
-use super::ExecBody;
+use super::{ExecBody, TrigBody};
 
 /// Bot `Command` that stores trigger condition callback and a execution functon
 /// 
@@ -16,7 +16,7 @@ use super::ExecBody;
 /// 
 /// AdminOnly commands can only be ran by admin 
 /// 
-/// Use `asyncfn_box()` on custom async execution bodies
+/// Use `execution_async()` on custom async execution bodies
 #[derive(Clone)]
 pub struct Command
 {
@@ -28,6 +28,7 @@ pub struct Command
     admin_override : bool,
     prefix : String,
     custom_cond_fn : fn(Arc<Bot>,PrivmsgMessage) -> bool,
+    custom_cond_async : Arc<TrigBody>,
 }
 
 impl Command
@@ -44,26 +45,51 @@ impl Command
 
         async fn execbody(_:Arc<Bot>,_:ServerMessage) -> Result<String,String> 
         { Result::Ok("success".to_string()) }
+        async fn condition01(_:Arc<Bot>,_:ServerMessage) -> bool { true }
 
         Command {
             commands ,
             prefix ,
-            exec_fn : Arc::new(asyncfn_box(execbody)),
+            exec_fn : Arc::new(execution_async(execbody)),
             min_badge : Badge::Vip,
             admin_only : true,
             admin_override : false ,
             custom_cond_fn : |_:Arc<Bot>,_:PrivmsgMessage| true,
+            custom_cond_async : Arc::new(condition_async(condition01)),
         }
     }
 
-    /// set a trigger conditin callback that returns true if the listener shoud trigger
+    /// set a trigger conditin callback that returns true if the command should trigger
     pub fn set_custom_cond_fn(&mut self,cond_fn: fn(Arc<Bot>,PrivmsgMessage) -> bool) {
         self.custom_cond_fn = cond_fn;
     }
 
+    
+    /// sets the async trigger condition for listener
+    /// 
+    /// Same as `set_custom_cond_fn()` , but async define
+    /// 
+    /// Use`execution_async()` on the async fn when storing
+    /// 
+    /// Example - 
+    /// ```rust
+    /// /* 1. Create a new blank Listener */
+    /// let mut cmd = Command::new();
+    ///
+    /// /* 2. define an async function */
+    /// async fn condition01(_:Arc<Bot>,_:ServerMessage) -> bool { true }
+    /// 
+    /// /* 3. Set and Store the execution body using `async_box()`  */
+    /// cmd.set_custom_cond_async(condition_async(condition01));
+    /// ```
+    /// 
+    pub fn set_custom_cond_async(&mut self,condition:TrigBody ) {
+        self.custom_cond_async = Arc::new(condition);
+    }
+
     /// sets the execution body of the listener for when it triggers
     /// 
-    /// Use`asyncfn_box()` on the async fn when storing
+    /// Use`execution_async()` on the async fn when storing
     /// 
     /// 
     pub fn set_exec_fn(&mut self,exec_fn:ExecBody ) {
diff --git a/src/botcore/bot_objects/listener.rs b/src/botcore/bot_objects/listener.rs
index 2bebb8e..cc170df 100644
--- a/src/botcore/bot_objects/listener.rs
+++ b/src/botcore/bot_objects/listener.rs
@@ -2,9 +2,9 @@ use std::sync::Arc;
 
 use twitch_irc::message::ServerMessage;
 
-use crate::{asyncfn_box, Bot};
+use crate::{botcore::bot_objects::condition_async, execution_async, Bot};
 
-use super::ExecBody;
+use super::{ExecBody, TrigBody};
 
 /// Bot `Listener`` that stores trigger condition callback and a execution functon
 /// 
@@ -14,6 +14,8 @@ pub struct Listener
 {
     /// trigger condition
     trigger_cond_fn : fn(Arc<Bot>,ServerMessage) -> bool,
+    /// trigger condition for async
+    trigger_cond_async : Arc<TrigBody> ,
     /// execution body
     exec_fn : Arc<ExecBody>,
 }
@@ -26,10 +28,11 @@ impl Listener
     pub fn new() -> Listener {
 
         async fn execbody(_:Arc<Bot>,_:ServerMessage) -> Result<String,String> {Result::Ok("success".to_string()) }
-
+        async fn condition01(_:Arc<Bot>,_:ServerMessage) -> bool { true }
         Listener {
             trigger_cond_fn : |_:Arc<Bot>,_:ServerMessage| false,
-            exec_fn : Arc::new(asyncfn_box(execbody))
+            trigger_cond_async : Arc::new(condition_async(condition01)),
+            exec_fn : Arc::new(execution_async(execbody)),
         }
     }
 
@@ -38,6 +41,29 @@ impl Listener
         self.trigger_cond_fn = cond_fn;
     }
 
+    /// sets the async trigger condition for listener
+    /// 
+    /// Same as `set_trigger_cond_fn()` , but async define
+    /// 
+    /// Use`asyncfn_box()` on the async fn when storing
+    /// 
+    /// Example - 
+    /// ```rust
+    /// /* 1. Create a new blank Listener */
+    /// let mut listener = Listener::new();
+    ///
+    /// /* 2. define an async function */
+    /// async fn condition01(_:Arc<Bot>,_:ServerMessage) -> bool { true }
+    /// 
+    /// /* 3. Set and Store the execution body using `async_box()`  */
+    /// listener.set_trigger_cond_async(condition_async(condition01));
+    /// ```
+    /// 
+    pub fn set_trigger_cond_async(&mut self,condition:TrigBody ) {
+        self.trigger_cond_async = Arc::new(condition);
+    }
+    
+
     /// sets the execution body of the listener for when it triggers
     /// 
     /// Use`asyncfn_box()` on the async fn when storing
@@ -60,7 +86,13 @@ impl Listener
 
     /// checks if the trigger condition is met
     pub fn cond_triggered(&self,bot:Arc<Bot>,msg:ServerMessage) -> bool {
-        (self.trigger_cond_fn)(bot,msg)
+        (self.trigger_cond_fn)(bot,msg) 
+    }
+
+    /// executes the listeners executon body
+    pub async fn cond_async_triggered(&self,bot:Arc<Bot>,msg:ServerMessage) -> bool {
+        // (self.exec_fn)(bot,msg)
+        (self.trigger_cond_async)(bot,msg).await
     }
 
     /// executes the listeners executon body
diff --git a/src/custom_mods/guest_badge.rs b/src/custom_mods/guest_badge.rs
index 9e9807c..ee1eb16 100644
--- a/src/custom_mods/guest_badge.rs
+++ b/src/custom_mods/guest_badge.rs
@@ -2,7 +2,7 @@ use std::{sync::Arc, time::{Duration, Instant}};
 
 use twitch_irc::message::ServerMessage;
 
-use crate::{asyncfn_box, Badge, Bot, Command, Module};
+use crate::{execution_async, Badge, Bot, Command, Module};
 
 /// guest_badge / guest module
 /// 
@@ -88,7 +88,7 @@ fn create_cmd_vip() -> Command {
         Result::Err("Not Valid message type".to_string()) 
     }
 
-    cmd.set_exec_fn(asyncfn_box(execbody));
+    cmd.set_exec_fn(execution_async(execbody));
 
     cmd.set_admin_only(false);
     cmd.set_admin_override(true);
@@ -131,7 +131,7 @@ fn create_cmd_mod() -> Command {
         Result::Err("Not Valid message type".to_string()) 
     }
 
-    cmd.set_exec_fn(asyncfn_box(execbody));
+    cmd.set_exec_fn(execution_async(execbody));
 
     cmd.set_admin_only(false);
     cmd.set_admin_override(true);
diff --git a/src/custom_mods/pyramid.rs b/src/custom_mods/pyramid.rs
index 5874a07..de633bb 100644
--- a/src/custom_mods/pyramid.rs
+++ b/src/custom_mods/pyramid.rs
@@ -1,14 +1,17 @@
+
+
 use std::sync::{Arc, Mutex};
 
 use twitch_irc::message::{PrivmsgMessage, ServerMessage};
 
-use crate::{asyncfn_box, Bot, Listener, Module};
+use crate::{condition_async, Badge, Bot, Command, Listener, Module};
 
 /// pyramid module
 /// 
 /// for detecting & handling pyramids
 /// 
-/// 
+/// - listener - detects pyramid
+/// - cmd & listener - interrupts some chatters temporarily
 /// 
 /// 
 use lazy_static::lazy_static;
@@ -38,13 +41,21 @@ fn create_pyramid_detector() -> Listener {
         /* 1. Create a new blank Listener */
         let mut listener = Listener::new();
 
-        /* 2. Set a trigger condition function for listener */
-        listener.set_trigger_cond_fn(
-            |_bot:Arc<Bot>,_message:ServerMessage| 
-                true
-        );
+        /* 2. Define an async trigger condition callback */
+        async fn condition01(bot:Arc<Bot>,message:ServerMessage) -> bool {
+            if let ServerMessage::Privmsg(msg) = message {
+                if detect_pyramid_complete_ok(bot.clone(), msg.clone()).await {
+                    return true;
+                }
+            }
+            false 
+        }
+
+        /* 3. Set a trigger condition function for listener */
+        listener.set_trigger_cond_async(condition_async(condition01));
+
     
-        /* 3. Define an async fn callback execution */
+        /* 4. Define an async fn callback execution */
         async fn execbody(bot:Arc<Bot>,message:ServerMessage) -> Result<String,String> {
             if let ServerMessage::Privmsg(msg) = message {
                 if detect_pyramid_complete_ok(bot.clone(), msg.clone()).await {
@@ -55,8 +66,8 @@ fn create_pyramid_detector() -> Listener {
             Result::Err("Not Valid message type".to_string()) 
         }
     
-        /* 4. Set and Store the execution body using `async_box()`  */
-        listener.set_exec_fn(asyncfn_box(execbody));
+        /* 5. Set and Store the execution body using `async_box()`  */
+        listener.set_exec_fn(Box::new(move |a,b| Box::pin(execbody(a,b))));
 
         listener
 
@@ -109,6 +120,10 @@ lazy_static!{
     pub static ref START_PATTERNS_PER_CHNL: Mutex<Vec<(String,Mutex<String>)>> = Mutex::new(vec![]);
     /// temp message stack checker 
     pub static ref TEMP_MSG_STACK: Mutex<Vec<String>> = Mutex::new(vec![]);
+    
+    /// interruptor targets - (channel:String,chatters:Vec<String>>)
+    pub static ref INTERRUPT_TRG_PER_CHNL: Mutex<Vec<(String,Mutex<Vec<String>>)>>  = Mutex::new(vec![]);
+
 }
 
 fn read_top_of_compare(channel:String) -> Option<String> {
@@ -268,3 +283,46 @@ fn symmetry_ok(channel:String) -> bool {
 
 }
 
+
+/// pyramid interruptor #todo
+/// 
+/// pick chatters that will be interrupted if they solo build
+/// 
+/// takes in arguments as chatters
+/// 
+/// chatters are then interrupted for a random duration under 15m
+/// 
+/// if a duration is given, take that duration eg 15m , 25m 
+/// 
+/// 
+fn create_interruptor_cmd() -> Command {
+    let mut cmd = Command::new(vec![
+        "no pyramid".to_string(),
+        "no pyramids".to_string()
+        ], 
+    "".to_string());
+
+        /* 2. Define an async fn callback execution */
+        async fn execbody(bot:Arc<Bot>,message:ServerMessage) -> Result<String,String> {
+            if let ServerMessage::Privmsg(msg) = message {
+                let _ = bot.client.say_in_reply_to(&msg, String::from("test success")).await;
+                return Result::Ok("Success".to_string()) ;
+            }
+            Result::Err("Not Valid message type".to_string()) 
+        }
+
+        /* 3. Set and Store the execution body using `async_box()`  */
+        cmd.set_exec_fn(Box::new(move |a,b| Box::pin(execbody(a,b))));
+
+        /* 4. optionally, remove admin only default flag */
+        cmd.set_admin_only(false);
+    
+        /* 5. optionally, set min badge*/
+        cmd.set_min_badge(Badge::Moderator);
+
+
+    cmd
+}
+
+
+
diff --git a/src/lib.rs b/src/lib.rs
index cf5fdc9..7981025 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -36,65 +36,65 @@
 //! 
 //! ```rust
 //! use forcebot_rs_v2::Bot;
-//! 
-//! #[tokio::main]
-//! pub async fn main() {
-//! 
-//!     /* Create the bot using env */
-//!     let mut bot = Bot::new();
-//! 
-//!     /* load the Module */
-//!     bot.load_module(custom_mod::new());
-//! 
-//!     /* Run the bot */
-//!     bot.run().await;
-//! 
-//! }
-//! 
-//! 
-//! pub mod custom_mod {
-//!     use std::sync::Arc;
-//! 
-//!     use forcebot_rs_v2::{asyncfn_box, Badge, Bot, Command, Module};
-//!     use twitch_irc::message::ServerMessage;
-//! 
-//! 
-//!     /// Module definition with a loaded command
-//!     pub fn new() -> Module {
-//!         /* 1. Create a new module */
-//!         let mut custom_mod = Module::new(
-//!         vec!["test".to_string()], 
-//!          "".to_string());
-//! 
-//!         /* 2. Load the cmd into a new module */
-//!         custom_mod.load_command(cmd_test());
-//! 
-//!         custom_mod
-//! 
-//!     }
-//! 
-//!     /// Command definition 
-//!     pub fn cmd_test() -> Command {
-//!         /* 1. Create a new cmd */
-//!         let mut cmd = Command::new(vec!["test".to_string()],"".to_string());
-//! 
-//!         /* 2. Define exec callback  */
-//!         async fn execbody(bot:Arc<Bot>,message:ServerMessage) -> Result<String,String> {
-//!             if let ServerMessage::Privmsg(msg) = message {
-//!                 let _= bot.client.say_in_reply_to(
-//!                     &msg, "test return".to_string()).await;
-//!             }
-//!             Result::Err("Not Valid message type".to_string()) 
-//!         }
-//! z
-//!         /* 3. Set Command flags */
-//!         cmd.set_exec_fn(asyncfn_box(execbody));
-//!         cmd.set_admin_only(false);
-//!         cmd.set_min_badge(Badge::Moderator);
-//! 
-//!         cmd
-//!         }
-//! }
+//!    
+//!    #[tokio::main]
+//!    pub async fn main() {
+//!    
+//!        /* Create the bot using env */
+//!        let mut bot = Bot::new();
+//!    
+//!        /* load the Module */
+//!        bot.load_module(custom_mod::new());
+//!    
+//!        /* Run the bot */
+//!        bot.run().await;
+//!    
+//!    }
+//!    
+//!    pub mod custom_mod {
+//!        use std::sync::Arc;
+//!    
+//!        use forcebot_rs_v2::{execution_async, Badge, Bot, Command, Module};
+//!        use twitch_irc::message::ServerMessage;
+//!    
+//!    
+//!        /// Module definition with a loaded command
+//!        pub fn new() -> Module {
+//!            /* 1. Create a new module */
+//!            let mut custom_mod = Module::new(
+//!                vec!["test".to_string()], 
+//!                "".to_string());
+//!    
+//!            /* 2. Load the cmd into a new module */
+//!            custom_mod.load_command(cmd_test());
+//!    
+//!            custom_mod
+//!    
+//!        }
+//!    
+//!        /// Command definition 
+//!        pub fn cmd_test() -> Command {
+//!            /* 1. Create a new cmd */
+//!            let mut cmd = Command::new(vec!["test".to_string()],"".to_string());
+//!    
+//!            /* 2. Define exec callback  */
+//!            async fn execbody(bot:Arc<Bot>,message:ServerMessage) -> Result<String,String> {
+//!                if let ServerMessage::Privmsg(msg) = message {
+//!                    let _= bot.client.say_in_reply_to(
+//!                        &msg, "test return".to_string()).await;
+//!                }
+//!                Result::Err("Not Valid message type".to_string()) 
+//!            }
+//!    
+//!            /* 3. Set Command flags */
+//!            cmd.set_exec_fn(execution_async(execbody));
+//!            cmd.set_admin_only(false);
+//!            cmd.set_min_badge(Badge::Moderator);
+//!    
+//!            cmd
+//!        }
+//!    }
+//!    
 //! 
 //! ```
 //! 
@@ -104,7 +104,7 @@
 //! ```rust
 //! use std::sync::Arc;
 //! 
-//! use forcebot_rs_v2::{asyncfn_box, Bot, Listener};
+//! use forcebot_rs_v2::{execution_async, Bot, Listener};
 //! use twitch_irc::message::ServerMessage;
 //! 
 //! #[tokio::main]
@@ -128,7 +128,7 @@
 //!     }
 //! 
 //!     /* 2d. Set and Store the execution body using `async_box()`  */
-//!     listener.set_exec_fn(asyncfn_box(execbody));
+//!     listener.set_exec_fn(execution_async(execbody));
 //! 
 //!     /* 3. Load the listener into the bot */
 //!     bot.load_listener(listener);
@@ -147,7 +147,7 @@
 //! use std::sync::Arc;
 //! 
 //! use forcebot_rs_v2::Bot;
-//! use forcebot_rs_v2::asyncfn_box;
+//! use forcebot_rs_v2::execution_async;
 //! use forcebot_rs_v2::Listener;
 //! use twitch_irc::message::ServerMessage;
 //! 
@@ -187,7 +187,7 @@
 //!     }
 //! 
 //!     /* 4. Set and Store the execution body using `async_box()`  */
-//!     listener.set_exec_fn(asyncfn_box(execbody));
+//!     listener.set_exec_fn(execution_async(execbody));
 //! 
 //!     /* 5. Load the listener into the bot */
 //!     bot.load_listener(listener);
@@ -202,7 +202,8 @@
 pub mod botcore;
 pub mod custom_mods;
 pub use crate::botcore::bot::Bot;
-pub use crate::botcore::bot_objects::asyncfn_box;
+pub use crate::botcore::bot_objects::execution_async;
+pub use crate::botcore::bot_objects::condition_async;
 pub use crate::botcore::bot_objects::listener::Listener;
 pub use crate::botcore::bot_objects::command::Command;
 pub use crate::botcore::modules::Module;