Last active
November 30, 2021 21:04
-
-
Save AidenMontgomery/8a052a62589e86dbd299dab09c217bf9 to your computer and use it in GitHub Desktop.
add-special-role slash command for devie-bot
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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