diff --git a/.env.example b/.env.example index 5d46e09..1441c42 100644 --- a/.env.example +++ b/.env.example @@ -1,10 +1,10 @@ DISCORD_TOKEN="" -SUPABASE_URL="" -SUPABASE_KEY="" - -# Optional -VERIFIED_ROLE_ID="" -GUILD_ID="" WEATHER_TOKEN="" -# Weather API token from: https://www.weatherapi.com/ \ No newline at end of file +VERIFIED_ROLE_ID="" +GUILD_ID="" +LOGS_CHANNEL_ID="" +HONEYPOT_CHANNEL_ID="" + +SUPABASE_URL="" +SUPABASE_KEY="" diff --git a/src/commands/mods_only.rs b/src/commands/mods_only.rs index 9c816b1..a94942c 100644 --- a/src/commands/mods_only.rs +++ b/src/commands/mods_only.rs @@ -1,6 +1,76 @@ use crate::{Context, Error}; +use dotenv::dotenv; use poise::CreateReply; -use serenity::all::CreateEmbed; +use serenity::{all::CreateEmbed, builder::CreateMessage, model::id::ChannelId}; + +/// Send message to logs channel +pub async fn log_embed( + ctx: Context<'_>, + title: Option, + title_url: Option, + description: Option, + footer: Option, + colour: Option, + thumbnail_url: Option, + image_url: Option, + timestamp: Option, +) -> Result<(), Error> { + dotenv().ok(); + let mut embed = CreateEmbed::new(); + + // Set title and title URL + if let Some(title) = title { + embed = embed.title(title); + if let Some(url) = title_url { + embed = embed.url(url); + } + } + + // Set description + if let Some(desc) = description { + embed = embed.description(desc); + } + + // Set footer + if let Some(footer_text) = footer { + embed = embed.footer(serenity::all::CreateEmbedFooter::new(footer_text)); + } + + // Set color (parse hex color) + if let Some(color_str) = colour { + if let Ok(color_value) = u32::from_str_radix(color_str.trim_start_matches('#'), 16) { + embed = embed.color(color_value); + } + } + + // Set thumbnail + if let Some(thumb_url) = thumbnail_url { + embed = embed.thumbnail(thumb_url); + } + + // Set image + if let Some(img_url) = image_url { + embed = embed.image(img_url); + } + + // Set timestamp + if timestamp.unwrap_or(false) { + embed = embed.timestamp(serenity::model::Timestamp::now()); + } + + // Send the embed + let logs_channel_id_env = std::env::var("LOGS_CHANNEL_ID") + .expect("missing LOGS_CHANNEL_ID") + .parse::() + .expect("Invalid LOGS_CHANNEL_ID value"); + let logs_channel_id = ChannelId::new(logs_channel_id_env); + let builder = CreateMessage::new().embed(embed); + + let send_log = logs_channel_id.send_message(ctx, builder).await; + send_log.expect("LOG FAIL"); + + Ok(()) +} /// Create a message embed #[poise::command( diff --git a/src/events.rs b/src/events.rs index 95ec4e9..49002e6 100644 --- a/src/events.rs +++ b/src/events.rs @@ -1,2 +1,3 @@ pub mod ready; -pub mod interaction_create; \ No newline at end of file +pub mod interaction_create; +pub mod message; \ No newline at end of file diff --git a/src/events/interaction_create.rs b/src/events/interaction_create.rs index fe2e588..68edaf6 100644 --- a/src/events/interaction_create.rs +++ b/src/events/interaction_create.rs @@ -5,8 +5,7 @@ use crate::{ commands::verification::{StudentRow, VerificationModal}, }; use ::serenity::all::{ - ComponentInteraction, Context, CreateEmbed, CreateEmbedFooter, CreateInteractionResponse, - CreateInteractionResponseFollowup, CreateInteractionResponseMessage, GuildId, RoleId, + ComponentInteraction, Context, CreateEmbed, CreateEmbedFooter, CreateInteractionResponse, CreateInteractionResponseFollowup, CreateInteractionResponseMessage, GuildId, RoleId }; use dotenv::dotenv; use poise::{modal, serenity_prelude as serenity}; @@ -205,6 +204,9 @@ pub async fn on_interaction_create( format!("You have been assigned the <@&{}> role!", verified_role_id), ) .await?; + + // post to logs channel + } else { embed_followup( ctx, diff --git a/src/events/message.rs b/src/events/message.rs new file mode 100644 index 0000000..c1053f8 --- /dev/null +++ b/src/events/message.rs @@ -0,0 +1,28 @@ +use crate::Error; +use dotenv::dotenv; +use poise::serenity_prelude as serenity; +use ::serenity::model::id::{ChannelId, GuildId}; + +pub async fn on_message( + ctx: &serenity::Context, + new_message: &serenity::Message +) -> Result<(), Error> { + dotenv().ok(); + // check if it's the honeypot channel + let discord_guild_id = std::env::var("GUILD_ID").expect("missing GUILD_ID").parse::().expect("Invalid GUILD_ID value"); + + let honeypot_channel_id_env = std::env::var("HONEYPOT_CHANNEL_ID") + .expect("missing HONEYPOT_CHANNEL_ID") + .parse::() + .expect("Invalid HONEYPOT_CHANNEL_ID value"); + let honeypot_channel_id = ChannelId::new(honeypot_channel_id_env); + let current_channel_id = &new_message.channel_id; + + if honeypot_channel_id.eq(current_channel_id) { + let user = &new_message.author; + let ban_user = GuildId::new(discord_guild_id).ban_with_reason(ctx, user, 2, "Message sent in honeypot channel.").await; + ban_user.expect("Failed to ban user"); + } + + Ok(()) +} diff --git a/src/main.rs b/src/main.rs index fe8a072..f840851 100644 --- a/src/main.rs +++ b/src/main.rs @@ -48,6 +48,9 @@ async fn event_handler( serenity::FullEvent::InteractionCreate { interaction } => { events::interaction_create::on_interaction_create(ctx, interaction, &data).await?; } + serenity::FullEvent::Message { new_message } => { + events::message::on_message(ctx, new_message).await?; + } _ => {} } Ok(()) @@ -61,7 +64,7 @@ async fn main() { // -- discord bot start -- let token = std::env::var("DISCORD_TOKEN").expect("missing DISCORD_TOKEN"); - let intents = serenity::GatewayIntents::non_privileged(); + let intents = serenity::GatewayIntents::non_privileged() | serenity::GatewayIntents::MESSAGE_CONTENT; let framework = poise::Framework::builder() .options(poise::FrameworkOptions { @@ -96,7 +99,7 @@ async fn main() { .expect("Client failed to start") .start() .await - .expect("Client failed to start 2"); + .expect("Client failed to start"); // -- discord bot end -- }