Start of context menus
diff --git a/src/actions/tickets/create.ts b/src/actions/tickets/create.ts
index 66bbe42..e1821ef 100644
--- a/src/actions/tickets/create.ts
+++ b/src/actions/tickets/create.ts
@@ -1,4 +1,4 @@
-import Discord, { ActionRowBuilder, ButtonBuilder, ButtonStyle } from "discord.js";
+import Discord, { ActionRowBuilder, ButtonBuilder, ButtonStyle, CommandInteraction } from "discord.js";
import { tickets, toHexArray } from "../../utils/calculate.js";
import client from "../../utils/client.js";
import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
@@ -9,7 +9,8 @@
return s.length < 3 ? s.toUpperCase() : s[0].toUpperCase() + s.slice(1).toLowerCase();
}
-export default async function (interaction) {
+export default async function (interaction: CommandInteraction) {
+ if (!interaction.guild) return;
const { log, NucleusColors, entry, renderUser, renderChannel, renderDelta } = client.logger;
const config = await client.database.guilds.read(interaction.guild.id);
diff --git a/src/actions/tickets/delete.ts b/src/actions/tickets/delete.ts
index 0db4232..33860b7 100644
--- a/src/actions/tickets/delete.ts
+++ b/src/actions/tickets/delete.ts
@@ -4,9 +4,10 @@
import getEmojiByName from "../../utils/getEmojiByName.js";
export default async function (interaction: Discord.CommandInteraction) {
+ if (!interaction.guild) return;
const { log, NucleusColors, entry, renderUser, renderChannel, renderDelta } = client.logger;
- const config = await client.database.guilds.read(interaction.guild!.id);
+ const config = await client.database.guilds.read(interaction.guild.id);
let thread = false;
if (interaction.channel instanceof Discord.ThreadChannel) thread = true;
const threadChannel = interaction.channel as Discord.ThreadChannel;
diff --git a/src/commands/mod/ban.ts b/src/commands/mod/ban.ts
index 6deb4ad..e32a720 100644
--- a/src/commands/mod/ban.ts
+++ b/src/commands/mod/ban.ts
@@ -24,6 +24,7 @@
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;
@@ -69,7 +70,7 @@
reason = reason.length ? reason : null
let dmSent = false;
let dmMessage;
- const config = await client.database.guilds.read(interaction.guild!.id);
+ const config = await client.database.guilds.read(interaction.guild.id);
try {
if (notify) {
const messageData: {
@@ -81,7 +82,7 @@
.setEmoji("PUNISH.BAN.RED")
.setTitle("Banned")
.setDescription(
- `You have been banned in ${interaction.guild!.name}` + (reason ? ` for:\n> ${reason}` : ".")
+ `You have been banned in ${interaction.guild.name}` + (reason ? ` for:\n> ${reason}` : ".")
)
.setStatus("Danger")
],
@@ -110,7 +111,7 @@
deleteMessageSeconds: days * 24 * 60 * 60,
reason: reason ?? "*No reason provided*"
});
- await client.database.history.create("ban", interaction.guild!.id, member.user, interaction.user, reason);
+ 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: {
@@ -128,10 +129,10 @@
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())),
- serverMemberCount: interaction.guild!.memberCount
+ serverMemberCount: interaction.guild.memberCount
},
hidden: {
- guild: interaction.guild!.id
+ guild: interaction.guild.id
}
};
log(data);
@@ -175,20 +176,21 @@
};
const check = async (interaction: CommandInteraction) => {
+ if (!interaction.guild) return;
const member = interaction.member as GuildMember;
- const me = interaction.guild!.members.me!;
+ 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;
let applyPos = 0
try {
- apply = await interaction.guild!.members.fetch(apply.id) as GuildMember
+ 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 ban the owner of the server");
+ if (member.id === interaction.guild.ownerId) throw new Error("You cannot ban 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
@@ -196,7 +198,7 @@
// Do not allow banning Nucleus
if (member.id === me.id) throw new Error("I cannot ban myself");
// Allow the owner to ban anyone
- if (member.id === interaction.guild!.ownerId) return true;
+ if (member.id === interaction.guild.ownerId) return true;
// Check if the user has 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
diff --git a/src/commands/mod/kick.ts b/src/commands/mod/kick.ts
index f6052f8..2feb5d7 100644
--- a/src/commands/mod/kick.ts
+++ b/src/commands/mod/kick.ts
@@ -1,7 +1,9 @@
+import { LinkWarningFooter } from './../../utils/defaultEmbeds';
import { CommandInteraction, GuildMember, ActionRowBuilder, ButtonBuilder, ButtonStyle } from "discord.js";
// @ts-expect-error
import humanizeDuration from "humanize-duration";
import type { SlashCommandSubcommandBuilder } from "@discordjs/builders";
+import type Discord from "discord.js";
import confirmationMessage from "../../utils/confirmationMessage.js";
import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
import keyValueList from "../../utils/generateKeyValueList.js";
@@ -14,77 +16,103 @@
.addUserOption((option) => option.setName("user").setDescription("The user to kick").setRequired(true));
const callback = async (interaction: CommandInteraction): Promise<unknown> => {
+ if (!interaction.guild) return;
const { renderUser } = client.logger;
// TODO:[Modals] Replace this with a modal
- let reason = null;
+ let reason: string | null = null;
let notify = true;
let confirmation;
let timedOut = false;
- let chosen = false;
- while (!timedOut && !chosen) {
+ let success = false;
+ do {
confirmation = await new confirmationMessage(interaction)
.setEmoji("PUNISH.KICK.RED")
.setTitle("Kick")
.setDescription(
keyValueList({
- user: renderUser(interaction.options.getUser("user")),
+ user: renderUser(interaction.options.getUser("user")!),
reason: reason ? "\n> " + (reason).replaceAll("\n", "\n> ") : "*No reason provided*"
}) +
- `The user **will${notify ? "" : " not"}** be notified\n\n` +
`Are you sure you want to kick <@!${(interaction.options.getMember("user") as GuildMember).id}>?`
)
.setColor("Danger")
+ .addCustomBoolean(
+ "notify",
+ "Notify user",
+ false,
+ null,
+ "The user will be sent a DM",
+ "ICONS.NOTIFY." + (notify ? "ON" : "OFF"),
+ notify
+ )
.addReasonButton(reason ?? "")
.send(reason !== null);
reason = reason ?? "";
if (confirmation.cancelled) timedOut = true;
- else if (confirmation.success !== undefined) chosen = true;
+ else if (confirmation.success !== undefined) success = true;
else if (confirmation.newReason) reason = confirmation.newReason;
else if (confirmation.components) {
notify = confirmation.components["notify"]!.active;
}
- }
+ } while (!timedOut && !success)
if (timedOut) return;
- let dmd = false;
- let dm;
- const config = await client.database.guilds.read(interaction.guild!.id);
+ if (!confirmation.success) {
+ await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji("PUNISH.KICK.GREEN")
+ .setTitle("Kick")
+ .setDescription("No changes were made")
+ .setStatus("Success")
+ ],
+ components: []
+ });
+ return;
+ }
+ let dmSent = false;
+ let dmMessage;
+ const config = await client.database.guilds.read(interaction.guild.id);
try {
if (notify) {
- dm = await (interaction.options.getMember("user") as GuildMember).send({
+ const messageData: {
+ embeds: EmojiEmbed[];
+ components: ActionRowBuilder<ButtonBuilder>[];
+ } = {
embeds: [
new EmojiEmbed()
.setEmoji("PUNISH.KICK.RED")
.setTitle("Kicked")
.setDescription(
- `You have been kicked in ${interaction.guild!.name}` + (reason ? ` for:\n> ${reason}` : ".")
+ `You have been kicked from ${interaction.guild.name}` +
+ (reason ? ` for:\n> ${reason}` : ".\n*No reason was provided.*")
)
.setStatus("Danger")
],
- components: [
- new ActionRowBuilder().addComponents(
- config.moderation.kick.text
- ? [
- new ButtonBuilder()
- .setStyle(ButtonStyle.Link)
- .setLabel(config.moderation.kick.text)
- .setURL(config.moderation.kick.link)
- ]
- : []
- )
- ]
- });
- dmd = true;
+ components: []
+ };
+ if (config.moderation.kick.text && config.moderation.kick.link) {
+ messageData.embeds[0]!.setFooter(LinkWarningFooter)
+ messageData.components.push(new ActionRowBuilder<Discord.ButtonBuilder>()
+ .addComponents(new ButtonBuilder()
+ .setStyle(ButtonStyle.Link)
+ .setLabel(config.moderation.kick.text)
+ .setURL(config.moderation.kick.link)
+ )
+ )
+ }
+ dmMessage = await (interaction.options.getMember("user") as GuildMember).send(messageData);
+ dmSent = true;
}
} catch {
- dmd = false;
+ dmSent = false;
}
try {
- (interaction.options.getMember("user") as GuildMember).kick(reason ?? "No reason provided.");
+ (interaction.options.getMember("user") as GuildMember).kick(reason || "No reason provided");
const member = interaction.options.getMember("user") as GuildMember;
- await client.database.history.create("kick", interaction.guild!.id, member.user, interaction.user, reason);
+ await client.database.history.create("kick", interaction.guild.id, member.user, interaction.user, reason);
const { log, NucleusColors, entry, renderUser, renderDelta } = client.logger;
const timeInServer = member.joinedTimestamp ? entry(
- new Date().getTime() - member.joinedTimestamp,
+ (new Date().getTime() - member.joinedTimestamp).toString(),
humanizeDuration(new Date().getTime() - member.joinedTimestamp, {
round: true
})
@@ -101,18 +129,27 @@
list: {
memberId: entry(member.id, `\`${member.id}\``),
name: entry(member.id, renderUser(member.user)),
- joined: entry(member.joinedAt, renderDelta(member.joinedAt)),
- kicked: entry(new Date().getTime(), renderDelta(new Date().getTime())),
+ joined: undefined as (unknown | typeof entry),
+ kicked: entry(new Date().getTime().toString(), renderDelta(new Date().getTime())),
kickedBy: entry(interaction.user.id, renderUser(interaction.user)),
reason: entry(reason, reason ? `\n> ${reason}` : "*No reason provided.*"),
timeInServer: timeInServer,
- accountCreated: entry(member.user.createdAt, renderDelta(member.user.createdAt)),
serverMemberCount: member.guild.memberCount
},
hidden: {
guild: member.guild.id
}
};
+ if (member.joinedTimestamp) {
+ data.list.joined = entry(member.joinedTimestamp.toString(), renderDelta(member.joinedTimestamp))
+ }
+ await client.database.history.create(
+ "kick",
+ interaction.guild.id,
+ member.user,
+ interaction.user,
+ reason
+ )
log(data);
} catch {
await interaction.editReply({
@@ -125,10 +162,10 @@
],
components: []
});
- if (dmd && dm) await dm.delete();
+ if (dmSent && dmMessage) await dmMessage.delete();
return;
}
- const failed = !dmd && notify;
+ const failed = !dmSent && notify;
await interaction.editReply({
embeds: [
new EmojiEmbed()
@@ -142,24 +179,25 @@
};
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!;
const apply = interaction.options.getMember("user") as 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 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) throw new Error("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");
// Check if Nucleus has permission to kick
- if (!me.permissions.has("KICK_MEMBERS")) throw new Error("I do not have the *Kick Members* permission");
+ if (!me.permissions.has("KickMembers")) throw new Error("I do not have the *Kick Members* permission");
// Do not allow kicking Nucleus
- if (member.id === interaction.guild!.me!.id) throw new Error("I cannot kick myself");
+ if (member.id === interaction.guild.members.me!.id) throw new Error("I cannot kick myself");
// Allow the owner to kick anyone
- if (member.id === interaction.guild!.ownerId) return true;
+ if (member.id === interaction.guild.ownerId) return true;
// Check if the user has kick_members permission
- if (!member.permissions.has("KICK_MEMBERS")) throw new Error("You do not have the *Kick Members* permission");
+ if (!member.permissions.has("KickMembers")) throw new Error("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");
// Allow kick
diff --git a/src/commands/mod/mute.ts b/src/commands/mod/mute.ts
index db0d68b..0e76cba 100644
--- a/src/commands/mod/mute.ts
+++ b/src/commands/mod/mute.ts
@@ -49,6 +49,7 @@
);
const callback = async (interaction: CommandInteraction): Promise<unknown> => {
+ if (!interaction.guild) return;
const { log, NucleusColors, renderUser, entry, renderDelta } = client.logger;
const user = interaction.options.getMember("user") as GuildMember;
const time = {
@@ -57,7 +58,7 @@
minutes: interaction.options.getInteger("minutes") ?? 0,
seconds: interaction.options.getInteger("seconds") ?? 0
};
- const config = await client.database.guilds.read(interaction.guild!.id);
+ const config = await client.database.guilds.read(interaction.guild.id);
let serverSettingsDescription = config.moderation.mute.timeout ? "given a timeout" : "";
if (config.moderation.mute.role)
serverSettingsDescription +=
@@ -187,9 +188,9 @@
.addCustomBoolean(
"appeal",
"Create appeal ticket",
- !(await areTicketsEnabled(interaction.guild!.id)),
+ !(await areTicketsEnabled(interaction.guild.id)),
async () =>
- await create(interaction.guild!, interaction.options.getUser("user")!, interaction.user, reason),
+ await create(interaction.guild, interaction.options.getUser("user")!, interaction.user, reason),
"An appeal ticket will be created when Confirm is clicked",
"CONTROL.TICKET",
createAppealTicket
@@ -226,7 +227,7 @@
.setEmoji("PUNISH.MUTE.RED")
.setTitle("Muted")
.setDescription(
- `You have been muted in ${interaction.guild!.name}` +
+ `You have been muted in ${interaction.guild.name}` +
(reason
? ` for:\n> ${reason}`
: ".\n\n" +
@@ -267,7 +268,7 @@
if (config.moderation.mute.role !== null) {
await member.roles.add(config.moderation.mute.role);
await client.database.eventScheduler.schedule("naturalUnmute", new Date().getTime() + muteTime * 1000, {
- guild: interaction.guild!.id,
+ guild: interaction.guild.id,
user: user.id,
expires: new Date().getTime() + muteTime * 1000
});
@@ -280,7 +281,7 @@
if (config.moderation.mute.role !== null) {
await member.roles.add(config.moderation.mute.role);
await client.database.eventScheduler.schedule("unmuteRole", new Date().getTime() + muteTime * 1000, {
- guild: interaction.guild!.id,
+ guild: interaction.guild.id,
user: user.id,
role: config.moderation.mute.role
});
@@ -303,7 +304,7 @@
if (dmd && dm) await dm.delete();
return;
}
- await client.database.history.create("mute", interaction.guild!.id, member.user, interaction.user, reason);
+ await client.database.history.create("mute", interaction.guild.id, member.user, interaction.user, reason);
const failed = !dmd && notify;
await interaction.editReply({
embeds: [
@@ -342,7 +343,7 @@
reason: entry(reason, reason ? reason : "*No reason provided*")
},
hidden: {
- guild: interaction.guild!.id
+ guild: interaction.guild.id
}
};
log(data);
@@ -361,14 +362,15 @@
};
const check = (interaction: CommandInteraction) => {
+ if (!interaction.guild) return;
const member = interaction.member as GuildMember;
- const me = interaction.guild!.me!;
+ const me = interaction.guild.me!;
const apply = interaction.options.getMember("user") as 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 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) throw new Error("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");
// Check if Nucleus has permission to mute
@@ -376,7 +378,7 @@
// Do not allow muting Nucleus
if (member.id === me.id) throw new Error("I cannot mute myself");
// Allow the owner to mute anyone
- if (member.id === interaction.guild!.ownerId) return true;
+ if (member.id === interaction.guild.ownerId) return true;
// Check if the user has moderate_members permission
if (!member.permissions.has("MODERATE_MEMBERS"))
throw new Error("You do not have the *Moderate Members* permission");
diff --git a/src/commands/mod/purge.ts b/src/commands/mod/purge.ts
index a19a627..e9aa41a 100644
--- a/src/commands/mod/purge.ts
+++ b/src/commands/mod/purge.ts
@@ -26,7 +26,7 @@
);
const callback = async (interaction: CommandInteraction): Promise<unknown> => {
- const user = (interaction.options.getMember("user") as GuildMember) ?? null;
+ const user = (interaction.options.getMember("user") as GuildMember);
const channel = interaction.channel as GuildChannel;
if (
!["GUILD_TEXT", "GUILD_NEWS", "GUILD_NEWS_THREAD", "GUILD_PUBLIC_THREAD", "GUILD_PRIVATE_THREAD"].includes(
diff --git a/src/commands/mod/slowmode.ts b/src/commands/mod/slowmode.ts
index 3e883b3..b565deb 100644
--- a/src/commands/mod/slowmode.ts
+++ b/src/commands/mod/slowmode.ts
@@ -34,7 +34,7 @@
);
const callback = async (interaction: CommandInteraction): Promise<void> => {
- let time = parseInt(interaction.options.getString("time") ?? "0");
+ let time = parseInt(interaction.options.get("time")?.value as string || "0");
if (time === 0 && (interaction.channel as TextChannel).rateLimitPerUser === 0) {
time = 10;
}
@@ -91,10 +91,9 @@
const check = (interaction: CommandInteraction) => {
const member = interaction.member as GuildMember;
// Check if Nucleus can set the slowmode
- if (!interaction.guild.me.permissions.has("MANAGE_CHANNELS"))
- throw new Error("I do not have the *Manage Channels* permission");
+ if (!interaction.guild!.members.me!.permissions.has("ManageChannels")) throw new Error("I do not have the *Manage Channels* permission");
// Check if the user has manage_channel permission
- if (!member.permissions.has("MANAGE_CHANNELS")) throw new Error("You do not have the *Manage Channels* permission");
+ if (!member.permissions.has("ManageChannels")) throw new Error("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 6c0396d..c9a71f6 100644
--- a/src/commands/mod/softban.ts
+++ b/src/commands/mod/softban.ts
@@ -1,5 +1,5 @@
import { CommandInteraction, GuildMember, ActionRowBuilder, ButtonBuilder, ButtonStyle } from "discord.js";
-import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
+import type { SlashCommandSubcommandBuilder } from "@discordjs/builders";
import confirmationMessage from "../../utils/confirmationMessage.js";
import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
import keyValueList from "../../utils/generateKeyValueList.js";
diff --git a/src/commands/mod/unban.ts b/src/commands/mod/unban.ts
index 81a29a2..d34f303 100644
--- a/src/commands/mod/unban.ts
+++ b/src/commands/mod/unban.ts
@@ -14,6 +14,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");
let resolved = bans.find((ban) => ban.user.id === user);
@@ -107,6 +108,7 @@
};
const check = (interaction: CommandInteraction) => {
+ if (!interaction.guild) return;
const member = interaction.member as GuildMember;
const me = interaction.guild.me!;
// Check if Nucleus can unban members
diff --git a/src/commands/mod/unmute.ts b/src/commands/mod/unmute.ts
index 0ce63d1..40510a8 100644
--- a/src/commands/mod/unmute.ts
+++ b/src/commands/mod/unmute.ts
@@ -1,5 +1,5 @@
-import { CommandInteraction, GuildMember } from "discord.js";
-import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
+import type { CommandInteraction, GuildMember } 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";
@@ -12,40 +12,51 @@
.addUserOption((option) => option.setName("user").setDescription("The user to unmute").setRequired(true));
const callback = async (interaction: CommandInteraction): Promise<unknown> => {
+ if (!interaction.guild) return;
const { log, NucleusColors, renderUser, entry, renderDelta } = client.logger;
// TODO:[Modals] Replace this with a modal
- let reason = null;
+ let reason: string | null = null;
let notify = false;
let confirmation;
+ let timedOut = false;
let success = false;
- while (!success) {
+ do {
confirmation = await new confirmationMessage(interaction)
.setEmoji("PUNISH.MUTE.RED")
.setTitle("Unmute")
.setDescription(
keyValueList({
- user: renderUser(interaction.options.getUser("user")),
+ user: renderUser(interaction.options.getUser("user")!),
reason: `\n> ${reason ? reason : "*No reason provided*"}`
}) +
- `The user **will${notify ? "" : " not"}** be notified\n\n` +
`Are you sure you want to unmute <@!${(interaction.options.getMember("user") as GuildMember).id}>?`
)
.setColor("Danger")
+ .addCustomBoolean(
+ "notify",
+ "Notify user",
+ false,
+ null,
+ "The user will be sent a DM",
+ "ICONS.NOTIFY." + (notify ? "ON" : "OFF"),
+ notify
+ )
.addReasonButton(reason ?? "")
.send(reason !== null);
- if (confirmation.success) success = true;
+ if (confirmation.cancelled) timedOut = true;
+ else if (confirmation.success !== undefined) success = true;
else if (confirmation.newReason) reason = confirmation.newReason;
else if (confirmation.components) {
- notify = confirmation.components.notify.active;
+ notify = confirmation.components!["notify"]!.active;
}
- }
+ } while (!timedOut && !success);
if (confirmation.cancelled) return;
if (confirmation.success) {
- let dmd = false;
- let dm;
+ let dmSent = false;
+ let dmMessage;
try {
if (notify) {
- dm = await (interaction.options.getMember("user") as GuildMember).send({
+ dmMessage = await (interaction.options.getMember("user") as GuildMember).send({
embeds: [
new EmojiEmbed()
.setEmoji("PUNISH.MUTE.GREEN")
@@ -57,10 +68,10 @@
.setStatus("Success")
]
});
- dmd = true;
+ dmSent = true;
}
} catch {
- dmd = false;
+ dmSent = false;
}
const member = interaction.options.getMember("user") as GuildMember;
try {
@@ -76,7 +87,7 @@
],
components: []
});
- if (dmd) await dm.delete();
+ if (dmSent && dmMessage) await dmMessage.delete();
return;
}
await client.database.history.create(
@@ -98,7 +109,7 @@
list: {
memberId: entry(member.user.id, `\`${member.user.id}\``),
name: entry(member.user.id, renderUser(member.user)),
- unmuted: entry(new Date().getTime(), renderDelta(new Date().getTime())),
+ unmuted: entry(new Date().getTime().toString(), renderDelta(new Date().getTime())),
unmutedBy: entry(interaction.user.id, renderUser(interaction.user))
},
hidden: {
@@ -106,7 +117,7 @@
}
};
log(data);
- const failed = !dmd && notify;
+ const failed = !dmSent && notify;
await interaction.editReply({
embeds: [
new EmojiEmbed()
@@ -132,10 +143,10 @@
};
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!;
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 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;
@@ -144,11 +155,11 @@
// Check if Nucleus can unmute the member
if (!(mePos > applyPos)) throw new Error("I do not have a role higher than that member");
// Check if Nucleus has permission to unmute
- if (!me.permissions.has("MODERATE_MEMBERS")) throw new Error("I do not have the *Moderate Members* permission");
+ if (!me.permissions.has("ModerateMembers")) throw new Error("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("MODERATE_MEMBERS"))
+ if (!member.permissions.has("ModerateMembers"))
throw new Error("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");
diff --git a/src/commands/mod/warn.ts b/src/commands/mod/warn.ts
index 5125587..1c5223f 100644
--- a/src/commands/mod/warn.ts
+++ b/src/commands/mod/warn.ts
@@ -14,6 +14,7 @@
.addUserOption((option) => option.setName("user").setDescription("The user to warn").setRequired(true));
const callback = async (interaction: CommandInteraction): Promise<unknown> => {
+ if (interaction.guild === null) return;
const { log, NucleusColors, renderUser, entry } = client.logger;
// TODO:[Modals] Replace this with a modal
let reason: string | null = null;
@@ -37,7 +38,7 @@
.addCustomBoolean(
"appeal",
"Create appeal ticket",
- !(await areTicketsEnabled(interaction.guild!.id)),
+ !(await areTicketsEnabled(interaction.guild.id)),
async () => await create(interaction.guild!, interaction.options.getUser("user")!, interaction.user, reason),
"An appeal ticket will be created",
"CONTROL.TICKET",
@@ -64,79 +65,166 @@
}
} while (!timedOut && !success)
if (timedOut) return;
- if (confirmation.success) {
- let dmSent = false;
- const config = await client.database.guilds.read(interaction.guild!.id);
- try {
- if (notify) {
- const messageData: {
- embeds: EmojiEmbed[];
- components: ActionRowBuilder<ButtonBuilder>[];
- } = {
- embeds: [
- new EmojiEmbed()
- .setEmoji("PUNISH.WARN.RED")
- .setTitle("Warned")
- .setDescription(
- `You have been warned in ${interaction.guild!.name}` +
- (reason ? ` for:\n> ${reason}` : ".\n*No reason was provided*") +
- "\n\n" +
- (createAppealTicket
- ? `You can appeal this in the ticket created in <#${confirmation.components!["appeal"]!.response}>`
- : "")
- )
- .setStatus("Danger")
- ],
- components: []
- };
- if (config.moderation.warn.text && config.moderation.warn.link) {
- messageData.embeds[0]!.setFooter(LinkWarningFooter)
- messageData.components.push(new ActionRowBuilder<Discord.ButtonBuilder>()
- .addComponents(new ButtonBuilder()
- .setStyle(ButtonStyle.Link)
- .setLabel(config.moderation.warn.text)
- .setURL(config.moderation.warn.link)
- )
- )
- }
- await (interaction.options.getMember("user") as GuildMember).send(messageData);
- dmSent = true;
+ if (!confirmation.success) {
+ await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji("PUNISH.WARN.GREEN")
+ .setTitle("Warn")
+ .setDescription("No changes were made")
+ .setStatus("Success")
+ ],
+ components: []
+ });
+ return;
+ }
+ let dmSent = false;
+ const config = await client.database.guilds.read(interaction.guild.id);
+ try {
+ if (notify) {
+ const messageData: {
+ embeds: EmojiEmbed[];
+ components: ActionRowBuilder<ButtonBuilder>[];
+ } = {
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji("PUNISH.WARN.RED")
+ .setTitle("Warned")
+ .setDescription(
+ `You have been warned in ${interaction.guild.name}` +
+ (reason ? ` for:\n> ${reason}` : ".\n*No reason was provided*") +
+ "\n\n" +
+ (createAppealTicket
+ ? `You can appeal this in the ticket created in <#${confirmation.components!["appeal"]!.response}>`
+ : "")
+ )
+ .setStatus("Danger")
+ ],
+ components: []
+ };
+ if (config.moderation.warn.text && config.moderation.warn.link) {
+ messageData.embeds[0]!.setFooter(LinkWarningFooter)
+ messageData.components.push(new ActionRowBuilder<Discord.ButtonBuilder>()
+ .addComponents(new ButtonBuilder()
+ .setStyle(ButtonStyle.Link)
+ .setLabel(config.moderation.warn.text)
+ .setURL(config.moderation.warn.link)
+ )
+ )
}
- } catch (e) {
- dmSent = false;
+ await (interaction.options.getMember("user") as GuildMember).send(messageData);
+ dmSent = true;
}
- const data = {
- meta: {
- type: "memberWarn",
- displayName: "Member warned",
- calculateType: "guildMemberPunish",
- color: NucleusColors.yellow,
- emoji: "PUNISH.WARN.YELLOW",
- timestamp: new Date().getTime()
- },
- list: {
- user: entry(
- (interaction.options.getMember("user") as GuildMember).user.id,
- renderUser((interaction.options.getMember("user") as GuildMember).user)
- ),
- warnedBy: entry(interaction.member!.user.id, renderUser(interaction.member!.user as Discord.User)),
- reason: reason ? `\n> ${reason}` : "*No reason provided*"
- },
- hidden: {
- guild: interaction.guild!.id
- }
- };
- await client.database.history.create(
- "warn",
- interaction.guild!.id,
- (interaction.options.getMember("user") as GuildMember).user,
- interaction.user,
- reason
- );
- log(data);
- const failed = !dmSent && notify;
- if (!failed) {
- await interaction.editReply({
+ } catch (e) {
+ dmSent = false;
+ }
+ const data = {
+ meta: {
+ type: "memberWarn",
+ displayName: "Member warned",
+ calculateType: "guildMemberPunish",
+ color: NucleusColors.yellow,
+ emoji: "PUNISH.WARN.YELLOW",
+ timestamp: new Date().getTime()
+ },
+ list: {
+ user: entry(
+ (interaction.options.getMember("user") as GuildMember).user.id,
+ renderUser((interaction.options.getMember("user") as GuildMember).user)
+ ),
+ warnedBy: entry(interaction.member!.user.id, renderUser(interaction.member!.user as Discord.User)),
+ reason: reason ? `\n> ${reason}` : "*No reason provided*"
+ },
+ hidden: {
+ guild: interaction.guild.id
+ }
+ };
+ await client.database.history.create(
+ "warn",
+ interaction.guild.id,
+ (interaction.options.getMember("user") as GuildMember).user,
+ interaction.user,
+ reason
+ );
+ log(data);
+ const failed = !dmSent && notify;
+ if (!failed) {
+ await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji("PUNISH.WARN.GREEN")
+ .setTitle("Warn")
+ .setDescription(
+ "The user was warned" +
+ (createAppealTicket
+ ? ` and an appeal ticket was opened in <#${confirmation.components!["appeal"]!.response}>`
+ : "")
+ )
+ .setStatus("Success")
+ ],
+ components: []
+ });
+ } else {
+ const canSeeChannel = (interaction.options.getMember("user") as GuildMember)
+ .permissionsIn(interaction.channel as Discord.TextChannel)
+ .has("ViewChannel");
+ const m = (await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji("PUNISH.WARN.RED")
+ .setTitle("Warn")
+ .setDescription("The user's DMs are not open\n\nWhat would you like to do?")
+ .setStatus("Danger")
+ ],
+ components: [
+ new ActionRowBuilder<Discord.ButtonBuilder>().addComponents(
+ new Discord.ButtonBuilder().setCustomId("log").setLabel("Ignore and log").setStyle(ButtonStyle.Secondary),
+ new Discord.ButtonBuilder()
+ .setCustomId("here")
+ .setLabel("Warn here")
+ .setStyle(canSeeChannel ? ButtonStyle.Primary : ButtonStyle.Secondary)
+ .setDisabled(!canSeeChannel),
+ new Discord.ButtonBuilder()
+ .setCustomId("ticket")
+ .setLabel("Create ticket")
+ .setStyle(canSeeChannel ? ButtonStyle.Primary : ButtonStyle.Secondary)
+ .setDisabled(createAppealTicket)
+ )
+ ]
+ })) as Discord.Message;
+ let component;
+ try {
+ component = await m.awaitMessageComponent({
+ filter: (m) => m.user.id === interaction.user.id,
+ time: 300000
+ });
+ } catch (e) {
+ return await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji("PUNISH.WARN.GREEN")
+ .setTitle("Warn")
+ .setDescription("No changes were made")
+ .setStatus("Success")
+ ],
+ components: []
+ });
+ }
+ if (component.customId === "here") {
+ await interaction.channel!.send({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji("PUNISH.WARN.RED")
+ .setTitle("Warn")
+ .setDescription("You have been warned" + (reason ? ` for:\n> ${reason}` : "."))
+ .setStatus("Danger")
+ ],
+ content: `<@!${(interaction.options.getMember("user") as GuildMember).id}>`,
+ allowedMentions: {
+ users: [(interaction.options.getMember("user") as GuildMember).id]
+ }
+ });
+ return await interaction.editReply({
embeds: [
new EmojiEmbed()
.setEmoji("PUNISH.WARN.GREEN")
@@ -151,139 +239,53 @@
],
components: []
});
- } else {
- const canSeeChannel = (interaction.options.getMember("user") as GuildMember)
- .permissionsIn(interaction.channel as Discord.TextChannel)
- .has("ViewChannel");
- const m = (await interaction.editReply({
+ } else if (component.customId === "log") {
+ await interaction.editReply({
embeds: [
new EmojiEmbed()
- .setEmoji("PUNISH.WARN.RED")
+ .setEmoji("PUNISH.WARN.GREEN")
.setTitle("Warn")
- .setDescription("The user's DMs are not open\n\nWhat would you like to do?")
- .setStatus("Danger")
+ .setDescription("The warn was logged")
+ .setStatus("Success")
],
- components: [
- new ActionRowBuilder<Discord.ButtonBuilder>().addComponents(
- new Discord.ButtonBuilder().setCustomId("log").setLabel("Ignore and log").setStyle(ButtonStyle.Secondary),
- new Discord.ButtonBuilder()
- .setCustomId("here")
- .setLabel("Warn here")
- .setStyle(canSeeChannel ? ButtonStyle.Primary : ButtonStyle.Secondary)
- .setDisabled(!canSeeChannel),
- new Discord.ButtonBuilder()
- .setCustomId("ticket")
- .setLabel("Create ticket")
- .setStyle(canSeeChannel ? ButtonStyle.Primary : ButtonStyle.Secondary)
- .setDisabled(createAppealTicket)
- )
- ]
- })) as Discord.Message;
- let component;
- try {
- component = await m.awaitMessageComponent({
- filter: (m) => m.user.id === interaction.user.id,
- time: 300000
- });
- } catch (e) {
+ components: []
+ });
+ } else if (component.customId === "ticket") {
+ const ticketChannel = await create(
+ interaction.guild,
+ interaction.options.getUser("user")!,
+ interaction.user,
+ reason,
+ "Warn Notification"
+ );
+ if (ticketChannel === null) {
return await interaction.editReply({
embeds: [
new EmojiEmbed()
- .setEmoji("PUNISH.WARN.GREEN")
- .setTitle("Warn")
- .setDescription("No changes were made")
- .setStatus("Success")
- ],
- components: []
- });
- }
- if (component.customId === "here") {
- await interaction.channel!.send({
- embeds: [
- new EmojiEmbed()
.setEmoji("PUNISH.WARN.RED")
.setTitle("Warn")
- .setDescription("You have been warned" + (reason ? ` for:\n> ${reason}` : "."))
+ .setDescription("A ticket could not be created")
.setStatus("Danger")
],
- content: `<@!${(interaction.options.getMember("user") as GuildMember).id}>`,
- allowedMentions: {
- users: [(interaction.options.getMember("user") as GuildMember).id]
- }
- });
- return await interaction.editReply({
- embeds: [
- new EmojiEmbed()
- .setEmoji("PUNISH.WARN.GREEN")
- .setTitle("Warn")
- .setDescription(
- "The user was warned" +
- (createAppealTicket
- ? ` and an appeal ticket was opened in <#${confirmation.components!["appeal"]!.response}>`
- : "")
- )
- .setStatus("Success")
- ],
- components: []
- });
- } else if (component.customId === "log") {
- await interaction.editReply({
- embeds: [
- new EmojiEmbed()
- .setEmoji("PUNISH.WARN.GREEN")
- .setTitle("Warn")
- .setDescription("The warn was logged")
- .setStatus("Success")
- ],
- components: []
- });
- } else if (component.customId === "ticket") {
- const ticketChannel = await create(
- interaction.guild!,
- interaction.options.getUser("user")!,
- interaction.user,
- reason,
- "Warn Notification"
- );
- if (ticketChannel === null) {
- return await interaction.editReply({
- embeds: [
- new EmojiEmbed()
- .setEmoji("PUNISH.WARN.RED")
- .setTitle("Warn")
- .setDescription("A ticket could not be created")
- .setStatus("Danger")
- ],
- components: []
- });
- }
- await interaction.editReply({
- embeds: [
- new EmojiEmbed()
- .setEmoji("PUNISH.WARN.GREEN")
- .setTitle("Warn")
- .setDescription(`A ticket was created in <#${ticketChannel}>`)
- .setStatus("Success")
- ],
components: []
});
}
+ await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji("PUNISH.WARN.GREEN")
+ .setTitle("Warn")
+ .setDescription(`A ticket was created in <#${ticketChannel}>`)
+ .setStatus("Success")
+ ],
+ components: []
+ });
}
- } else {
- await interaction.editReply({
- embeds: [
- new EmojiEmbed()
- .setEmoji("PUNISH.WARN.GREEN")
- .setTitle("Warn")
- .setDescription("No changes were made")
- .setStatus("Success")
- ],
- components: []
- });
}
};
const check = (interaction: CommandInteraction) => {
+ 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");
@@ -292,7 +294,7 @@
// Do not allow warning bots
if (member.user.bot) throw new Error("I cannot warn bots");
// Allow the owner to warn anyone
- if (member.id === interaction.guild!.ownerId) return true;
+ 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");
diff --git a/src/commands/settings/tickets.ts b/src/commands/settings/tickets.ts
index 48d419d..70ba52d 100644
--- a/src/commands/settings/tickets.ts
+++ b/src/commands/settings/tickets.ts
@@ -62,6 +62,7 @@
);
const callback = async (interaction: CommandInteraction): Promise<unknown> => {
+ if (!interaction.guild) return;
let m = (await interaction.reply({
embeds: LoadingEmbed,
ephemeral: true,
@@ -77,7 +78,7 @@
if (options.category) {
let channel: GuildChannel | null;
try {
- channel = await interaction.guild!.channels.fetch(options.category.id);
+ channel = await interaction.guild.channels.fetch(options.category.id);
} catch {
return await interaction.editReply({
embeds: [
@@ -91,7 +92,7 @@
}
if (!channel) return;
channel = channel as Discord.CategoryChannel;
- if (channel.guild.id !== interaction.guild!.id)
+ if (channel.guild.id !== interaction.guild.id)
return interaction.editReply({
embeds: [
new EmojiEmbed()
@@ -117,7 +118,7 @@
let role: Role | null;
if (options.supportping) {
try {
- role = await interaction.guild!.roles.fetch(options.supportping.id);
+ role = await interaction.guild.roles.fetch(options.supportping.id);
} catch {
return await interaction.editReply({
embeds: [
@@ -131,7 +132,7 @@
}
if (!role) return;
role = role as Discord.Role;
- if (role.guild.id !== interaction.guild!.id)
+ if (role.guild.id !== interaction.guild.id)
return interaction.editReply({
embeds: [
new EmojiEmbed()
@@ -170,7 +171,7 @@
if (options.maxtickets) toUpdate["tickets.maxTickets"] = options.maxtickets;
if (options.supportping) toUpdate["tickets.supportRole"] = options.supportping.id;
try {
- await client.database.guilds.write(interaction.guild!.id, toUpdate);
+ await client.database.guilds.write(interaction.guild.id, toUpdate);
} catch (e) {
return interaction.editReply({
embeds: [
@@ -196,7 +197,7 @@
});
}
}
- let data = await client.database.guilds.read(interaction.guild!.id);
+ let data = await client.database.guilds.read(interaction.guild.id);
data.tickets.customTypes = (data.tickets.customTypes || []).filter(
(value: string, index: number, array: string[]) => array.indexOf(value) === index
);
@@ -284,19 +285,19 @@
if ((i.component as Component).customId === "clearCategory") {
if (lastClicked === "cat") {
lastClicked = "";
- await client.database.guilds.write(interaction.guild!.id, null, ["tickets.category"]);
+ await client.database.guilds.write(interaction.guild.id, null, ["tickets.category"]);
data.category = undefined;
} else lastClicked = "cat";
} else if ((i.component as Component).customId === "clearMaxTickets") {
if (lastClicked === "max") {
lastClicked = "";
- await client.database.guilds.write(interaction.guild!.id, null, ["tickets.maxTickets"]);
+ await client.database.guilds.write(interaction.guild.id, null, ["tickets.maxTickets"]);
data.maxTickets = 5;
} else lastClicked = "max";
} else if ((i.component as Component).customId === "clearSupportPing") {
if (lastClicked === "sup") {
lastClicked = "";
- await client.database.guilds.write(interaction.guild!.id, null, ["tickets.supportRole"]);
+ await client.database.guilds.write(interaction.guild.id, null, ["tickets.supportRole"]);
data.supportRole = undefined;
} else lastClicked = "sup";
} else if ((i.component as Component).customId === "send") {
@@ -732,7 +733,7 @@
const check = (interaction: CommandInteraction) => {
const member = interaction.member as Discord.GuildMember;
- if (!member.permissions.has("MANAGE_GUILD"))
+ if (!member.permissions.has("ManageGuild"))
throw new Error("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 b3eb11a..cceadae 100644
--- a/src/commands/settings/verify.ts
+++ b/src/commands/settings/verify.ts
@@ -30,6 +30,7 @@
);
const callback = async (interaction: CommandInteraction): Promise<unknown> => {
+ if (!interaction.guild) return;
const m = (await interaction.reply({
embeds: LoadingEmbed,
ephemeral: true,
@@ -51,7 +52,7 @@
});
}
role = role as Discord.Role;
- if (role.guild.id !== interaction.guild!.id) {
+ if (role.guild.id !== interaction.guild.id) {
return interaction.editReply({
embeds: [
new EmojiEmbed()
@@ -72,7 +73,7 @@
if (confirmation.cancelled) return;
if (confirmation.success) {
try {
- await client.database.guilds.write(interaction.guild!.id, {
+ await client.database.guilds.write(interaction.guild.id, {
"verify.role": role.id,
"verify.enabled": true
});
@@ -92,7 +93,7 @@
role: entry(role.id, renderRole(role))
},
hidden: {
- guild: interaction.guild!.id
+ guild: interaction.guild.id
}
};
log(data);
@@ -123,7 +124,7 @@
}
}
let clicks = 0;
- const data = await client.database.guilds.read(interaction.guild!.id);
+ const data = await client.database.guilds.read(interaction.guild.id);
let role = data.verify.role;
let timedOut = false;
@@ -166,7 +167,7 @@
clicks += 1;
if (clicks === 2) {
clicks = 0;
- await client.database.guilds.write(interaction.guild!.id, null, ["verify.role", "verify.enabled"]);
+ await client.database.guilds.write(interaction.guild.id, null, ["verify.role", "verify.enabled"]);
role = undefined;
}
} else if ((i.component as Component).customId === "send") {
@@ -379,7 +380,7 @@
const check = (interaction: CommandInteraction) => {
const member = interaction.member as Discord.GuildMember;
- if (!member.permissions.has("MANAGE_GUILD"))
+ if (!member.permissions.has("ManageGuild"))
throw new Error("You must have the *Manage Server* permission to use this command");
return true;
};
diff --git a/src/config/format.ts b/src/config/format.ts
index ddd164e..53aba72 100644
--- a/src/config/format.ts
+++ b/src/config/format.ts
@@ -11,6 +11,8 @@
owners: [],
commandsFolder: "Your built commands folder (usually dist/commands)",
eventsFolder: "Your built events folder (usually dist/events)",
+ messageContextFolder: "Your built message context folder (usually dist/context/messages)",
+ userContextFolder: "Your built user context folder (usually dist/context/users)",
verifySecret:
"If using verify, enter a code here which matches the secret sent back by your website. You can use a random code if you do not have one already. (Optional)",
mongoUrl: "Your Mongo connection string, e.g. mongodb://127.0.0.1:27017",
diff --git a/src/utils/commandRegistration/register.ts b/src/utils/commandRegistration/register.ts
index 64f6e77..d1b58f1 100644
--- a/src/utils/commandRegistration/register.ts
+++ b/src/utils/commandRegistration/register.ts
@@ -1,4 +1,5 @@
-import { Interaction, SlashCommandBuilder } from 'discord.js';
+import { typeSlashCommandSubcommandBuilder } from '@discordjs/builders';
+import { Interaction, SlashCommandBuilder, ApplicationCommandType } from 'discord.js';
// @ts-expect-error
import config from "../../config/main.json" assert { type: "json" };
import client from "../client.js";
@@ -88,8 +89,64 @@
console.log(`Loaded ${files.length - errors} events (${errors} failed)`)
};
+async function registerContextMenus() {
+ console.log("Reading context menus")
+ const messageFiles = fs.readdirSync(config.messageContextFolder, { withFileTypes: true }).filter(
+ file => !file.name.endsWith(".ts") && !file.name.endsWith(".map")
+ );
+ const userFiles = fs.readdirSync(config.userContextFolder, { withFileTypes: true }).filter(
+ file => !file.name.endsWith(".ts") && !file.name.endsWith(".map")
+ );
+ console.log(`Registering ${messageFiles.length} message context menus and ${userFiles.length} user context menus`)
+ let i = 0;
+ let errors = 0;
+ for (const file of messageFiles) {
+ const last = i === messageFiles.length - 1 ? "└" : "├";
+ i++;
+ try {
+ console.log(`${last}─ ${colours.yellow}Loading message context menu ${file.name}${colours.none}`)
+ const context = (await import(`../../../${config.messageContextFolder}/${file.name}`));
+ context.command.setType(ApplicationCommandType.Message);
+
+ client.commands["contextCommands/message/" + file.name.replace(".js", "")] = context;
+
+ console.log(`${last.replace("└", " ").replace("├", "│")} └─ ${colours.green}Loaded ${file.name} [${i} / ${messageFiles.length}]${colours.none}`)
+ } catch (e) {
+ errors++;
+ console.log(`${last.replace("└", " ").replace("├", "│")} └─ ${colours.red}Failed to load ${file.name} [${i} / ${messageFiles.length}]${colours.none}`)
+ }
+ }
+ for (const file of userFiles) {
+ const last = i === userFiles.length - 1 ? "└" : "├";
+ i++;
+ try {
+ console.log(`${last}─ ${colours.yellow}Loading user context menu ${file.name}${colours.none}`)
+ const context = (await import(`../../../${config.userContextFolder}/${file.name}`));
+ context.command.setType(ApplicationCommandType.User);
+
+ client.commands["contextCommands/user/" + file.name.replace(".js", "")] = context;
+
+ console.log(`${last.replace("└", " ").replace("├", "│")} └─ ${colours.green}Loaded ${file.name} [${i} / ${userFiles.length}]${colours.none}`)
+ } catch (e) {
+ errors++;
+ console.log(`${last.replace("└", " ").replace("├", "│")} └─ ${colours.red}Failed to load ${file.name} [${i} / ${userFiles.length}]${colours.none}`)
+ }
+ }
+
+ console.log(`Loaded ${messageFiles.length + userFiles.length - errors} context menus (${errors} failed)`)
+};
+
async function registerCommandHandler() {
client.on("interactionCreate", async (interaction: Interaction) => {
+ if (interaction.isUserContextMenuCommand()) {;
+ const commandName = interaction.commandName;
+ console.log(commandName);
+ return;
+ } else if (interaction.isMessageContextMenuCommand()) {
+ const commandName = interaction.commandName;
+ console.log(commandName);
+ return;
+ }
if (!interaction.isChatInputCommand()) return;
const commandName = interaction.commandName;
@@ -118,7 +175,8 @@
}
export default async function register() {
- await registerCommands();
+ let commandList: (SlashCommandBuilder | SlashCommandSubcommandBuilder)[] = []
+ commandList.concat(await registerCommands());
await registerCommandHandler();
await registerEvents();
console.log(`${colours.green}Registered commands and events${colours.none}`)