blob: d4e0d75db89bcad2bc75a1dc49e6b50a14b19380 [file] [log] [blame]
pineafan5d1908e2022-02-28 21:34:47 +00001import { CommandInteraction, GuildMember } from "discord.js";
pineafan4f164f32022-02-26 22:07:12 +00002import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
pineafan5d1908e2022-02-28 21:34:47 +00003import confirmationMessage from "../../utils/confirmationMessage.js";
pineafan4edb7762022-06-26 19:21:04 +01004import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
pineafan5d1908e2022-02-28 21:34:47 +00005import keyValueList from "../../utils/generateKeyValueList.js";
pineafan4edb7762022-06-26 19:21:04 +01006import client from "../../utils/client.js";
pineafan4f164f32022-02-26 22:07:12 +00007
8const command = (builder: SlashCommandSubcommandBuilder) =>
9 builder
pineafan63fc5e22022-08-04 22:04:10 +010010 .setName("unmute")
11 .setDescription("Unmutes a user")
12 .addUserOption(option => option.setName("user").setDescription("The user to unmute").setRequired(true));
pineafan4f164f32022-02-26 22:07:12 +000013
pineafanbd02b4a2022-08-05 22:01:38 +010014const callback = async (interaction: CommandInteraction): Promise<void | unknown> => {
pineafan63fc5e22022-08-04 22:04:10 +010015 const { log, NucleusColors, renderUser, entry, renderDelta } = client.logger;
pineafan5d1908e2022-02-28 21:34:47 +000016 // TODO:[Modals] Replace this with a modal
pineafan73a7c4a2022-07-24 10:38:04 +010017 let reason = null;
pineafan02ba0232022-07-24 22:16:15 +010018 let notify = false;
pineafan73a7c4a2022-07-24 10:38:04 +010019 let confirmation;
20 while (true) {
21 confirmation = await new confirmationMessage(interaction)
22 .setEmoji("PUNISH.MUTE.RED")
23 .setTitle("Unmute")
24 .setDescription(keyValueList({
25 "user": renderUser(interaction.options.getUser("user")),
26 "reason": `\n> ${reason ? reason : "*No reason provided*"}`
27 })
pineafan63fc5e22022-08-04 22:04:10 +010028 + `The user **will${notify ? "" : " not"}** be notified\n\n`
pineafan73a7c4a2022-07-24 10:38:04 +010029 + `Are you sure you want to unmute <@!${(interaction.options.getMember("user") as GuildMember).id}>?`)
30 .setColor("Danger")
31 .addReasonButton(reason ?? "")
pineafan63fc5e22022-08-04 22:04:10 +010032 .send(reason !== null);
33 if (confirmation.success) break;
34 if (confirmation.newReason) reason = confirmation.newReason;
pineafan02ba0232022-07-24 22:16:15 +010035 if (confirmation.components) {
pineafan63fc5e22022-08-04 22:04:10 +010036 notify = confirmation.components.notify.active;
pineafan02ba0232022-07-24 22:16:15 +010037 }
pineafan73a7c4a2022-07-24 10:38:04 +010038 }
pineafan63fc5e22022-08-04 22:04:10 +010039 if (confirmation.cancelled) return;
pineafan377794f2022-04-18 19:01:01 +010040 if (confirmation.success) {
pineafan63fc5e22022-08-04 22:04:10 +010041 let dmd = false;
pineafan5d1908e2022-02-28 21:34:47 +000042 let dm;
43 try {
pineafan02ba0232022-07-24 22:16:15 +010044 if (notify) {
pineafan5d1908e2022-02-28 21:34:47 +000045 dm = await (interaction.options.getMember("user") as GuildMember).send({
pineafan4edb7762022-06-26 19:21:04 +010046 embeds: [new EmojiEmbed()
pineafan5d1908e2022-02-28 21:34:47 +000047 .setEmoji("PUNISH.MUTE.GREEN")
48 .setTitle("Unmuted")
49 .setDescription(`You have been unmuted in ${interaction.guild.name}` +
pineafan73a7c4a2022-07-24 10:38:04 +010050 (reason ? ` for:\n> ${reason}` : " with no reason provided."))
pineafan5d1908e2022-02-28 21:34:47 +000051 .setStatus("Success")
52 ]
pineafan63fc5e22022-08-04 22:04:10 +010053 });
54 dmd = true;
pineafan5d1908e2022-02-28 21:34:47 +000055 }
pineafan63fc5e22022-08-04 22:04:10 +010056 } catch { dmd = false; }
57 const member = (interaction.options.getMember("user") as GuildMember);
pineafan5d1908e2022-02-28 21:34:47 +000058 try {
pineafan63fc5e22022-08-04 22:04:10 +010059 member.timeout(0, reason || "No reason provided");
pineafan5d1908e2022-02-28 21:34:47 +000060 } catch {
pineafan4edb7762022-06-26 19:21:04 +010061 await interaction.editReply({embeds: [new EmojiEmbed()
pineafan5d1908e2022-02-28 21:34:47 +000062 .setEmoji("PUNISH.MUTE.RED")
pineafan63fc5e22022-08-04 22:04:10 +010063 .setTitle("Unmute")
pineafan5d1908e2022-02-28 21:34:47 +000064 .setDescription("Something went wrong and the user was not unmuted")
65 .setStatus("Danger")
pineafan63fc5e22022-08-04 22:04:10 +010066 ], components: []});
67 if (dmd) await dm.delete();
68 return;
pineafan5d1908e2022-02-28 21:34:47 +000069 }
pineafan63fc5e22022-08-04 22:04:10 +010070 await client.database.history.create("unmute", interaction.guild.id, (interaction.options.getMember("user") as GuildMember).user, interaction.user, reason);
71 const data = {
pineafan73a7c4a2022-07-24 10:38:04 +010072 meta: {
pineafan63fc5e22022-08-04 22:04:10 +010073 type: "memberUnmute",
74 displayName: "Unmuted",
75 calculateType: "guildMemberPunish",
pineafan73a7c4a2022-07-24 10:38:04 +010076 color: NucleusColors.green,
77 emoji: "PUNISH.MUTE.GREEN",
78 timestamp: new Date().getTime()
79 },
80 list: {
81 memberId: entry(member.user.id, `\`${member.user.id}\``),
82 name: entry(member.user.id, renderUser(member.user)),
83 unmuted: entry(new Date().getTime(), renderDelta(new Date().getTime())),
pineafan63fc5e22022-08-04 22:04:10 +010084 unmutedBy: entry(interaction.user.id, renderUser(interaction.user))
pineafan73a7c4a2022-07-24 10:38:04 +010085 },
86 hidden: {
87 guild: interaction.guild.id
88 }
pineafan63fc5e22022-08-04 22:04:10 +010089 };
pineafan73a7c4a2022-07-24 10:38:04 +010090 log(data);
pineafan63fc5e22022-08-04 22:04:10 +010091 const failed = (dmd === false && notify);
pineafan4edb7762022-06-26 19:21:04 +010092 await interaction.editReply({embeds: [new EmojiEmbed()
pineafan5d1908e2022-02-28 21:34:47 +000093 .setEmoji(`PUNISH.MUTE.${failed ? "YELLOW" : "GREEN"}`)
pineafan63fc5e22022-08-04 22:04:10 +010094 .setTitle("Unmute")
pineafan5d1908e2022-02-28 21:34:47 +000095 .setDescription("The member was unmuted" + (failed ? ", but could not be notified" : ""))
96 .setStatus(failed ? "Warning" : "Success")
pineafan63fc5e22022-08-04 22:04:10 +010097 ], components: []});
pineafan5d1908e2022-02-28 21:34:47 +000098 } else {
pineafan4edb7762022-06-26 19:21:04 +010099 await interaction.editReply({embeds: [new EmojiEmbed()
pineafan5d1908e2022-02-28 21:34:47 +0000100 .setEmoji("PUNISH.MUTE.GREEN")
pineafan63fc5e22022-08-04 22:04:10 +0100101 .setTitle("Unmute")
pineafan5d1908e2022-02-28 21:34:47 +0000102 .setDescription("No changes were made")
103 .setStatus("Success")
pineafan63fc5e22022-08-04 22:04:10 +0100104 ], components: []});
pineafan5d1908e2022-02-28 21:34:47 +0000105 }
pineafan63fc5e22022-08-04 22:04:10 +0100106};
pineafan4f164f32022-02-26 22:07:12 +0000107
pineafanbd02b4a2022-08-05 22:01:38 +0100108const check = (interaction: CommandInteraction) => {
pineafan63fc5e22022-08-04 22:04:10 +0100109 const member = (interaction.member as GuildMember);
110 const me = (interaction.guild.me as GuildMember);
111 const apply = (interaction.options.getMember("user") as GuildMember);
112 if (member === null || me === null || apply === null) throw "That member is not in the server";
113 const memberPos = member.roles ? member.roles.highest.position : 0;
114 const mePos = me.roles ? me.roles.highest.position : 0;
115 const applyPos = apply.roles ? apply.roles.highest.position : 0;
pineafanc1c18792022-08-03 21:41:36 +0100116 // Do not allow unmuting the owner
pineafan63fc5e22022-08-04 22:04:10 +0100117 if (member.id === interaction.guild.ownerId) throw "You cannot unmute the owner of the server";
pineafan5d1908e2022-02-28 21:34:47 +0000118 // Check if Nucleus can unmute the member
pineafan63fc5e22022-08-04 22:04:10 +0100119 if (! (mePos > applyPos)) throw "I do not have a role higher than that member";
pineafan5d1908e2022-02-28 21:34:47 +0000120 // Check if Nucleus has permission to unmute
pineafane23c4ec2022-07-27 21:56:27 +0100121 if (! me.permissions.has("MODERATE_MEMBERS")) throw "I do not have the *Moderate Members* permission";
pineafan5d1908e2022-02-28 21:34:47 +0000122 // Allow the owner to unmute anyone
pineafan63fc5e22022-08-04 22:04:10 +0100123 if (member.id === interaction.guild.ownerId) return true;
pineafan5d1908e2022-02-28 21:34:47 +0000124 // Check if the user has moderate_members permission
pineafane23c4ec2022-07-27 21:56:27 +0100125 if (! member.permissions.has("MODERATE_MEMBERS")) throw "You do not have the *Moderate Members* permission";
pineafan5d1908e2022-02-28 21:34:47 +0000126 // Check if the user is below on the role list
pineafan63fc5e22022-08-04 22:04:10 +0100127 if (! (memberPos > applyPos)) throw "You do not have a role higher than that member";
pineafan5d1908e2022-02-28 21:34:47 +0000128 // Allow unmute
pineafan63fc5e22022-08-04 22:04:10 +0100129 return true;
130};
pineafan4f164f32022-02-26 22:07:12 +0000131
pineafan8b4b17f2022-02-27 20:42:52 +0000132export { command, callback, check };