debug module and fix issue with modules

This commit is contained in:
modulatingforce 2025-02-03 21:33:44 -05:00
parent 5a02b090c6
commit 1e522940c9
18 changed files with 360 additions and 93 deletions
forcebot_core/src
moderator_reactor/src
new_empty_bot/src
readme.md
simple_command_bot/src
simple_debug_listener/src
simple_module_example/src

View file

@ -18,7 +18,7 @@
//! - More Info - <https://dev.twitch.tv/docs/authentication>
// use forcebot_rs_v2::{custom_mods::{guest_badge, pyramid}, Bot};
use forcebot_core::{custom_mods::{guest_badge, pyramid}, Bot};
use forcebot_core::{custom_mods::{debug, guest_badge, pyramid}, Bot};
@ -26,7 +26,7 @@ use forcebot_core::{custom_mods::{guest_badge, pyramid}, Bot};
pub async fn main() {
/* Create the bot using env */
let mut bot = Bot::new();
let bot = Bot::new().await;
/* 1. Load the module into the bot */
bot.load_module(funbot_objs::create_module()).await;
@ -34,6 +34,7 @@ pub async fn main() {
/* 2. Load Custom Modules */
bot.load_module(guest_badge::create_module()).await;
bot.load_module(pyramid::create_module()).await;
bot.load_module(debug::create_module()).await;
/* 3. Run the bot */
bot.run().await;

View file

@ -16,7 +16,7 @@ use forcebot_core::Bot;
pub async fn main() {
/* 1. Create the bot using env */
let bot = Bot::new();
let bot = Bot::new().await;
/* 2. Run the bot */
bot.run().await;

View file

@ -0,0 +1,47 @@
//! Example simple Binary crate that creates & runs bot based on `.env`
//! Be sure the followig is defined in `.env`
//! - login_name
//! - access_token
//! - bot_channels
//! - prefix
//! - bot_admins
//!
//! Bot access tokens be generated here -
//! - Get a Bot Chat Token here - <https://twitchtokengenerator.com>
//! - More Info - <https://dev.twitch.tv/docs/authentication>
use std::sync::Arc;
use forcebot_core::{execution_async, Bot, Listener};
use twitch_irc::message::ServerMessage;
#[tokio::main]
pub async fn main() {
/* 1. Create the bot using env */
let bot = Bot::new().await;
/* 2a. Create a new blank Listener */
let mut listener = Listener::new();
/* 2b. Set a trigger condition function for listener */
listener.set_trigger_cond_fn(
|_:Arc<Bot>,_:ServerMessage| true
);
/* 2c. Define an async fn callback execution */
async fn execbody(_:Arc<Bot>,message:ServerMessage) -> Result<String,String> {
dbg!(message); /* outputs message to debug */
Result::Ok("Success".to_string())
}
/* 2d. Set and Store the execution body using `async_box()` */
listener.set_exec_fn(execution_async(execbody));
/* 3. Load the listener into the bot */
bot.load_listener(listener).await;
/* 4. Run the bot */
bot.run().await;
}

View file

@ -23,7 +23,7 @@ use forcebot_core::Bot;
pub async fn main() {
/* Create the bot using env */
let mut bot = Bot::new();
let bot = Bot::new().await;
/* load the Module */
bot.load_module(custom_mod::new()).await;

View file

@ -3,7 +3,7 @@
use tokio::sync::{mpsc::UnboundedReceiver, Mutex};
use twitch_irc::{login::StaticLoginCredentials, message::{PrivmsgMessage, ServerMessage}, SecureTCPTransport, TwitchIRCClient};
use dotenv::dotenv;
use std::{env, sync::Arc, time::{Duration, Instant}};
use std::{env, sync::{Arc, RwLock}, time::{Duration, Instant}};
// use crate::{Badge, Command, Listener, Module};
use super::bot_objects::command::Command;
@ -30,13 +30,13 @@ pub struct Bot
/// admin chatters
admins : Vec<String>,
/// listeners
listeners: Vec<Listener>,
listeners: Mutex<Vec<Listener>>,
/// commands
commands: Vec<Command>,
commands: Mutex<Vec<Command>>,
/// modules
modules: Vec<Module>,
modules: RwLock<Vec<Module>>,
/// channel module status
channel_module_status: Mutex<Vec<(String,String,modules::Status)>>,
channel_module_status: RwLock<Vec<(String,String,modules::Status)>>,
/// chatter guest badges - chatter,channel,Badge,start_time,duration
chatter_guest_badges: Mutex<Vec<(String,String,Badge,Instant,Duration)>>,
/// Message cache
@ -55,7 +55,7 @@ impl Bot
/// - bot_channels
/// - prefix
/// - bot_admins
pub fn new() -> Bot {
pub async fn new() -> Bot {
@ -72,7 +72,7 @@ impl Bot
botchannels.push(chnl.to_owned());
}
Bot::new_from(bot_login_name, oauth_token, prefix, botchannels)
Bot::new_from(bot_login_name, oauth_token, prefix, botchannels).await
}
@ -80,7 +80,7 @@ impl Bot
/// Creates a new `Bot` using bot information
///
/// Bot will join `botchannels` argument
pub fn new_from(bot_login_name:String,oauth_token:String,prefix:String,botchannels:Vec<String>) -> Bot {
pub async fn new_from(bot_login_name:String,oauth_token:String,prefix:String,botchannels:Vec<String>) -> Bot {
dotenv().ok();
let bot_login_name = bot_login_name;
@ -106,22 +106,22 @@ impl Bot
}
let mut bot = Bot {
let bot = Bot {
prefix,
incoming_msgs : Mutex::new(incoming_messages),
client,
botchannels : botchannels_all,
listeners : vec![],
commands : vec![],
listeners : Mutex::new(vec![]),
commands : Mutex::new(vec![]),
admins,
modules: vec![],
channel_module_status: Mutex::new(vec![]),
modules: RwLock::new(vec![]),
channel_module_status: RwLock::new(vec![]),
chatter_guest_badges: Mutex::new(vec![]),
message_cache : Mutex::new(vec![]),
};
for cmd in built_in_objects::create_commands() {
bot.load_command(cmd);
bot.load_command(cmd).await;
}
bot
@ -143,8 +143,8 @@ impl Bot
while let Some(message) = in_msgs_lock.recv().await {
for listener in &(*bot).listeners {
let bot_listener_lock = bot.listeners.lock().await;
for listener in bot_listener_lock.iter() {
let a = listener.clone();
if a.cond_triggered(bot.clone(),message.clone()).await {
@ -160,8 +160,8 @@ impl Bot
// dbg!(cache_lock.clone());
drop(cache_lock);
for cmd in &(*bot).commands {
let cmd_lock = bot.commands.lock().await;
for cmd in cmd_lock.iter() {
let a = cmd.clone();
if a.command_triggered(bot.clone(),msg.clone()).await {
@ -171,40 +171,61 @@ impl Bot
}
'module_loop: for module in &(*bot).modules {
// skip modules that are disable
let cms_lock = bot.channel_module_status.lock().await;
fn get_enabled_channel_modules(bot: Arc<Bot>,channel:String) -> Vec<Module> {
let botmodules_lock = bot.modules.read().unwrap();
let botmodules_cpy = botmodules_lock.clone();
drop(botmodules_lock);
let mut enabled_mods = Vec::new();
'module_loop: for module in &*botmodules_cpy {
// dbg!("try cms read");
let cms_lock = bot.channel_module_status.read().unwrap();
// dbg!("cms read lock");
// dbg!(module.get_names());
for channel_flags in cms_lock.iter() {
if channel_flags.0 == msg.channel_login.clone() {
if channel_flags.0 == channel {
if module.get_names().contains(&channel_flags.1) && channel_flags.2 == Status::Disabled {
continue 'module_loop;
// disabled_mods.push(module);
}
}
}
for listener in module.get_listeners() {
let a = listener.clone();
if a.cond_triggered(bot.clone(),message.clone()).await {
let _ = listener.execute_fn(bot.clone(),message.clone()).await;
}
}
for cmd in module.get_commands() {
let a = cmd.clone();
if a.command_triggered(bot.clone(),msg.clone()).await {
let _ = cmd.execute_fn(bot.clone(),message.clone()).await;
}
}
enabled_mods.push(module.clone());
}
enabled_mods
}
for module in get_enabled_channel_modules(bot.clone(), msg.clone().channel_login) {
for listener in module.get_listeners() {
let a = listener.clone();
if a.cond_triggered(bot.clone(),message.clone()).await {
let _ = listener.execute_fn(bot.clone(),message.clone()).await;
}
}
for cmd in module.get_commands() {
let a = cmd.clone();
if a.command_triggered(bot.clone(),msg.clone()).await {
let _ = cmd.execute_fn(bot.clone(),message.clone()).await;
}
}
}
} else {} ;
@ -217,20 +238,25 @@ impl Bot
}
/// Loads a `Listener` into the bot
pub fn load_listener(&mut self,l : Listener) {
self.listeners.push(l);
pub async fn load_listener(&self,l : Listener) {
let a = Arc::new(self);
let mut listlock = a.listeners.lock().await;
listlock.push(l);
}
/// Loads a `Command` into the bot
pub fn load_command(&mut self,c : Command) {
self.commands.push(c);
pub async fn load_command(&self,c : Command) {
let a = Arc::new(self);
let mut cmdlock = a.commands.lock().await;
cmdlock.push(c);
}
pub fn get_module(&self,module:String) -> Option<Module> {
for modl in self.modules.clone() {
pub async fn get_module(&self,module:String) -> Option<Module> {
let modlock = self.modules.read().unwrap();
for modl in modlock.iter() {
if modl.get_names().contains(&module) {
return Some(modl);
return Some(modl.clone());
}
}
None
@ -247,20 +273,35 @@ impl Bot
}
/// loads a `Module` and its bot objects
pub async fn load_module(&mut self,m: Module) {
pub async fn load_module(&self,m: Module) {
// dbg!("load module - start",m.get_names().first().unwrap());
let bot = Arc::new(self);
// let bot_lock = bot.lock().await;
// dbg!("bot arc");
if m.get_status_by_default() == Status::Disabled {
for chnl in &self.botchannels {
self.disable_module(chnl.clone(),
// dbg!("module fund disabled by default");
// dbg!("inner if");
for (_index,chnl) in bot.botchannels.iter().enumerate() {
// dbg!("iter - ",index);
bot.disable_module(chnl.clone(),
m.get_names().first().unwrap().clone()).await
}
}
self.modules.push(m)
// dbg!("aftee disable check");
// dbg!(bot.modules);
let mut botmods = bot.modules.write().unwrap();
// dbg!(m);
// dbg!("loading module ",m.get_names());
botmods.push(m);
}
pub async fn get_channel_module_status(&self,channel:String,module:String) -> Status {
// dbg!("get channel module status");
let found_disabled:bool = {
let cms_lock = self.channel_module_status.lock().await;
// dbg!("try cms read");
let cms_lock = self.channel_module_status.read().unwrap();
// dbg!("cms read lock");
// dbg!(module.clone());
let mut found = false;
for channel_flags in cms_lock.iter() {
@ -272,15 +313,37 @@ impl Bot
}
found
};
let module_loaded:bool = {
let mut loaded_yn = false;
for loaded_m in self.modules.read().unwrap().iter() {
if loaded_m.get_names().contains(&module) {
loaded_yn = true;
}
}
loaded_yn
};
if found_disabled { return Status::Disabled;}
else if !module_loaded { return Status::NotLoaded ;}
else { return Status::Enabled; };
}
pub async fn disable_module(&self,channel:String,module:String){
// dbg!("disable module called",channel.clone(),module.clone());
let found_disabled:bool = {
let cms_lock = self.channel_module_status.lock().await;
// dbg!("finding disabled mod");
// dbg!("try cms read");
let cms_lock = self.channel_module_status.read().unwrap();
// dbg!("cms read lock");
// dbg!(module.clone());
let mut found = false;
@ -291,13 +354,20 @@ impl Bot
}
}
}
drop(cms_lock);
found
};
if !found_disabled {
let mut cms_lock = self.channel_module_status.lock().await;
cms_lock.push((channel,module,Status::Disabled));
// self.channel_module_status.
// dbg!("try cms write"); /*,self.channel_module_status */
let mut cms_lock = self.channel_module_status.write().unwrap();
// cms_lock.
// dbg!("cms write lock");
cms_lock.push((channel,module.clone(),Status::Disabled));
// dbg!(module.clone());
drop(cms_lock);
}
@ -306,8 +376,12 @@ impl Bot
}
pub async fn enable_module(&self,channel:String,module:String){
let mut lock = self.channel_module_status.lock().await;
if lock.contains(&(channel.clone(),module.clone(),Status::Disabled)) {
// dbg!("enable module called",channel.clone(),module.clone());
// dbg!("try cms write");
let mut lock = self.channel_module_status.write().unwrap();
// dbg!("cms write lock");
// dbg!(module.clone());
while lock.contains(&(channel.clone(),module.clone(),Status::Disabled)) {
let index = lock
.iter()
@ -316,6 +390,7 @@ impl Bot
.unwrap();
lock.remove(index);
}
drop(lock);
}
pub async fn get_channel_guest_badges(&self,chatter:String,channel:String) -> Vec<(Badge,Instant,Duration)> {

View file

@ -184,7 +184,7 @@ pub mod built_in_objects {
bot.enable_module(msg.channel_login.clone(), arg.to_string()).await;
//bot.get_modules()
if let Some(found_mod) = bot.get_module(arg.to_string()) {
if let Some(found_mod) = bot.get_module(arg.to_string()).await {
bot_message = bot_message.to_string() + found_mod.get_bot_read_description().as_str();
}
re_enabled = true;

View file

@ -6,7 +6,8 @@ use super::bot_objects::listener::Listener;
#[derive(PartialEq, Eq,Debug,Clone)]
pub enum Status {
Disabled,
Enabled
Enabled,
NotLoaded,
}
/// Bot `Module` that groups a set of `bot_objects`

View file

@ -1,2 +1,3 @@
pub mod guest_badge;
pub mod pyramid;
pub mod pyramid;
pub mod debug;

View file

@ -0,0 +1,146 @@
use std::sync::{Arc};
use crate::{execution_async, modules::Status, Bot, Command, Listener, Module};
use twitch_irc::message::ServerMessage;
// use lazy_static::lazy_static;
// lazy_static!{
// /// Listener per channel (channel:String,Listener)
// pub static ref LISTENER_PER_CHNL: Mutex<Vec<(String,Mutex<Listener>)>> = Mutex::new(vec![]);
// }
/// debug module
///
/// Commands to enable debugging messages in chat
///
/// `debug on` to start
///
/// `debug off` to stop
///
///
/// Use this function when loading modules into the bot
///
/// For example
/// ```rust
/// bot.load_module(debug::create_module());
/// ```
///
pub fn create_module() -> Module {
/* 1. Create a new module */
let mut custom_mod = Module::new(
vec!["debug".to_string()],
"".to_string());
/* 2. Load the cmd into a new module */
custom_mod.load_command(cmd_debug_on());
custom_mod.load_command(cmd_debug_off());
custom_mod
}
/// Command definition for debug command
fn cmd_debug_on() -> Command {
/* 1. Create a new cmd */
let mut cmd = Command::new(vec!["debug on".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 {
// dbg!("debug cmd on executed");
let modulename="debug listener".to_string();
if let Status::NotLoaded = bot.get_channel_module_status(msg.channel_login.clone(), modulename.clone()).await {
let module = create_listener_module(modulename.clone());
bot.load_module(module.clone()).await;
}
let modl = bot.get_module(modulename).await.unwrap();
bot.enable_module(msg.channel_login.clone(), modl.get_names().first().unwrap().clone()).await;
println!("Debug enabled for channel {}",msg.channel_login);
}
Result::Err("Not Valid message type".to_string())
}
/* 3. Set Command flags */
cmd.set_exec_fn(execution_async(execbody));
cmd.set_admin_only(true);
// cmd.set_min_badge(Badge::Moderator);
cmd.set_admin_override(true);
cmd
}
/// Command definition for debug off command
fn cmd_debug_off() -> Command {
/* 1. Create a new cmd */
let mut cmd = Command::new(vec!["debug off".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 {
// dbg!("debug cmd on executed");
let modulename="debug listener".to_string();
// if let Status::NotLoaded = bot.get_channel_module_status(msg.channel_login.clone(), modulename.clone()).await {
// let module = create_listener_module(modulename.clone());
// bot.load_module(module.clone()).await;
// }
let modl = bot.get_module(modulename).await.unwrap();
bot.disable_module(msg.channel_login.clone(), modl.get_names().first().unwrap().clone()).await;
println!("Debug disabled for channel {}",msg.channel_login);
}
Result::Err("Not Valid message type".to_string())
}
/* 3. Set Command flags */
cmd.set_exec_fn(execution_async(execbody));
cmd.set_admin_only(true);
// cmd.set_min_badge(Badge::Moderator);
cmd.set_admin_override(true);
cmd
}
fn create_listener_module(name:String) -> Module {
let mut custom_mod = Module::new(
vec![name],
"".to_string());
// dbg!("debug listener module created");
custom_mod.load_listener(cmd_debug_listener());
custom_mod.set_status_by_default(Status::Disabled);
custom_mod
}
/// Listener for debug
fn cmd_debug_listener() -> Listener {
// dbg!("Creating debug listener");
/* 2a. Create a new blank Listener */
let mut listener = Listener::new();
/* 2b. Set a trigger condition function for listener */
listener.set_trigger_cond_fn(
|_:Arc<Bot>,_:ServerMessage| true
);
/* 2c. Define an async fn callback execution */
async fn execbody(_:Arc<Bot>,message:ServerMessage) -> Result<String,String> {
if let ServerMessage::Privmsg(msg) = message {
dbg!(msg); /* outputs message to debug */
}
Result::Err("Not Valid message type".to_string())
}
/* 2d. Set and Store the execution body using `execution_async()` */
listener.set_exec_fn(execution_async(execbody));
listener
}

View file

@ -7,7 +7,7 @@ use crate::{execution_async, Badge, Bot, Command, Module};
/// guest_badge / guest module
///
/// Temporary badges can be issued to chatters. The bot then opens functionality
/// to that chatter baded on the recognized role
/// to that chatter based on the recognized role
///
/// Chatters with real badge roles will be able to share guest
/// badges based on their role

View file

@ -149,9 +149,7 @@ fn read_top_of_compare(channel:String) -> Option<(String,String)> {
return msg_stack.last().cloned();
}
}
None
}
fn pop_top_of_compare(channel:String) -> Option<(String,String)> {
@ -165,7 +163,6 @@ fn pop_top_of_compare(channel:String) -> Option<(String,String)> {
return popped;
}
}
None
}
@ -283,7 +280,7 @@ fn symmetry_ok(channel:String) -> bool {
return false;
}
} else { /* dbg!("failed catchall"); */ return false; }
} else { return false; }
if checking_started && read_top_of_compare(channel.clone()).unwrap().1 == get_start_pattern(channel.clone()) {
temp_stack.clear();
@ -309,7 +306,7 @@ fn symmetry_ok(channel:String) -> bool {
/// if a duration is given, take that duration eg 15m , 25m
///
///
fn create_interruptor_cmd() -> Command {
fn _create_interruptor_cmd() -> Command {
let mut cmd = Command::new(vec![
"no pyramid".to_string(),
"no pyramids".to_string()
@ -339,7 +336,7 @@ fn create_interruptor_cmd() -> Command {
}
/// #todo
fn create_interruptor_module(channel:String) -> Module {
fn _create_interruptor_module(channel:String) -> Module {
/* 1. Create a new module */
let modname = format!("interruptor {}",channel);
let mut custom_mod = Module::new(
@ -347,14 +344,14 @@ fn create_interruptor_module(channel:String) -> Module {
"".to_string());
/* 2. Load the cmd into a new module */
custom_mod.load_listener(create_interruptor_listener());
custom_mod.load_listener(_create_interruptor_listener());
custom_mod
}
/// #todo
fn create_interruptor_listener() -> Listener {
fn _create_interruptor_listener() -> Listener {
/* 2a. Create a new blank Listener */
let mut listener = Listener::new();
@ -365,7 +362,7 @@ fn create_interruptor_listener() -> Listener {
/* 2c. Define an async fn callback execution */
async fn execbody(_:Arc<Bot>,message:ServerMessage) -> Result<String,String> {
dbg!(message);
dbg!(message); /* outputs message to debug */
Result::Ok("Success".to_string())
}
@ -379,6 +376,6 @@ fn create_interruptor_listener() -> Listener {
/// #todo
///
/// Returns Some(chatter) if the pyramid in progress is being built by a solo
fn solo_building(channel:String) -> Option<String> {
fn _solo_building(_channel:String) -> Option<String> {
None
}

View file

@ -147,7 +147,7 @@
//!
//! /* 2c. Define an async fn callback execution */
//! async fn execbody(_:Arc<Bot>,message:ServerMessage) -> Result<String,String> {
//! dbg!(message);
//! dbg!(message); /* outputs message to debug */
//! Result::Ok("Success".to_string())
//! }
//!
@ -190,7 +190,6 @@
//! 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");

View file

@ -23,7 +23,7 @@ use twitch_irc::message::ServerMessage;
pub async fn main() {
/* Create the bot using env */
let mut bot = Bot::new();
let bot = Bot::new().await;
/* 1. Create a new blank Listener */
let mut listener = Listener::new();
@ -33,7 +33,6 @@ pub async fn main() {
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");
@ -57,7 +56,7 @@ pub async fn main() {
listener.set_exec_fn(execution_async(execbody));
/* 5. Load the listener into the bot */
bot.load_listener(listener);
bot.load_listener(listener).await;
/* Run the bot */
bot.run().await;

View file

@ -16,7 +16,7 @@ use forcebot_core::Bot;
pub async fn main() {
/* 1. Create the bot using env */
let bot = Bot::new();
let bot = Bot::new().await;
/* 2. Run the bot */
bot.run().await;

View file

@ -30,6 +30,7 @@ cargo run -p forcebot_core
- Quick Start to use full feature set bot
- Moderators & Broadcasters can `disable` or `enable` `Modules` of bot functionality through chat `Commands`
- Full Feature Set `forcebot_core` bot has the following modules loaded
- `debug` - outputs to console messages from the channel where it was enabled. Toggle debug with the Commands `debug on` or `debug off`
- `guest_badge` - Temporary badges can be issued to chatters
- `besty` - Tomfoolery
- `pyramid` - for detecting & handling pyramids
@ -280,7 +281,7 @@ pub async fn main() {
/* 2c. Define an async fn callback execution */
async fn execbody(_:Arc<Bot>,message:ServerMessage) -> Result<String,String> {
dbg!(message);
dbg!(message); /* outputs message to debug */
Result::Ok("Success".to_string())
}
@ -323,7 +324,7 @@ pub async fn main() {
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");

View file

@ -26,7 +26,7 @@ use twitch_irc::message::ServerMessage;
pub async fn main() {
/* Create the bot using env */
let mut bot = Bot::new();
let mut bot = Bot::new().await;
/* 1. Create a new blank cmd */
let mut cmd = Command::new(vec!["test".to_string()],"".to_string());

View file

@ -19,7 +19,7 @@ use twitch_irc::message::ServerMessage;
pub async fn main() {
/* 1. Create the bot using env */
let mut bot = Bot::new();
let bot = Bot::new().await;
/* 2a. Create a new blank Listener */
let mut listener = Listener::new();
@ -31,7 +31,7 @@ pub async fn main() {
/* 2c. Define an async fn callback execution */
async fn execbody(_:Arc<Bot>,message:ServerMessage) -> Result<String,String> {
dbg!(message);
dbg!(message); /* outputs message to debug */
Result::Ok("Success".to_string())
}
@ -39,7 +39,7 @@ pub async fn main() {
listener.set_exec_fn(execution_async(execbody));
/* 3. Load the listener into the bot */
bot.load_listener(listener);
bot.load_listener(listener).await;
/* 4. Run the bot */
bot.run().await;

View file

@ -23,7 +23,7 @@ use forcebot_core::Bot;
pub async fn main() {
/* Create the bot using env */
let mut bot = Bot::new();
let bot = Bot::new().await;
/* load the Module */
bot.load_module(custom_mod::new()).await;