const { PermissionFlagsBits, ApplicationCommandOptionType } = require('discord.js') // Bulk targeting is "by existing role" only — the spec also mentions an // explicit list of members, but Discord slash commands have no multi-user // picker, so that variant is deferred rather than faked with a handful of // user1..user5 options that would feel arbitrary and cramped. module.exports = { data: { name: 'roles', description: 'Bulk role operations across members who share an existing role.', default_member_permissions: PermissionFlagsBits.ManageRoles.toString(), options: [ { name: 'bulk-assign', description: 'Add a role to every member who has another role.', type: ApplicationCommandOptionType.Subcommand, options: [ { name: 'has-role', description: 'Members with this role are targeted', type: ApplicationCommandOptionType.Role, required: true }, { name: 'add-role', description: 'Role to add to those members', type: ApplicationCommandOptionType.Role, required: true }, ], }, { name: 'bulk-remove', description: 'Remove a role from every member who has another role.', type: ApplicationCommandOptionType.Subcommand, options: [ { name: 'has-role', description: 'Members with this role are targeted', type: ApplicationCommandOptionType.Role, required: true }, { name: 'remove-role', description: 'Role to remove from those members', type: ApplicationCommandOptionType.Role, required: true }, ], }, ], }, async execute(interaction) { const sub = interaction.options.getSubcommand() // Fetching every member + looping role updates can easily exceed // Discord's 3-second initial-response window. await interaction.deferReply({ ephemeral: true }) const hasRole = interaction.options.getRole('has-role', true) const members = await interaction.guild.members.fetch() const targets = members.filter((m) => m.roles.cache.has(hasRole.id)) if (sub === 'bulk-assign') { const addRole = interaction.options.getRole('add-role', true) let count = 0 for (const member of targets.values()) { if (!member.roles.cache.has(addRole.id)) { await member.roles.add(addRole.id).catch(() => {}) count++ } } await interaction.editReply({ content: `Added ${addRole} to ${count} member(s) who have ${hasRole}.` }) return } if (sub === 'bulk-remove') { const removeRole = interaction.options.getRole('remove-role', true) let count = 0 for (const member of targets.values()) { if (member.roles.cache.has(removeRole.id)) { await member.roles.remove(removeRole.id).catch(() => {}) count++ } } await interaction.editReply({ content: `Removed ${removeRole} from ${count} member(s) who have ${hasRole}.` }) } }, }