Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

11 implement basic moderation commands #12

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>;

Expand All @@ -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))
},
Expand Down
1 change: 1 addition & 0 deletions src/moderation/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod purge;
115 changes: 115 additions & 0 deletions src/moderation/purge.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
use poise::serenity_prelude::{
self as serenity,
futures::{StreamExt, TryStreamExt},
Builder, GetMessages,
};

use crate::{error::BotError, Context};

#[poise::command(
slash_command,
guild_only,
subcommands("after", "any", "before"),
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, up to 1000. Defaults to 100."]
#[min = 1]
#[max = 1000]
amount: Option<u16>,
) -> Result<(), BotError> {
ctx.defer_ephemeral().await?;
let mut count: u16 = 0;
let mut left = amount.unwrap_or(100);
let mut after_id = message_id;

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", count)).await?;

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, up to 1000. Defaults to 100."]
#[min = 1]
#[max = 1000]
amount: Option<u16>,
) -> Result<(), BotError> {
ctx.defer_ephemeral().await?;
let mut messages = ctx.channel_id().messages_iter(ctx.http()).boxed();
let mut count = 0;

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 {count} messages")).await?;

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<u16>,
) -> 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(())
}
Loading