forcebot-rs-v2/src/botcore/bot.rs
2025-01-27 13:07:33 -05:00

130 lines
No EOL
3.6 KiB
Rust

use tokio::sync::{mpsc::UnboundedReceiver, Mutex};
use twitch_irc::{login::StaticLoginCredentials, message::ServerMessage, SecureTCPTransport, TwitchIRCClient};
use dotenv::dotenv;
use std::{env, sync::Arc};
use super::bot_objects::listener::Listener;
/// Twitch chat bot
pub struct Bot
{
/// Prefix for commands
_prefix: char,
/// inbound chat msg stream
incoming_msgs: Mutex<UnboundedReceiver<ServerMessage>>,
/// outbound chat client msg stream
pub client: TwitchIRCClient<SecureTCPTransport,StaticLoginCredentials>,
/// joined channels
botchannels: Vec<String>,
/// listeners
listeners: Vec<Listener>,
}
impl Bot
{
/// Creates a new `Bot` using env variables
///
/// Be sure the following is defined in an `.env` file
/// - login_name
/// - access_token
/// - bot_channels
/// - prefix
/// - bot_admins
pub fn new() -> Bot {
dotenv().ok();
let bot_login_name = env::var("login_name").unwrap().to_owned();
let oauth_token = env::var("access_token").unwrap().to_owned();
let prefix = env::var("prefix")
.unwrap()
.to_owned()
.chars()
.next()
.expect("ERROR : when defining prefix");
let mut botchannels = Vec::new();
for chnl in env::var("bot_channels").unwrap().split(',') {
botchannels.push(chnl.to_owned());
}
Bot::new_from(bot_login_name, oauth_token, prefix, botchannels)
}
/// Creates a new `Bot` using bot information
///
/// Bot joined channels will include channels from `.env` and `botchannels` argument
pub fn new_from(bot_login_name:String,oauth_token:String,prefix:char,botchannels:Vec<String>) -> Bot {
dotenv().ok();
let bot_login_name = bot_login_name;
let config = twitch_irc::ClientConfig::new_simple(StaticLoginCredentials::new(
bot_login_name.to_owned(),
Some(oauth_token.to_owned()),
));
let (incoming_messages, client) =
TwitchIRCClient::<SecureTCPTransport, StaticLoginCredentials>::new(config);
let mut botchannels_all = Vec::new();
botchannels_all.extend(botchannels);
for chnl in env::var("bot_channels").unwrap().split(',') {
botchannels_all.push(chnl.to_owned());
}
Bot {
_prefix : prefix,
incoming_msgs : Mutex::new(incoming_messages),
client,
botchannels : botchannels_all,
listeners : vec![],
}
}
/// Runs the bot
pub async fn run(self) {
for chnl in &self.botchannels {
self.client.join(chnl.to_owned()).unwrap();
}
let bot = Arc::new(self);
let join_handle = tokio::spawn(async move {
let mut in_msgs_lock = bot.incoming_msgs.lock().await;
while let Some(message) = in_msgs_lock.recv().await {
// dbg!("Received message: {:?}", message.clone());
for listener in &(*bot).listeners {
let a = listener.clone();
if a.cond_triggered(bot.clone(),message.clone()) {
let _ = listener.execute_fn(bot.clone(),message.clone()).await;
}
}
}
drop(in_msgs_lock);
});
join_handle.await.unwrap();
}
/// Loads a `Listener` into the bot
pub fn load_listener(&mut self,l : Listener) {
self.listeners.push(l);
}
}