summaryrefslogtreecommitdiff
path: root/src/handler
diff options
context:
space:
mode:
authorseth <[email protected]>2023-11-30 22:18:51 -0500
committerseth <[email protected]>2023-12-01 07:12:49 -0500
commit76c0f94e6d7aa108424b34826eb7d8514b026287 (patch)
tree7315bd6dfe52c158041bed64ba39781718a69335 /src/handler
parentdb52e639b85d79bed870020aec7a045851ca5ee3 (diff)
feat: use eyre, better logging, & refactor
small commits be damned
Diffstat (limited to 'src/handler')
-rw-r--r--src/handler/message.rs35
-rw-r--r--src/handler/mod.rs40
-rw-r--r--src/handler/pinboard.rs77
-rw-r--r--src/handler/reactboard.rs66
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(())
-}