refactor moderation; change prefix to r
This commit is contained in:
parent
174d93544c
commit
20e2dbbe46
3 changed files with 123 additions and 52 deletions
|
@ -15,7 +15,7 @@ pub fn to_global_commands() -> Vec<Command<Data, Report>> {
|
||||||
general::say(),
|
general::say(),
|
||||||
general::stars(),
|
general::stars(),
|
||||||
general::tag(),
|
general::tag(),
|
||||||
moderation::ban_user(),
|
moderation::ban(),
|
||||||
moderation::kick_user(),
|
moderation::kick(),
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,25 +1,94 @@
|
||||||
use crate::{consts::COLORS, Context};
|
use crate::{consts::COLORS, Context};
|
||||||
|
|
||||||
use color_eyre::eyre::{eyre, Result};
|
use color_eyre::eyre::{eyre, Result};
|
||||||
use poise::serenity_prelude::{CreateEmbed, User};
|
use poise::serenity_prelude::{
|
||||||
|
futures::TryFutureExt, CreateEmbed, CreateMessage, FutureExt, Guild, Timestamp, User, UserId,
|
||||||
|
};
|
||||||
|
|
||||||
fn create_moderation_embed(
|
struct Action {
|
||||||
title: String,
|
reason: String,
|
||||||
user: &User,
|
data: ActionData,
|
||||||
delete_messages_days: Option<u8>,
|
}
|
||||||
reason: Option<String>,
|
|
||||||
) -> impl FnOnce(&mut CreateEmbed) -> &mut CreateEmbed {
|
|
||||||
let fields = [
|
|
||||||
("User", format!("{} ({})", user.name, user.id), false),
|
|
||||||
("Reason", reason.unwrap_or("None".to_string()), false),
|
|
||||||
(
|
|
||||||
"Deleted messages",
|
|
||||||
format!("Last {} days", delete_messages_days.unwrap_or(0)),
|
|
||||||
false,
|
|
||||||
),
|
|
||||||
];
|
|
||||||
|
|
||||||
|e: &mut CreateEmbed| e.title(title).fields(fields).color(COLORS["red"])
|
enum ActionData {
|
||||||
|
Kick,
|
||||||
|
Ban { purge: u8 },
|
||||||
|
Timeout { until: Timestamp },
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_dm<'a, 'b>(
|
||||||
|
message: &'b mut CreateMessage<'a>,
|
||||||
|
guild: &Guild,
|
||||||
|
action: &Action,
|
||||||
|
) -> &'b mut CreateMessage<'a> {
|
||||||
|
let description = match &action.data {
|
||||||
|
ActionData::Kick => "kicked from".to_string(),
|
||||||
|
ActionData::Ban { purge: _ } => "banned from".to_string(),
|
||||||
|
ActionData::Timeout { until } => {
|
||||||
|
format!("timed out until <t:{}> in", until.unix_timestamp())
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let guild_name = &guild.name;
|
||||||
|
let reason = &action.reason;
|
||||||
|
message.content(format!(
|
||||||
|
"You have been {description} {guild_name}.\nReason: {reason}"
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn moderate(
|
||||||
|
ctx: &Context<'_>,
|
||||||
|
users: &Vec<UserId>,
|
||||||
|
action: &Action,
|
||||||
|
quiet: bool,
|
||||||
|
) -> Result<()> {
|
||||||
|
let guild = ctx
|
||||||
|
.guild()
|
||||||
|
.ok_or_else(|| eyre!("Couldn't get guild from message!"))?;
|
||||||
|
let reason = &action.reason;
|
||||||
|
|
||||||
|
let mut count = 0;
|
||||||
|
|
||||||
|
for user in users {
|
||||||
|
if quiet {
|
||||||
|
if let Ok(channel) = user.create_dm_channel(ctx.http()).await {
|
||||||
|
let _ = channel
|
||||||
|
.send_message(ctx.http(), |message| build_dm(message, &guild, action))
|
||||||
|
.await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let success = match action.data {
|
||||||
|
ActionData::Kick => guild
|
||||||
|
.kick_with_reason(ctx.http(), user, reason)
|
||||||
|
.await
|
||||||
|
.is_ok(),
|
||||||
|
|
||||||
|
ActionData::Ban { purge } => guild
|
||||||
|
.ban_with_reason(ctx.http(), user, purge, reason)
|
||||||
|
.await
|
||||||
|
.is_ok(),
|
||||||
|
|
||||||
|
ActionData::Timeout { until } => guild
|
||||||
|
.edit_member(ctx.http(), user, |member| {
|
||||||
|
member.disable_communication_until_datetime(until)
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
.is_ok(),
|
||||||
|
};
|
||||||
|
if success {
|
||||||
|
count += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let total = users.len();
|
||||||
|
if count == total {
|
||||||
|
ctx.reply("✅ Done!").await?;
|
||||||
|
} else {
|
||||||
|
ctx.reply(format!("⚠️ {count}/{total} succeeded!"))
|
||||||
|
.await?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Ban a user
|
/// Ban a user
|
||||||
|
@ -27,28 +96,28 @@ fn create_moderation_embed(
|
||||||
slash_command,
|
slash_command,
|
||||||
prefix_command,
|
prefix_command,
|
||||||
default_member_permissions = "BAN_MEMBERS",
|
default_member_permissions = "BAN_MEMBERS",
|
||||||
required_permissions = "BAN_MEMBERS"
|
required_permissions = "BAN_MEMBERS",
|
||||||
|
aliases("ban")
|
||||||
)]
|
)]
|
||||||
pub async fn ban_user(
|
pub async fn ban(
|
||||||
ctx: Context<'_>,
|
ctx: Context<'_>,
|
||||||
user: User,
|
users: Vec<UserId>,
|
||||||
delete_messages_days: Option<u8>,
|
purge: Option<u8>,
|
||||||
reason: Option<String>,
|
reason: Option<String>,
|
||||||
|
quiet: Option<bool>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let days = delete_messages_days.unwrap_or(1);
|
moderate(
|
||||||
let guild = ctx
|
&ctx,
|
||||||
.guild()
|
&users,
|
||||||
.ok_or_else(|| eyre!("Couldn't get guild from message; Unable to ban!"))?;
|
&Action {
|
||||||
|
reason: reason.unwrap_or_default(),
|
||||||
guild
|
data: ActionData::Ban {
|
||||||
.ban_with_reason(ctx, &user, days, reason.clone().unwrap_or_default())
|
purge: purge.unwrap_or(0),
|
||||||
.await?;
|
},
|
||||||
|
},
|
||||||
let embed = create_moderation_embed("User banned!".to_string(), &user, Some(days), reason);
|
quiet.unwrap_or(false),
|
||||||
|
)
|
||||||
ctx.send(|m| m.embed(embed)).await?;
|
.await
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Kick a user
|
/// Kick a user
|
||||||
|
@ -58,18 +127,20 @@ pub async fn ban_user(
|
||||||
default_member_permissions = "KICK_MEMBERS",
|
default_member_permissions = "KICK_MEMBERS",
|
||||||
required_permissions = "KICK_MEMBERS"
|
required_permissions = "KICK_MEMBERS"
|
||||||
)]
|
)]
|
||||||
pub async fn kick_user(ctx: Context<'_>, user: User, reason: Option<String>) -> Result<()> {
|
pub async fn kick(
|
||||||
let guild = ctx
|
ctx: Context<'_>,
|
||||||
.guild()
|
users: Vec<UserId>,
|
||||||
.ok_or_else(|| eyre!("Couldn't get guild from message; Unable to ban!"))?;
|
reason: Option<String>,
|
||||||
|
quiet: Option<bool>,
|
||||||
guild
|
) -> Result<()> {
|
||||||
.kick_with_reason(ctx, &user, &reason.clone().unwrap_or_default())
|
moderate(
|
||||||
.await?;
|
&ctx,
|
||||||
|
&users,
|
||||||
let embed = create_moderation_embed("User kicked!".to_string(), &user, None, reason);
|
&Action {
|
||||||
|
reason: reason.unwrap_or_default(),
|
||||||
ctx.send(|m| m.embed(embed)).await?;
|
data: ActionData::Kick {},
|
||||||
|
},
|
||||||
Ok(())
|
quiet.unwrap_or(false),
|
||||||
|
)
|
||||||
|
.await
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,7 +62,7 @@ async fn main() -> Result<()> {
|
||||||
Box::pin(handlers::handle_event(ctx, event, framework, data))
|
Box::pin(handlers::handle_event(ctx, event, framework, data))
|
||||||
},
|
},
|
||||||
prefix_options: PrefixFrameworkOptions {
|
prefix_options: PrefixFrameworkOptions {
|
||||||
prefix: Some("!".into()),
|
prefix: Some("r".into()),
|
||||||
edit_tracker: Some(EditTracker::for_timespan(Duration::from_secs(3600))),
|
edit_tracker: Some(EditTracker::for_timespan(Duration::from_secs(3600))),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue