Tickets! and a lot of bug fixes
diff --git a/src/commands/help.ts b/src/commands/help.ts
index c9bba7d..767ca46 100644
--- a/src/commands/help.ts
+++ b/src/commands/help.ts
@@ -8,13 +8,13 @@
const callback = async (interaction: CommandInteraction): Promise<void> => {
interaction.reply({components: [new ActionRowBuilder<ButtonBuilder>().addComponents(
new ButtonBuilder()
- .setLabel("Verify")
+ .setLabel("Create ticket")
.setStyle(ButtonStyle.Primary)
- .setCustomId("verifybutton")
+ .setCustomId("createticket")
)]}); // TODO: FINISH THIS FOR RELEASE
};
-const check = (_interaction: CommandInteraction) => {
+const check = () => {
return true;
};
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;
};
diff --git a/src/commands/nucleus/ping.ts b/src/commands/nucleus/ping.ts
index 3cbd049..12f1c6b 100644
--- a/src/commands/nucleus/ping.ts
+++ b/src/commands/nucleus/ping.ts
@@ -1,4 +1,4 @@
-import { LoadingEmbed } from "./../../utils/defaultEmbeds.js";
+import { LoadingEmbed } from "../../utils/defaults.js";
import type { CommandInteraction } from "discord.js";
import type { SlashCommandSubcommandBuilder } from "@discordjs/builders";
import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
diff --git a/src/commands/nucleus/premium.ts b/src/commands/nucleus/premium.ts
index 9bbc36e..745f167 100644
--- a/src/commands/nucleus/premium.ts
+++ b/src/commands/nucleus/premium.ts
@@ -1,5 +1,5 @@
-import { CommandInteraction } from "discord.js";
-import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
+import type { CommandInteraction } from "discord.js";
+import type { SlashCommandSubcommandBuilder } from "@discordjs/builders";
import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
const command = (builder: SlashCommandSubcommandBuilder) =>
diff --git a/src/commands/nucleus/suggest.ts b/src/commands/nucleus/suggest.ts
index e31696b..de0e69b 100644
--- a/src/commands/nucleus/suggest.ts
+++ b/src/commands/nucleus/suggest.ts
@@ -1,4 +1,4 @@
-import { LoadingEmbed } from './../../utils/defaultEmbeds.js';
+import { LoadingEmbed } from '../../utils/defaults.js';
import { ButtonStyle, CommandInteraction } from "discord.js";
import Discord from "discord.js";
import type { SlashCommandSubcommandBuilder } from "@discordjs/builders";
@@ -29,56 +29,44 @@
)
.setColor("Danger")
.setInverted(true)
+ .setFailedMessage("Your suggestion was deleted", "Success", "ICONS.ADD")
.send(true);
- if (confirmation.cancelled) return;
- if (confirmation.success) {
- await (client.channels.cache.get("955161206459600976") as Discord.TextChannel).send({
- embeds: [
- new EmojiEmbed()
- .setTitle("Suggestion")
- .setDescription(
- `**From:** ${renderUser(interaction.member!.user as Discord.User)}\n**Suggestion:**\n> ${suggestion}\n\n` +
- `**Server:** ${interaction.guild!.name} (${interaction.guild!.id})\n`,
- )
- .setStatus("Warning")
- ], components: [new Discord.ActionRowBuilder<Discord.ButtonBuilder>().addComponents(
- new Discord.ButtonBuilder()
- .setCustomId("suggestionAccept")
- .setLabel("Accept")
- .setStyle(ButtonStyle.Secondary)
- .setEmoji(getEmojiByName("ICONS.ADD", "id")),
- new Discord.ButtonBuilder()
- .setCustomId("suggestionDeny")
- .setLabel("Delete")
- .setStyle(ButtonStyle.Secondary)
- .setEmoji(getEmojiByName("ICONS.REMOVE", "id"))
- )]
- });
- await interaction.editReply({
- embeds: [
- new EmojiEmbed()
- .setEmoji("ICONS.ADD")
- .setTitle("Suggest")
- .setDescription("Your suggestion was sent successfully")
- .setStatus("Success")
- ],
- components: []
- });
- } else {
- await interaction.editReply({
- embeds: [
- new EmojiEmbed()
- .setEmoji("ICONS.OPP.ADD")
- .setTitle("Suggest")
- .setDescription("No changes were made")
- .setStatus("Danger")
- ],
- components: []
- });
- }
+ if (confirmation.cancelled || !confirmation.success) return;
+ await (client.channels.cache.get("955161206459600976") as Discord.TextChannel).send({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Suggestion")
+ .setDescription(
+ `**From:** ${renderUser(interaction.member!.user as Discord.User)}\n**Suggestion:**\n> ${suggestion}\n\n` +
+ `**Server:** ${interaction.guild!.name} (${interaction.guild!.id})\n`,
+ )
+ .setStatus("Warning")
+ ], components: [new Discord.ActionRowBuilder<Discord.ButtonBuilder>().addComponents(
+ new Discord.ButtonBuilder()
+ .setCustomId("suggestionAccept")
+ .setLabel("Accept")
+ .setStyle(ButtonStyle.Secondary)
+ .setEmoji(getEmojiByName("ICONS.ADD", "id")),
+ new Discord.ButtonBuilder()
+ .setCustomId("suggestionDeny")
+ .setLabel("Delete")
+ .setStyle(ButtonStyle.Secondary)
+ .setEmoji(getEmojiByName("ICONS.REMOVE", "id"))
+ )]
+ });
+ await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji("ICONS.ADD")
+ .setTitle("Suggest")
+ .setDescription("Your suggestion was sent successfully")
+ .setStatus("Success")
+ ],
+ components: []
+ });
};
-const check = (_interaction: CommandInteraction) => {
+const check = () => {
return true;
};
diff --git a/src/commands/privacy.ts b/src/commands/privacy.ts
index a427688..9100302 100644
--- a/src/commands/privacy.ts
+++ b/src/commands/privacy.ts
@@ -1,43 +1,17 @@
-import { LoadingEmbed } from "./../utils/defaultEmbeds.js";
-import Discord, { CommandInteraction, ActionRowBuilder, ButtonBuilder, ButtonStyle } from "discord.js";
+import { LoadingEmbed } from "../utils/defaults.js";
+import Discord, { CommandInteraction, ActionRowBuilder, ButtonBuilder, ButtonStyle, StringSelectMenuOptionBuilder, SelectMenuOptionBuilder, StringSelectMenuBuilder } from "discord.js";
import { SlashCommandBuilder } from "@discordjs/builders";
import EmojiEmbed from "../utils/generateEmojiEmbed.js";
import getEmojiByName from "../utils/getEmojiByName.js";
import createPageIndicator from "../utils/createPageIndicator.js";
import client from "../utils/client.js";
import confirmationMessage from "../utils/confirmationMessage.js";
+import { Embed } from "../utils/defaults.js";
const command = new SlashCommandBuilder()
.setName("privacy")
.setDescription("Information and options for you and your server's settings");
-class Embed {
- embed: Discord.EmbedBuilder;
- title: string;
- description = "";
- pageId = 0;
- components?: ActionRowBuilder[] = [];
- setEmbed(embed: Discord.EmbedBuilder) {
- this.embed = embed;
- return this;
- }
- setTitle(title: string) {
- this.title = title;
- return this;
- }
- setDescription(description: string) {
- this.description = description;
- return this;
- }
- setPageId(pageId: number) {
- this.pageId = pageId;
- return this;
- }
- setComponents(components: ActionRowBuilder[]) {
- this.components = components;
- return this;
- }
-}
const callback = async (interaction: CommandInteraction): Promise<void> => {
const pages = [
@@ -78,7 +52,7 @@
.setDescription(
"**Facebook** - Facebook trackers include data such as your date of birth, and guess your age if not entered, your preferences, who you interact with and more.\n" +
"**AMP** - AMP is a technology that allows websites to be served by Google. This means Google can store and track data, and are pushing this to as many pages as possible.\n\n" +
- "Transcripts allow you to store all messages sent in a channel. This could be an issue in some cases, as they are hosted on [Pastebin](https://pastebin.com), so a leaked link could show all messages sent in the channel.\n"
+ "Transcripts allow you to store all messages sent in a channel. This could be an issue in some cases, as they are hosted on [Pastebin](https://pastebin.com), so a leaked link could show all messages sent in the channel.\n" // TODO: Not on pastebin
)
.setEmoji("NUCLEUS.LOGO")
.setStatus("Danger")
@@ -87,7 +61,7 @@
.setDescription("Regarding Facebook and AMP filter types, and ticket transcripts")
.setPageId(2)
].concat(
- (interaction.member as Discord.GuildMember).permissions.has("ADMINISTRATOR")
+ (interaction.member as Discord.GuildMember).permissions.has("Administrator")
? [
new Embed()
.setEmbed(
@@ -101,7 +75,7 @@
.setDescription("Options")
.setPageId(3)
.setComponents([
- new ActionRowBuilder().addComponents([
+ new ActionRowBuilder<ButtonBuilder>().addComponents([
new ButtonBuilder()
.setLabel("Clear all data")
.setCustomId("clear-all-data")
@@ -116,20 +90,20 @@
fetchReply: true,
ephemeral: true
});
- let page = 0;
+ let page = parseInt(client.preloadPage[interaction.channel!.id] ? client.preloadPage[interaction.channel!.id]?.argument! : "0");
let selectPaneOpen = false;
let nextFooter = null;
let timedOut = false;
while (!timedOut) {
- let selectPane = [];
+ let selectPane: Discord.ActionRowBuilder<ButtonBuilder | StringSelectMenuBuilder>[] = [];
if (selectPaneOpen) {
- const options = [];
+ const options: SelectMenuOptionBuilder[] = [];
pages.forEach((embed) => {
options.push(
- new SelectMenuOption({
+ new StringSelectMenuOptionBuilder({
label: embed.title,
value: embed.pageId.toString(),
description: embed.description || ""
@@ -137,8 +111,8 @@
);
});
selectPane = [
- new ActionRowBuilder().addComponents([
- new Discord.SelectMenuBuilder()
+ new ActionRowBuilder<StringSelectMenuBuilder>().addComponents([
+ new Discord.StringSelectMenuBuilder()
.addOptions(options)
.setCustomId("page")
.setMaxValues(1)
@@ -146,8 +120,8 @@
])
];
}
- const components = selectPane.concat([
- new ActionRowBuilder().addComponents([
+ const components: ActionRowBuilder<ButtonBuilder | StringSelectMenuBuilder>[] = selectPane.concat([
+ new ActionRowBuilder<ButtonBuilder>().addComponents(
new ButtonBuilder()
.setCustomId("left")
.setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
@@ -163,36 +137,39 @@
.setEmoji(getEmojiByName("CONTROL.RIGHT", "id"))
.setStyle(ButtonStyle.Secondary)
.setDisabled(page === pages.length - 1)
- ])
+ )
]);
- const em = new Discord.EmbedBuilder(pages[page].embed);
- em.setDescription(em.description + "\n\n" + createPageIndicator(pages.length, page));
- em.setFooter({ text: nextFooter ?? "" });
+ const em = new Discord.EmbedBuilder(pages[page]!.embed);
+ em.setDescription(em.data.description + "\n\n" + createPageIndicator(pages.length, page));
+ if (nextFooter) em.setFooter({ text: nextFooter });
await interaction.editReply({
embeds: [em],
- components: components.concat(pages[page].components)
+ components: components.concat(pages[page]?.componentsToSet ?? [])
});
let i;
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;
}
nextFooter = null;
i.deferUpdate();
- if (i.component.customId === "left") {
+ if (i.customId === "left") {
if (page > 0) page--;
selectPaneOpen = false;
- } else if (i.component.customId === "right") {
+ } else if (i.customId === "right") {
if (page < pages.length - 1) page++;
selectPaneOpen = false;
- } else if (i.component.customId === "select") {
+ } else if (i.customId === "select") {
selectPaneOpen = !selectPaneOpen;
- } else if (i.component.customId === "page") {
- page = parseInt(i.values[0]);
+ } else if (i.customId === "page" && i.isStringSelectMenu()) {
+ page = parseInt(i.values[0]!);
selectPaneOpen = false;
- } else if (i.component.customId === "clear-all-data") {
+ } else if (i.customId === "clear-all-data") {
const confirmation = await new confirmationMessage(interaction)
.setEmoji("CONTROL.BLOCKCROSS")
.setTitle("Clear All Data")
@@ -206,8 +183,8 @@
break;
}
if (confirmation.success) {
- client.database.guilds.delete(interaction.guild.id);
- client.database.history.delete(interaction.guild.id);
+ client.database.guilds.delete(interaction.guild!.id);
+ client.database.history.delete(interaction.guild!.id);
nextFooter = "All data cleared";
continue;
} else {
@@ -215,15 +192,15 @@
continue;
}
} else {
- const em = new Discord.EmbedBuilder(pages[page].embed);
- em.setDescription(em.description + "\n\n" + createPageIndicator(pages.length, page));
+ const em = new Discord.EmbedBuilder(pages[page]!.embed);
+ em.setDescription(em.data.description + "\n\n" + createPageIndicator(pages.length, page));
em.setFooter({ text: "Message closed" });
interaction.editReply({ embeds: [em], components: [] });
return;
}
}
- const em = new Discord.EmbedBuilder(pages[page].embed);
- em.setDescription(em.description + "\n\n" + createPageIndicator(pages.length, page));
+ const em = new Discord.EmbedBuilder(pages[page]!.embed);
+ em.setDescription(em.data.description + "\n\n" + createPageIndicator(pages.length, page));
em.setFooter({ text: "Message timed out" });
await interaction.editReply({
embeds: [em],
@@ -231,7 +208,7 @@
});
};
-const check = (_interaction: CommandInteraction) => {
+const check = () => {
return true;
};
diff --git a/src/commands/role/user.ts b/src/commands/role/user.ts
index ac94b47..ad29811 100644
--- a/src/commands/role/user.ts
+++ b/src/commands/role/user.ts
@@ -1,5 +1,5 @@
-import { CommandInteraction, GuildMember, Role } from "discord.js";
-import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
+import type { CommandInteraction, GuildMember, Role, User } from "discord.js";
+import type { SlashCommandSubcommandBuilder } from "@discordjs/builders";
import client from "../../utils/client.js";
import confirmationMessage from "../../utils/confirmationMessage.js";
import keyValueList from "../../utils/generateKeyValueList.js";
@@ -28,79 +28,68 @@
const callback = async (interaction: CommandInteraction): Promise<unknown> => {
const { renderUser, renderRole } = client.logger;
- const action = interaction.options.getString("action");
+ const action = interaction.options.get("action")?.value as string;
+ const role: Role = (await interaction.guild!.roles.fetch(interaction.options.get("role")?.value as string))!;
// TODO:[Modals] Replace this with a modal
const confirmation = await new confirmationMessage(interaction)
.setEmoji("GUILD.ROLES.DELETE")
.setTitle("Role")
.setDescription(
keyValueList({
- user: renderUser(interaction.options.getUser("user")),
- role: renderRole(interaction.options.get("role"))
+ user: renderUser(interaction.options.getUser("user")! as User),
+ role: renderRole(role)
}) +
`\nAre you sure you want to ${
action === "give" ? "give the role to" : "remove the role from"
} ${interaction.options.getUser("user")}?`
)
.setColor("Danger")
+ .setFailedMessage("No changes were made", "Success", "GUILD.ROLES.CREATE")
.send();
- if (confirmation.cancelled) return;
- if (confirmation.success) {
- try {
- const member = interaction.options.getMember("user") as GuildMember;
- const role = interaction.options.get("role") as unknown as Role;
- if (interaction.options.getString("action") === "give") {
- member.roles.add(role);
- } else {
- member.roles.remove(role);
- }
- } catch (e) {
- return await interaction.editReply({
- embeds: [
- new EmojiEmbed()
- .setTitle("Role")
- .setDescription("Something went wrong and the role could not be added")
- .setStatus("Danger")
- .setEmoji("CONTROL.BLOCKCROSS")
- ],
- components: []
- });
+ if (confirmation.cancelled || !confirmation.success) return;
+ try {
+ const member = interaction.options.getMember("user") as GuildMember;
+ if ((interaction.options.get("action")?.value as string) === "give") {
+ member.roles.add(role);
+ } else {
+ member.roles.remove(role);
}
+ } catch (e) {
return await interaction.editReply({
embeds: [
new EmojiEmbed()
.setTitle("Role")
- .setDescription(`The role has been ${action === "give" ? "given" : "removed"} successfully`)
- .setStatus("Success")
- .setEmoji("GUILD.ROLES.CREATE")
- ],
- components: []
- });
- } else {
- await interaction.editReply({
- embeds: [
- new EmojiEmbed()
- .setEmoji("GUILD.ROLES.CREATE")
- .setTitle("Role")
- .setDescription("No changes were made.")
+ .setDescription("Something went wrong and the role could not be added")
.setStatus("Danger")
+ .setEmoji("CONTROL.BLOCKCROSS")
],
components: []
});
}
+ return await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Role")
+ .setDescription(`The role has been ${action === "give" ? "given" : "removed"} successfully`)
+ .setStatus("Success")
+ .setEmoji("GUILD.ROLES.CREATE")
+ ],
+ components: []
+ });
};
const check = (interaction: CommandInteraction) => {
const member = interaction.member as GuildMember;
- const me = interaction.guild.me!;
+ if (!interaction.guild) return
+ const me = interaction.guild.members.me!;
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";
// Check if Nucleus has permission to role
- if (!me.permissions.has("MANAGE_ROLES")) throw new Error("I do not have the *Manage Roles* permission");
+ if (!me.permissions.has("ManageRoles")) return "I do not have the *Manage Roles* permission";
// Allow the owner to role anyone
if (member.id === interaction.guild.ownerId) return true;
// Check if the user has manage_roles permission
- 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";
// Allow role
return true;
};
diff --git a/src/commands/rolemenu.ts b/src/commands/rolemenu.ts
index 9aad543..c1ceb2e 100644
--- a/src/commands/rolemenu.ts
+++ b/src/commands/rolemenu.ts
@@ -10,7 +10,7 @@
await roleMenu(interaction);
};
-const check = (_interaction: CommandInteraction) => {
+const check = () => {
return true;
};
diff --git a/src/commands/server/about.ts b/src/commands/server/about.ts
index e5bea60..23a53b7 100644
--- a/src/commands/server/about.ts
+++ b/src/commands/server/about.ts
@@ -74,7 +74,7 @@
});
};
-const check = (_interaction: CommandInteraction) => {
+const check = () => {
return true;
};
diff --git a/src/commands/settings/commands.ts b/src/commands/settings/commands.ts
index 4493f79..34a197b 100644
--- a/src/commands/settings/commands.ts
+++ b/src/commands/settings/commands.ts
@@ -1,4 +1,4 @@
-import { LoadingEmbed } from "./../../utils/defaultEmbeds.js";
+import { LoadingEmbed } from "../../utils/defaults.js";
import Discord, { CommandInteraction, ActionRowBuilder, ButtonBuilder, TextInputComponent, Role, ButtonStyle } from "discord.js";
import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
import getEmojiByName from "../../utils/getEmojiByName.js";
@@ -108,7 +108,10 @@
});
let i;
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;
@@ -209,8 +212,8 @@
const check = (interaction: CommandInteraction) => {
const member = interaction.member as Discord.GuildMember;
- if (!member.permissions.has("MANAGE_GUILD"))
- throw new Error("You must have the *Manage Server* permission to use this command");
+ if (!member.permissions.has("ManageGuild"))
+ return "You must have the *Manage Server* permission to use this command";
return true;
};
diff --git a/src/commands/settings/filters.ts b/src/commands/settings/filters.ts
index 1a297ca..f0291b9 100644
--- a/src/commands/settings/filters.ts
+++ b/src/commands/settings/filters.ts
@@ -10,8 +10,8 @@
const check = (interaction: CommandInteraction) => {
const member = interaction.member as Discord.GuildMember;
- if (!member.permissions.has("MANAGE_MESSAGES"))
- throw new Error("You must have the *Manage Messages* permission to use this command");
+ if (!member.permissions.has("ManageMessages"))
+ return "You must have the *Manage Messages* permission to use this command";
return true;
};
diff --git a/src/commands/settings/logs/attachment.ts b/src/commands/settings/logs/attachment.ts
index 7d4fef3..326246a 100644
--- a/src/commands/settings/logs/attachment.ts
+++ b/src/commands/settings/logs/attachment.ts
@@ -1,4 +1,4 @@
-import { LoadingEmbed } from "./../../../utils/defaultEmbeds.js";
+import { LoadingEmbed } from "../../../utils/defaults.js";
import { ChannelType } from "discord-api-types/v9";
import Discord, { CommandInteraction, ActionRowBuilder, ButtonBuilder, ButtonStyle } from "discord.js";
import EmojiEmbed from "../../../utils/generateEmojiEmbed.js";
@@ -147,7 +147,10 @@
});
let i;
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;
@@ -190,8 +193,8 @@
const check = (interaction: CommandInteraction) => {
const member = interaction.member as Discord.GuildMember;
- if (!member.permissions.has("MANAGE_GUILD"))
- throw new Error("You must have the *Manage Server* permission to use this command");
+ if (!member.permissions.has("ManageGuild"))
+ return "You must have the *Manage Server* permission to use this command";
return true;
};
diff --git a/src/commands/settings/logs/channel.ts b/src/commands/settings/logs/channel.ts
index 0288bf7..9129841 100644
--- a/src/commands/settings/logs/channel.ts
+++ b/src/commands/settings/logs/channel.ts
@@ -1,4 +1,4 @@
-import { LoadingEmbed } from "./../../../utils/defaultEmbeds.js";
+import { LoadingEmbed } from "../../../utils/defaults.js";
import { ChannelType } from "discord-api-types/v9";
import Discord, { CommandInteraction, ActionRowBuilder, ButtonBuilder, ButtonStyle } from "discord.js";
import EmojiEmbed from "../../../utils/generateEmojiEmbed.js";
@@ -140,7 +140,10 @@
});
let i;
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;
}
@@ -182,8 +185,8 @@
const check = (interaction: CommandInteraction) => {
const member = interaction.member as Discord.GuildMember;
- if (!member.permissions.has("MANAGE_GUILD"))
- throw new Error("You must have the *Manage Server* permission to use this command");
+ if (!member.permissions.has("ManageGuild"))
+ return "You must have the *Manage Server* permission to use this command";
return true;
};
diff --git a/src/commands/settings/logs/events.ts b/src/commands/settings/logs/events.ts
index 9eaf25c..ae04e89 100644
--- a/src/commands/settings/logs/events.ts
+++ b/src/commands/settings/logs/events.ts
@@ -1,4 +1,4 @@
-import { LoadingEmbed } from "./../../../utils/defaultEmbeds.js";
+import { LoadingEmbed } from "../../../utils/defaults.js";
import Discord, { CommandInteraction, Message, ActionRowBuilder, ButtonBuilder, SelectMenuBuilder, ButtonStyle } from "discord.js";
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
import EmojiEmbed from "../../../utils/generateEmojiEmbed.js";
@@ -75,7 +75,10 @@
})) as Message;
let i;
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;
@@ -105,8 +108,8 @@
const check = (interaction: CommandInteraction) => {
const member = interaction.member as Discord.GuildMember;
- if (!member.permissions.has("MANAGE_GUILD"))
- throw new Error("You must have the *Manage Server* permission to use this command");
+ if (!member.permissions.has("ManageGuild"))
+ return "You must have the *Manage Server* permission to use this command";
return true;
};
diff --git a/src/commands/settings/logs/staff.ts b/src/commands/settings/logs/staff.ts
index c1b2380..5a23839 100644
--- a/src/commands/settings/logs/staff.ts
+++ b/src/commands/settings/logs/staff.ts
@@ -1,4 +1,4 @@
-import { LoadingEmbed } from "./../../../utils/defaultEmbeds.js";
+import { LoadingEmbed } from "../../../utils/defaults.js";
import { ChannelType } from "discord-api-types/v9";
import Discord, { CommandInteraction, ActionRowBuilder, ButtonBuilder, ButtonStyle } from "discord.js";
import EmojiEmbed from "../../../utils/generateEmojiEmbed.js";
@@ -144,7 +144,10 @@
});
let i;
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;
@@ -187,8 +190,8 @@
const check = (interaction: CommandInteraction) => {
const member = interaction.member as Discord.GuildMember;
- if (!member.permissions.has("MANAGE_GUILD"))
- throw new Error("You must have the *Manage Server* permission to use this command");
+ if (!member.permissions.has("ManageGuild"))
+ return "You must have the *Manage Server* permission to use this command";
return true;
};
diff --git a/src/commands/settings/rolemenu.ts b/src/commands/settings/rolemenu.ts
index 02ab93e..e05485b 100644
--- a/src/commands/settings/rolemenu.ts
+++ b/src/commands/settings/rolemenu.ts
@@ -14,8 +14,8 @@
const check = (interaction: CommandInteraction) => {
const member = interaction.member as Discord.GuildMember;
- if (!member.permissions.has("MANAGE_ROLES"))
- throw Error("You must have the *Manage Roles* permission to use this command");
+ if (!member.permissions.has("ManageRoles"))
+ return "You must have the *Manage Roles* permission to use this command";
return true;
};
diff --git a/src/commands/settings/stats.ts b/src/commands/settings/stats.ts
index a768cb8..0e4c50b 100644
--- a/src/commands/settings/stats.ts
+++ b/src/commands/settings/stats.ts
@@ -1,4 +1,4 @@
-import { LoadingEmbed } from "./../../utils/defaultEmbeds.js";
+import { LoadingEmbed } from "../../utils/defaults.js";
import Discord, { CommandInteraction, Message, ActionRowBuilder, SelectMenuBuilder } from "discord.js";
import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
import confirmationMessage from "../../utils/confirmationMessage.js";
@@ -196,7 +196,10 @@
});
let i;
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;
@@ -219,8 +222,8 @@
const check = (interaction: CommandInteraction) => {
const member = interaction.member as Discord.GuildMember;
- if (!member.permissions.has("MANAGE_CHANNELS"))
- throw new Error("You must have the *Manage Channels* permission to use this command");
+ if (!member.permissions.has("manageChannels"))
+ return "You must have the *Manage Channels* permission to use this command";
return true;
};
@@ -237,3 +240,4 @@
export { command };
export { callback };
export { check };
+export { autocomplete };
\ No newline at end of file
diff --git a/src/commands/settings/tickets.ts b/src/commands/settings/tickets.ts
index 70ba52d..ee0f2d1 100644
--- a/src/commands/settings/tickets.ts
+++ b/src/commands/settings/tickets.ts
@@ -1,4 +1,4 @@
-import { LoadingEmbed } from "./../../utils/defaultEmbeds.js";
+import { LoadingEmbed } from "../../utils/defaults.js";
import getEmojiByName from "../../utils/getEmojiByName.js";
import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
import confirmationMessage from "../../utils/confirmationMessage.js";
@@ -276,7 +276,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;
@@ -376,7 +379,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) {
innerTimedOut = true;
continue;
@@ -627,7 +633,10 @@
}
let i;
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;
@@ -734,7 +743,7 @@
const check = (interaction: CommandInteraction) => {
const member = interaction.member as Discord.GuildMember;
if (!member.permissions.has("ManageGuild"))
- throw new Error("You must have the *Manage Server* permission to use this command");
+ return "You must have the *Manage Server* permission to use this command";
return true;
};
diff --git a/src/commands/settings/verify.ts b/src/commands/settings/verify.ts
index cceadae..a8b0ae0 100644
--- a/src/commands/settings/verify.ts
+++ b/src/commands/settings/verify.ts
@@ -1,4 +1,4 @@
-import { LoadingEmbed } from "./../../utils/defaultEmbeds.js";
+import { LoadingEmbed } from "../../utils/defaults.js";
import Discord, {
CommandInteraction,
Interaction,
@@ -157,7 +157,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) {
timedOut = true;
continue;
@@ -243,7 +246,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) {
innerTimedOut = true;
continue;
@@ -381,7 +387,7 @@
const check = (interaction: CommandInteraction) => {
const member = interaction.member as Discord.GuildMember;
if (!member.permissions.has("ManageGuild"))
- throw new Error("You must have the *Manage Server* permission to use this command");
+ return "You must have the *Manage Server* permission to use this command";
return true;
};
diff --git a/src/commands/settings/welcome.ts b/src/commands/settings/welcome.ts
index 7f02cd7..9892638 100644
--- a/src/commands/settings/welcome.ts
+++ b/src/commands/settings/welcome.ts
@@ -1,4 +1,4 @@
-import { LoadingEmbed } from "./../../utils/defaultEmbeds.js";
+import { LoadingEmbed } from "../../utils/defaults.js";
import Discord, {
Channel,
CommandInteraction,
@@ -240,7 +240,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;
@@ -298,7 +301,7 @@
const check = (interaction: CommandInteraction) => {
const member = interaction.member as Discord.GuildMember;
if (!member.permissions.has("ManageGuild"))
- throw new Error("You must have the *Manage Server* permission to use this command");
+ return "You must have the *Manage Server* permission to use this command";
return true;
};
diff --git a/src/commands/tags/create.ts b/src/commands/tags/create.ts
index 5379bf8..788902e 100644
--- a/src/commands/tags/create.ts
+++ b/src/commands/tags/create.ts
@@ -64,7 +64,7 @@
ephemeral: true
});
const confirmation = await new confirmationMessage(interaction)
- .setEmoji("PUNISH.NICKNAME.YELLOW", "PUNISH.NICKNAME.RED")
+ .setEmoji("PUNISH.NICKNAME.YELLOW")
.setTitle("Tag create")
.setDescription(
keyValueList({
@@ -74,18 +74,9 @@
)
.setColor("Warning")
.setInverted(true)
+ .setFailedMessage("No changes were made", "Success", "PUNISH.NICKNAME.GREEN")
.send();
- if (confirmation.cancelled) return;
- if (!confirmation.success)
- return await interaction.editReply({
- embeds: [
- new EmojiEmbed()
- .setTitle("Tag Create")
- .setDescription("No changes were made")
- .setStatus("Success")
- .setEmoji("PUNISH.NICKNAME.GREEN")
- ]
- });
+ if (confirmation.cancelled || !confirmation.success) return;
try {
await client.database.guilds.write(interaction.guild!.id, {
[`tags.${name}`]: value
@@ -118,7 +109,7 @@
const check = (interaction: CommandInteraction) => {
const member = interaction.member as Discord.GuildMember;
if (!member.permissions.has("ManageMessages"))
- throw new Error("You must have the *Manage Messages* permission to use this command");
+ return "You must have the *Manage Messages* permission to use this command";
return true;
};
diff --git a/src/commands/tags/delete.ts b/src/commands/tags/delete.ts
index 6d76eb1..18143d3 100644
--- a/src/commands/tags/delete.ts
+++ b/src/commands/tags/delete.ts
@@ -27,7 +27,7 @@
ephemeral: true
});
const confirmation = await new confirmationMessage(interaction)
- .setEmoji("PUNISH.NICKNAME.YELLOW", "PUNISH.NICKNAME.RED")
+ .setEmoji("PUNISH.NICKNAME.YELLOW")
.setTitle("Tag Delete")
.setDescription(
keyValueList({
@@ -37,18 +37,9 @@
)
.setColor("Warning")
.setInverted(true)
+ .setFailedMessage("No changes were made", "Success", "PUNISH.NICKNAME.GREEN")
.send();
- if (confirmation.cancelled) return;
- if (!confirmation.success)
- return await interaction.editReply({
- embeds: [
- new EmojiEmbed()
- .setTitle("Tag Delete")
- .setDescription("No changes were made")
- .setStatus("Success")
- .setEmoji("PUNISH.NICKNAME.GREEN")
- ]
- });
+ if (confirmation.cancelled || !confirmation.success) return;
try {
await client.database.guilds.write(interaction.guild!.id, null, ["tags." + name]);
await client.memory.forceUpdate(interaction.guild!.id);
@@ -80,7 +71,7 @@
const check = (interaction: CommandInteraction) => {
const member = interaction.member as Discord.GuildMember;
if (!member.permissions.has("ManageMessages"))
- throw new Error("You must have the *Manage Messages* permission to use this command");
+ return "You must have the *Manage Messages* permission to use this command";
return true;
};
diff --git a/src/commands/tags/edit.ts b/src/commands/tags/edit.ts
index 018a0bb..e15f9ac 100644
--- a/src/commands/tags/edit.ts
+++ b/src/commands/tags/edit.ts
@@ -19,9 +19,9 @@
const callback = async (interaction: CommandInteraction): Promise<unknown> => {
if (!interaction.guild) return;
- const name = interaction.options.getString("name");
- const value = interaction.options.getString("value") ?? "";
- const newname = interaction.options.getString("newname") ?? "";
+ const name = interaction.options.get("name")?.value as string;
+ const value = interaction.options.get("value")?.value as string;
+ const newname = interaction.options.get("newname")?.value as string;
if (!newname && !value)
return await interaction.reply({
embeds: [
@@ -79,7 +79,7 @@
ephemeral: true
});
const confirmation = await new confirmationMessage(interaction)
- .setEmoji("PUNISH.NICKNAME.YELLOW", "PUNISH.NICKNAME.RED")
+ .setEmoji("PUNISH.NICKNAME.YELLOW")
.setTitle("Tag Edit")
.setDescription(
keyValueList({
@@ -89,27 +89,18 @@
)
.setColor("Warning")
.setInverted(true)
+ .setFailedMessage("No changes were made", "Success", "PUNISH.NICKNAME.GREEN")
.send();
if (confirmation.cancelled) return;
- if (!confirmation.success)
- return await interaction.editReply({
- embeds: [
- new EmojiEmbed()
- .setTitle("Tag Edit")
- .setDescription("No changes were made")
- .setStatus("Success")
- .setEmoji("PUNISH.NICKNAME.GREEN")
- ]
- });
try {
const toSet: Record<string, string> = {};
const toUnset: string[] = [];
if (value) toSet[`tags.${name}`] = value;
if (newname) {
toUnset.push(`tags.${name}`);
- toSet[`tags.${newname}`] = data.tags[name];
+ toSet[`tags.${newname}`] = data.tags[name]!;
}
- await client.database.guilds.write(interaction.guild.id, toSet === {} ? null : toSet, toUnset);
+ await client.database.guilds.write(interaction.guild.id, Object.keys(toSet).length === 0 ? null : toSet, toUnset);
await client.memory.forceUpdate(interaction.guild!.id);
} catch (e) {
return await interaction.editReply({
@@ -138,7 +129,7 @@
const check = (interaction: CommandInteraction) => {
const member = interaction.member as GuildMember;
if (!member.permissions.has("ManageMessages"))
- throw new Error("You must have the *Manage Messages* permission to use this command");
+ return "You must have the *Manage Messages* permission to use this command";
return true;
};
diff --git a/src/commands/tags/list.ts b/src/commands/tags/list.ts
index aee4c71..f0563c7 100644
--- a/src/commands/tags/list.ts
+++ b/src/commands/tags/list.ts
@@ -1,21 +1,22 @@
-import { LoadingEmbed } from "./../../utils/defaultEmbeds.js";
+import { LoadingEmbed } from "../../utils/defaults.js";
import Discord, {
CommandInteraction,
Message,
ActionRowBuilder,
- Component,
ButtonBuilder,
MessageComponentInteraction,
EmbedBuilder,
- SelectMenuInteraction,
- MessageSelectOptionData,
- ButtonStyle
+ ButtonStyle,
+ ButtonComponent,
+ StringSelectMenuBuilder
} from "discord.js";
import type { SlashCommandSubcommandBuilder } from "@discordjs/builders";
import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
import client from "../../utils/client.js";
import getEmojiByName from "../../utils/getEmojiByName.js";
import createPageIndicator from "../../utils/createPageIndicator.js";
+interface MessageSelectOptionData { label: string; value: string; description?: string; }
+
class Embed {
embed: Discord.EmbedBuilder = new EmbedBuilder();
@@ -45,9 +46,9 @@
const callback = async (interaction: CommandInteraction): Promise<void> => {
const data = await client.database.guilds.read(interaction.guild!.id);
- const tags = data.getKey("tags");
+ const tags = data.tags;
let strings = [];
- if (data === {}) strings = ["*No tags exist*"];
+ if (Object.keys(tags).length === 0) strings = ["*No tags exist*"];
else {
let string = "";
for (const tag in tags) {
@@ -86,8 +87,7 @@
let cancelled = false;
let timedOut = false;
while (!cancelled && !timedOut) {
- let selectPane: ActionRowBuilder[] = [];
-
+ let selectPane: ActionRowBuilder<ButtonBuilder | StringSelectMenuBuilder>[] = [];
if (selectPaneOpen) {
const options: MessageSelectOptionData[] = [];
pages.forEach((embed) => {
@@ -98,8 +98,8 @@
});
});
selectPane = [
- new ActionRowBuilder().addComponents([
- new Discord.SelectMenuBuilder()
+ new ActionRowBuilder<StringSelectMenuBuilder>().addComponents([
+ new Discord.StringSelectMenuBuilder()
.addOptions(options)
.setCustomId("page")
.setMaxValues(1)
@@ -107,12 +107,12 @@
])
];
}
- const em = new Discord.EmbedBuilder(pages[page]!.embed);
- em.setDescription(em.description + "\n\n" + createPageIndicator(pages.length, page));
+ const em = new Discord.EmbedBuilder(pages[page]!.embed.data);
+ em.setDescription(em.data.description + "\n\n" + createPageIndicator(pages.length, page));
await interaction.editReply({
embeds: [em],
components: selectPane.concat([
- new ActionRowBuilder().addComponents([
+ new ActionRowBuilder<ButtonBuilder>().addComponents([
new ButtonBuilder()
.setCustomId("left")
.setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
@@ -137,32 +137,35 @@
});
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;
}
i.deferUpdate();
- if ((i.component as Component).customId === "left") {
+ if ((i.component as ButtonComponent).customId === "left") {
if (page > 0) page--;
selectPaneOpen = false;
- } else if ((i.component as Component).customId === "right") {
+ } else if ((i.component as ButtonComponent).customId === "right") {
if (page < pages.length - 1) page++;
selectPaneOpen = false;
- } else if ((i.component as Component).customId === "select") {
+ } else if (i.customId === "select") {
selectPaneOpen = !selectPaneOpen;
- } else if ((i.component as Component).customId === "page") {
- page = parseInt((i as SelectMenuInteraction).values[0]!);
+ } else if (i.customId === "page" && i.isStringSelectMenu()) {
+ page = parseInt(i.values[0]!);
selectPaneOpen = false;
} else {
cancelled = true;
}
}
- const em = new Discord.EmbedBuilder(pages[page]!.embed);
+ const em = new Discord.EmbedBuilder(pages[page]!.embed.data);
if (timedOut) {
- em.setDescription(em.description + "\n\n" + createPageIndicator(pages.length, page) + " | Message timed out");
+ em.setDescription(em.data.description + "\n\n" + createPageIndicator(pages.length, page) + " | Message timed out");
} else {
- em.setDescription(em.description + "\n\n" + createPageIndicator(pages.length, page) + " | Message closed");
+ em.setDescription(em.data.description + "\n\n" + createPageIndicator(pages.length, page) + " | Message closed");
}
await interaction.editReply({
embeds: [em],
diff --git a/src/commands/user/about.ts b/src/commands/user/about.ts
index aa45690..e43ecb7 100644
--- a/src/commands/user/about.ts
+++ b/src/commands/user/about.ts
@@ -1,4 +1,4 @@
-import { LoadingEmbed, Embed } from "./../../utils/defaultEmbeds.js";
+import { LoadingEmbed, Embed } from "../../utils/defaults.js";
import Discord, {
CommandInteraction,
GuildMember,
@@ -256,7 +256,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 {
timedOut = true;
continue;
diff --git a/src/commands/user/avatar.ts b/src/commands/user/avatar.ts
index 5980072..88b3270 100644
--- a/src/commands/user/avatar.ts
+++ b/src/commands/user/avatar.ts
@@ -35,7 +35,7 @@
});
};
-const check = (_interaction: CommandInteraction) => {
+const check = () => {
return true;
};
diff --git a/src/commands/user/track.ts b/src/commands/user/track.ts
index 06f498a..0ab5c10 100644
--- a/src/commands/user/track.ts
+++ b/src/commands/user/track.ts
@@ -1,4 +1,4 @@
-import { LoadingEmbed } from "./../../utils/defaultEmbeds.js";
+import { LoadingEmbed } from "../../utils/defaults.js";
import Discord, { CommandInteraction, GuildMember, Message, ActionRowBuilder, ButtonBuilder, ButtonStyle } from "discord.js";
import type { SlashCommandSubcommandBuilder } from "@discordjs/builders";
import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
@@ -166,7 +166,10 @@
})) as Message;
let component;
try {
- component = await m.awaitMessageComponent({ time: 300000 });
+ component = 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;
diff --git a/src/commands/verify.ts b/src/commands/verify.ts
index b9556a6..4fafe69 100644
--- a/src/commands/verify.ts
+++ b/src/commands/verify.ts
@@ -8,7 +8,7 @@
verify(interaction);
};
-const check = (_interaction: CommandInteraction) => {
+const check = () => {
return true;
};