diff options
| author | seth <[email protected]> | 2023-11-30 22:18:51 -0500 |
|---|---|---|
| committer | seth <[email protected]> | 2023-12-01 07:12:49 -0500 |
| commit | 76c0f94e6d7aa108424b34826eb7d8514b026287 (patch) | |
| tree | 7315bd6dfe52c158041bed64ba39781718a69335 /src/handler | |
| parent | db52e639b85d79bed870020aec7a045851ca5ee3 (diff) | |
feat: use eyre, better logging, & refactor
small commits be damned
Diffstat (limited to 'src/handler')
| -rw-r--r-- | src/handler/message.rs | 35 | ||||
| -rw-r--r-- | src/handler/mod.rs | 40 | ||||
| -rw-r--r-- | src/handler/pinboard.rs | 77 | ||||
| -rw-r--r-- | src/handler/reactboard.rs | 66 |
4 files changed, 0 insertions, 218 deletions
diff --git a/src/handler/message.rs b/src/handler/message.rs deleted file mode 100644 index 37a49bf..0000000 --- a/src/handler/message.rs +++ /dev/null @@ -1,35 +0,0 @@ -use crate::{consts, utils, Data, Error}; -use log::*; -use poise::serenity_prelude as serenity; -use poise::{Event, FrameworkContext}; - -fn should_echo(framework: FrameworkContext<'_, Data, Error>, msg: &serenity::Message) -> bool { - let gid = msg.guild_id.unwrap_or_default(); - if msg.author.id == framework.bot_id || !utils::is_guild_allowed(gid) { - info!("not running copypasta command in {gid}"); - return false; - } - - let content = &msg.content; - - content == "🗿" - || consts::TEAMOJIS.contains(&content.as_str()) - || content.to_ascii_lowercase() == "moyai" - || content - .to_ascii_lowercase() - .contains("twitter's recommendation algorithm") -} - -pub async fn handle( - ctx: &serenity::Context, - _event: &Event<'_>, - framework: FrameworkContext<'_, Data, Error>, - _data: &Data, - msg: &serenity::Message, -) -> Result<(), Error> { - if should_echo(framework, msg) { - msg.reply(ctx, &msg.content).await?; - } - - Ok(()) -} diff --git a/src/handler/mod.rs b/src/handler/mod.rs deleted file mode 100644 index 3489b4a..0000000 --- a/src/handler/mod.rs +++ /dev/null @@ -1,40 +0,0 @@ -use crate::{Data, Error}; -use poise::serenity_prelude as serenity; -use poise::Event; - -mod message; -pub mod pinboard; -mod reactboard; - -pub async fn handle( - ctx: &serenity::Context, - event: &Event<'_>, - framework: poise::FrameworkContext<'_, Data, Error>, - data: &Data, -) -> Result<(), Error> { - match event { - Event::Ready { data_about_bot } => { - log::info!("logged in as {}", data_about_bot.user.name) - } - - Event::Message { new_message } => { - message::handle(ctx, event, framework, data, new_message).await? - } - - Event::ChannelPinsUpdate { pin } => { - if let Some(settings) = &data.settings { - pinboard::handle(ctx, pin, settings).await - } - } - - Event::ReactionAdd { add_reaction } => { - if let Some(settings) = &data.settings { - reactboard::handle(ctx, add_reaction, settings).await? - } - } - - _ => {} - } - - Ok(()) -} diff --git a/src/handler/pinboard.rs b/src/handler/pinboard.rs deleted file mode 100644 index 0c87a5b..0000000 --- a/src/handler/pinboard.rs +++ /dev/null @@ -1,77 +0,0 @@ -use crate::settings::Settings; -use crate::utils; - -use log::*; -use poise::serenity_prelude::model::prelude::*; -use poise::serenity_prelude::Context; - -pub async fn handle(ctx: &Context, pin: &ChannelPinsUpdateEvent, settings: &Settings) { - if let Some(sources) = &settings.pinboard_sources { - if !sources.contains(&pin.channel_id) { - warn!("can't access source of pin!"); - return; - } - } - - let mut pinner = guess_pinner(ctx, pin).await; - let pins = pin - .channel_id - .pins(&ctx.http) - .await - .expect("couldn't get a list of pins!?"); - - for pin in pins { - // We call `take` because it's supposed to be just for the latest message. - redirect(ctx, &pin, pinner.take(), settings.pinboard_target).await; - pin.unpin(&ctx).await.expect("couldn't unpin message"); - } -} - -async fn redirect(ctx: &Context, pin: &Message, pinner: Option<UserId>, target: ChannelId) { - let pinner = pinner.map_or("*someone*".to_owned(), |u| format!("<@{u}>")); - let embed = utils::resolve_message_to_embed(ctx, pin).await; - - target - .send_message(&ctx.http, |m| { - m.allowed_mentions(|am| am.empty_parse()) - .content(format!("📌'd by {pinner} in {}", pin.link())) - .set_embed(embed) - }) - .await - .expect("couldn't redirect message"); -} - -/// (Desperate, best-effort) attempt to get the user that pinned the last message -/// -/// Now, since Discord is SUPER annoying, it doesn't actually tell you which bloody user -/// that triggered the pins update event. So, you have to dig into the audit log. -/// Unfortunately, while you do get a timestamp, the REST API does not return the time at -/// which each action is logged, which, to me, means that it is not a freaking log *at all*. -/// -/// I love Discord. -/// -/// So, the plan is that only the first pinned message gets clear pinner information, -/// since we can just get the latest pin, which should happen on the exact second. -/// We can't reliably say the same for any existing pins, so we can only /shrug and say -/// *somebody* did it. Ugh. -async fn guess_pinner(ctx: &Context, pin: &ChannelPinsUpdateEvent) -> Option<UserId> { - if let Some(g) = pin.guild_id { - g.audit_logs( - &ctx.http, - // This `num` call shouldn't be necessary. - // See https://github.com/serenity-rs/serenity/issues/2488 - Some(Action::Message(MessageAction::Pin).num()), - None, // user id - None, // before - Some(1), // limit - ) - .await - .ok() - .and_then(|mut logs| logs.entries.pop()) - .map(|first| first.user_id) - } else { - // TODO: mayyyyybe we can guess who pinned something in a DM...? - warn!("couldn't figure out who pinned in {}!", pin.channel_id); - None - } -} diff --git a/src/handler/reactboard.rs b/src/handler/reactboard.rs deleted file mode 100644 index 36f8361..0000000 --- a/src/handler/reactboard.rs +++ /dev/null @@ -1,66 +0,0 @@ -use crate::Error; -use crate::{settings::Settings, utils}; -use log::*; -use poise::serenity_prelude::{Context, Message, MessageReaction, Reaction}; - -pub async fn handle(ctx: &Context, reaction: &Reaction, settings: &Settings) -> Result<(), Error> { - let msg = match reaction.message(&ctx.http).await { - Ok(msg) => msg, - Err(why) => { - warn!("couldn't get message of reaction! {}", why); - return Err(Box::new(why)); - } - }; - - if let Some(matched) = msg - .clone() - .reactions - .into_iter() - .find(|r| r.reaction_type == reaction.emoji) - { - send_to_reactboard(ctx, &matched, &msg, settings).await?; - } else { - warn!( - "couldn't find any matching reactions for {} in {}", - reaction.emoji.as_data(), - msg.id - ) - } - - Ok(()) -} - -async fn send_to_reactboard( - ctx: &Context, - reaction: &MessageReaction, - msg: &Message, - settings: &Settings, -) -> Result<(), Error> { - if !settings.can_use_reaction(reaction) { - info!("reaction {} can't be used!", reaction.reaction_type); - return Ok(()); - } - - if reaction.count == settings.reactboard_requirement.unwrap_or(5) { - let embed = utils::resolve_message_to_embed(ctx, msg).await; - - settings - .reactboard_target - .send_message(&ctx.http, |m| { - m.allowed_mentions(|am| am.empty_parse()) - .content(format!( - "{} **#{}**", - reaction.reaction_type, reaction.count - )) - .set_embed(embed) - }) - .await?; - } else { - info!( - "not putting message {} on reactboard, not enough reactions", - msg.id - ) - } - - Ok(()) -} |
