use twitch_irc::login::StaticLoginCredentials; use twitch_irc::ClientConfig; use twitch_irc::SecureTCPTransport; use twitch_irc::TwitchIRCClient; use twitch_irc::message::ServerMessage; use std::env; // use std::time::Instant; use rand::Rng; use dotenv::dotenv; // mod helpers; use std::collections::HashMap; mod ratelimiter; use ratelimiter::RateLimiter; #[tokio::main] pub async fn main() { dotenv().ok(); let login_name = "modulatingforcebot".to_owned(); let oauth_token = env::var("access_token").unwrap().to_owned(); /* Vector of channels to join */ let mut botchannels = Vec::new(); /* botchannels.push(String::from("modulatingforcebot")); botchannels.push(String::from("notohh")); botchannels.push(String::from("modulatingforce")); botchannels.push(String::from("secondsocksan")); */ for chnl in env::var("bot_channels").unwrap().split(',') { // println!("(Env Var # {})",chnl); botchannels.push(String::from(chnl)); } let config = ClientConfig::new_simple( StaticLoginCredentials::new(login_name, Some(oauth_token)) ); let (mut incoming_messages, client) = TwitchIRCClient::::new(config); // client.join("modulatingforcebot".to_owned()).unwrap(); // client.say("modulatingforcebot".to_owned(), "Connected!".to_owned()).await.unwrap(); for chnl in &botchannels { client.join(chnl.to_owned()).unwrap(); // client.say(chnl.to_owned(), "Connected!".to_owned()).await.unwrap(); //client.say(chnl.to_owned(), "annytfLurk".to_owned()).await.unwrap(); } // Adding rate limit functionality to be under : https://dev.twitch.tv/docs/irc/#rate-limits // ratelimiters are a hashmap of channel and a corresponding rate limiter let mut ratelimiters:HashMap = HashMap::new(); for chnl in &botchannels { let n = RateLimiter::new(); ratelimiters.insert(chnl.to_owned(),n); } println!("{:?}",ratelimiters); let join_handle = tokio::spawn(async move { while let Some(message) = incoming_messages.recv().await { // Below can be used to debug if I want to capture all messages // println!("Received message: {:?}", message); match message { ServerMessage::Notice(msg) => { if let Some(chnl) = msg.channel_login { println!("NOTICE : (#{}) {}", chnl, msg.message_text); } } ServerMessage::Privmsg(msg) => { println!("(#{}) {}: {}", msg.channel_login, msg.sender.name, msg.message_text); let contextratelimiter = ratelimiters.get_mut(&msg.channel_login).expect("ERROR: Issue with Rate limiters"); match contextratelimiter.check_limiter() { ratelimiter::LimiterResp::Allow => { let maxblanks = rand::thread_rng().gen_range(1..=5); //let mut outmsg = "GotTrolled ".to_owned(); let mut outmsg = "annytfLurk ".to_owned(); for _i in 1..maxblanks { let blankspace: &str = "󠀀"; outmsg.push_str(blankspace); } client.say_in_reply_to(&msg,outmsg).await.unwrap(); println!("(#{}) > {}", msg.channel_login, "rate limit counter increase"); contextratelimiter.increment_counter(); println!("{:?}",ratelimiters); }, ratelimiter::LimiterResp::Skip => { (); // do nothing otherwise } } }, ServerMessage::Whisper(msg) => { println!("(w) {}: {}", msg.sender.name, msg.message_text); }, ServerMessage::Join(msg) => { println!("JOINED: {}", msg.channel_login); }, ServerMessage::Part(msg) => { println!("PARTED: {}", msg.channel_login); }, _ => {} } } }); join_handle.await.unwrap(); }