54 lines
2.1 KiB
TypeScript
54 lines
2.1 KiB
TypeScript
import { Guild, CommandInteraction, Role, SlashCommandBuilder } from 'discord.js';
|
|
import { isColorRole, isPronounRole } from '../lib/assignableRoles';
|
|
import { Command } from '../types/index';
|
|
|
|
async function fetchRoleMembers(role: Role) {
|
|
const members = await role.guild.members.fetch();
|
|
return members.filter(m => m.roles.cache.has(role.id));
|
|
}
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
async function garbageCollectRoles(guild: Guild, dryRun: boolean): Promise<Role[]> {
|
|
const roles = guild.roles.cache;
|
|
const garbageRoles = roles.filter((r: Role) => isColorRole(r.name) || isPronounRole(r.name));
|
|
const deletedRoles = garbageRoles.map(async (role: Role) => {
|
|
const members = await fetchRoleMembers(role);
|
|
if (members.size === 0) {
|
|
if (dryRun) return role;
|
|
return await role.delete('garbage collection');
|
|
}
|
|
});
|
|
return (await Promise.all(deletedRoles)).filter(r => r) as Role[];
|
|
}
|
|
|
|
export default {
|
|
data: new SlashCommandBuilder()
|
|
.setName('garbage-collect-roles')
|
|
.setDescription('[ADMIN] Garbage collect unused self-assignable roles')
|
|
.addBooleanOption((option) => option.setName('dry-run').setDescription('Only show roles that would be deleted'))
|
|
.setDefaultMemberPermissions(0)
|
|
.setDMPermission(false),
|
|
|
|
execute: async (interaction: CommandInteraction) => {
|
|
if (!interaction.isChatInputCommand()) return;
|
|
|
|
await interaction.deferReply({
|
|
ephemeral: false
|
|
});
|
|
|
|
const dryrun = interaction.options.getBoolean('dry-run');
|
|
const colorRoles = await garbageCollectRoles(interaction.guild!, dryrun || false);
|
|
|
|
if (dryrun) {
|
|
interaction.followUp({
|
|
content: `${colorRoles.length} role${colorRoles.length === 1 ? '' : 's'} would be deleted${colorRoles.length === 0 ? '.' : ':\n'}${colorRoles.map(r => `\`${r.name}\``).join('\n')}`,
|
|
ephemeral: true,
|
|
});
|
|
} else {
|
|
interaction.followUp({
|
|
content: `${colorRoles.length} role${colorRoles.length === 1 ? ' was' : 's were'} deleted${colorRoles.length === 0 ? '.' : ':\n'}${colorRoles.map(r => `\`${r.name}\``).join('\n')}`,
|
|
ephemeral: true,
|
|
});
|
|
}
|
|
}
|
|
} satisfies Command; |