mirror of
https://github.com/ReVanced/revanced-bots.git
synced 2026-01-11 13:56:15 +00:00
feat(bots/discord/commands): add purge and role-preset commands
This commit is contained in:
73
bots/discord/src/commands/moderation/purge.ts
Normal file
73
bots/discord/src/commands/moderation/purge.ts
Normal file
@@ -0,0 +1,73 @@
|
||||
import { EmbedBuilder, GuildChannel, SlashCommandBuilder } from 'discord.js'
|
||||
|
||||
import CommandError, { CommandErrorType } from '$/classes/CommandError'
|
||||
import { config } from '$/context'
|
||||
import { applyCommonEmbedStyles } from '$/utils/discord/embeds'
|
||||
|
||||
import type { Command } from '..'
|
||||
|
||||
export default {
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('purge')
|
||||
.setDescription('Purge messages from a channel')
|
||||
.addIntegerOption(option =>
|
||||
option.setName('amount').setDescription('The amount of messages to remove').setMaxValue(100).setMinValue(1),
|
||||
)
|
||||
.addUserOption(option =>
|
||||
option.setName('user').setDescription('The user to remove messages from (needs `until`)'),
|
||||
)
|
||||
.addStringOption(option =>
|
||||
option.setName('until').setDescription('The message ID to remove messages until (overrides `amount`)'),
|
||||
)
|
||||
.toJSON(),
|
||||
|
||||
memberRequirements: {
|
||||
roles: config.moderation?.roles ?? [],
|
||||
},
|
||||
|
||||
global: false,
|
||||
|
||||
async execute({ logger }, interaction) {
|
||||
const amount = interaction.options.getInteger('amount')
|
||||
const user = interaction.options.getUser('user')
|
||||
const until = interaction.options.getString('until')
|
||||
|
||||
if (!amount && !until)
|
||||
throw new CommandError(CommandErrorType.MissingArgument, 'Either `amount` or `until` must be provided.')
|
||||
|
||||
const channel = interaction.channel!
|
||||
if (!(channel.isTextBased() && channel instanceof GuildChannel))
|
||||
throw new CommandError(CommandErrorType.InvalidChannel, 'The supplied channel is not a text channel.')
|
||||
|
||||
const embed = applyCommonEmbedStyles(
|
||||
new EmbedBuilder({
|
||||
title: 'Purging messages',
|
||||
description: 'Accumulating messages...',
|
||||
}),
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
)
|
||||
|
||||
const msgsPromise = channel.messages.fetch(until ? { after: until } : { limit: amount! })
|
||||
const reply = await interaction.reply({ embeds: [embed] }).then(it => it.fetch())
|
||||
|
||||
const messages = (
|
||||
user ? (await msgsPromise).filter(msg => msg.author.id === user.id) : await msgsPromise
|
||||
).filter(msg => msg.id !== reply.id)
|
||||
|
||||
await channel.bulkDelete(messages, true)
|
||||
|
||||
logger.info(
|
||||
`Moderator ${interaction.user.tag} (${interaction.user.id}) purged ${messages.size} messages in #${channel.name} (${channel.id})`,
|
||||
)
|
||||
await reply.edit({
|
||||
embeds: [
|
||||
embed.setTitle('Purged messages').setDescription(null).addFields({
|
||||
name: 'Deleted messages',
|
||||
value: messages.size.toString(),
|
||||
}),
|
||||
],
|
||||
})
|
||||
},
|
||||
} satisfies Command
|
||||
84
bots/discord/src/commands/moderation/role-preset.ts
Normal file
84
bots/discord/src/commands/moderation/role-preset.ts
Normal file
@@ -0,0 +1,84 @@
|
||||
import { SlashCommandBuilder } from 'discord.js'
|
||||
|
||||
import CommandError, { CommandErrorType } from '$/classes/CommandError'
|
||||
import { sendPresetReplyAndLogs } from '$/utils/discord/moderation'
|
||||
import { applyRolePreset, removeRolePreset } from '$/utils/discord/rolePresets'
|
||||
import { parseDuration } from '$/utils/duration'
|
||||
import type { Command } from '..'
|
||||
|
||||
export default {
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('role-preset')
|
||||
.setDescription('Manage role presets for a member')
|
||||
.addStringOption(option =>
|
||||
option
|
||||
.setName('action')
|
||||
.setRequired(true)
|
||||
.setDescription('The action to perform')
|
||||
.addChoices([
|
||||
{ name: 'apply', value: 'apply' },
|
||||
{ name: 'remove', value: 'remove' },
|
||||
]),
|
||||
)
|
||||
.addUserOption(option => option.setName('member').setRequired(true).setDescription('The member to manage'))
|
||||
.addStringOption(option =>
|
||||
option.setName('preset').setRequired(true).setDescription('The preset to apply or remove'),
|
||||
)
|
||||
.addStringOption(option =>
|
||||
option.setName('duration').setDescription('The duration to apply the preset for (only for apply action)'),
|
||||
)
|
||||
.toJSON(),
|
||||
|
||||
memberRequirements: {
|
||||
roles: ['955220417969262612', '973886585294704640'],
|
||||
},
|
||||
|
||||
global: false,
|
||||
|
||||
async execute({ logger }, interaction) {
|
||||
const action = interaction.options.getString('action', true) as 'apply' | 'remove'
|
||||
const user = interaction.options.getUser('member', true)
|
||||
const preset = interaction.options.getString('preset', true)
|
||||
const duration = interaction.options.getString('duration')
|
||||
|
||||
let expires: number | null | undefined = undefined
|
||||
const moderator = await interaction.guild!.members.fetch(interaction.user.id)
|
||||
const member = await interaction.guild!.members.fetch(user.id)
|
||||
if (!member)
|
||||
throw new CommandError(
|
||||
CommandErrorType.InvalidUser,
|
||||
'The provided member is not in the server or does not exist.',
|
||||
)
|
||||
|
||||
if (member.manageable)
|
||||
throw new CommandError(CommandErrorType.Generic, 'This user cannot be managed by the bot.')
|
||||
|
||||
if (action === 'apply') {
|
||||
const durationMs = duration ? parseDuration(duration) : null
|
||||
if (Number.isInteger(durationMs) && durationMs! < 1)
|
||||
throw new CommandError(
|
||||
CommandErrorType.InvalidDuration,
|
||||
'The duration must be at least 1 millisecond long.',
|
||||
)
|
||||
|
||||
if (moderator.roles.highest.comparePositionTo(member.roles.highest) <= 0)
|
||||
throw new CommandError(
|
||||
CommandErrorType.InvalidUser,
|
||||
'You cannot apply a role preset to a user with a role equal to or higher than yours.',
|
||||
)
|
||||
|
||||
expires = durationMs ? Date.now() + durationMs : null
|
||||
await applyRolePreset(member, preset, expires)
|
||||
logger.info(
|
||||
`Moderator ${interaction.user.tag} (${interaction.user.id}) applied role preset ${preset} to ${user.id} until ${expires}`,
|
||||
)
|
||||
} else if (action === 'remove') {
|
||||
await removeRolePreset(member, preset)
|
||||
logger.info(
|
||||
`Moderator ${interaction.user.tag} (${interaction.user.id}) removed role preset ${preset} from ${user.id}`,
|
||||
)
|
||||
}
|
||||
|
||||
await sendPresetReplyAndLogs(action, interaction, user, preset, expires)
|
||||
},
|
||||
} satisfies Command
|
||||
Reference in New Issue
Block a user