2023-11-27 16:14:08 +01:00
import { Guild , CommandInteraction , Role , SlashCommandBuilder } from 'discord.js' ;
2022-07-16 21:24:13 +02:00
import { isColorRole , isPronounRole } from '../lib/assignableRoles' ;
2023-11-16 11:33:11 +01:00
import { Command } from '../types/index' ;
2022-07-16 21:24:13 +02:00
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 [ ] ;
}
2023-11-16 11:33:11 +01:00
export default {
2022-07-16 21:24:13 +02:00
data : new SlashCommandBuilder ( )
. setName ( 'garbage-collect-roles' )
2023-11-27 16:14:08 +01:00
. 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 ) ,
2023-09-25 18:24:18 +02:00
2023-11-16 11:33:11 +01:00
execute : async ( interaction : CommandInteraction ) = > {
2023-06-11 17:23:57 +02:00
if ( ! interaction . isChatInputCommand ( ) ) return ;
2022-07-16 21:24:13 +02:00
await interaction . deferReply ( {
ephemeral : false
} ) ;
const dryrun = interaction . options . getBoolean ( 'dry-run' ) ;
2023-11-16 11:33:11 +01:00
const colorRoles = await garbageCollectRoles ( interaction . guild ! , dryrun || false ) ;
2022-07-16 21:24:13 +02:00
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 ,
} ) ;
}
}
2023-11-16 11:33:11 +01:00
} satisfies Command ;