blob: c6f063356bcf42d800505467f77b4830eba08197 [file] [log] [blame]
pineafanbd02b4a2022-08-05 22:01:38 +01001import { CommandInteraction, GuildMember } from "discord.js";
pineafan32767212022-03-14 21:27:39 +00002import { 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
8const command = (builder: SlashCommandSubcommandBuilder) =>
9 builder
pineafan63fc5e22022-08-04 22:04:10 +010010 .setName("nick")
11 .setDescription("Changes a users nickname")
Skyler Grey11236ba2022-08-08 21:13:33 +010012 .addUserOption((option) => option.setName("user").setDescription("The user to change").setRequired(true))
Skyler Grey75ea9172022-08-06 10:22:23 +010013 .addStringOption((option) =>
Skyler Grey11236ba2022-08-08 21:13:33 +010014 option.setName("name").setDescription("The name to set | Leave blank to clear").setRequired(false)
Skyler Grey75ea9172022-08-06 10:22:23 +010015 );
pineafan32767212022-03-14 21:27:39 +000016
pineafan3a02ea32022-08-11 21:35:04 +010017const callback = async (interaction: CommandInteraction): Promise<unknown> => {
pineafan63fc5e22022-08-04 22:04:10 +010018 const { renderUser } = client.logger;
pineafan377794f2022-04-18 19:01:01 +010019 // TODO:[Modals] Replace this with a modal
pineafan02ba0232022-07-24 22:16:15 +010020 let notify = true;
21 let confirmation;
22 while (true) {
23 confirmation = await new confirmationMessage(interaction)
24 .setEmoji("PUNISH.NICKNAME.RED")
25 .setTitle("Nickname")
Skyler Grey75ea9172022-08-06 10:22:23 +010026 .setDescription(
27 keyValueList({
28 user: renderUser(interaction.options.getUser("user")),
29 "new nickname": `${
Skyler Grey11236ba2022-08-08 21:13:33 +010030 interaction.options.getString("name") ? interaction.options.getString("name") : "*No nickname*"
Skyler Grey75ea9172022-08-06 10:22:23 +010031 }`
32 }) +
33 `The user **will${notify ? "" : " not"}** be notified\n\n` +
Skyler Grey11236ba2022-08-08 21:13:33 +010034 `Are you sure you want to ${interaction.options.getString("name") ? "change" : "clear"} <@!${
35 (interaction.options.getMember("user") as GuildMember).id
Skyler Grey75ea9172022-08-06 10:22:23 +010036 }>'s nickname?`
37 )
pineafan02ba0232022-07-24 22:16:15 +010038 .setColor("Danger")
Skyler Grey75ea9172022-08-06 10:22:23 +010039 .addCustomBoolean(
40 "notify",
41 "Notify user",
42 false,
43 null,
44 null,
45 "ICONS.NOTIFY." + (notify ? "ON" : "OFF"),
46 notify
47 )
pineafan63fc5e22022-08-04 22:04:10 +010048 .send(interaction.options.getString("name") !== null);
49 if (confirmation.cancelled) return;
50 if (confirmation.success) break;
pineafan02ba0232022-07-24 22:16:15 +010051 if (confirmation.components) {
pineafan63fc5e22022-08-04 22:04:10 +010052 notify = confirmation.components.notify.active;
pineafan02ba0232022-07-24 22:16:15 +010053 }
54 }
pineafan377794f2022-04-18 19:01:01 +010055 if (confirmation.success) {
pineafan63fc5e22022-08-04 22:04:10 +010056 let dmd = false;
pineafan377794f2022-04-18 19:01:01 +010057 let dm;
58 try {
pineafan02ba0232022-07-24 22:16:15 +010059 if (notify) {
Skyler Grey11236ba2022-08-08 21:13:33 +010060 dm = await (interaction.options.getMember("user") as GuildMember).send({
Skyler Grey75ea9172022-08-06 10:22:23 +010061 embeds: [
62 new EmojiEmbed()
63 .setEmoji("PUNISH.NICKNAME.RED")
64 .setTitle("Nickname changed")
65 .setDescription(
66 `Your nickname was ${
Skyler Grey11236ba2022-08-08 21:13:33 +010067 interaction.options.getString("name") ? "changed" : "cleared"
Skyler Grey75ea9172022-08-06 10:22:23 +010068 } in ${interaction.guild.name}.` +
69 (interaction.options.getString("name")
Skyler Grey11236ba2022-08-08 21:13:33 +010070 ? ` it is now: ${interaction.options.getString("name")}`
Skyler Grey75ea9172022-08-06 10:22:23 +010071 : "") +
72 "\n\n" +
73 (confirmation.components.appeal.response
74 ? `You can appeal this here: <#${confirmation.components.appeal.response}>`
75 : "")
76 )
77 .setStatus("Danger")
pineafan377794f2022-04-18 19:01:01 +010078 ]
pineafan63fc5e22022-08-04 22:04:10 +010079 });
80 dmd = true;
pineafan377794f2022-04-18 19:01:01 +010081 }
Skyler Grey75ea9172022-08-06 10:22:23 +010082 } catch {
83 dmd = false;
84 }
pineafan377794f2022-04-18 19:01:01 +010085 try {
Skyler Grey75ea9172022-08-06 10:22:23 +010086 const member = interaction.options.getMember("user") as GuildMember;
pineafan63fc5e22022-08-04 22:04:10 +010087 const before = member.nickname;
88 const nickname = interaction.options.getString("name");
89 member.setNickname(nickname ?? null, "Nucleus Nickname command");
90 await client.database.history.create(
Skyler Grey75ea9172022-08-06 10:22:23 +010091 "nickname",
92 interaction.guild.id,
93 member.user,
94 interaction.user,
95 null,
96 before,
97 nickname
98 );
Skyler Grey11236ba2022-08-08 21:13:33 +010099 const { log, NucleusColors, entry, renderUser, renderDelta } = client.logger;
pineafan63fc5e22022-08-04 22:04:10 +0100100 const data = {
pineafane625d782022-05-09 18:04:32 +0100101 meta: {
pineafan63fc5e22022-08-04 22:04:10 +0100102 type: "memberUpdate",
103 displayName: "Member Updated",
104 calculateType: "guildMemberUpdate",
pineafane625d782022-05-09 18:04:32 +0100105 color: NucleusColors.yellow,
106 emoji: "PUNISH.NICKNAME.YELLOW",
107 timestamp: new Date().getTime()
108 },
109 list: {
pineafanda6e5342022-07-03 10:03:16 +0100110 memberId: entry(member.id, `\`${member.id}\``),
pineafan63fc5e22022-08-04 22:04:10 +0100111 before: entry(before, before ? before : "*None*"),
112 after: entry(nickname, nickname ? nickname : "*None*"),
Skyler Grey11236ba2022-08-08 21:13:33 +0100113 updated: entry(new Date().getTime(), renderDelta(new Date().getTime())),
114 updatedBy: entry(interaction.user.id, renderUser(interaction.user))
pineafane625d782022-05-09 18:04:32 +0100115 },
116 hidden: {
117 guild: interaction.guild.id
118 }
pineafan63fc5e22022-08-04 22:04:10 +0100119 };
pineafan4edb7762022-06-26 19:21:04 +0100120 log(data);
pineafan377794f2022-04-18 19:01:01 +0100121 } catch {
Skyler Grey75ea9172022-08-06 10:22:23 +0100122 await interaction.editReply({
123 embeds: [
124 new EmojiEmbed()
125 .setEmoji("PUNISH.NICKNAME.RED")
126 .setTitle("Nickname")
Skyler Grey11236ba2022-08-08 21:13:33 +0100127 .setDescription("Something went wrong and the users nickname could not be changed.")
Skyler Grey75ea9172022-08-06 10:22:23 +0100128 .setStatus("Danger")
129 ],
130 components: []
131 });
pineafan63fc5e22022-08-04 22:04:10 +0100132 if (dmd) await dm.delete();
133 return;
pineafan377794f2022-04-18 19:01:01 +0100134 }
Skyler Grey75ea9172022-08-06 10:22:23 +0100135 const failed = !dmd && notify;
136 await interaction.editReply({
137 embeds: [
138 new EmojiEmbed()
139 .setEmoji(`PUNISH.NICKNAME.${failed ? "YELLOW" : "GREEN"}`)
140 .setTitle("Nickname")
141 .setDescription(
142 "The members nickname was changed" +
143 (failed ? ", but was not notified" : "") +
144 (confirmation.components.appeal.response
145 ? ` and an appeal ticket was opened in <#${confirmation.components.appeal.response}>`
146 : "")
147 )
148 .setStatus(failed ? "Warning" : "Success")
149 ],
150 components: []
151 });
pineafan377794f2022-04-18 19:01:01 +0100152 } else {
Skyler Grey75ea9172022-08-06 10:22:23 +0100153 await interaction.editReply({
154 embeds: [
155 new EmojiEmbed()
156 .setEmoji("PUNISH.NICKNAME.GREEN")
157 .setTitle("Nickname")
158 .setDescription("No changes were made")
159 .setStatus("Success")
160 ],
161 components: []
162 });
pineafan377794f2022-04-18 19:01:01 +0100163 }
pineafan63fc5e22022-08-04 22:04:10 +0100164};
pineafan32767212022-03-14 21:27:39 +0000165
pineafanbd02b4a2022-08-05 22:01:38 +0100166const check = (interaction: CommandInteraction) => {
Skyler Grey75ea9172022-08-06 10:22:23 +0100167 const member = interaction.member as GuildMember;
168 const me = interaction.guild.me!;
169 const apply = interaction.options.getMember("user") as GuildMember;
pineafan3a02ea32022-08-11 21:35:04 +0100170 if (member === null || me === null || apply === null) throw new Error("That member is not in the server");
pineafan63fc5e22022-08-04 22:04:10 +0100171 const memberPos = member.roles ? member.roles.highest.position : 0;
172 const mePos = me.roles ? me.roles.highest.position : 0;
173 const applyPos = apply.roles ? apply.roles.highest.position : 0;
pineafanc1c18792022-08-03 21:41:36 +0100174 // Do not allow any changing of the owner
pineafan3a02ea32022-08-11 21:35:04 +0100175 if (member.id === interaction.guild.ownerId) throw new Error("You cannot change the owner's nickname");
pineafan377794f2022-04-18 19:01:01 +0100176 // Check if Nucleus can change the nickname
pineafan3a02ea32022-08-11 21:35:04 +0100177 if (!(mePos > applyPos)) throw new Error("I do not have a role higher than that member");
pineafan377794f2022-04-18 19:01:01 +0100178 // Check if Nucleus has permission to change the nickname
pineafan3a02ea32022-08-11 21:35:04 +0100179 if (!me.permissions.has("MANAGE_NICKNAMES")) throw new Error("I do not have the *Manage Nicknames* permission");
pineafan377794f2022-04-18 19:01:01 +0100180 // Allow the owner to change anyone's nickname
pineafan63fc5e22022-08-04 22:04:10 +0100181 if (member.id === interaction.guild.ownerId) return true;
pineafan377794f2022-04-18 19:01:01 +0100182 // Check if the user has manage_nicknames permission
pineafan3a02ea32022-08-11 21:35:04 +0100183 if (!member.permissions.has("MANAGE_NICKNAMES"))
184 throw new Error("You do not have the *Manage Nicknames* permission");
pineafane625d782022-05-09 18:04:32 +0100185 // Allow changing your own nickname
pineafan63fc5e22022-08-04 22:04:10 +0100186 if (member === apply) return true;
pineafan377794f2022-04-18 19:01:01 +0100187 // Check if the user is below on the role list
pineafan3a02ea32022-08-11 21:35:04 +0100188 if (!(memberPos > applyPos)) throw new Error("You do not have a role higher than that member");
pineafan377794f2022-04-18 19:01:01 +0100189 // Allow change
pineafan63fc5e22022-08-04 22:04:10 +0100190 return true;
191};
pineafan32767212022-03-14 21:27:39 +0000192
Skyler Grey75ea9172022-08-06 10:22:23 +0100193export { command, callback, check };