Command registration (for mini)
diff --git a/package.json b/package.json
index d4a4025..affb107 100644
--- a/package.json
+++ b/package.json
@@ -19,6 +19,7 @@
"immutable": "^4.1.0",
"mongodb": "^4.7.0",
"node-cron": "^3.0.0",
+ "node-fetch": "^3.3.0",
"node-tesseract-ocr": "^2.2.1",
"pastebin-api": "^5.1.1",
"structured-clone": "^0.2.2",
diff --git a/src/commands/help.ts b/src/commands/help.ts
index 4295f9c..e85cf6b 100644
--- a/src/commands/help.ts
+++ b/src/commands/help.ts
@@ -1,7 +1,9 @@
-import { CommandInteraction } from "discord.js";
+import type { CommandInteraction } from "discord.js";
import { SlashCommandBuilder } from "@discordjs/builders";
-const command = new SlashCommandBuilder().setName("help").setDescription("Shows help for commands");
+const command = new SlashCommandBuilder()
+ .setName("help")
+ .setDescription("Shows help for commands");
const callback = async (interaction: CommandInteraction): Promise<void> => {
interaction.reply("hel p D:"); // TODO: FINISH THIS FOR RELEASE
diff --git a/src/commands/verify.ts b/src/commands/verify.ts
index b9556a6..bf6a306 100644
--- a/src/commands/verify.ts
+++ b/src/commands/verify.ts
@@ -5,6 +5,7 @@
const command = new SlashCommandBuilder().setName("verify").setDescription("Get verified in the server");
const callback = async (interaction: CommandInteraction): Promise<void> => {
+ interaction.reply("boo")
verify(interaction);
};
diff --git a/src/config/default.json b/src/config/default.json
index 7f2fdbd..824f12c 100644
--- a/src/config/default.json
+++ b/src/config/default.json
@@ -50,6 +50,7 @@
}
},
"verify": {
+ "enabled": false,
"role": null
},
"tickets": {
diff --git a/src/events/channelCreate.ts b/src/events/channelCreate.ts
index f3a4785..b3cba33 100644
--- a/src/events/channelCreate.ts
+++ b/src/events/channelCreate.ts
@@ -1,6 +1,6 @@
import type { GuildAuditLogsEntry } from "discord.js";
import type { GuildBasedChannel } from "discord.js";
-import type { HaikuClient } from "../utils/haiku/index.js";
+import type { NucleusClient } from "../utils/client.js";
export const event = "channelCreate";
export async function callback(client: NucleusClient, channel: GuildBasedChannel) {
diff --git a/src/events/channelDelete.ts b/src/events/channelDelete.ts
index d92c994..2c48b02 100644
--- a/src/events/channelDelete.ts
+++ b/src/events/channelDelete.ts
@@ -6,12 +6,12 @@
ThreadChannel,
VoiceChannel
} from "discord.js";
-import type { HaikuClient } from "../utils/haiku/index.js";
+import type { NucleusClient } from "../utils/client.js";
import getEmojiByName from "../utils/getEmojiByName.js";
export const event = "channelDelete";
-export async function callback(client: HaikuClient, channel: GuildBasedChannel) {
+export async function callback(client: NucleusClient, channel: GuildBasedChannel) {
const { getAuditLog, log, NucleusColors, entry, renderDelta, renderUser } = client.logger;
const auditLog = await getAuditLog(channel.guild, "CHANNEL_DELETE");
diff --git a/src/events/guildBanAdd.ts b/src/events/guildBanAdd.ts
index d1649a3..5fd0b49 100644
--- a/src/events/guildBanAdd.ts
+++ b/src/events/guildBanAdd.ts
@@ -1,11 +1,11 @@
import type { GuildAuditLogsEntry, GuildBan } from "discord.js";
import { purgeByUser } from "../actions/tickets/delete.js";
import { callback as statsChannelRemove } from "../reflex/statsChannelUpdate.js";
-import type { HaikuClient } from "../utils/haiku/index.js";
+import type { NucleusClient } from "../utils/client.js";
export const event = "guildBanAdd";
-export async function callback(client: HaikuClient, ban: GuildBan) {
+export async function callback(client: NucleusClient, ban: GuildBan) {
await statsChannelRemove(client, undefined, ban.guild, ban.user);
purgeByUser(ban.user.id, ban.guild);
const { log, NucleusColors, entry, renderUser, renderDelta, getAuditLog } = client.logger;
diff --git a/src/events/guildBanRemove.ts b/src/events/guildBanRemove.ts
index 2c3fc7b..f9b427a 100644
--- a/src/events/guildBanRemove.ts
+++ b/src/events/guildBanRemove.ts
@@ -1,10 +1,10 @@
import type { GuildAuditLogsEntry, GuildBan } from "discord.js";
import { purgeByUser } from "../actions/tickets/delete.js";
-import type { HaikuClient } from "../utils/haiku/index.js";
+import type { NucleusClient } from "../utils/client.js";
export const event = "guildBanRemove";
-export async function callback(client: HaikuClient, ban: GuildBan) {
+export async function callback(client: NucleusClient, ban: GuildBan) {
purgeByUser(ban.user.id, ban.guild);
const { log, NucleusColors, entry, renderUser, renderDelta, getAuditLog } = client.logger;
const auditLog = await getAuditLog(ban.guild, "MEMBER_BAN_REMOVE");
diff --git a/src/events/guildCreate.ts b/src/events/guildCreate.ts
index b1adbaa..ff6c6b2 100644
--- a/src/events/guildCreate.ts
+++ b/src/events/guildCreate.ts
@@ -1,9 +1,9 @@
import type { Guild } from "discord.js";
-import type { HaikuClient } from "../utils/haiku/index.js";
+import type { NucleusClient } from "../utils/client.js";
import guide from "../reflex/guide.js";
export const event = "guildCreate";
-export async function callback(_client: HaikuClient, guild: Guild) {
+export async function callback(_client: NucleusClient, guild: Guild) {
guide(guild);
}
diff --git a/src/events/guildMemberUpdate.ts b/src/events/guildMemberUpdate.ts
index 543d6ff..0ebfc3d 100644
--- a/src/events/guildMemberUpdate.ts
+++ b/src/events/guildMemberUpdate.ts
@@ -1,9 +1,9 @@
import type { GuildAuditLogsEntry, GuildMember } from "discord.js";
-import type { HaikuClient } from "../utils/haiku/index.js";
+import type { NucleusClient } from "../utils/client.js";
export const event = "guildMemberUpdate";
-export async function callback(client: HaikuClient, before: GuildMember, after: GuildMember) {
+export async function callback(client: NucleusClient, before: GuildMember, after: GuildMember) {
try {
const { log, NucleusColors, entry, renderUser, renderDelta, getAuditLog } = client.logger;
const auditLog = await getAuditLog(after.guild, "MEMBER_UPDATE");
diff --git a/src/events/guildUpdate.ts b/src/events/guildUpdate.ts
index 703b2d9..e463007 100644
--- a/src/events/guildUpdate.ts
+++ b/src/events/guildUpdate.ts
@@ -1,10 +1,10 @@
-import type { HaikuClient } from "../utils/haiku/index.js";
+import type { NucleusClient } from "../utils/client.js";
import type { Guild, GuildAuditLogsEntry } from "discord.js";
import { callback as statsChannelUpdate } from "../reflex/statsChannelUpdate.js";
export const event = "guildUpdate";
-export async function callback(client: HaikuClient, before: Guild, after: Guild) {
+export async function callback(client: NucleusClient, before: Guild, after: Guild) {
await statsChannelUpdate(client, after.me!);
const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta } = client.logger;
const auditLog = await getAuditLog(after, "GUILD_UPDATE");
diff --git a/src/events/interactionCreate.ts b/src/events/interactionCreate.ts
index 4feee82..ddc143b 100644
--- a/src/events/interactionCreate.ts
+++ b/src/events/interactionCreate.ts
@@ -6,7 +6,7 @@
import Fuse from "fuse.js";
import { autocomplete as tagAutocomplete } from "../commands/tag.js";
import type { AutocompleteInteraction, Interaction, MessageComponentInteraction } from "discord.js";
-import type { HaikuClient } from "../utils/haiku/index.js";
+import type { NucleusClient } from "../utils/client.js";
export const event = "interactionCreate";
@@ -102,6 +102,6 @@
}
}
-export async function callback(_client: HaikuClient, interaction: Interaction) {
+export async function callback(_client: NucleusClient, interaction: Interaction) {
await interactionCreate(interaction);
}
diff --git a/src/events/inviteCreate.ts b/src/events/inviteCreate.ts
index 76dfc1e..7dbf8a7 100644
--- a/src/events/inviteCreate.ts
+++ b/src/events/inviteCreate.ts
@@ -1,11 +1,11 @@
import type { GuildAuditLogsEntry, Invite } from "discord.js";
// @ts-expect-error
import humanizeDuration from "humanize-duration";
-import type { HaikuClient } from "../utils/haiku/index.js";
+import type { NucleusClient } from "../utils/client.js";
export const event = "inviteCreate";
-export async function callback(client: HaikuClient, invite: Invite) {
+export async function callback(client: NucleusClient, invite: Invite) {
const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta, renderChannel } = client.logger;
const auditLog = await getAuditLog(invite.guild, "INVITE_CREATE");
const audit = auditLog.entries
diff --git a/src/events/inviteDelete.ts b/src/events/inviteDelete.ts
index cdc6828..e74ad15 100644
--- a/src/events/inviteDelete.ts
+++ b/src/events/inviteDelete.ts
@@ -1,11 +1,11 @@
import type { GuildAuditLogsEntry, Invite } from "discord.js";
// @ts-expect-error
import humanizeDuration from "humanize-duration";
-import type { HaikuClient } from "../utils/haiku/index.js";
+import type { NucleusClient } from "../utils/client.js";
export const event = "inviteDelete";
-export async function callback(client: HaikuClient, invite: Invite) {
+export async function callback(client: NucleusClient, invite: Invite) {
const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta, renderChannel } = client.logger;
const auditLog = await getAuditLog(invite.guild, "INVITE_DELETE");
const audit = auditLog.entries
diff --git a/src/events/memberJoin.ts b/src/events/memberJoin.ts
index 95dfde2..93c9186 100644
--- a/src/events/memberJoin.ts
+++ b/src/events/memberJoin.ts
@@ -1,11 +1,11 @@
import type { GuildMember } from "discord.js";
import { callback as statsChannelAdd } from "../reflex/statsChannelUpdate.js";
import { callback as welcome } from "../reflex/welcome.js";
-import type { HaikuClient } from "../utils/haiku/index.js";
+import type { NucleusClient } from "../utils/client.js";
export const event = "guildMemberAdd";
-export async function callback(client: HaikuClient, member: GuildMember) {
+export async function callback(client: NucleusClient, member: GuildMember) {
welcome(client, member);
statsChannelAdd(client, member);
const { log, NucleusColors, entry, renderUser, renderDelta } = client.logger;
diff --git a/src/events/memberLeave.ts b/src/events/memberLeave.ts
index 8fa0c76..4731d58 100644
--- a/src/events/memberLeave.ts
+++ b/src/events/memberLeave.ts
@@ -1,12 +1,12 @@
import type { GuildAuditLogsEntry, GuildMember } from "discord.js";
-import type { HaikuClient } from "../utils/haiku/index.js";
+import type { NucleusClient } from "../utils/client.js";
import { purgeByUser } from "../actions/tickets/delete.js";
import { callback as statsChannelRemove } from "../reflex/statsChannelUpdate.js";
export const event = "guildMemberRemove";
-export async function callback(client: HaikuClient, member: GuildMember) {
+export async function callback(client: NucleusClient, member: GuildMember) {
purgeByUser(member.id, member.guild);
await statsChannelRemove(client, member);
const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta } = client.logger;
diff --git a/src/events/messageCreate.ts b/src/events/messageCreate.ts
index 76b6855..3f85de6 100644
--- a/src/events/messageCreate.ts
+++ b/src/events/messageCreate.ts
@@ -1,4 +1,4 @@
-import type { HaikuClient } from "../utils/haiku/index.js";
+import type { NucleusClient } from "../utils/client.js";
import { LinkCheck, MalwareCheck, NSFWCheck, SizeCheck, TestString, TestImage } from "../reflex/scanners.js";
import logAttachment from "../premium/attachmentLogs.js";
import createLogException from "../utils/createLogException.js";
@@ -9,7 +9,7 @@
export const event = "messageCreate";
-export async function callback(_client: HaikuClient, message: Message) {
+export async function callback(_client: NucleusClient, message: Message) {
if (!message.guild) return;
if (message.author.bot) return;
if (message.channel.type === "DM") return;
diff --git a/src/events/messageDelete.ts b/src/events/messageDelete.ts
index bc668f1..ddeff96 100644
--- a/src/events/messageDelete.ts
+++ b/src/events/messageDelete.ts
@@ -1,9 +1,9 @@
-import type { HaikuClient } from "../utils/haiku/index.js";
+import type { NucleusClient } from "../utils/client.js";
import type { GuildAuditLogsEntry, Message } from "discord.js";
export const event = "messageDelete";
-export async function callback(client: HaikuClient, message: Message) {
+export async function callback(client: NucleusClient, message: Message) {
try {
if (message.author.id === client.user.id) return;
if (client.noLog.includes(`${message.id}/${message.channel.id}/${message.id}`)) return;
diff --git a/src/events/messageEdit.ts b/src/events/messageEdit.ts
index 4c482cc..37178a7 100644
--- a/src/events/messageEdit.ts
+++ b/src/events/messageEdit.ts
@@ -1,9 +1,9 @@
-import type { HaikuClient } from "../utils/haiku/index.js";
+import type { NucleusClient } from "../utils/client.js";
import type { Message, MessageReference } from "discord.js";
export const event = "messageUpdate";
-export async function callback(client: HaikuClient, oldMessage: Message, newMessage: Message) {
+export async function callback(client: NucleusClient, oldMessage: Message, newMessage: Message) {
if (newMessage.author.id === client.user.id) return;
if (!newMessage.guild) return;
const { log, NucleusColors, entry, renderUser, renderDelta, renderNumberDelta, renderChannel } = client.logger;
diff --git a/src/events/roleCreate.ts b/src/events/roleCreate.ts
index c8a32b1..25e9c98 100644
--- a/src/events/roleCreate.ts
+++ b/src/events/roleCreate.ts
@@ -1,9 +1,9 @@
-import type { HaikuClient } from "../utils/haiku/index.js";
+import type { NucleusClient } from "../utils/client.js";
import type { GuildAuditLogsEntry, Role } from "discord.js";
export const event = "roleCreate";
-export async function callback(client: HaikuClient, role: Role) {
+export async function callback(client: NucleusClient, role: Role) {
const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta, renderRole } = client.logger;
if (role.managed) return;
const auditLog = await getAuditLog(role.guild, "ROLE_CREATE");
diff --git a/src/events/roleDelete.ts b/src/events/roleDelete.ts
index 1f71f25..4c89565 100644
--- a/src/events/roleDelete.ts
+++ b/src/events/roleDelete.ts
@@ -1,10 +1,10 @@
import getEmojiByName from "../utils/getEmojiByName.js";
-import type { HaikuClient } from "../utils/haiku/index.js";
+import type { NucleusClient } from "../utils/client.js";
import type { GuildAuditLogsEntry, Role } from "discord.js";
export const event = "roleDelete";
-export async function callback(client: HaikuClient, role: Role) {
+export async function callback(client: NucleusClient, role: Role) {
const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta } = client.logger;
if (role.managed) return;
const auditLog = await getAuditLog(role.guild, "ROLE_DELETE");
diff --git a/src/events/roleUpdate.ts b/src/events/roleUpdate.ts
index 357a22f..fc26d6c 100644
--- a/src/events/roleUpdate.ts
+++ b/src/events/roleUpdate.ts
@@ -1,10 +1,10 @@
import type { Role } from "discord.js";
-import type { HaikuClient } from "../utils/haiku/index.js";
+import type { NucleusClient } from "../utils/client.js";
import getEmojiByName from "../utils/getEmojiByName.js";
export const event = "roleUpdate";
-export async function callback(client: HaikuClient, or: Role, nr: Role) {
+export async function callback(client: NucleusClient, or: Role, nr: Role) {
const { getAuditLog, log, NucleusColors, entry, renderDelta, renderUser, renderRole } = client.logger;
const auditLog = await getAuditLog(nr.guild, "ROLE_UPDATE");
diff --git a/src/events/stickerCreate.ts b/src/events/stickerCreate.ts
index b7a417c..295d48b 100644
--- a/src/events/stickerCreate.ts
+++ b/src/events/stickerCreate.ts
@@ -1,9 +1,9 @@
-import type { HaikuClient } from "../utils/haiku/index.js";
+import type { NucleusClient } from "../utils/client.js";
import type { GuildAuditLogsEntry, Sticker } from "discord.js";
export const event = "stickerDelete";
-export async function callback(client: HaikuClient, emoji: Sticker) {
+export async function callback(client: NucleusClient, emoji: Sticker) {
const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta } = client.logger;
const auditLog = await getAuditLog(emoji.guild, "STICKER_CREATE");
const audit = auditLog.entries.filter((entry: GuildAuditLogsEntry) => entry.target!.id === emoji.id).first();
diff --git a/src/events/stickerDelete.ts b/src/events/stickerDelete.ts
index 8130d8a..fed99e6 100644
--- a/src/events/stickerDelete.ts
+++ b/src/events/stickerDelete.ts
@@ -1,9 +1,9 @@
-import type { HaikuClient } from "../utils/haiku/index.js";
+import type { NucleusClient } from "../utils/client.js";
import type { GuildAuditLogsEntry, Sticker } from "discord.js";
export const event = "stickerDelete";
-export async function callback(client: HaikuClient, emoji: Sticker) {
+export async function callback(client: NucleusClient, emoji: Sticker) {
const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta } = client.logger;
const auditLog = await getAuditLog(emoji.guild, "STICKER_DELETE");
const audit = auditLog.entries.filter((entry: GuildAuditLogsEntry) => entry.target!.id === emoji.id).first();
diff --git a/src/events/stickerUpdate.ts b/src/events/stickerUpdate.ts
index 1421ec2..0ac000e 100644
--- a/src/events/stickerUpdate.ts
+++ b/src/events/stickerUpdate.ts
@@ -1,9 +1,9 @@
-import type { HaikuClient } from "../utils/haiku/index.js";
+import type { NucleusClient } from "../utils/client.js";
import type { Sticker } from "discord.js";
export const event = "stickerUpdate";
-export async function callback(client: HaikuClient, oe: Sticker, ne: Sticker) {
+export async function callback(client: NucleusClient, oe: Sticker, ne: Sticker) {
const { getAuditLog, log, NucleusColors, entry, renderDelta, renderUser } = client.logger;
if (oe.name === ne.name) return;
diff --git a/src/events/threadCreate.ts b/src/events/threadCreate.ts
index f0f32e5..1f1b758 100644
--- a/src/events/threadCreate.ts
+++ b/src/events/threadCreate.ts
@@ -1,10 +1,10 @@
import type { GuildAuditLogsEntry, ThreadChannel } from "discord.js";
// @ts-expect-error
import humanizeDuration from "humanize-duration";
-import type { HaikuClient } from "../utils/haiku/index.js";
+import type { NucleusClient } from "../utils/client.js";
export const event = "threadCreate";
-export async function callback(client: HaikuClient, thread: ThreadChannel) {
+export async function callback(client: NucleusClient, thread: ThreadChannel) {
const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta, renderChannel } = client.logger;
const auditLog = await getAuditLog(thread.guild, "THREAD_CREATE");
const audit = auditLog.entries.filter((entry: GuildAuditLogsEntry) => entry.target!.id === thread.id).first();
diff --git a/src/events/threadDelete.ts b/src/events/threadDelete.ts
index c166f86..cdc89ee 100644
--- a/src/events/threadDelete.ts
+++ b/src/events/threadDelete.ts
@@ -1,10 +1,10 @@
import type { GuildAuditLogsEntry, ThreadChannel } from "discord.js";
// @ts-expect-error
import humanizeDuration from "humanize-duration";
-import type { HaikuClient } from "../utils/haiku/index.js";
+import type { NucleusClient } from "../utils/client.js";
export const event = "threadDelete";
-export async function callback(client: HaikuClient, thread: ThreadChannel) {
+export async function callback(client: NucleusClient, thread: ThreadChannel) {
const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta, renderChannel } = client.logger;
const auditLog = await getAuditLog(thread.guild, "THREAD_UPDATE");
const audit = auditLog.entries.filter((entry: GuildAuditLogsEntry) => entry.target!.id === thread.id).first();
diff --git a/src/events/threadUpdate.ts b/src/events/threadUpdate.ts
index 20247d6..9125fcb 100644
--- a/src/events/threadUpdate.ts
+++ b/src/events/threadUpdate.ts
@@ -1,11 +1,11 @@
import type { GuildAuditLogsEntry, ThreadChannel } from "discord.js";
// @ts-expect-error
import humanizeDuration from "humanize-duration";
-import type { HaikuClient } from "../utils/haiku/index.js";
+import type { NucleusClient } from "../utils/client.js";
export const event = "threadUpdate";
-export async function callback(client: HaikuClient, before: ThreadChannel, after: ThreadChannel) {
+export async function callback(client: NucleusClient, before: ThreadChannel, after: ThreadChannel) {
const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta, renderChannel } = client.logger;
const auditLog = await getAuditLog(after.guild, "THREAD_UPDATE");
const audit = auditLog.entries.filter((entry: GuildAuditLogsEntry) => entry.target!.id === after.id).first();
diff --git a/src/events/webhookUpdate.ts b/src/events/webhookUpdate.ts
index e4e9659..a991c66 100644
--- a/src/events/webhookUpdate.ts
+++ b/src/events/webhookUpdate.ts
@@ -1,9 +1,9 @@
import type { GuildAuditLogsEntry, Webhook } from "discord.js";
import type Discord from "discord.js";
-import type { HaikuClient } from "../utils/haiku/index.js";
+import type { NucleusClient } from "../utils/client.js";
export const event = "webhookUpdate";
-export async function callback(client: HaikuClient, channel: Discord.GuildChannel) {
+export async function callback(client: NucleusClient, channel: Discord.GuildChannel) {
try {
const { getAuditLog, log, NucleusColors, entry, renderUser, renderChannel, renderDelta } = client.logger;
let auditLogCreate = getAuditLog(channel.guild, "WEBHOOK_CREATE");
diff --git a/src/premium/createTranscript.ts b/src/premium/createTranscript.ts
index f2358d8..6805017 100644
--- a/src/premium/createTranscript.ts
+++ b/src/premium/createTranscript.ts
@@ -11,10 +11,9 @@
import EmojiEmbed from "../utils/generateEmojiEmbed.js";
import getEmojiByName from "../utils/getEmojiByName.js";
import { PasteClient, Publicity, ExpireDate } from "pastebin-api";
-import config from "../config/main.json" assert { type: "json" };
import client from "../utils/client.js";
-const pbClient = new PasteClient(config.pastebinApiKey);
+const pbClient = new PasteClient(client.config.pastebinApiKey);
export default async function (interaction: CommandInteraction | MessageComponentInteraction) {
if (interaction.channel === null) return;
diff --git a/src/reflex/statsChannelUpdate.ts b/src/reflex/statsChannelUpdate.ts
index cd1c8ef..d807267 100644
--- a/src/reflex/statsChannelUpdate.ts
+++ b/src/reflex/statsChannelUpdate.ts
@@ -1,5 +1,5 @@
import type { Guild, User } from "discord.js";
-import type { HaikuClient } from "../utils/haiku/index.js";
+import type { NucleusClient } from "../utils/client.js";
import type { GuildMember } from "discord.js";
import convertCurlyBracketString from "../utils/convertCurlyBracketString.js";
import singleNotify from "../utils/singleNotify.js";
@@ -9,7 +9,7 @@
name: string;
}
-export async function callback(client: HaikuClient, member?: GuildMember, guild?: Guild, user?: User) {
+export async function callback(client: NucleusClient, member?: GuildMember, guild?: Guild, user?: User) {
if (!member && !guild) return;
guild = await client.guilds.fetch(member ? member.guild.id : guild!.id);
if (!guild) return;
diff --git a/src/reflex/verify.ts b/src/reflex/verify.ts
index bbb0992..6458439 100644
--- a/src/reflex/verify.ts
+++ b/src/reflex/verify.ts
@@ -2,11 +2,10 @@
import Discord, {
CommandInteraction,
GuildMember,
- Interaction,
MessageComponentInteraction,
- Permissions,
Role,
- ButtonStyle
+ ButtonStyle,
+ PermissionsBitField
} from "discord.js";
import EmojiEmbed from "../utils/generateEmojiEmbed.js";
import fetch from "node-fetch";
@@ -22,7 +21,7 @@
uName: string;
gName: string;
gIcon: string;
- interaction: Interaction;
+ interaction: Discord.MessageComponentInteraction;
}
function step(i: number) {
@@ -44,7 +43,7 @@
.setTitle("Verify")
.setDescription("Verify is not enabled on this server")
.setFooter({
- text: (interaction.member!.permissions as Permissions).has("MANAGE_GUILD")
+ text: (interaction.member!.permissions as PermissionsBitField).has("ManageGuild")
? "You can enable it by running /settings verify"
: ""
})
@@ -95,7 +94,7 @@
.setEmoji("CONTROL.BLOCKCROSS")
],
components: [
- new Discord.ActionRowBuilder().addComponents([
+ new Discord.ActionRowBuilder<Discord.ButtonBuilder>().addComponents([
new Discord.ButtonBuilder()
.setLabel("Check webpage")
.setStyle(ButtonStyle.Link)
@@ -120,9 +119,7 @@
});
if (
await NSFWCheck(
- (interaction.member as GuildMember).user.displayAvatarURL({
- format: "png"
- })
+ (interaction.member as GuildMember).user.displayAvatarURL({extension: "png", forceStatic: true})
)
) {
return await interaction.editReply({
@@ -139,7 +136,7 @@
});
}
}
- if (config.filters.wordFilter) {
+ if (config.filters.wordFilter.enabled) {
await interaction.editReply({
embeds: [
new EmojiEmbed()
@@ -217,8 +214,8 @@
rName: role.name,
uName: interaction.member!.user.username,
gName: interaction.guild!.name,
- gIcon: interaction.guild!.iconURL({ format: "png" }),
- interaction: interaction
+ gIcon: interaction.guild!.iconURL({ extension: "png", size: 256 }) ?? "https://assets-global.website-files.com/6257adef93867e50d84d30e2/636e0a6a49cf127bf92de1e2_icon_clyde_blurple_RGB.png",
+ interaction: interaction as MessageComponentInteraction
};
await interaction.editReply({
embeds: [
@@ -229,7 +226,7 @@
.setEmoji("MEMBER.JOIN")
],
components: [
- new Discord.ActionRowBuilder().addComponents([
+ new Discord.ActionRowBuilder<Discord.ButtonBuilder>().addComponents([
new Discord.ButtonBuilder()
.setLabel("Verify")
.setStyle(ButtonStyle.Link)
diff --git a/src/reflex/welcome.ts b/src/reflex/welcome.ts
index 241185d..47ed140 100644
--- a/src/reflex/welcome.ts
+++ b/src/reflex/welcome.ts
@@ -1,10 +1,10 @@
-import type { HaikuClient } from "../utils/haiku/index.js";
+import type { NucleusClient } from "../utils/client.js";
import convertCurlyBracketString from "../utils/convertCurlyBracketString.js";
import client from "../utils/client.js";
import EmojiEmbed from "../utils/generateEmojiEmbed.js";
import { GuildChannel, GuildMember, BaseGuildTextChannel } from "discord.js";
-export async function callback(_client: HaikuClient, member: GuildMember) {
+export async function callback(_client: NucleusClient, member: GuildMember) {
if (member.user.bot) return;
const config = await client.database.guilds.read(member.guild.id);
if (!config.welcome.enabled) return;
diff --git a/src/utils/client.ts b/src/utils/client.ts
index 7d608c7..6aa9b43 100644
--- a/src/utils/client.ts
+++ b/src/utils/client.ts
@@ -1,14 +1,16 @@
-import { Client } from 'discord.js';
+import Discord, { Client, Interaction } from 'discord.js';
import { Logger } from "../utils/log.js";
import Memory from "../utils/memory.js";
import type { VerifySchema } from "../reflex/verify.js";
import { Guilds, History, ModNotes, Premium } from "../utils/database.js";
import EventScheduler from "../utils/eventScheduler.js";
import type { RoleMenuSchema } from "../actions/roleMenu.js";
+import config from "../config/main.json" assert { type: "json" };
class NucleusClient extends Client {
logger = Logger;
+ config: typeof config = config;
verify: Record<string, VerifySchema> = {};
roleMenu: Record<string, RoleMenuSchema> = {};
memory: Memory = new Memory() as Memory;
@@ -20,6 +22,14 @@
premium: Premium;
eventScheduler: EventScheduler;
};
+ // commands: Record<string, {
+ // command: Discord.SlashCommandBuilder |
+ // ((builder: Discord.SlashCommandBuilder) => Discord.SlashCommandBuilder) |
+ // Discord.SlashCommandSubcommandBuilder | ((builder: Discord.SlashCommandSubcommandBuilder) => Discord.SlashCommandSubcommandBuilder) | Discord.SlashCommandSubcommandGroupBuilder | ((builder: Discord.SlashCommandSubcommandGroupBuilder) => Discord.SlashCommandSubcommandGroupBuilder),
+ // callback: (interaction: Interaction) => Promise<void>,
+ // check: (interaction: Interaction) => Promise<boolean> | boolean
+ // }> = {};
+ commands: Discord.Collection<string, [Function, Function]> = new Discord.Collection();
constructor(database: typeof NucleusClient.prototype.database) {
super({ intents: 32767 });
diff --git a/src/utils/commandRegistration/getFilesInFolder.ts b/src/utils/commandRegistration/getFilesInFolder.ts
index a669065..d8a1298 100644
--- a/src/utils/commandRegistration/getFilesInFolder.ts
+++ b/src/utils/commandRegistration/getFilesInFolder.ts
@@ -1,23 +1,27 @@
import fs from "fs";
-export default async function getSubcommandsInFolder(path: string) {
+export default async function getSubcommandsInFolder(path: string, indent: string = "") {
const files = fs.readdirSync(path, { withFileTypes: true }).filter(
file => !file.name.endsWith(".ts") && !file.name.endsWith(".map")
);
const subcommands = [];
const subcommandGroups = [];
+ let errors = 0;
for (const file of files) {
if (file.name === "_meta.js") continue;
- // If its a folder
- if (file.isDirectory()) {
- // Get the _meta.ts file
- console.log(`│ ├─ Loading subcommand group ${file.name}}`)
- subcommandGroups.push((await import(`../../../${path}/${file.name}/_meta.js`)).command);
- } else if (file.name.endsWith(".js")) {
- // If its a file
- console.log(`│ ├─ Loading subcommand ${file.name}}`)
- subcommands.push((await import(`../../../${path}/${file.name}`)).command);
+ try {
+ if (file.isDirectory()) {
+ // Get the _meta.ts file
+ subcommandGroups.push((await import(`../../../${path}/${file.name}/_meta.js`)).command);
+ } else if (file.name.endsWith(".js")) {
+ // If its a file
+ console.log(`│ ${indent}├─ Loading subcommand ${file.name}`)
+ subcommands.push((await import(`../../../${path}/${file.name}`)).command);
+ }
+ } catch (e) {
+ console.error(`│ ${indent}│ └─ Error loading ${file.name}: ${e}`);
+ errors++;
}
}
- return {subcommands, subcommandGroups};
+ return {subcommands, subcommandGroups, errors};
}
diff --git a/src/utils/commandRegistration/register.ts b/src/utils/commandRegistration/register.ts
index af0b5fc..a734921 100644
--- a/src/utils/commandRegistration/register.ts
+++ b/src/utils/commandRegistration/register.ts
@@ -1,9 +1,16 @@
-import { SlashCommandBuilder } from 'discord.js';
+import { Interaction, SlashCommandBuilder } from 'discord.js';
import config from "../../config/main.json" assert { type: "json" };
import client from "../client.js";
import fs from "fs";
+const colours = {
+ red: "\x1b[31m",
+ green: "\x1b[32m",
+ yellow: "\x1b[33m",
+ none: "\x1b[0m"
+}
+
async function registerCommands() {
const developmentMode = config.enableDevelopment;
const commands = [];
@@ -14,15 +21,18 @@
console.log(`Registering ${files.length} commands`)
let i = 0;
for (const file of files) {
- // Box drawing characters: | └ ─ ┌ ┐ ┘ ┬ ┤ ├ ┴ ┼
- console.log(`├─ ${file.name}`)
+ const last = i === files.length - 1 ? "└" : "├";
if (file.isDirectory()) {
+ console.log(`${last}─ ${colours.yellow}Loading subcommands of ${file.name}${colours.none}`)
commands.push((await import(`../../../${config.commandsFolder}/${file.name}/_meta.js`)).command);
} else if (file.name.endsWith(".js")) {
- commands.push((await import(`../../../${config.commandsFolder}/${file.name}`)).command);
+ console.log(`${last}─ ${colours.yellow}Loading command ${file.name}${colours.none}`)
+ const fetched = (await import(`../../../${config.commandsFolder}/${file.name}`));
+ commands.push(fetched.command);
+ client.commands.set(fetched.command.name, [fetched.check, fetched.callback]);
}
i++;
- console.log(`├─ Loaded ${file.name} [${i} / ${files.length}]`)
+ console.log(`${last.replace("└", " ").replace("├", "│")} └─ ${colours.green}Loaded ${file.name} [${i} / ${files.length}]${colours.none}`)
}
console.log(`Loaded ${commands.length} commands, processing...`)
const processed = []
@@ -39,11 +49,9 @@
if (developmentMode) {
const guild = await client.guilds.fetch(config.developmentGuildID);
- guild.commands.set([])
guild.commands.set(processed);
console.log(`Commands registered in ${guild.name}`)
} else {
- client.application!.commands.set([])
client.application!.commands.set(processed);
console.log(`Commands registered globally`)
}
@@ -51,11 +59,83 @@
};
async function registerEvents() {
- // pass
+ console.log("Reading events")
+ const files = fs.readdirSync(config.eventsFolder, { withFileTypes: true }).filter(
+ file => !file.name.endsWith(".ts") && !file.name.endsWith(".map")
+ );
+ console.log(`Registering ${files.length} events`)
+ let i = 0;
+ let errors = 0;
+ for (const file of files) {
+ const last = i === files.length - 1 ? "└" : "├";
+ i++;
+ try {
+ console.log(`${last}─ ${colours.yellow}Loading event ${file.name}${colours.none}`)
+ const event = (await import(`../../../${config.eventsFolder}/${file.name}`));
+
+ client.on(event.event, event.callback.bind(null, client));
+
+ console.log(`${last.replace("└", " ").replace("├", "│")} └─ ${colours.green}Loaded ${file.name} [${i} / ${files.length}]${colours.none}`)
+ } catch (e) {
+ errors++;
+ console.log(`${last.replace("└", " ").replace("├", "│")} └─ ${colours.red}Failed to load ${file.name} [${i} / ${files.length}]${colours.none}`)
+ }
+ }
+ console.log(`Loaded ${files.length - errors} events (${errors} failed)`)
};
+async function registerCommandHandler() {
+ client.on("interactionCreate", async (interaction: Interaction) => {
+ if (!interaction.isCommand()) return;
+
+ const commandName = interaction.commandName;
+ const subcommandGroupName = interaction.options.getSubcommandGroup(false);
+ const subcommandName = interaction.options.getSubcommand(false);
+
+ let fullCommandName = commandName + (subcommandGroupName ? ` ${subcommandGroupName}` : "") + (subcommandName ? ` ${subcommandName}` : "");
+
+ const command = this.commands.get(fullCommandName);
+ if (!command) return;
+
+ const sendErrorMessage = async (error: Error) => {
+ if (this.listenerCount("commandError")) {
+ return this.emit("commandError", interaction, error);
+ }
+ let method = (!interaction.deferred && !interaction.replied) ? interaction.reply.bind(interaction) : interaction.followUp.bind(interaction);
+ await method({
+ embeds: [
+ new Embed()
+ .setColor(0xff0000)
+ .setTitle("I couldn't run that command")
+ .setDescription(error.message ?? error.toString())
+ ]
+ , ephemeral: true});
+ }
+
+ try {
+ let hasPermission = await command.check(interaction);
+
+ if (!hasPermission) {
+ sendErrorMessage(new CheckFailedError("You don't have permission to run this command"));
+ return;
+ }
+ } catch (error) {
+ sendErrorMessage(error);
+ return;
+ }
+ try {
+ await command.callback(interaction);
+ } catch (error) {
+ this._error(error);
+ sendErrorMessage(error);
+ return;
+ }
+ });
+}
+
export default async function register() {
- console.log("> Registering commands")
await registerCommands();
+ await registerCommandHandler();
await registerEvents();
+ console.log(`${colours.green}Registered commands and events${colours.none}`)
};
diff --git a/src/utils/commandRegistration/slashCommandBuilder.ts b/src/utils/commandRegistration/slashCommandBuilder.ts
index 719855f..c7ac55f 100644
--- a/src/utils/commandRegistration/slashCommandBuilder.ts
+++ b/src/utils/commandRegistration/slashCommandBuilder.ts
@@ -4,8 +4,17 @@
import getSubcommandsInFolder from "./getFilesInFolder.js";
+const colours = {
+ red: "\x1b[31m",
+ green: "\x1b[32m",
+ none: "\x1b[0m"
+}
+
+
export async function group(name: string, description: string, path: string) {
- const fetched = await getSubcommandsInFolder(config.commandsFolder + "/" + path)
+ console.log(`│ ├─ Loading group ${name}`)
+ const fetched = await getSubcommandsInFolder(config.commandsFolder + "/" + path, "│ ")
+ console.log(`│ │ └─ ${fetched.errors ? colours.red : colours.green}Loaded ${fetched.subcommands.length} subcommands for ${name} (${fetched.errors} failed)${colours.none}`)
return (subcommandGroup: SlashCommandSubcommandGroupBuilder) => {
subcommandGroup
.setName(name)
@@ -21,7 +30,7 @@
export async function command(name: string, description: string, path: string) {
const fetched = await getSubcommandsInFolder(config.commandsFolder + "/" + path);
- console.log(`│ ├─ Loaded ${fetched.subcommands.length} subcommands and ${fetched.subcommandGroups.length} subcommand groups for ${name}`)
+ console.log(`│ ├─ ${fetched.errors ? colours.red : colours.green}Loaded ${fetched.subcommands.length} subcommands and ${fetched.subcommandGroups.length} subcommand groups for ${name} (${fetched.errors} failed)${colours.none}`)
return (command: SlashCommandBuilder) => {
command.setName(name)
command.setDescription(description)