Tickets! and a lot of bug fixes
diff --git a/src/commands/mod/about.ts b/src/commands/mod/about.ts
index c69f4a9..130cdbc 100644
--- a/src/commands/mod/about.ts
+++ b/src/commands/mod/about.ts
@@ -1,4 +1,4 @@
-import { LoadingEmbed } from '../../utils/defaultEmbeds.js';
+import { LoadingEmbed } from '../../utils/defaults.js';
import type { HistorySchema } from "../../utils/database.js";
import Discord, {
CommandInteraction,
@@ -251,7 +251,10 @@
}
let i: MessageComponentInteraction;
try {
- i = await m.awaitMessageComponent({ time: 300000 });
+ i = await m.awaitMessageComponent({
+ time: 300000,
+ filter: (i) => { return i.user.id === interaction.user.id && i.channel!.id === interaction.channel!.id }
+ });
} catch (e) {
interaction.editReply({
embeds: [
@@ -354,7 +357,10 @@
})) as Message;
let i: MessageComponentInteraction;
try {
- i = await m.awaitMessageComponent({ time: 300000 });
+ i = await m.awaitMessageComponent({
+ time: 300000,
+ filter: (i) => { return i.user.id === interaction.user.id && i.channel!.id === interaction.channel!.id }
+ });
} catch (e) {
timedOut = true;
continue;
@@ -426,7 +432,7 @@
const check = (interaction: CommandInteraction) => {
const member = interaction.member as GuildMember;
if (!member.permissions.has("ModerateMembers"))
- throw new Error("You do not have the *Moderate Members* permission");
+ return "You do not have the *Moderate Members* permission";
return true;
};
diff --git a/src/commands/mod/ban.ts b/src/commands/mod/ban.ts
index 330edfd..18b6c7e 100644
--- a/src/commands/mod/ban.ts
+++ b/src/commands/mod/ban.ts
@@ -5,7 +5,7 @@
import keyValueList from "../../utils/generateKeyValueList.js";
import addPlurals from "../../utils/plurals.js";
import client from "../../utils/client.js";
-import { LinkWarningFooter } from "../../utils/defaultEmbeds.js";
+import { LinkWarningFooter } from "../../utils/defaults.js";
const command = (builder: SlashCommandSubcommandBuilder) =>
@@ -84,7 +84,7 @@
.setEmoji("PUNISH.BAN.RED")
.setTitle("Banned")
.setDescription(
- `You have been banned in ${interaction.guild.name}` +
+ `You have been banned from ${interaction.guild.name}` +
(reason ? ` for:\n${reason}` : ".\n*No reason was provided.*")
)
.setStatus("Danger")
@@ -131,7 +131,7 @@
banned: entry(new Date().getTime().toString(), renderDelta(new Date().getTime())),
bannedBy: entry(interaction.user.id, renderUser(interaction.user)),
reason: entry(reason, reason ? `\n> ${reason}` : "*No reason provided.*"),
- accountCreated: entry(member.user.createdAt.toString(), renderDelta(member.user.createdAt.getTime())),
+ accountCreated: entry(member.user.createdTimestamp, renderDelta(member.user.createdTimestamp)),
serverMemberCount: interaction.guild.memberCount
},
hidden: {
diff --git a/src/commands/mod/kick.ts b/src/commands/mod/kick.ts
index a4b9774..bdbb9ee 100644
--- a/src/commands/mod/kick.ts
+++ b/src/commands/mod/kick.ts
@@ -1,4 +1,4 @@
-import { LinkWarningFooter } from './../../utils/defaultEmbeds.js';
+import { LinkWarningFooter } from '../../utils/defaults.js';
import { CommandInteraction, GuildMember, ActionRowBuilder, ButtonBuilder, ButtonStyle } from "discord.js";
// @ts-expect-error
import humanizeDuration from "humanize-duration";
@@ -177,19 +177,19 @@
const mePos = me.roles.cache.size > 1 ? me.roles.highest.position : 0;
const applyPos = apply.roles.cache.size > 1 ? apply.roles.highest.position : 0;
// Do not allow kicking the owner
- if (member.id === interaction.guild.ownerId) throw new Error("You cannot kick the owner of the server");
+ if (member.id === interaction.guild.ownerId) return "You cannot kick the owner of the server";
// Check if Nucleus can kick the member
- if (!(mePos > applyPos)) throw new Error("I do not have a role higher than that member");
+ if (!(mePos > applyPos)) return "I do not have a role higher than that member";
// Check if Nucleus has permission to kick
- if (!me.permissions.has("KickMembers")) throw new Error("I do not have the *Kick Members* permission");
+ if (!me.permissions.has("KickMembers")) return "I do not have the *Kick Members* permission";
// Do not allow kicking Nucleus
- if (member.id === interaction.guild.members.me!.id) throw new Error("I cannot kick myself");
+ if (member.id === interaction.guild.members.me!.id) return "I cannot kick myself";
// Allow the owner to kick anyone
if (member.id === interaction.guild.ownerId) return true;
// Check if the user has kick_members permission
- if (!member.permissions.has("KickMembers")) throw new Error("You do not have the *Kick Members* permission");
+ if (!member.permissions.has("KickMembers")) return "You do not have the *Kick Members* permission";
// Check if the user is below on the role list
- if (!(memberPos > applyPos)) throw new Error("You do not have a role higher than that member");
+ if (!(memberPos > applyPos)) return "You do not have a role higher than that member";
// Allow kick
return true;
};
diff --git a/src/commands/mod/mute.ts b/src/commands/mod/mute.ts
index b558e87..3270d37 100644
--- a/src/commands/mod/mute.ts
+++ b/src/commands/mod/mute.ts
@@ -1,4 +1,4 @@
-import { LinkWarningFooter, LoadingEmbed } from "./../../utils/defaultEmbeds.js";
+import { LinkWarningFooter, LoadingEmbed } from "../../utils/defaults.js";
import Discord, { CommandInteraction, GuildMember, ActionRowBuilder, ButtonBuilder, ButtonStyle } from "discord.js";
import type { SlashCommandSubcommandBuilder } from "@discordjs/builders";
import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
@@ -370,20 +370,20 @@
const mePos = me.roles.cache.size > 1 ? me.roles.highest.position : 0;
const applyPos = apply.roles.cache.size > 1 ? apply.roles.highest.position : 0;
// Do not allow muting the owner
- if (member.id === interaction.guild.ownerId) throw new Error("You cannot mute the owner of the server");
+ if (member.id === interaction.guild.ownerId) return "You cannot mute the owner of the server";
// Check if Nucleus can mute the member
- if (!(mePos > applyPos)) throw new Error("I do not have a role higher than that member");
+ if (!(mePos > applyPos)) return "I do not have a role higher than that member";
// Check if Nucleus has permission to mute
- if (!me.permissions.has("ModerateMembers")) throw new Error("I do not have the *Moderate Members* permission");
+ if (!me.permissions.has("ModerateMembers")) return "I do not have the *Moderate Members* permission";
// Do not allow muting Nucleus
- if (member.id === me.id) throw new Error("I cannot mute myself");
+ if (member.id === me.id) return "I cannot mute myself";
// Allow the owner to mute anyone
if (member.id === interaction.guild.ownerId) return true;
// Check if the user has moderate_members permission
if (!member.permissions.has("ModerateMembers"))
- throw new Error("You do not have the *Moderate Members* permission");
+ return "You do not have the *Moderate Members* permission";
// Check if the user is below on the role list
- if (!(memberPos > applyPos)) throw new Error("You do not have a role higher than that member");
+ if (!(memberPos > applyPos)) return "You do not have a role higher than that member";
// Allow mute
return true;
};
diff --git a/src/commands/mod/nick.ts b/src/commands/mod/nick.ts
index c5e45b6..1fbde64 100644
--- a/src/commands/mod/nick.ts
+++ b/src/commands/mod/nick.ts
@@ -176,20 +176,20 @@
const applyPos = apply.roles.cache.size ? apply.roles.highest.position : 0;
if (!interaction.guild) return false;
// Do not allow any changing of the owner
- if (member.id === interaction.guild.ownerId) throw new Error("You cannot change the owner's nickname");
+ if (member.id === interaction.guild.ownerId) return "You cannot change the owner's nickname";
// Check if Nucleus can change the nickname
- if (!(mePos > applyPos)) throw new Error("I do not have a role higher than that member");
+ if (!(mePos > applyPos)) return "I do not have a role higher than that member";
// Check if Nucleus has permission to change the nickname
- if (!me.permissions.has("ManageNicknames")) throw new Error("I do not have the *Manage Nicknames* permission");
+ if (!me.permissions.has("ManageNicknames")) return "I do not have the *Manage Nicknames* permission";
// Allow the owner to change anyone's nickname
if (member.id === interaction.guild.ownerId) return true;
// Check if the user has manage_nicknames permission
if (!member.permissions.has("ManageNicknames"))
- throw new Error("You do not have the *Manage Nicknames* permission");
+ return "You do not have the *Manage Nicknames* permission";
// Allow changing your own nickname
if (member === apply) return true;
// Check if the user is below on the role list
- if (!(memberPos > applyPos)) throw new Error("You do not have a role higher than that member");
+ if (!(memberPos > applyPos)) return "You do not have a role higher than that member";
// Allow change
return true;
};
diff --git a/src/commands/mod/purge.ts b/src/commands/mod/purge.ts
index 5425714..e6b4670 100644
--- a/src/commands/mod/purge.ts
+++ b/src/commands/mod/purge.ts
@@ -1,3 +1,4 @@
+import { JSONTranscriptFromMessageArray, JSONTranscriptToHumanReadable } from '../../utils/logTranscripts.js';
import Discord, { CommandInteraction, GuildChannel, GuildMember, TextChannel, ButtonStyle, ButtonBuilder } from "discord.js";
import type { SlashCommandSubcommandBuilder } from "@discordjs/builders";
import confirmationMessage from "../../utils/confirmationMessage.js";
@@ -93,7 +94,7 @@
let component;
try {
component = m.awaitMessageComponent({
- filter: (m) => m.user.id === interaction.user.id,
+ filter: (m) => m.user.id === interaction.user.id && m.channel!.id === interaction.channel!.id,
time: 300000
});
} catch (e) {
@@ -146,7 +147,7 @@
displayName: "Channel Purged",
calculateType: "messageDelete",
color: NucleusColors.red,
- emoji: "PUNISH.BAN.RED",
+ emoji: "CHANNEL.PURGE.RED",
timestamp: new Date().getTime()
},
list: {
@@ -160,19 +161,9 @@
}
};
log(data);
- let out = "";
- deleted.reverse().forEach((message) => {
- out += `${message.author.username}#${message.author.discriminator} (${message.author.id}) [${new Date(
- message.createdTimestamp
- ).toISOString()}]\n`;
- const lines = message.content.split("\n");
- lines.forEach((line) => {
- out += `> ${line}\n`;
- });
- out += "\n\n";
- });
+ const transcript = JSONTranscriptToHumanReadable(JSONTranscriptFromMessageArray(deleted)!);
const attachmentObject = {
- attachment: Buffer.from(out),
+ attachment: Buffer.from(transcript),
name: `purge-${channel.id}-${Date.now()}.txt`,
description: "Purge log"
};
@@ -197,7 +188,7 @@
let component;
try {
component = await m.awaitMessageComponent({
- filter: (m) => m.user.id === interaction.user.id,
+ filter: (m) => m.user.id === interaction.user.id && m.channel!.id === interaction.channel!.id,
time: 300000
});
} catch {
@@ -304,7 +295,7 @@
displayName: "Channel Purged",
calculateType: "messageDelete",
color: NucleusColors.red,
- emoji: "PUNISH.BAN.RED",
+ emoji: "CHANNEL.PURGE.RED",
timestamp: new Date().getTime()
},
list: {
@@ -367,7 +358,7 @@
let component;
try {
component = await m.awaitMessageComponent({
- filter: (m) => m.user.id === interaction.user.id,
+ filter: (m) => m.user.id === interaction.user.id && m.channel!.id === interaction.channel!.id,
time: 300000
});
} catch {
@@ -405,11 +396,11 @@
const member = interaction.member as GuildMember;
const me = interaction.guild.members.me!;
// Check if nucleus has the manage_messages permission
- if (!me.permissions.has("ManageMessages")) throw new Error("I do not have the *Manage Messages* permission");
+ if (!me.permissions.has("ManageMessages")) return "I do not have the *Manage Messages* permission";
// Allow the owner to purge
if (member.id === interaction.guild.ownerId) return true;
// Check if the user has manage_messages permission
- if (!member.permissions.has("ManageMessages")) throw new Error("You do not have the *Manage Messages* permission");
+ if (!member.permissions.has("ManageMessages")) return "You do not have the *Manage Messages* permission";
// Allow purge
return true;
};
diff --git a/src/commands/mod/slowmode.ts b/src/commands/mod/slowmode.ts
index 9bd994d..9792827 100644
--- a/src/commands/mod/slowmode.ts
+++ b/src/commands/mod/slowmode.ts
@@ -79,9 +79,9 @@
const check = (interaction: CommandInteraction) => {
const member = interaction.member as GuildMember;
// Check if Nucleus can set the slowmode
- if (!interaction.guild!.members.me!.permissions.has("ManageChannels")) throw new Error("I do not have the *Manage Channels* permission");
+ if (!interaction.guild!.members.me!.permissions.has("ManageChannels")) return "I do not have the *Manage Channels* permission";
// Check if the user has manage_channel permission
- if (!member.permissions.has("ManageChannels")) throw new Error("You do not have the *Manage Channels* permission");
+ if (!member.permissions.has("ManageChannels")) return "You do not have the *Manage Channels* permission";
// Allow slowmode
return true;
};
diff --git a/src/commands/mod/softban.ts b/src/commands/mod/softban.ts
index 12bfc3e..35f275f 100644
--- a/src/commands/mod/softban.ts
+++ b/src/commands/mod/softban.ts
@@ -1,173 +1,201 @@
-import { CommandInteraction, GuildMember, ActionRowBuilder, ButtonBuilder, ButtonStyle } from "discord.js";
+import Discord, { CommandInteraction, GuildMember, ActionRowBuilder, ButtonBuilder, User, ButtonStyle } from "discord.js";
import type { SlashCommandSubcommandBuilder } from "@discordjs/builders";
import confirmationMessage from "../../utils/confirmationMessage.js";
import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
import keyValueList from "../../utils/generateKeyValueList.js";
+import addPlurals from "../../utils/plurals.js";
import client from "../../utils/client.js";
-import addPlural from "../../utils/plurals.js";
+import { LinkWarningFooter } from "../../utils/defaults.js";
+
const command = (builder: SlashCommandSubcommandBuilder) =>
builder
.setName("softban")
.setDescription("Kicks a user and deletes their messages")
.addUserOption((option) => option.setName("user").setDescription("The user to softban").setRequired(true))
- .addIntegerOption((option) =>
+ .addNumberOption((option) =>
option
.setName("delete")
- .setDescription("The days of messages to delete | Default: 0")
+ .setDescription("Delete this number of days of messages from the user | Default: 0")
.setMinValue(0)
.setMaxValue(7)
.setRequired(false)
);
-const callback = async (interaction: CommandInteraction): Promise<unknown> => {
+
+const callback = async (interaction: CommandInteraction): Promise<void> => {
+ if (!interaction.guild) return;
const { renderUser } = client.logger;
// TODO:[Modals] Replace this with a modal
let reason = null;
let notify = true;
let confirmation;
+ let chosen = false;
let timedOut = false;
- let success = false;
- while (!timedOut && !success) {
- const confirmation = await new confirmationMessage(interaction)
+ do {
+ confirmation = await new confirmationMessage(interaction)
.setEmoji("PUNISH.BAN.RED")
.setTitle("Softban")
.setDescription(
keyValueList({
- user: renderUser(interaction.options.getUser("user")),
- reason: reason ? "\n> " + (reason ?? "").replaceAll("\n", "\n> ") : "*No reason provided*"
+ user: renderUser(interaction.options.getUser("user")!),
+ reason: reason ? "\n> " + (reason).replaceAll("\n", "\n> ") : "*No reason provided*"
}) +
`The user **will${notify ? "" : " not"}** be notified\n` +
- `${addPlural(
- interaction.options.getInteger("delete") ? interaction.options.getInteger("delete") : 0,
- "day"
- )} of messages will be deleted\n\n` +
+ `${addPlurals(
+ (interaction.options.get("delete")?.value as number | null) ?? 0, "day")
+ } of messages will be deleted\n\n` +
`Are you sure you want to softban <@!${(interaction.options.getMember("user") as GuildMember).id}>?`
)
- .setColor("Danger")
.addCustomBoolean(
"notify",
"Notify user",
false,
- null,
- null,
+ undefined,
+ "The user will be sent a DM",
null,
"ICONS.NOTIFY." + (notify ? "ON" : "OFF"),
notify
)
+ .setColor("Danger")
.addReasonButton(reason ?? "")
+ .setFailedMessage("No changes were made", "Success", "PUNISH.BAN.GREEN")
.send(reason !== null);
reason = reason ?? "";
if (confirmation.cancelled) timedOut = true;
- else if (confirmation.success) success = true;
+ else if (confirmation.success !== undefined) chosen = true;
else if (confirmation.newReason) reason = confirmation.newReason;
- else if (confirmation.components) {
- notify = confirmation.components.notify.active;
- }
- }
- if (timedOut) return;
- if (confirmation.success) {
- let dmd = false;
- const config = await client.database.guilds.read(interaction.guild.id);
- try {
- if (notify) {
- await (interaction.options.getMember("user") as GuildMember).send({
- embeds: [
- new EmojiEmbed()
- .setEmoji("PUNISH.BAN.RED")
- .setTitle("Softbanned")
- .setDescription(
- `You have been softbanned from ${interaction.guild.name}` +
- (reason ? ` for:\n> ${reason}` : ".")
- )
- .setStatus("Danger")
- ],
- components: [
- new ActionRowBuilder().addComponents(
- config.moderation.ban.text
- ? [
- new ButtonBuilder()
- .setStyle(ButtonStyle.Link)
- .setLabel(config.moderation.ban.text)
- .setURL(config.moderation.ban.link)
- ]
- : []
- )
- ]
- });
- dmd = true;
- }
- } catch {
- dmd = false;
- }
- const member = interaction.options.getMember("user") as GuildMember;
- try {
- await member.ban({
- days: Number(interaction.options.getInteger("delete") ?? 0),
- reason: reason
- });
- await interaction.guild.members.unban(member, "Softban");
- } catch {
- await interaction.editReply({
+ else if (confirmation.components) notify = confirmation.components["notify"]!.active;
+ } while (!timedOut && !chosen)
+ if (timedOut || !confirmation.success) return;
+ reason = reason.length ? reason : null
+ let dmSent = false;
+ let dmMessage;
+ const config = await client.database.guilds.read(interaction.guild.id);
+ try {
+ if (notify) {
+ if (reason) { reason = reason.split("\n").map((line) => "> " + line).join("\n") }
+ const messageData: {
+ embeds: EmojiEmbed[];
+ components: ActionRowBuilder<ButtonBuilder>[];
+ } = {
embeds: [
new EmojiEmbed()
.setEmoji("PUNISH.BAN.RED")
.setTitle("Softban")
- .setDescription("Something went wrong and the user was not softbanned")
+ .setDescription(
+ `You have been softbanned from ${interaction.guild.name}` +
+ (reason ? ` for:\n${reason}` : ".\n*No reason was provided.*")
+ )
.setStatus("Danger")
],
components: []
- });
+ };
+ if (config.moderation.softban.text && config.moderation.softban.link) {
+ messageData.embeds[0]!.setFooter(LinkWarningFooter)
+ messageData.components.push(new ActionRowBuilder<Discord.ButtonBuilder>()
+ .addComponents(new ButtonBuilder()
+ .setStyle(ButtonStyle.Link)
+ .setLabel(config.moderation.softban.text)
+ .setURL(config.moderation.softban.link)
+ )
+ )
+ }
+ dmMessage = await (interaction.options.getMember("user") as GuildMember).send(messageData);
+ dmSent = true;
}
- await client.database.history.create("softban", interaction.guild.id, member.user, reason);
- const failed = !dmd && notify;
- await interaction.editReply({
- embeds: [
- new EmojiEmbed()
- .setEmoji(`PUNISH.BAN.${failed ? "YELLOW" : "GREEN"}`)
- .setTitle("Softban")
- .setDescription("The member was softbanned" + (failed ? ", but could not be notified" : ""))
- .setStatus(failed ? "Warning" : "Success")
- ],
- components: []
- });
- } else {
- await interaction.editReply({
- embeds: [
- new EmojiEmbed()
- .setEmoji("PUNISH.BAN.GREEN")
- .setTitle("Softban")
- .setDescription("No changes were made")
- .setStatus("Success")
- ],
- components: []
- });
+ } catch {
+ dmSent = false;
}
+ try {
+ const member = interaction.options.getMember("user") as GuildMember;
+ const days: number = interaction.options.get("delete")?.value as number | null ?? 0;
+ member.ban({
+ deleteMessageSeconds: days * 24 * 60 * 60,
+ reason: reason ?? "*No reason provided*"
+ });
+ await interaction.guild.members.unban(member, "Softban");
+ await client.database.history.create("ban", interaction.guild.id, member.user, interaction.user, reason);
+ const { log, NucleusColors, entry, renderUser, renderDelta } = client.logger;
+ const data = {
+ meta: {
+ type: "memberSoftban",
+ displayName: "Member Softbanned",
+ calculateType: "guildMemberPunish",
+ color: NucleusColors.yellow,
+ emoji: "PUNISH.BAN.YELLOW",
+ timestamp: new Date().getTime()
+ },
+ list: {
+ memberId: entry(member.user.id, `\`${member.user.id}\``),
+ name: entry(member.user.id, renderUser(member.user)),
+ softbanned: entry(new Date().getTime().toString(), renderDelta(new Date().getTime())),
+ softbannedBy: entry(interaction.user.id, renderUser(interaction.user)),
+ reason: entry(reason, reason ? `\n> ${reason}` : "*No reason provided.*"),
+ accountCreated: entry(member.user.createdTimestamp, renderDelta(member.user.createdTimestamp)),
+ serverMemberCount: interaction.guild.memberCount
+ },
+ hidden: {
+ guild: interaction.guild.id
+ }
+ };
+ log(data);
+ } catch {
+ await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji("PUNISH.BAN.RED")
+ .setTitle("Softban")
+ .setDescription("Something went wrong and the user was not softbanned")
+ .setStatus("Danger")
+ ],
+ components: []
+ });
+ if (dmSent && dmMessage) await dmMessage.delete();
+ return;
+ }
+ const failed = !dmSent && notify;
+ await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji(`PUNISH.BAN.${failed ? "YELLOW" : "GREEN"}`)
+ .setTitle("Softban")
+ .setDescription("The member was softbanned" + (failed ? ", but could not be notified" : ""))
+ .setStatus(failed ? "Warning" : "Success")
+ ],
+ components: []
+ });
};
-const check = (interaction: CommandInteraction) => {
+const check = async (interaction: CommandInteraction) => {
+ if (!interaction.guild) return;
const member = interaction.member as GuildMember;
- const me = interaction.guild.me!;
- const apply = interaction.options.getMember("user") as GuildMember;
- if (member === null || me === null || apply === null) throw new Error("That member is not in the server");
+ const me = interaction.guild.members.me!;
+ let apply = interaction.options.getUser("user") as User | GuildMember;
const memberPos = member.roles.cache.size > 1 ? member.roles.highest.position : 0;
const mePos = me.roles.cache.size > 1 ? me.roles.highest.position : 0;
- const applyPos = apply.roles.cache.size > 1 ? apply.roles.highest.position : 0;
- // Do not allow softbanning the owner
+ let applyPos = 0
+ try {
+ apply = await interaction.guild.members.fetch(apply.id) as GuildMember
+ applyPos = apply.roles.cache.size > 1 ? apply.roles.highest.position : 0;
+ } catch {
+ apply = apply as User
+ }
+ // Do not allow banning the owner
if (member.id === interaction.guild.ownerId) throw new Error("You cannot softban the owner of the server");
// Check if Nucleus can ban the member
if (!(mePos > applyPos)) throw new Error("I do not have a role higher than that member");
// Check if Nucleus has permission to ban
- if (!me.permissions.has("BAN_MEMBERS")) throw new Error("I do not have the *Ban Members* permission");
- // Do not allow softbanning Nucleus
+ if (!me.permissions.has("BanMembers")) throw new Error("I do not have the *Ban Members* permission");
+ // Do not allow banning Nucleus
if (member.id === me.id) throw new Error("I cannot softban myself");
- // Allow the owner to softban anyone
+ // Allow the owner to ban anyone
if (member.id === interaction.guild.ownerId) return true;
// Check if the user has ban_members permission
- if (!member.permissions.has("BAN_MEMBERS")) throw new Error("You do not have the *Ban Members* permission");
+ if (!member.permissions.has("BanMembers")) throw new Error("You do not have the *Ban Members* permission");
// Check if the user is below on the role list
if (!(memberPos > applyPos)) throw new Error("You do not have a role higher than that member");
- // Allow softban
+ // Allow ban
return true;
};
diff --git a/src/commands/mod/unban.ts b/src/commands/mod/unban.ts
index d34f303..37fee99 100644
--- a/src/commands/mod/unban.ts
+++ b/src/commands/mod/unban.ts
@@ -1,5 +1,5 @@
-import { CommandInteraction, GuildMember, User } from "discord.js";
-import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
+import type { CommandInteraction, GuildMember, User } from "discord.js";
+import type { SlashCommandSubcommandBuilder } from "@discordjs/builders";
import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
import keyValueList from "../../utils/generateKeyValueList.js";
import confirmationMessage from "../../utils/confirmationMessage.js";
@@ -16,7 +16,7 @@
const callback = async (interaction: CommandInteraction): Promise<unknown> => {
if (!interaction.guild) return;
const bans = await interaction.guild.bans.fetch();
- const user = interaction.options.getString("user");
+ const user = interaction.options.get("user")?.value as string;
let resolved = bans.find((ban) => ban.user.id === user);
if (!resolved) resolved = bans.find((ban) => ban.user.username.toLowerCase() === user.toLowerCase());
if (!resolved) resolved = bans.find((ban) => ban.user.tag.toLowerCase() === user.toLowerCase());
@@ -48,7 +48,7 @@
try {
await interaction.guild.members.unban(resolved.user as User, "Unban");
const member = resolved.user as User;
- await client.database.history.create("unban", interaction.guild.id, member, interaction.user);
+ await client.database.history.create("unban", interaction.guild.id, member, interaction.user, "No reason provided");
const { log, NucleusColors, entry, renderUser, renderDelta } = client.logger;
const data = {
meta: {
@@ -64,7 +64,7 @@
name: entry(member.id, renderUser(member)),
unbanned: entry(new Date().getTime(), renderDelta(new Date().getTime())),
unbannedBy: entry(interaction.user.id, renderUser(interaction.user)),
- accountCreated: entry(member.createdAt, renderDelta(member.createdAt))
+ accountCreated: entry(member.createdTimestamp, renderDelta(member.createdTimestamp))
},
hidden: {
guild: interaction.guild.id
@@ -110,13 +110,13 @@
const check = (interaction: CommandInteraction) => {
if (!interaction.guild) return;
const member = interaction.member as GuildMember;
- const me = interaction.guild.me!;
+ const me = interaction.guild.members.me!;
// Check if Nucleus can unban members
- if (!me.permissions.has("BAN_MEMBERS")) throw new Error("I do not have the *Ban Members* permission");
+ if (!me.permissions.has("BanMembers")) return "I do not have the *Ban Members* permission";
// Allow the owner to unban anyone
if (member.id === interaction.guild.ownerId) return true;
// Check if the user has ban_members permission
- if (!member.permissions.has("BAN_MEMBERS")) throw new Error("You do not have the *Ban Members* permission");
+ if (!member.permissions.has("BanMembers")) return "You do not have the *Ban Members* permission";
// Allow unban
return true;
};
diff --git a/src/commands/mod/unmute.ts b/src/commands/mod/unmute.ts
index c93f8cc..e2585e1 100644
--- a/src/commands/mod/unmute.ts
+++ b/src/commands/mod/unmute.ts
@@ -43,6 +43,7 @@
notify
)
.addReasonButton(reason ?? "")
+ .setFailedMessage("No changes were made", "Success", "PUNISH.MUTE.GREEN")
.send(reason !== null);
if (confirmation.cancelled) timedOut = true;
else if (confirmation.success !== undefined) success = true;
@@ -51,96 +52,83 @@
notify = confirmation.components!["notify"]!.active;
}
} while (!timedOut && !success);
- if (confirmation.cancelled) return;
- if (confirmation.success) {
- let dmSent = false;
- let dmMessage;
- try {
- if (notify) {
- dmMessage = await (interaction.options.getMember("user") as GuildMember).send({
- embeds: [
- new EmojiEmbed()
- .setEmoji("PUNISH.MUTE.GREEN")
- .setTitle("Unmuted")
- .setDescription(
- `You have been unmuted in ${interaction.guild.name}` +
- (reason ? ` for:\n> ${reason}` : " with no reason provided.")
- )
- .setStatus("Success")
- ]
- });
- dmSent = true;
- }
- } catch {
- dmSent = false;
- }
- const member = interaction.options.getMember("user") as GuildMember;
- try {
- member.timeout(0, reason ?? "*No reason provided*");
- } catch {
- await interaction.editReply({
+ if (confirmation.cancelled || !confirmation.success) return;
+ let dmSent = false;
+ let dmMessage;
+ try {
+ if (notify) {
+ dmMessage = await (interaction.options.getMember("user") as GuildMember).send({
embeds: [
new EmojiEmbed()
- .setEmoji("PUNISH.MUTE.RED")
- .setTitle("Unmute")
- .setDescription("Something went wrong and the user was not unmuted")
- .setStatus("Danger")
- ],
- components: []
+ .setEmoji("PUNISH.MUTE.GREEN")
+ .setTitle("Unmuted")
+ .setDescription(
+ `You have been unmuted in ${interaction.guild.name}` +
+ (reason ? ` for:\n> ${reason}` : " with no reason provided.")
+ )
+ .setStatus("Success")
+ ]
});
- if (dmSent && dmMessage) await dmMessage.delete();
- return;
+ dmSent = true;
}
- await client.database.history.create(
- "unmute",
- interaction.guild.id,
- (interaction.options.getMember("user") as GuildMember).user,
- interaction.user,
- reason
- );
- const data = {
- meta: {
- type: "memberUnmute",
- displayName: "Unmuted",
- calculateType: "guildMemberPunish",
- color: NucleusColors.green,
- emoji: "PUNISH.MUTE.GREEN",
- timestamp: new Date().getTime()
- },
- list: {
- memberId: entry(member.user.id, `\`${member.user.id}\``),
- name: entry(member.user.id, renderUser(member.user)),
- unmuted: entry(new Date().getTime().toString(), renderDelta(new Date().getTime())),
- unmutedBy: entry(interaction.user.id, renderUser(interaction.user))
- },
- hidden: {
- guild: interaction.guild.id
- }
- };
- log(data);
- const failed = !dmSent && notify;
- await interaction.editReply({
- embeds: [
- new EmojiEmbed()
- .setEmoji(`PUNISH.MUTE.${failed ? "YELLOW" : "GREEN"}`)
- .setTitle("Unmute")
- .setDescription("The member was unmuted" + (failed ? ", but could not be notified" : ""))
- .setStatus(failed ? "Warning" : "Success")
- ],
- components: []
- });
- } else {
- await interaction.editReply({
- embeds: [
- new EmojiEmbed()
- .setEmoji("PUNISH.MUTE.GREEN")
- .setTitle("Unmute")
- .setDescription("No changes were made")
- .setStatus("Success")
- ],
- components: []
- });
+ } catch {
+ dmSent = false;
}
+ const member = interaction.options.getMember("user") as GuildMember;
+ try {
+ member.timeout(0, reason ?? "*No reason provided*");
+ } catch {
+ await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji("PUNISH.MUTE.RED")
+ .setTitle("Unmute")
+ .setDescription("Something went wrong and the user was not unmuted")
+ .setStatus("Danger")
+ ],
+ components: []
+ });
+ if (dmSent && dmMessage) await dmMessage.delete();
+ return;
+ }
+ await client.database.history.create(
+ "unmute",
+ interaction.guild.id,
+ (interaction.options.getMember("user") as GuildMember).user,
+ interaction.user,
+ reason
+ );
+ const data = {
+ meta: {
+ type: "memberUnmute",
+ displayName: "Unmuted",
+ calculateType: "guildMemberPunish",
+ color: NucleusColors.green,
+ emoji: "PUNISH.MUTE.GREEN",
+ timestamp: new Date().getTime()
+ },
+ list: {
+ memberId: entry(member.user.id, `\`${member.user.id}\``),
+ name: entry(member.user.id, renderUser(member.user)),
+ unmuted: entry(new Date().getTime().toString(), renderDelta(new Date().getTime())),
+ unmutedBy: entry(interaction.user.id, renderUser(interaction.user))
+ },
+ hidden: {
+ guild: interaction.guild.id
+ }
+ };
+ log(data);
+ const failed = !dmSent && notify;
+ await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji(`PUNISH.MUTE.${failed ? "YELLOW" : "GREEN"}`)
+ .setTitle("Unmute")
+ .setDescription("The member was unmuted" + (failed ? ", but could not be notified" : ""))
+ .setStatus(failed ? "Warning" : "Success")
+ ],
+ components: []
+ });
};
const check = (interaction: CommandInteraction) => {
@@ -152,18 +140,18 @@
const mePos = me.roles.cache.size > 1 ? me.roles.highest.position : 0;
const applyPos = apply.roles.cache.size > 1 ? apply.roles.highest.position : 0;
// Do not allow unmuting the owner
- if (member.id === interaction.guild.ownerId) throw new Error("You cannot unmute the owner of the server");
+ if (member.id === interaction.guild.ownerId) return "You cannot unmute the owner of the server";
// Check if Nucleus can unmute the member
- if (!(mePos > applyPos)) throw new Error("I do not have a role higher than that member");
+ if (!(mePos > applyPos)) return "I do not have a role higher than that member";
// Check if Nucleus has permission to unmute
- if (!me.permissions.has("ModerateMembers")) throw new Error("I do not have the *Moderate Members* permission");
+ if (!me.permissions.has("ModerateMembers")) return "I do not have the *Moderate Members* permission";
// Allow the owner to unmute anyone
if (member.id === interaction.guild.ownerId) return true;
// Check if the user has moderate_members permission
if (!member.permissions.has("ModerateMembers"))
- throw new Error("You do not have the *Moderate Members* permission");
+ return "You do not have the *Moderate Members* permission";
// Check if the user is below on the role list
- if (!(memberPos > applyPos)) throw new Error("You do not have a role higher than that member");
+ if (!(memberPos > applyPos)) return "You do not have a role higher than that member";
// Allow unmute
return true;
};
diff --git a/src/commands/mod/viewas.ts b/src/commands/mod/viewas.ts
index 8b2864a..6216a37 100644
--- a/src/commands/mod/viewas.ts
+++ b/src/commands/mod/viewas.ts
@@ -1,10 +1,13 @@
+import { LoadingEmbed } from './../../utils/defaults.js';
import Discord, {
CommandInteraction,
GuildMember,
ActionRowBuilder,
ButtonBuilder,
ButtonStyle,
- NonThreadGuildBasedChannel
+ NonThreadGuildBasedChannel,
+ StringSelectMenuOptionBuilder,
+ StringSelectMenuBuilder
} from "discord.js";
import type { SlashCommandSubcommandBuilder } from "@discordjs/builders";
import type { GuildBasedChannel } from "discord.js";
@@ -26,183 +29,155 @@
"null": channel[]
}
*/
+ const m = await interaction.reply({embeds: LoadingEmbed, ephemeral: true, fetchReply: true})
- const channels: Record<string, GuildBasedChannel[]> = {"": [] as GuildBasedChannel[]};
+ let channels: Record<string, GuildBasedChannel[]> = {"": []};
- interaction.guild!.channels.fetch().then(channelCollection => {
- channelCollection.forEach(channel => {
- if (!channel) return; // if no channel
- if (channel.type === Discord.ChannelType.GuildCategory) {
- if(!channels[channel!.id]) channels[channel!.id] = [channel];
- } else if (channel.parent) {
- if (!channels[channel.parent.id]) channels[channel.parent.id] = [channel];
- else (channels[channel.parent.id as string])!.push(channel);
- } else {
- channels[""]!.push(channel);
- }
- });
+ const channelCollection = await interaction.guild!.channels.fetch();
+
+ channelCollection.forEach(channel => {
+ if (!channel) return; // if no channel
+ if (channel.type === Discord.ChannelType.GuildCategory) {
+ if(!channels[channel!.id]) channels[channel!.id] = [];
+ } else if (channel.parent) {
+ if (!channels[channel.parent.id]) channels[channel.parent.id] = [channel];
+ else (channels[channel.parent.id as string])!.push(channel);
+ } else {
+ channels[""]!.push(channel);
+ }
});
const member = interaction.options.getMember("member") as Discord.GuildMember;
const autoSortBelow = [Discord.ChannelType.GuildVoice, Discord.ChannelType.GuildStageVoice];
- // for each category, sort its channels. This should be based on the order of the channels, with voice and stage channels sorted below text
- channels = Object.values(channels).map((c) => {
- return c.sort((a: GuildBasedChannel, b: GuildBasedChannel) => {
- if (a.type === Discord.ChannelType.PrivateThread || b.type === Discord.ChannelType.PrivateThread)
- if (autoSortBelow.includes(a.type) && autoSortBelow.includes(b.type)) return a.position ?? 0 - b.position ;
+
+ for (const category in channels) {
+ channels[category] = channels[category]!.sort((a: GuildBasedChannel, b: GuildBasedChannel) => {
+ const disallowedTypes = [Discord.ChannelType.PublicThread, Discord.ChannelType.PrivateThread, Discord.ChannelType.AnnouncementThread];
+ if (disallowedTypes.includes(a.type) || disallowedTypes.includes(b.type)) return 0;
+ a = a as NonThreadGuildBasedChannel;
+ b = b as NonThreadGuildBasedChannel;
+ if (autoSortBelow.includes(a.type) && autoSortBelow.includes(b.type)) return a.position - b.position;
if (autoSortBelow.includes(a.type)) return 1;
if (autoSortBelow.includes(b.type)) return -1;
- return a - b;
+ return a.position - b.position;
});
}
-
+ for (const category in channels) {
+ channels[category] = channels[category]!.filter((c) => {
+ return c.permissionsFor(member).has("ViewChannel");
+ });
+ }
+ for (const category in channels) {
+ channels[category] = channels[category]!.filter((c) => {
+ return !(c.type === Discord.ChannelType.PublicThread || c.type === Discord.ChannelType.PrivateThread || c.type === Discord.ChannelType.AnnouncementThread)
+ });
+ }
+ channels = Object.fromEntries(Object.entries(channels).filter(([_, v]) => v.length > 0));
+ let page = 0;
+ let closed = false;
+ const categoryIDs = Object.keys(channels);
+ const categoryNames = Object.values(channels).map((c) => {
+ return c[0]!.parent?.name ?? "Uncategorised";
+ });
+ // Split the category names into the first and last 25, ignoring the last 25 if there are 25 or less
+ const first25 = categoryNames.slice(0, 25);
+ const last25 = categoryNames.slice(25);
+ const categoryNames25: string[][] = [first25];
+ if (last25.length > 0) categoryNames25.push(last25);
- //OLD CODE START
- // const unprocessedChannels: GuildBasedChannel[] = [];
- // let m;
- // interaction.guild!.channels.cache.forEach((channel) => {
- // if (!channel.parent && channel.type !== Discord.ChannelType.GuildCategory) unprocessedChannels.push(channel);
- // });
- // let channels: GuildBasedChannel[][] = [unprocessedChannels];
- // channels = channels.concat(
- // interaction.guild!.channels.cache
- // .filter((c) => c.type === Discord.ChannelType.GuildCategory)
- // .map((c) => (c as CategoryChannel).children.map((c) => c))
- // );
- // const autoSortBelow = ["GUILD_VOICE", "GUILD_STAGE_VOICE"];
- // channels = channels.map((c) =>
- // c.sort((a, b) => {
- // if (autoSortBelow.includes(a.type) && autoSortBelow.includes(b.type)) return a.position - b.position;
- // if (autoSortBelow.includes(a.type)) return 1;
- // if (autoSortBelow.includes(b.type)) return -1;
- // return a.position - b.position;
- // })
- // );
- // // Sort all arrays by the position of the first channels parent position
- // channels = channels.sort((a, b) => {
- // if (!a[0].parent) return -1;
- // if (!b[0].parent) return 1;
- // return a[0].parent.position - b[0].parent.position;
- // });
- // const member = interaction.options.getMember("member") as Discord.GuildMember;
- // m = await interaction.reply({
- // embeds: [
- // new EmojiEmbed()
- // .setEmoji("MEMBER.JOIN")
- // .setTitle("Viewing as " + member.displayName)
- // .setStatus("Success")
- // ],
- // ephemeral: true,
- // fetchReply: true
- // });
- // let page = 0;
- // let timedOut = false;
- // while (!timedOut) {
- // m = await interaction.editReply({
- // embeds: [
- // new EmojiEmbed()
- // .setEmoji("MEMBER.JOIN")
- // .setTitle("Viewing as " + member.displayName)
- // .setStatus("Success")
- // .setDescription(
- // `**${channels[page][0].parent ? channels[page][0].parent.name : "Uncategorised"}**` +
- // "\n" +
- // channels[page]
- // .map((c) => {
- // let channelType = c.type;
- // if (interaction.guild.rulesChannelId === c.id) channelType = "RULES";
- // else if ("nsfw" in c && c.nsfw) channelType += "_NSFW";
- // return c.permissionsFor(member).has("VIEW_CHANNEL")
- // ? `${getEmojiByName("ICONS.CHANNEL." + channelType)} ${c.name}\n` +
- // (() => {
- // if ("threads" in c && c.threads.cache.size > 0) {
- // return (
- // c.threads.cache
- // .map(
- // (t) =>
- // ` ${
- // getEmojiByName("ICONS.CHANNEL.THREAD_PIPE") +
- // " " +
- // getEmojiByName("ICONS.CHANNEL.THREAD_CHANNEL")
- // } ${t.name}`
- // )
- // .join("\n") + "\n"
- // );
- // }
- // return "";
- // })()
- // : "";
- // })
- // .join("") +
- // "\n" +
- // pageIndicator(channels.length, page)
- // )
- // ],
- // components: [
- // new ActionRowBuilder().addComponents([
- // new SelectMenuBuilder()
- // .setOptions(
- // channels.map((c, index) => ({
- // label: c[0].parent ? c[0].parent.name : "Uncategorised",
- // value: index.toString(),
- // default: page === index
- // }))
- // )
- // .setCustomId("select")
- // .setMaxValues(1)
- // .setMinValues(1)
- // .setPlaceholder("Select a category")
- // ]),
- // new ActionRowBuilder().addComponents([
- // new ButtonBuilder()
- // .setLabel(
- // page === 0
- // ? ""
- // : channels[page - 1][0].parent
- // ? channels[page - 1][0].parent.name
- // : "Uncategorised"
- // )
- // .setDisabled(page === 0)
- // .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
- // .setStyle(ButtonStyle.Primary)
- // .setCustomId("previous"),
- // new ButtonBuilder()
- // .setLabel(
- // page === channels.length - 1
- // ? ""
- // : channels[page + 1][0].parent
- // ? channels[page + 1][0].parent.name
- // : "Uncategorised"
- // )
- // .setDisabled(page === channels.length - 1)
- // .setEmoji(getEmojiByName("CONTROL.RIGHT", "id"))
- // .setStyle(ButtonStyle.Primary)
- // .setCustomId("next")
- // ])
- // ]
- // });
- // let i;
- // try {
- // i = await m.awaitMessageComponent({ time: 300000 });
- // } catch (e) {
- // timedOut = true;
- // continue;
- // }
- // i.deferUpdate();
- // if (i.customId === "next") {
- // page++;
- // } else if (i.customId === "previous") {
- // page--;
- // } else if (i.customId === "select") {
- // page = parseInt(i.values[0]);
- // }
- // }
-
+ const channelTypeEmoji: Record<number, string> = {
+ 0: "GUILD_TEXT", // Text channel
+ 2: "GUILD_VOICE", // Voice channel
+ 5: "GUILD_NEWS", // Announcement channel
+ 13: "GUILD_STAGE_VOICE", // Stage channel
+ 15: "FORUM", // Forum channel
+ 99: "RULES" // Rules channel
+ };
+ const NSFWAvailable: number[] = [0, 2, 5, 13];
+ const rulesChannel = interaction.guild!.rulesChannel?.id;
+
+ async function nameFromChannel(channel: GuildBasedChannel): Promise<string> {
+ let channelType = channel.type;
+ if (channelType === Discord.ChannelType.GuildCategory) return "";
+ if (channel.id === rulesChannel) channelType = 99
+ let threads: Discord.ThreadChannel[] = [];
+ if ("threads" in channel) {
+ threads = channel.threads.cache.toJSON().map((t) => t as Discord.ThreadChannel);
+ }
+ const nsfw = ("nsfw" in channel ? channel.nsfw : false) && NSFWAvailable.includes(channelType)
+ const emojiName = channelTypeEmoji[channelType] + (nsfw ? "_NSFW" : "");
+ const emoji = getEmojiByName("ICONS.CHANNEL." + (threads.length ? "THREAD_CHANNEL" : emojiName));
+ let current = `${emoji} ${channel.name}`;
+ if (threads.length) {
+ for (const thread of threads) {
+ current += `\n${getEmojiByName("ICONS.CHANNEL.THREAD_PIPE")} ${thread.name}`;
+ }
+ }
+ return current;
+ }
+
+ while (!closed) {
+ const category = categoryIDs[page]!;
+ let description = "";
+ for (const channel of channels[category]!) {
+ description += `${await nameFromChannel(channel)}\n`;
+ }
+
+ const parsedCategorySelectMenu: ActionRowBuilder<StringSelectMenuBuilder | ButtonBuilder>[] = categoryNames25.map(
+ (categories, set) => { return new ActionRowBuilder<StringSelectMenuBuilder>().addComponents(new StringSelectMenuBuilder()
+ .setCustomId("category")
+ .setMinValues(1)
+ .setMaxValues(1)
+ .setOptions(categories.map((c, i) => {
+ return new StringSelectMenuOptionBuilder()
+ .setLabel(c)
+ .setValue((set * 25 + i).toString())
+ // @ts-expect-error
+ .setEmoji(getEmojiByName("ICONS.CHANNEL.CATEGORY", "id")) // Again, this is valid but TS doesn't think so
+ .setDefault((set * 25 + i) === page)
+ }))
+ )}
+ );
+
+ const components: ActionRowBuilder<ButtonBuilder | StringSelectMenuBuilder>[] = parsedCategorySelectMenu
+ components.push(new ActionRowBuilder<ButtonBuilder>().addComponents(
+ new ButtonBuilder()
+ .setCustomId("back")
+ .setStyle(ButtonStyle.Secondary)
+ .setDisabled(page === 0)
+ .setEmoji(getEmojiByName("CONTROL.LEFT", "id")),
+ new ButtonBuilder()
+ .setCustomId("right")
+ .setStyle(ButtonStyle.Secondary)
+ .setDisabled(page === categoryIDs.length - 1)
+ .setEmoji(getEmojiByName("CONTROL.RIGHT", "id"))
+ ));
+
+ await interaction.editReply({
+ embeds: [new EmojiEmbed()
+ .setEmoji("MEMBER.JOIN")
+ .setTitle("Viewing as " + member.displayName)
+ .setStatus("Success")
+ .setDescription(description + "\n" + pageIndicator(categoryIDs.length, page))
+ ], components: components
+ });
+ let i;
+ try {
+ i = await m.awaitMessageComponent({filter: (i) => i.user.id === interaction.user.id, time: 30000});
+ } catch (e) {
+ closed = true;
+ continue;
+ }
+ i.deferUpdate();
+ if (i.customId === "back") page--;
+ else if (i.customId === "right") page++;
+ else if (i.customId === "category" && i.isStringSelectMenu()) page = parseInt(i.values[0]!);
+ }
};
const check = (interaction: CommandInteraction) => {
const member = interaction.member as GuildMember;
- if (!member.permissions.has("MANAGE_ROLES")) throw new Error("You do not have the *Manage Roles* permission");
+ if (!member.permissions.has("ManageRoles")) return "You do not have the *Manage Roles* permission";
return true;
};
diff --git a/src/commands/mod/warn.ts b/src/commands/mod/warn.ts
index c4aa7c3..93241e1 100644
--- a/src/commands/mod/warn.ts
+++ b/src/commands/mod/warn.ts
@@ -5,7 +5,7 @@
import keyValueList from "../../utils/generateKeyValueList.js";
import { create, areTicketsEnabled } from "../../actions/createModActionTicket.js";
import client from "../../utils/client.js";
-import { LinkWarningFooter } from "../../utils/defaultEmbeds.js";
+import { LinkWarningFooter } from "../../utils/defaults.js";
const command = (builder: SlashCommandSubcommandBuilder) =>
builder
@@ -186,7 +186,7 @@
let component;
try {
component = await m.awaitMessageComponent({
- filter: (m) => m.user.id === interaction.user.id,
+ filter: (m) => m.user.id === interaction.user.id && m.channel!.id === interaction.channel!.id,
time: 300000
});
} catch (e) {
@@ -279,18 +279,18 @@
if (!interaction.guild) return;
const member = interaction.member as GuildMember;
const apply = interaction.options.getMember("user") as GuildMember | null;
- if (apply === null) throw new Error("That member is not in the server");
+ if (apply === null) return "That member is not in the server";
const memberPos = member.roles.cache.size ? member.roles.highest.position : 0;
const applyPos = apply.roles.cache.size ? apply.roles.highest.position : 0;
// Do not allow warning bots
- if (member.user.bot) throw new Error("I cannot warn bots");
+ if (member.user.bot) return "I cannot warn bots";
// Allow the owner to warn anyone
if (member.id === interaction.guild.ownerId) return true;
// Check if the user has moderate_members permission
if (!member.permissions.has("ModerateMembers"))
- throw new Error("You do not have the *Moderate Members* permission");
+ return "You do not have the *Moderate Members* permission";
// Check if the user is below on the role list
- if (!(memberPos > applyPos)) throw new Error("You do not have a role higher than that member");
+ if (!(memberPos > applyPos)) return "You do not have a role higher than that member";
// Allow warn
return true;
};