diff --git a/src/db/mod.rs b/src/db/mod.rs index 551a206..fbd4a3f 100644 --- a/src/db/mod.rs +++ b/src/db/mod.rs @@ -23,7 +23,7 @@ impl Database { }) } - pub async fn get_logging_channel( + pub async fn get_logging_channels( &self, guild_id: GuildId, ) -> Result> { diff --git a/src/discord/commands.rs b/src/discord/commands.rs index 5fb00c5..d48ee88 100644 --- a/src/discord/commands.rs +++ b/src/discord/commands.rs @@ -1,9 +1,7 @@ -use super::{Context, Error}; +use super::{Context, Result}; use super::utils::serenity; -type Result = ::std::result::Result<(), Error>; - #[allow(clippy::unused_async)] #[poise::command( slash_command, @@ -57,7 +55,7 @@ pub async fn list_channels(ctx: Context<'_>) -> Result { let response = match ctx.guild_id() { None => "Error: Could not determine the guild's ID".to_owned(), Some(guild_id) => { - match ctx.data().database.get_logging_channel(guild_id).await { + match ctx.data().database.get_logging_channels(guild_id).await { Err(e) => format!("Could not retrieve loggers: {e:?}"), Ok(channels) => { if channels.is_empty() { diff --git a/src/discord/events.rs b/src/discord/events.rs index e69de29..f60ba9e 100644 --- a/src/discord/events.rs +++ b/src/discord/events.rs @@ -0,0 +1,72 @@ +use crate::db::Database; + +use super::{utils::BotData, Error, Result}; + +use poise::{serenity_prelude as serenity, Event}; +use tracing::{error, info}; + +async fn handle_everyone_mention( + ctx: &serenity::Context, + database: &Database, + message: &serenity::Message, +) -> Result { + use serenity::ChannelId; + if let Some(guild_id) = message.guild_id { + if message.mention_everyone { + let author = message.author.clone(); + let message_channel = message.channel_id; + let channels: Vec = database + .get_logging_channels(guild_id) + .await? + .iter() + .map(|channel_id| serenity::ChannelId(channel_id.to_owned())) + .collect(); + for channel in &channels { + channel + .send_message(&ctx, |m| { + m.embed(|e| { + e.title("Someone mentioned everyone!") + .field("Author", author.clone(), true) + .field( + "When", + message.timestamp.naive_local().to_string(), + true, + ) + .field( + "Channel", + format!("<#{message_channel}>"), + true, + ) + .field("Link", format!("https://discord.com/channels/{guild_id}/{}/{}", channel.0, message.id), false) + }) + }) + .await + .map_err(|e| { + error!("Failed to send message: {e:?}"); + e + })?; + } + } + } else { + error!("Could not determine guild id of message {message:?}"); + } + Ok(()) +} + +pub async fn event_handler( + ctx: &serenity::Context, + event: &Event<'_>, + _framework: poise::FrameworkContext<'_, BotData, Error>, + data: &BotData, +) -> Result { + match event { + Event::Ready { data_about_bot } => { + info!("Logged in as {}", data_about_bot.user.name); + } + Event::Message { new_message } => { + handle_everyone_mention(ctx, &data.database, new_message).await?; + } + _ => {} + } + Ok(()) +} diff --git a/src/discord/mod.rs b/src/discord/mod.rs index daea786..a436a40 100644 --- a/src/discord/mod.rs +++ b/src/discord/mod.rs @@ -8,10 +8,17 @@ use utils::serenity; use commands::logging; use utils::{BotData, Context, Error}; +use self::events::event_handler; + +pub type Result = ::std::result::Result<(), Error>; + pub fn make_bot() -> FrameworkBuilder { poise::Framework::builder() .options(poise::FrameworkOptions { commands: vec![logging()], + event_handler: |ctx, event, framework, data| { + Box::pin(event_handler(ctx, event, framework, data)) + }, ..Default::default() }) .token(std::env::var("DISCORD_TOKEN").expect("missing DISCORD_TOKEN"))