130 lines
No EOL
3.6 KiB
Rust
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);
|
|
}
|
|
|
|
} |