import { Guild, GuildMember, CommandInteraction, Role, SlashCommandBuilder } from 'discord.js'; import { isColorRole, isPronounRole } from '../lib/assignableRoles'; import { knownServers } from '../lib/knownServers'; 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 { 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('Garbage collect unused roles for colors and pronouns.') .addBooleanOption((option) => option.setName('dry-run').setDescription('Only show roles that would be deleted.')) .setDefaultMemberPermissions('0'), serverWhitelist: [...knownServers.firepit], 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;