Skip to content

Instantly share code, notes, and snippets.

@AidenMontgomery
Last active November 30, 2021 21:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AidenMontgomery/8a052a62589e86dbd299dab09c217bf9 to your computer and use it in GitHub Desktop.
Save AidenMontgomery/8a052a62589e86dbd299dab09c217bf9 to your computer and use it in GitHub Desktop.
add-special-role slash command for devie-bot
import { SlashCommandBuilder } from '@discordjs/builders';
import { CommandInteraction, Message, MessageActionRow, MessageButton, Role, GuildMember } from 'discord.js';
import { SlashCommandConfig } from '../types';
class RoleLookup {
public existingRole: Role | undefined;
public targetRole: Role | undefined;
}
export const AddSpecialRoleCommand: SlashCommandConfig = {
name: 'add-special-role',
roles: [],
commandJSON: () => new SlashCommandBuilder()
.setName('add-special-role')
.setDescription('Adds a special role to everyone in the provided role')
.addStringOption(
option => option.setRequired(true)
.setName('existingrole')
.setDescription('Enter the existing role to target'))
.addStringOption(
option => option.setRequired(true)
.setName('targetrole')
.setDescription('Enter the target role to add'))
.toJSON(),
execute: async (interaction: CommandInteraction) => {
const existingrole = interaction.options.getString('existingrole')
const targetrole = interaction.options.getString('targetrole')
const REPLY = {
YES: 'yes',
NO: 'no',
};
const noButton = new MessageButton()
.setCustomId(REPLY.NO)
.setLabel('Cancel')
.setStyle('DANGER');
const yesButton = new MessageButton()
.setCustomId(REPLY.YES)
.setLabel('Add role')
.setStyle('PRIMARY');
const buttonRow = new MessageActionRow()
.addComponents(
noButton,
yesButton,
);
if (existingrole === undefined || existingrole == null) {
interaction.reply({ content: 'Existing role missing, please try again.', ephemeral: true });
return;
}
if (targetrole === undefined || targetrole == null) {
interaction.reply({ content: 'Target role missing, please try again.', ephemeral: true });
return;
}
if (interaction.guild == undefined || interaction.guild == null) {
interaction.reply({ content: 'This interaction only works in a guild', ephemeral: true });
return;
}
const guildRoles = await interaction.guild.roles.fetch();
console.log(`There are ${guildRoles.size} roles.`);
const roleLookup: RoleLookup = guildRoles.reduce((result, role, key) => {
if (role.name.toLowerCase() === existingrole.trim().toLowerCase()) {
result.existingRole = role;
}
if (role.name.toLowerCase() === targetrole.trim().toLowerCase()) {
result.targetRole = role;
}
return result;
}, new RoleLookup());
if (roleLookup === undefined) {
interaction.reply({ content: 'The existing role does not exist on the server, please try again', ephemeral: true });
return;
}
if (roleLookup.existingRole === undefined || roleLookup.existingRole == null) {
interaction.reply({ content: 'The existing role does not exist on the server, please try again', ephemeral: true });
return;
}
if (roleLookup.targetRole === undefined || roleLookup.targetRole == null) {
interaction.reply({ content: 'The target role does not exist on the server, please try again', ephemeral: true });
return;
}
const guild = interaction.client.guilds.cache.get('450021773962903563');
if (guild === undefined) {
return;
}
const guildMembers = await guild.members.fetch();
console.log(`The guild has ${guildMembers.size} members`);
const originalRoleMembers: GuildMember[] = guildMembers.reduce((members: GuildMember[], member) => {
if (roleLookup.existingRole !== undefined && roleLookup.existingRole != null && roleLookup.targetRole !== undefined && roleLookup.targetRole != null) {
if (member.roles.cache.has(roleLookup.existingRole.id) && !member.roles.cache.has(roleLookup.targetRole.id)) {
members.push(member);
console.log(`${member.user.username}#${member.user.discriminator}, ${member.id}`);
}
else {
// console.log('Member does not have selected role');
}
}
return members;
}, []);
await interaction.reply({
content: `Are you sure you want to add \`${targetrole.trim()}\` to ${originalRoleMembers.length} members?`,
components: [buttonRow],
ephemeral: true,
});
const interactionMessage = await interaction.fetchReply();
if (!(interactionMessage instanceof Message)) { return; }
const buttonReply = await interaction.channel?.awaitMessageComponent({ componentType: 'BUTTON' });
if (!buttonReply) {
return;
}
const buttonSelected = buttonReply.customId;
buttonReply.update({ components: [] });
if (buttonSelected === REPLY.NO) {
buttonReply.followUp({
content: `"${targetrole.trim()}" was not added`,
ephemeral: true,
})
return;
}
else {
const delay = () => {
return new Promise((resolve) => setTimeout(resolve, 20));
}
try {
console.time('add-roles');
for (let index = 0; index < originalRoleMembers.length; index++) {
const member = originalRoleMembers[index];
await member.roles.add(roleLookup.targetRole);
await delay();
console.timeLog('add-roles');
}
console.timeEnd('add-roles');
}
catch (error) {
console.error('Error adding role', error);
}
}
},
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment