forcebot_core | ||
moderator_reactor | ||
new_empty_bot | ||
simple_command_bot | ||
simple_debug_listener | ||
simple_module_example | ||
.gitignore | ||
Cargo.lock | ||
Cargo.toml | ||
readme.md |
Customizable Twitch chat bot written in rust
Quick Start
Run a Simple bot with Built in functionality
-
Generate a twitch access token
- Get a Bot Chat Token here - https://twitchtokengenerator.com
- More Info - https://dev.twitch.tv/docs/authentication
-
Define an
.env
file with the following
login_name=BOTNAME
access_token=ACCESS_TOKEN
bot_channels=BOTNAME
prefix=`
bot_admins=ADMIN
- Build & run
cargo run -p forcebot_core
Features
- Quick Start to use full feature set bot
- Moderators & Broadcasters can
disable
orenable
Modules
of bot functionality through chatCommands
- Full Feature Set
forcebot_core
bot has the following modules loadeddebug
- outputs to console messages from the channel where it was enabled. Toggle debug with the Commandsdebug on
ordebug off
guest_badge
- Temporary badges can be issued to chattersbesty
- Tomfoolerypyramid
- for detecting & handling pyramids
forcebot_core
library API provides Custom package developers a way to add functionality by addingModules
that contain Bot Objects likeCommands
andListeners
Listeners
andCommands
listen for a defined callback trigger condition and run an defined execution callbackCommands
are similar toListeners
with refined trigger conditions including using botprefix
with theCommand
, triggers based onBadge
, and more- Workspace for package developers to independently code their own
Modules
- Workspace comes with binary crates with working or example bots that use
forcebot_core
librarymoderator_reactor
- bot kneels to all moderator messagessimple_module_example
- bot has atest
Module
with atest
Command
.Moderators & Broadcasters can manage theModule
in chat withenable
/disable
Commands
new_empty_bot
- while empty, hasdisable
andenable
chatCommands
. This is an example of the bot without any loaded modulessimple_command_bot
- bot responds to atest
Command
. As the command was not loaded through aModule
,disable
&enable
commands don't work on thetest
command. This could be a GlobalCommand
simple_debug_listener
- bot outputs all twitchServerMessages
received to terminal
Example Bots
Use the following to build and run built-in bots. No coding required!
New Empty Bot
Run an empty simple bot that logs into chat and has minimum built in functions
cargo run -p new_empty_bot
Full Featured Forcebot
Run a forcebot with fun catered customizations
cargo run -p forcebot_core
Simple Debug Listener
Run a bot that listens to all messages and output to console
cargo run -p simple_debug_listener
Simple Command Bot
Run a bot that uses the test
chat Command
. Commands
are prefixed and must be ran by a chatter with a vip
badge or above
cargo run -p simple_command_bot
Moderator Reactor
Run a bot that listens for messages with the moderator
badge, and replies to that mod with an emote
cargo run -p moderator_reactor
Module loaded Bot
Run a bot that has a test
chat Command
. As the command was loaded through a module, moderators or broadcastors can enable
or disable
the module through chat commands
cargo run -p simple_module_example
Workspace packages
Source is a workspace of packages . In particular, forcebot_core
is the main library crate to use
TIP : if you want to start customizing you own bot, create a binary package in the workspace for your bot's binary crate
More info about workspaces - https://doc.rust-lang.org/book/ch14-03-cargo-workspaces.html
Creating a new package
To create a new package
- Create a new package
For example, to create a new binary crate in the workspace
cargo new my_new_bot
- In the newly created directory for your package, adjust the
Cargo.toml
to the following
[dependencies]
forcebot_core = {path = "../forcebot_core"}
dotenv = "0.15.0"
lazy_static = "1.5.0"
tokio = { version = "1.33.0", features = ["full"] }
twitch-irc = "5.0.1"
-
Copy
main.rs
from thenew_empty_bot
package into your package -
Optionally, customize your
main()
to load modules before starting the bot -
Build and run your package
cargo run -p my_new_bot
Example Code
New Bot
Uses Env defined variables to create and run the bot
use forcebot_core::Bot;
#[tokio::main]
pub async fn main() {
/* 1. Create the bot using env */
let bot = Bot::new();
/* 2. Run the bot */
bot.run().await;
}
Customize by Loading Custom Modules
A Module
is a group of bot objects (eg Command
) that elevated users can manage through built in disable
and enable
commands
Custom Modules
can be loaded into a new bot with minimum coding : just load the modules and run the bot
use forcebot_core::{custom_mods::{guest_badge, pyramid}, Bot};
#[tokio::main]
pub async fn main() {
/* 1. Create the bot using env */
let mut bot = Bot::new();
/* 2. Load Custom Modules */
bot.load_module(guest_badge::create_module()).await;
bot.load_module(pyramid::create_module()).await;
/* 3. Run the bot */
bot.run().await;
}
Create your own Custom Modules
Create a custom Module
by :
-
Defining Functions that create the Custom Bot Objects (eg
Command
) -
Define a function that creates a
Module
with the Custom Bot Objects loaded
use forcebot_core::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()).await;
/* Run the bot */
bot.run().await;
}
pub mod custom_mod {
use std::sync::Arc;
use forcebot_core::{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
}
}
Simple Debug Listener
Bot with a simple listener that listens for all messages and prints in output
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 mut bot = Bot::new();
/* 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 `execution_async()` */
listener.set_exec_fn(execution_async(execbody));
/* 3. Load the listener into the bot */
bot.load_listener(listener);
/* 4. Run the bot */
bot.run().await;
}
Moderator Reactor
Example listener listens for a moderator badge and reply in chat
use std::sync::Arc;
use forcebot_core::Bot;
use forcebot_core::execution_async;
use forcebot_core::Listener;
use twitch_irc::message::ServerMessage;
#[tokio::main]
pub async fn main() {
/* Create the bot using env */
let mut bot = Bot::new();
/* 1. Create a new blank Listener */
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 {
for badge in msg.badges {
if matches!(badge, x if x.name == "moderator") {
// dbg!("moderator found");
return true;
}
}
false
} else { false }
);
/* 3. 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, "pepeKneel".to_string()).await ;
return Result::Ok("Success".to_string()) ;
}
Result::Err("Not Valid message type".to_string())
}
/* 4. Set and Store the execution body using `execution_async()` */
listener.set_exec_fn(execution_async(execbody));
/* 5. Load the listener into the bot */
bot.load_listener(listener);
/* Run the bot */
bot.run().await;
}
Simple Test Command
use std::sync::Arc;
use forcebot_core::Badge;
use forcebot_core::Bot;
use forcebot_core::execution_async;
use forcebot_core::Command;
use twitch_irc::message::ServerMessage;
#[tokio::main]
pub async fn main() {
/* Create the bot using env */
let mut bot = Bot::new();
/* 1. Create a new blank cmd */
let mut cmd = Command::new(vec!["test".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 `execution_async()` */
cmd.set_exec_fn(execution_async(execbody));
/* 4. optionally, remove admin only default flag */
cmd.set_admin_only(false);
/* 5. optionally, set min badge*/
cmd.set_min_badge(Badge::Moderator);
/* 6. Load the cmd into the bot */
bot.load_command(cmd);
/* Run the bot */
bot.run().await;
}
Crate Rust API Documentation
Create forcebot_rs_v2
Rust Crate documentation
Documentation - Clean Build & Open in Default Browser
cargo clean && cargo doc --open