From b99c2cf16b0ca6d664db14cac786a6e8cbcb36fd Mon Sep 17 00:00:00 2001 From: we sell insurance Date: Tue, 16 Apr 2024 20:53:44 -0500 Subject: [PATCH 1/4] Add purge after subcommand to purge after specific message --- src/main.rs | 4 +++- src/moderation/mod.rs | 1 + src/moderation/purge.rs | 41 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 src/moderation/mod.rs create mode 100644 src/moderation/purge.rs diff --git a/src/main.rs b/src/main.rs index 5421913..5a45e14 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,6 +4,8 @@ use poise::serenity_prelude as serenity; mod config; mod error; mod misc; +mod moderation; + struct Data {} type Context<'a> = poise::Context<'a, Data, BotError>; @@ -13,7 +15,7 @@ async fn main() { let intents = serenity::GatewayIntents::non_privileged(); let options = poise::FrameworkOptions { - commands: vec![misc::ping()], + commands: vec![misc::ping(), moderation::purge::purge()], event_handler: |ctx, event, framework, data| { Box::pin(event_handler(ctx, event, framework, data)) }, diff --git a/src/moderation/mod.rs b/src/moderation/mod.rs new file mode 100644 index 0000000..b2ea9cb --- /dev/null +++ b/src/moderation/mod.rs @@ -0,0 +1 @@ +pub mod purge; diff --git a/src/moderation/purge.rs b/src/moderation/purge.rs new file mode 100644 index 0000000..71cadec --- /dev/null +++ b/src/moderation/purge.rs @@ -0,0 +1,41 @@ +use poise::serenity_prelude::{self as serenity, Builder, GetMessages}; + +use crate::{error::BotError, Context}; + +#[poise::command( + slash_command, + guild_only, + subcommands("after"), + default_member_permissions = "MANAGE_MESSAGES" +)] +pub async fn purge(_ctx: Context<'_>, _amount: u64) -> Result<(), BotError> { + Ok(()) +} + +/// Deletes all messages after the given message. Defaults to 100 messages deleted. +#[poise::command(slash_command, ephemeral)] +async fn after( + ctx: Context<'_>, + #[description = "The ID of the message to delete after"] + message_id: serenity::MessageId, + #[description = "The amount of messages to delete. Must be less than 100. Defaults to 100."] + #[min = 1] + #[max = 100] + amount: Option, +) -> Result<(), BotError> { + ctx.defer_ephemeral().await?; + let messages = GetMessages::new() + .after(message_id) + .limit(amount.unwrap_or(100)) + .execute(ctx.http(), ctx.channel_id()) + .await?; + + for message in &messages { + message.delete(ctx.http()).await?; + } + + ctx.say(format!("Deleted {} messages", &messages.len())) + .await?; + + Ok(()) +} From 35cac91d44f1517a81d710553f9271e97884e0cc Mon Sep 17 00:00:00 2001 From: we sell insurance Date: Tue, 16 Apr 2024 21:24:05 -0500 Subject: [PATCH 2/4] Added purge any command to remove specified about of messages --- src/moderation/purge.rs | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/src/moderation/purge.rs b/src/moderation/purge.rs index 71cadec..55f3334 100644 --- a/src/moderation/purge.rs +++ b/src/moderation/purge.rs @@ -5,7 +5,7 @@ use crate::{error::BotError, Context}; #[poise::command( slash_command, guild_only, - subcommands("after"), + subcommands("after", "any"), default_member_permissions = "MANAGE_MESSAGES" )] pub async fn purge(_ctx: Context<'_>, _amount: u64) -> Result<(), BotError> { @@ -16,8 +16,7 @@ pub async fn purge(_ctx: Context<'_>, _amount: u64) -> Result<(), BotError> { #[poise::command(slash_command, ephemeral)] async fn after( ctx: Context<'_>, - #[description = "The ID of the message to delete after"] - message_id: serenity::MessageId, + #[description = "The ID of the message to delete after"] message_id: serenity::MessageId, #[description = "The amount of messages to delete. Must be less than 100. Defaults to 100."] #[min = 1] #[max = 100] @@ -39,3 +38,28 @@ async fn after( Ok(()) } + +/// Deletes the specifed amount of messages. Defaults to 100 messages deleted. +#[poise::command(slash_command, ephemeral)] +async fn any( + ctx: Context<'_>, + #[description = "The amount of messages to delete. Must be less than 100. Defaults to 100."] + #[min = 1] + #[max = 100] + amount: Option, +) -> Result<(), BotError> { + ctx.defer_ephemeral().await?; + let messages = GetMessages::new() + .limit(amount.unwrap_or(100)) + .execute(ctx.http(), ctx.channel_id()) + .await?; + + for message in &messages { + message.delete(ctx.http()).await?; + } + + ctx.say(format!("Deleted {} messages", &messages.len())) + .await?; + + Ok(()) +} From 425f7a6adcb51105b216c256bcb3b915f1f0aee1 Mon Sep 17 00:00:00 2001 From: we sell insurance Date: Wed, 17 Apr 2024 15:47:44 -0500 Subject: [PATCH 3/4] Increases limit of purge any and purge after to 1000 messages. --- src/moderation/purge.rs | 63 +++++++++++++++++++++++++---------------- 1 file changed, 39 insertions(+), 24 deletions(-) diff --git a/src/moderation/purge.rs b/src/moderation/purge.rs index 55f3334..62c384c 100644 --- a/src/moderation/purge.rs +++ b/src/moderation/purge.rs @@ -1,4 +1,8 @@ -use poise::serenity_prelude::{self as serenity, Builder, GetMessages}; +use poise::serenity_prelude::{ + self as serenity, + futures::{StreamExt, TryStreamExt}, + Builder, GetMessages, +}; use crate::{error::BotError, Context}; @@ -17,24 +21,32 @@ pub async fn purge(_ctx: Context<'_>, _amount: u64) -> Result<(), BotError> { async fn after( ctx: Context<'_>, #[description = "The ID of the message to delete after"] message_id: serenity::MessageId, - #[description = "The amount of messages to delete. Must be less than 100. Defaults to 100."] + #[description = "The amount of messages to delete, up to 1000. Defaults to 100."] #[min = 1] - #[max = 100] - amount: Option, + #[max = 1000] + amount: Option, ) -> Result<(), BotError> { ctx.defer_ephemeral().await?; - let messages = GetMessages::new() - .after(message_id) - .limit(amount.unwrap_or(100)) - .execute(ctx.http(), ctx.channel_id()) - .await?; + let mut count: u16 = 0; + let mut left = amount.unwrap_or(100); + let mut after_id = message_id; - for message in &messages { - message.delete(ctx.http()).await?; + while left > 0 { + let messages = GetMessages::new() + .limit(left as u8) + .after(after_id) + .execute(&ctx.http(), ctx.channel_id()) + .await?; + after_id = messages.last().unwrap().id; + + for message in messages { + message.delete(&ctx.http()).await?; + count += 1; + left -= 1; + } } - ctx.say(format!("Deleted {} messages", &messages.len())) - .await?; + ctx.say(format!("Deleted {} messages", count)).await?; Ok(()) } @@ -43,23 +55,26 @@ async fn after( #[poise::command(slash_command, ephemeral)] async fn any( ctx: Context<'_>, - #[description = "The amount of messages to delete. Must be less than 100. Defaults to 100."] + #[description = "The amount of messages to delete, up to 1000. Defaults to 100."] #[min = 1] - #[max = 100] - amount: Option, + #[max = 1000] + amount: Option, ) -> Result<(), BotError> { ctx.defer_ephemeral().await?; - let messages = GetMessages::new() - .limit(amount.unwrap_or(100)) - .execute(ctx.http(), ctx.channel_id()) - .await?; + let mut messages = ctx.channel_id().messages_iter(ctx.http()).boxed(); + let mut count = 0; - for message in &messages { - message.delete(ctx.http()).await?; + for _ in 0..amount.unwrap_or(100) { + match messages.try_next().await { + Ok(message) => { + message.unwrap().delete(&ctx.http()).await?; + count += 1; + } + Err(_) => break, + } } - ctx.say(format!("Deleted {} messages", &messages.len())) - .await?; + ctx.say(format!("Deleted {count} messages")).await?; Ok(()) } From 84079a3d151fa86a46d334982f3e09333902e636 Mon Sep 17 00:00:00 2001 From: we sell insurance Date: Sat, 27 Apr 2024 17:50:39 -0500 Subject: [PATCH 4/4] Add purge before command --- src/moderation/purge.rs | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/src/moderation/purge.rs b/src/moderation/purge.rs index 62c384c..ccc58d7 100644 --- a/src/moderation/purge.rs +++ b/src/moderation/purge.rs @@ -9,7 +9,7 @@ use crate::{error::BotError, Context}; #[poise::command( slash_command, guild_only, - subcommands("after", "any"), + subcommands("after", "any", "before"), default_member_permissions = "MANAGE_MESSAGES" )] pub async fn purge(_ctx: Context<'_>, _amount: u64) -> Result<(), BotError> { @@ -78,3 +78,38 @@ async fn any( Ok(()) } + +/// Deletes all messages before the given message. Defaults to 100 messages deleted. +#[poise::command(slash_command, ephemeral)] +async fn before( + ctx: Context<'_>, + #[description = "The ID of the message to delete before"] message_id: serenity::MessageId, + #[description = "The amount of messages to delete, up to 1000. Defaults to 100."] + #[min = 1] + #[max = 1000] + amount: Option, +) -> Result<(), BotError> { + ctx.defer_ephemeral().await?; + let mut count: u16 = 0; + let mut left = amount.unwrap_or(100); + let mut before_id = message_id; + + while left > 0 { + let messages = GetMessages::new() + .limit(left as u8) + .before(before_id) + .execute(&ctx.http(), ctx.channel_id()) + .await?; + before_id = messages.first().unwrap().id; + + for message in messages { + message.delete(&ctx.http()).await?; + count += 1; + left -= 1; + } + } + + ctx.say(format!("Deleted {} messages", count)).await?; + + Ok(()) +}