diff options
Diffstat (limited to 'src/main.rs')
| -rw-r--r-- | src/main.rs | 163 |
1 files changed, 98 insertions, 65 deletions
diff --git a/src/main.rs b/src/main.rs index 61a00c1..d9e1cd5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,30 +1,72 @@ -use lazy_static::lazy_static; +use once_cell::sync::Lazy; use regex::Regex; use serenity::async_trait; use serenity::framework::standard::macros::{command, group}; use serenity::framework::standard::{CommandResult, StandardFramework}; use serenity::model::application::command::Command; -use serenity::model::application::interaction::{Interaction, InteractionResponseType}; -use serenity::model::channel::Message; -use serenity::model::id::GuildId; -use serenity::model::prelude::Ready; +use serenity::model::prelude::*; use serenity::prelude::*; -use std::{env, vec}; +use utils::parse_snowflake_from_env; + +use crate::pinboard::PinBoard; +use crate::utils::parse_snowflakes_from_env; mod api; mod commands; mod consts; +mod pinboard; mod utils; const TEAWIE_GUILD: GuildId = GuildId(1055663552679137310); -const ALLOWED_GUILDS: [GuildId; 2] = [TEAWIE_GUILD, GuildId(1091969030694375444)]; -const BOT: u64 = 1056467120986271764; +const BOT: UserId = UserId(1056467120986271764); + +fn is_guild_allowed(gid: GuildId) -> bool { + // Had to be global state because Serenity doesn't allow you to store + // extra state in frameworks + static ALLOWED_GUILDS: Lazy<Vec<GuildId>> = Lazy::new(|| { + parse_snowflakes_from_env("ALLOWED_GUILDS", GuildId) + .unwrap_or_else(|| vec![TEAWIE_GUILD, GuildId(1091969030694375444)]) + }); + + ALLOWED_GUILDS.contains(&gid) +} #[group] #[commands(bing, ask, random_lore, random_teawie, teawiespam)] struct General; -struct Handler; +struct Handler { + bot: UserId, + pin_board: Option<PinBoard>, +} + +impl Handler { + pub fn new() -> Self { + let bot = parse_snowflake_from_env("BOT", UserId).unwrap_or(BOT); + let pin_board = PinBoard::new(); + + Self { bot, pin_board } + } + fn should_echo(&self, msg: &Message) -> bool { + static MOYAI_REGEX: Lazy<Regex> = + Lazy::new(|| Regex::new(r"^<a?:\w*moy?ai\w*:\d+>$").unwrap()); + + // Don't echo to anything we posted ourselves, and don't echo at all unless on certain + // servers + if msg.author.id == self.bot || !is_guild_allowed(msg.guild_id.unwrap_or_default()) { + return false; + } + + let content = &msg.content; + + content == "🗿" + || consts::TEAMOJIS.contains(&content.as_str()) + || MOYAI_REGEX.is_match(content) + || content + .to_ascii_lowercase() + .contains("twitter's recommendation algorithm") + } +} #[async_trait] impl EventHandler for Handler { @@ -32,55 +74,47 @@ impl EventHandler for Handler { * echo some messages when they're sent */ async fn message(&self, ctx: Context, msg: Message) { - let author = msg.author.id.as_u64(); - - if author == &BOT - || !ALLOWED_GUILDS.contains(&msg.guild_id.unwrap_or_else(|| GuildId::from(0))) - { - return; - } - - let mut echo_msgs = vec!["🗿", "Twitter's Recommendation Algorithm"]; - - for emoji in consts::TEAMOJIS { - // i was also lazy here - echo_msgs.push(emoji); - } - - let mut should_echo = echo_msgs.contains(&msg.content.as_str()); - - if !should_echo { - lazy_static! { - static ref EMOJI_RE: Regex = Regex::new(r"^<a?:(\w+):\d+>$").unwrap(); - } - if let Some(cap) = EMOJI_RE.captures(msg.content.as_str()) { - if let Some(emoji_name) = cap.get(1) { - let emoji_name = emoji_name.as_str(); - should_echo = emoji_name.contains("moai") || emoji_name.contains("moyai"); - } - } - } - - if should_echo { - let send = msg.reply(&ctx, msg.content.as_str()); + if self.should_echo(&msg) { + let send = msg.reply(&ctx, &msg.content); if let Err(why) = send.await { println!("error when replying to {:?}: {:?}", msg.content, why); } } } + async fn channel_pins_update(&self, ctx: Context, pin: ChannelPinsUpdateEvent) { + let Some(pin_board) = &self.pin_board else { + return; + }; + + println!( + "audit log: {:#?}", + pin.guild_id + .unwrap() + .audit_logs( + &ctx.http, + Some(Action::Message(MessageAction::Pin).num()), + None, + None, + Some(1), + ) + .await + ); + pin_board.handle_pin(&ctx, &pin).await; + } + async fn interaction_create(&self, ctx: Context, interaction: Interaction) { if let Interaction::ApplicationCommand(command) = interaction { - println!("Received command interaction: {:#?}", command); + println!("Received command interaction: {command:#?}"); let content = match command.data.name.as_str() { - "ask" => commands::ask::run(&command.data.options).await, - "bottom" => commands::bottom::run(&command.data.options).await, - "convertto" => commands::convert::run(&command.data.options).await, + "ask" => commands::ask::run(&command.data.options), + "bottom" => commands::bottom::run(&command.data.options), + "convertto" => commands::convert::run(&command.data.options), "copypasta" => { commands::copypasta::run(&command.data.options, command.channel_id, &ctx.http) .await } - "random_lore" => commands::random_lore::run(&command.data.options).await, + "random_lore" => commands::random_lore::run(&command.data.options), "random_teawie" => commands::random_teawie::run(&command.data.options).await, _ => "not implemented :(".to_string(), }; @@ -93,7 +127,7 @@ impl EventHandler for Handler { }) .await { - println!("cannot respond to slash command: {}", why); + println!("cannot respond to slash command: {why}"); } } } @@ -103,38 +137,41 @@ impl EventHandler for Handler { let guild_commands = GuildId::set_application_commands(&TEAWIE_GUILD, &ctx.http, |commands| { - commands - .create_application_command(|command| commands::copypasta::register(command)) + commands.create_application_command(commands::copypasta::register) }) .await; - println!("registered guild commands: {:#?}", guild_commands); + println!("registered guild commands: {guild_commands:#?}"); let commands = Command::set_global_application_commands(&ctx.http, |commands| { commands - .create_application_command(|command| commands::ask::register(command)) - .create_application_command(|command| commands::bottom::register(command)) - .create_application_command(|command| commands::convert::register(command)) - .create_application_command(|command| commands::random_lore::register(command)) - .create_application_command(|command| commands::random_teawie::register(command)) + .create_application_command(commands::ask::register) + .create_application_command(commands::bottom::register) + .create_application_command(commands::convert::register) + .create_application_command(commands::random_lore::register) + .create_application_command(commands::random_teawie::register) }) .await; - println!("registered global commands: {:#?}", commands); + println!("registered global commands: {commands:#?}"); } } #[tokio::main] async fn main() { + dotenvy::dotenv().unwrap(); + let framework = StandardFramework::new() .configure(|c| c.prefix("!")) .group(&GENERAL_GROUP); - let token = env::var("TOKEN").expect("couldn't find token in environment."); + let token = std::env::var("TOKEN").expect("couldn't find token in environment."); let intents = GatewayIntents::all(); + let handler = Handler::new(); + let mut client = Client::builder(token, intents) - .event_handler(Handler) + .event_handler(handler) .framework(framework) .await .expect("error creating client"); @@ -155,7 +192,7 @@ async fn bing(ctx: &Context, msg: &Message) -> CommandResult { #[command] async fn ask(ctx: &Context, msg: &Message) -> CommandResult { - let resp = utils::get_random_response().await; + let resp = utils::get_random_response(); msg.channel_id .send_message(&ctx.http, |m| m.content(resp)) .await?; @@ -165,7 +202,7 @@ async fn ask(ctx: &Context, msg: &Message) -> CommandResult { #[command] async fn random_lore(ctx: &Context, msg: &Message) -> CommandResult { - let resp = utils::get_random_lore().await; + let resp = utils::get_random_lore(); msg.channel_id .send_message(&ctx.http, |m| m.content(resp)) .await?; @@ -185,15 +222,11 @@ async fn random_teawie(ctx: &Context, msg: &Message) -> CommandResult { #[command] async fn teawiespam(ctx: &Context, msg: &Message) -> CommandResult { - if !ALLOWED_GUILDS.contains(&msg.guild_id.unwrap_or_else(|| GuildId::from(0))) { + if !is_guild_allowed(msg.guild_id.unwrap_or_default()) { return Ok(()); } - let mut resp = String::new(); - - for _ in 0..50 { - resp += "<:teawiesmile:1056438046440042546>"; - } + let resp = "<:teawiesmile:1056438046440042546>".repeat(50); msg.channel_id .send_message(&ctx.http, |m| m.content(resp)) |
