blob: b5e55547ff6302c3c4f0cf0332c12e53a39abe22 [file] [log] [blame]
pineafanbd02b4a2022-08-05 22:01:38 +01001import { CommandInteraction, GuildMember } from "discord.js";
PineaFan64486c42022-12-28 09:21:04 +00002import type { SlashCommandSubcommandBuilder } from "@discordjs/builders";
pineafan32767212022-03-14 21:27:39 +00003import confirmationMessage from "../../utils/confirmationMessage.js";
pineafan4edb7762022-06-26 19:21:04 +01004import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
pineafan32767212022-03-14 21:27:39 +00005import keyValueList from "../../utils/generateKeyValueList.js";
pineafan63fc5e22022-08-04 22:04:10 +01006import client from "../../utils/client.js";
pineafan32767212022-03-14 21:27:39 +00007
PineaFan64486c42022-12-28 09:21:04 +00008
9const command = (builder: SlashCommandSubcommandBuilder) => builder
10 .setName("nick")
11 .setDescription("Changes a users nickname")
12 .addUserOption((option) => option.setName("user").setDescription("The user to change").setRequired(true))
13 .addStringOption((option) =>
14 option.setName("name").setDescription("The name to set | Leave blank to clear").setRequired(false)
15 );
16
pineafan32767212022-03-14 21:27:39 +000017
pineafan3a02ea32022-08-11 21:35:04 +010018const callback = async (interaction: CommandInteraction): Promise<unknown> => {
pineafan63fc5e22022-08-04 22:04:10 +010019 const { renderUser } = client.logger;
pineafan377794f2022-04-18 19:01:01 +010020 // TODO:[Modals] Replace this with a modal
pineafan02ba0232022-07-24 22:16:15 +010021 let notify = true;
22 let confirmation;
Skyler Greyad002172022-08-16 18:48:26 +010023 let timedOut = false;
24 let success = false;
25 while (!timedOut && !success) {
pineafan02ba0232022-07-24 22:16:15 +010026 confirmation = await new confirmationMessage(interaction)
27 .setEmoji("PUNISH.NICKNAME.RED")
28 .setTitle("Nickname")
Skyler Grey75ea9172022-08-06 10:22:23 +010029 .setDescription(
30 keyValueList({
31 user: renderUser(interaction.options.getUser("user")),
32 "new nickname": `${
Skyler Grey11236ba2022-08-08 21:13:33 +010033 interaction.options.getString("name") ? interaction.options.getString("name") : "*No nickname*"
Skyler Grey75ea9172022-08-06 10:22:23 +010034 }`
35 }) +
36 `The user **will${notify ? "" : " not"}** be notified\n\n` +
Skyler Grey11236ba2022-08-08 21:13:33 +010037 `Are you sure you want to ${interaction.options.getString("name") ? "change" : "clear"} <@!${
38 (interaction.options.getMember("user") as GuildMember).id
Skyler Grey75ea9172022-08-06 10:22:23 +010039 }>'s nickname?`
40 )
pineafan02ba0232022-07-24 22:16:15 +010041 .setColor("Danger")
Skyler Grey75ea9172022-08-06 10:22:23 +010042 .addCustomBoolean(
43 "notify",
44 "Notify user",
45 false,
46 null,
47 null,
48 "ICONS.NOTIFY." + (notify ? "ON" : "OFF"),
49 notify
50 )
pineafan63fc5e22022-08-04 22:04:10 +010051 .send(interaction.options.getString("name") !== null);
Skyler Greyad002172022-08-16 18:48:26 +010052 if (confirmation.cancelled) timedOut = true;
53 else if (confirmation.success) success = true;
54 else if (confirmation.components) {
pineafan63fc5e22022-08-04 22:04:10 +010055 notify = confirmation.components.notify.active;
pineafan02ba0232022-07-24 22:16:15 +010056 }
57 }
Skyler Greyad002172022-08-16 18:48:26 +010058 if (timedOut) {
59 return await interaction.editReply({
Skyler Grey75ea9172022-08-06 10:22:23 +010060 embeds: [
61 new EmojiEmbed()
62 .setEmoji("PUNISH.NICKNAME.GREEN")
63 .setTitle("Nickname")
64 .setDescription("No changes were made")
65 .setStatus("Success")
66 ],
67 components: []
68 });
pineafan377794f2022-04-18 19:01:01 +010069 }
Skyler Greyad002172022-08-16 18:48:26 +010070 let dmd = false;
71 let dm;
72 try {
73 if (notify) {
74 dm = await (interaction.options.getMember("user") as GuildMember).send({
75 embeds: [
76 new EmojiEmbed()
77 .setEmoji("PUNISH.NICKNAME.RED")
78 .setTitle("Nickname changed")
79 .setDescription(
80 `Your nickname was ${interaction.options.getString("name") ? "changed" : "cleared"} in ${
81 interaction.guild.name
82 }.` +
83 (interaction.options.getString("name")
84 ? ` it is now: ${interaction.options.getString("name")}`
85 : "") +
86 "\n\n" +
87 (confirmation.components.appeal.response
88 ? `You can appeal this here: <#${confirmation.components.appeal.response}>`
89 : "")
90 )
91 .setStatus("Danger")
92 ]
93 });
94 dmd = true;
95 }
96 } catch {
97 dmd = false;
98 }
99 try {
100 const member = interaction.options.getMember("user") as GuildMember;
101 const before = member.nickname;
102 const nickname = interaction.options.getString("name");
103 member.setNickname(nickname ?? null, "Nucleus Nickname command");
104 await client.database.history.create(
105 "nickname",
106 interaction.guild.id,
107 member.user,
108 interaction.user,
109 null,
110 before,
111 nickname
112 );
113 const { log, NucleusColors, entry, renderUser, renderDelta } = client.logger;
114 const data = {
115 meta: {
116 type: "memberUpdate",
117 displayName: "Member Updated",
118 calculateType: "guildMemberUpdate",
119 color: NucleusColors.yellow,
120 emoji: "PUNISH.NICKNAME.YELLOW",
121 timestamp: new Date().getTime()
122 },
123 list: {
124 memberId: entry(member.id, `\`${member.id}\``),
125 before: entry(before, before ? before : "*None*"),
126 after: entry(nickname, nickname ? nickname : "*None*"),
127 updated: entry(new Date().getTime(), renderDelta(new Date().getTime())),
128 updatedBy: entry(interaction.user.id, renderUser(interaction.user))
129 },
130 hidden: {
131 guild: interaction.guild.id
132 }
133 };
134 log(data);
135 } catch {
136 await interaction.editReply({
137 embeds: [
138 new EmojiEmbed()
139 .setEmoji("PUNISH.NICKNAME.RED")
140 .setTitle("Nickname")
141 .setDescription("Something went wrong and the users nickname could not be changed.")
142 .setStatus("Danger")
143 ],
144 components: []
145 });
146 if (dmd) await dm.delete();
147 return;
148 }
149 const failed = !dmd && notify;
150 await interaction.editReply({
151 embeds: [
152 new EmojiEmbed()
153 .setEmoji(`PUNISH.NICKNAME.${failed ? "YELLOW" : "GREEN"}`)
154 .setTitle("Nickname")
155 .setDescription(
156 "The members nickname was changed" +
157 (failed ? ", but was not notified" : "") +
158 (confirmation.components.appeal.response
159 ? ` and an appeal ticket was opened in <#${confirmation.components.appeal.response}>`
160 : "")
161 )
162 .setStatus(failed ? "Warning" : "Success")
163 ],
164 components: []
165 });
pineafan63fc5e22022-08-04 22:04:10 +0100166};
pineafan32767212022-03-14 21:27:39 +0000167
pineafanbd02b4a2022-08-05 22:01:38 +0100168const check = (interaction: CommandInteraction) => {
Skyler Grey75ea9172022-08-06 10:22:23 +0100169 const member = interaction.member as GuildMember;
170 const me = interaction.guild.me!;
171 const apply = interaction.options.getMember("user") as GuildMember;
pineafan3a02ea32022-08-11 21:35:04 +0100172 if (member === null || me === null || apply === null) throw new Error("That member is not in the server");
pineafan62ce1922022-08-25 20:34:45 +0100173 const memberPos = member.roles.cache.size ? member.roles.highest.position : 0;
174 const mePos = me.roles.cache.size ? me.roles.highest.position : 0;
175 const applyPos = apply.roles.cache.size ? apply.roles.highest.position : 0;
pineafanc1c18792022-08-03 21:41:36 +0100176 // Do not allow any changing of the owner
pineafan3a02ea32022-08-11 21:35:04 +0100177 if (member.id === interaction.guild.ownerId) throw new Error("You cannot change the owner's nickname");
pineafan377794f2022-04-18 19:01:01 +0100178 // Check if Nucleus can change the nickname
pineafan3a02ea32022-08-11 21:35:04 +0100179 if (!(mePos > applyPos)) throw new Error("I do not have a role higher than that member");
pineafan377794f2022-04-18 19:01:01 +0100180 // Check if Nucleus has permission to change the nickname
pineafan3a02ea32022-08-11 21:35:04 +0100181 if (!me.permissions.has("MANAGE_NICKNAMES")) throw new Error("I do not have the *Manage Nicknames* permission");
pineafan377794f2022-04-18 19:01:01 +0100182 // Allow the owner to change anyone's nickname
pineafan63fc5e22022-08-04 22:04:10 +0100183 if (member.id === interaction.guild.ownerId) return true;
pineafan377794f2022-04-18 19:01:01 +0100184 // Check if the user has manage_nicknames permission
pineafan3a02ea32022-08-11 21:35:04 +0100185 if (!member.permissions.has("MANAGE_NICKNAMES"))
186 throw new Error("You do not have the *Manage Nicknames* permission");
pineafane625d782022-05-09 18:04:32 +0100187 // Allow changing your own nickname
pineafan63fc5e22022-08-04 22:04:10 +0100188 if (member === apply) return true;
pineafan377794f2022-04-18 19:01:01 +0100189 // Check if the user is below on the role list
pineafan3a02ea32022-08-11 21:35:04 +0100190 if (!(memberPos > applyPos)) throw new Error("You do not have a role higher than that member");
pineafan377794f2022-04-18 19:01:01 +0100191 // Allow change
pineafan63fc5e22022-08-04 22:04:10 +0100192 return true;
193};
pineafan32767212022-03-14 21:27:39 +0000194
Skyler Grey75ea9172022-08-06 10:22:23 +0100195export { command, callback, check };