blob: c09e19700578ad1e4c8c734ca6bcf5fa394d32fa [file] [log] [blame]
pineafan377794f2022-04-18 19:01:01 +01001import { CommandInteraction, GuildMember, MessageActionRow, MessageButton } from "discord.js";
pineafan32767212022-03-14 21:27:39 +00002import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
3import { WrappedCheck } from "jshaiku";
4import confirmationMessage from "../../utils/confirmationMessage.js";
pineafan377794f2022-04-18 19:01:01 +01005import generateEmojiEmbed from "../../utils/generateEmojiEmbed.js";
pineafan32767212022-03-14 21:27:39 +00006import keyValueList from "../../utils/generateKeyValueList.js";
pineafan377794f2022-04-18 19:01:01 +01007import { create, areTicketsEnabled } from "../../automations/createModActionTicket.js";
pineafan32767212022-03-14 21:27:39 +00008
9const command = (builder: SlashCommandSubcommandBuilder) =>
10 builder
11 .setName("nick")
12 .setDescription("Changes a users nickname")
13 .addUserOption(option => option.setName("user").setDescription("The user to change").setRequired(true))
pineafan377794f2022-04-18 19:01:01 +010014 .addStringOption(option => option.setName("name").setDescription("The name to set | Leave blank to clear").setRequired(false))
pineafan32767212022-03-14 21:27:39 +000015 .addStringOption(option => option.setName("notify").setDescription("If the user should get a message when their nickname is changed | Default no").setRequired(false)
16 .addChoices([["Yes", "yes"], ["No", "no"]])
17 )
18
19const callback = async (interaction: CommandInteraction) => {
pineafan377794f2022-04-18 19:01:01 +010020 // TODO:[Modals] Replace this with a modal
21 let confirmation = await new confirmationMessage(interaction)
22 .setEmoji("PUNISH.NICKNAME.RED")
23 .setTitle("Nickname")
24 .setDescription(keyValueList({
25 "user": `<@!${(interaction.options.getMember("user") as GuildMember).id}> (${(interaction.options.getMember("user") as GuildMember).user.username})`,
26 "new nickname": `${interaction.options.getString("name") ? interaction.options.getString("name") : "*No nickname*"}`
27 })
28 + `The user **will${interaction.options.getString("notify") == "yes" ? '' : ' not'}** be notified\n\n`
29 + `Are you sure you want to ${interaction.options.getString("name") ? "change" : "clear"} <@!${(interaction.options.getMember("user") as GuildMember).id}>'s nickname?`)
30 .setColor("Danger")
pineafan4092b862022-05-20 19:27:23 +010031 .addCustomBoolean(
pineafan377794f2022-04-18 19:01:01 +010032 "Create appeal ticket", !(await areTicketsEnabled(interaction.guild.id)),
pineafan6702cef2022-06-13 17:52:37 +010033 async () => await create(interaction.guild, interaction.options.getUser("user"), interaction.user, interaction.options.getString("reason")),
pineafan4092b862022-05-20 19:27:23 +010034 "An appeal ticket will be created when Confirm is clicked")
pineafan377794f2022-04-18 19:01:01 +010035 .send()
36 if (confirmation.success) {
37 let dmd = false
38 let dm;
39 try {
40 if (interaction.options.getString("notify") == "yes") {
41 dm = await (interaction.options.getMember("user") as GuildMember).send({
42 embeds: [new generateEmojiEmbed()
43 .setEmoji("PUNISH.NICKNAME.RED")
44 .setTitle("Nickname changed")
pineafane625d782022-05-09 18:04:32 +010045 .setDescription(`Your nickname was ${interaction.options.getString("name") ? "changed" : "cleared"} in ${interaction.guild.name}.` +
46 (interaction.options.getString("name") ? ` it is now: ${interaction.options.getString("name")}` : "") + "\n\n" +
PineappleFan30b5fda2022-05-22 15:41:47 +010047 (confirmation.buttonClicked ? `You can appeal this here: <#${confirmation.response}>` : ``))
pineafan377794f2022-04-18 19:01:01 +010048 .setStatus("Danger")
49 ]
50 })
51 dmd = true
52 }
53 } catch {}
54 try {
pineafane625d782022-05-09 18:04:32 +010055 let member = (interaction.options.getMember("user") as GuildMember)
56 let before = member.nickname
57 let nickname = interaction.options.getString("name")
58 member.setNickname(nickname ?? null, "Nucleus Nickname command")
59 // @ts-ignore
PineappleFanb3dd83c2022-06-17 10:53:48 +010060 const { log, NucleusColors, entry, renderUser, renderDelta, getAuditLog } = client.logger
pineafane625d782022-05-09 18:04:32 +010061 let data = {
62 meta: {
63 type: 'memberUpdate',
64 displayName: 'Member Updated',
65 calculateType: 'guildMemberUpdate',
66 color: NucleusColors.yellow,
67 emoji: "PUNISH.NICKNAME.YELLOW",
68 timestamp: new Date().getTime()
69 },
70 list: {
71 id: entry(member.id, `\`${member.id}\``),
72 before: entry(before, before ? before : '*None*'),
73 after: entry(nickname, nickname ? nickname : '*None*'),
74 updated: entry(new Date().getTime(), renderDelta(new Date().getTime())),
75 updatedBy: entry(interaction.user.id, renderUser(interaction.user))
76 },
77 hidden: {
78 guild: interaction.guild.id
79 }
80 }
PineappleFanb3dd83c2022-06-17 10:53:48 +010081 log(data, client);
pineafan377794f2022-04-18 19:01:01 +010082 } catch {
83 await interaction.editReply({embeds: [new generateEmojiEmbed()
84 .setEmoji("PUNISH.NICKNAME.RED")
85 .setTitle(`Nickname`)
86 .setDescription("Something went wrong and the users nickname could not be changed.")
87 .setStatus("Danger")
88 ], components: []})
89 if (dmd) await dm.delete()
90 return
91 }
92 let failed = (dmd == false && interaction.options.getString("notify") == "yes")
93 await interaction.editReply({embeds: [new generateEmojiEmbed()
94 .setEmoji(`PUNISH.NICKNAME.${failed ? "YELLOW" : "GREEN"}`)
95 .setTitle(`Nickname`)
pineafan4092b862022-05-20 19:27:23 +010096 .setDescription("The members nickname was changed" + (failed ? ", but was not notified" : "") + (confirmation.response ? ` and an appeal ticket was opened in <#${confirmation.response}>` : ``))
pineafan377794f2022-04-18 19:01:01 +010097 .setStatus(failed ? "Warning" : "Success")
98 ], components: []})
99 } else {
100 await interaction.editReply({embeds: [new generateEmojiEmbed()
101 .setEmoji("PUNISH.NICKNAME.GREEN")
102 .setTitle(`Nickname`)
103 .setDescription("No changes were made")
104 .setStatus("Success")
105 ], components: []})
106 }
pineafan32767212022-03-14 21:27:39 +0000107}
108
109const check = (interaction: CommandInteraction, defaultCheck: WrappedCheck) => {
pineafan377794f2022-04-18 19:01:01 +0100110 let member = (interaction.member as GuildMember)
111 let me = (interaction.guild.me as GuildMember)
112 let apply = (interaction.options.getMember("user") as GuildMember)
113 if (member == null || me == null || apply == null) throw "That member is not in the server"
114 let memberPos = member.roles ? member.roles.highest.position : 0
115 let mePos = me.roles ? me.roles.highest.position : 0
116 let applyPos = apply.roles ? apply.roles.highest.position : 0
117 // Check if Nucleus can change the nickname
118 if (! (mePos > applyPos)) throw "I do not have a role higher than that member"
119 // Check if Nucleus has permission to change the nickname
PineappleFan5fe720d2022-05-19 12:01:49 +0100120 if (! me.permissions.has("MANAGE_NICKNAMES")) throw "I do not have the `manage_nicknames` permission";
pineafan377794f2022-04-18 19:01:01 +0100121 // Allow the owner to change anyone's nickname
pineafan663dc472022-05-10 18:13:47 +0100122 if (member.id == interaction.guild.ownerId) return true
pineafan377794f2022-04-18 19:01:01 +0100123 // Check if the user has manage_nicknames permission
pineafan663dc472022-05-10 18:13:47 +0100124 if (! member.permissions.has("MANAGE_NICKNAMES")) throw "You do not have the `manage_nicknames` permission";
pineafane625d782022-05-09 18:04:32 +0100125 // Allow changing your own nickname
126 if (member == apply) return true
pineafan377794f2022-04-18 19:01:01 +0100127 // Check if the user is below on the role list
128 if (! (memberPos > applyPos)) throw "You do not have a role higher than that member"
129 // Allow change
130 return true
pineafan32767212022-03-14 21:27:39 +0000131}
132
133export { command, callback, check };