summaryrefslogtreecommitdiff
path: root/src/main.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs163
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))