diff --git a/.cspell/custom-dictionary-workspace.txt b/.cspell/custom-dictionary-workspace.txt index 8afb368..b7c0890 100644 --- a/.cspell/custom-dictionary-workspace.txt +++ b/.cspell/custom-dictionary-workspace.txt @@ -11,6 +11,7 @@ inom inställningar inte Krediter +multistream Nivå omdöme Omdöme diff --git a/src/config/example.discord.ts b/src/config/example.discord.ts new file mode 100644 index 0000000..682ff99 --- /dev/null +++ b/src/config/example.discord.ts @@ -0,0 +1,5 @@ +// Discord API token +export const token = ""; + +// Discord API id +export const clientId = ""; diff --git a/src/config/example.embed.ts b/src/config/example.embed.ts new file mode 100644 index 0000000..d6eebb1 --- /dev/null +++ b/src/config/example.embed.ts @@ -0,0 +1,17 @@ +// Dependencies +import { ColorResolvable } from "discord.js"; + +// Color for successfully actions +export const successColor: ColorResolvable = "#22bb33"; + +// Color for waiting actions +export const waitColor: ColorResolvable = "#f0ad4e"; + +// Color for error actions +export const errorColor: ColorResolvable = "#bb2124"; + +// Footer text +export const footerText = "https://github.com/ZynerOrg/xyter"; + +// Footer icon +export const footerIcon = "https://github.com/ZynerOrg.png"; diff --git a/src/config/example.other.ts b/src/config/example.other.ts new file mode 100644 index 0000000..14199d1 --- /dev/null +++ b/src/config/example.other.ts @@ -0,0 +1,5 @@ +// Development features +export const devMode = false; + +// Development guild +export const guildId = ""; diff --git a/src/events/interactionCreate/isCommand.ts b/src/events/interactionCreate/isCommand.ts index 03e457d..bb28847 100644 --- a/src/events/interactionCreate/isCommand.ts +++ b/src/events/interactionCreate/isCommand.ts @@ -1,55 +1,58 @@ -import { ColorResolvable, CommandInteraction } from "discord.js"; -import config from "../../../config.json"; -import logger from "../../logger"; -import guilds from "../../database/schemas/guild"; +// Dependencies +import { CommandInteraction, MessageEmbed } from "discord.js"; -import tools from "../../tools"; +import logger from "@logger"; + +import * as embed from "@config/embed"; + +import guildSchema from "@schemas/guild"; export default async (interaction: CommandInteraction) => { if (!interaction.isCommand()) return; - const { client, guild } = interaction; + const { client, guild, commandName, user } = interaction; - // Get command from collection - const command = client.commands.get(interaction.commandName); + const currentCommand = client.commands.get(commandName); + if (!currentCommand) return; // If command do not exist - if (!command) return; // Create guild if it does not exist already - await guilds.findOne({ guildId: guild?.id }, { new: true, upsert: true }); + await guildSchema.findOne( + { guildId: guild?.id }, + { new: true, upsert: true } + ); // Defer reply await interaction.deferReply({ ephemeral: true }); - try { - // Execute command - await command.execute(interaction, tools); + await currentCommand + .execute(interaction) + .then(async () => { + return logger.debug( + `Guild: ${guild?.id} (${guild?.name}) User: ${user?.tag} executed ${commandName}` + ); + }) + .catch(async (error: any) => { + console.log(error); - const { commandName, user } = interaction; + logger.error( + `Guild: ${guild?.id} (${guild?.name}) User: ${user?.tag} There was an error executing the command: ${commandName}` + ); - return logger?.verbose( - `Guild: ${guild?.id} User: ${user?.tag} executed ${commandName}` - ); - } catch (e) { - // Send debug message - logger.error(e); + logger.error(error); - // Send interaction reply - await interaction.editReply({ - embeds: [ - { - author: { - name: client?.user?.username, - icon_url: client?.user?.displayAvatarURL(), - url: "https://bot.zyner.org/", - }, - title: "Error", - description: "There was an error while executing this command!", - color: config.colors.error as ColorResolvable, - timestamp: new Date(), - }, - ], + return interaction.editReply({ + embeds: [ + new MessageEmbed() + .setTitle("Error") + .setDescription( + `There was an error executing the command: **${currentCommand.data.name}**.` + ) + .setColor(embed.errorColor) + .setTimestamp(new Date()) + .setFooter({ text: embed.footerText, iconURL: embed.footerIcon }), + ], + }); }); - } }; diff --git a/src/events/messageUpdate/index.ts b/src/events/messageUpdate/index.ts index 2aafc9d..2a38a73 100644 --- a/src/events/messageUpdate/index.ts +++ b/src/events/messageUpdate/index.ts @@ -10,7 +10,7 @@ export default { async execute(oldMessage: Message, newMessage: Message) { const { author } = newMessage; - logger.silly({ oldMessage, newMessage }); + logger.debug({ oldMessage, newMessage }); if (author?.bot) return; diff --git a/src/events/ready/index.ts b/src/events/ready/index.ts index 8f19384..6de258b 100644 --- a/src/events/ready/index.ts +++ b/src/events/ready/index.ts @@ -18,7 +18,7 @@ export default { const guilds = client.guilds.cache; guilds.map(async (guild) => { - logger.silly({ name: guild.name, members: guild.memberCount }); + logger.debug({ name: guild.name, members: guild.memberCount }); }); }, }; diff --git a/src/handlers/commands.ts b/src/handlers/commands.ts index f21c2d7..0e657b8 100644 --- a/src/handlers/commands.ts +++ b/src/handlers/commands.ts @@ -15,7 +15,7 @@ export default async (client: Client) => { const plugin = await import(`../plugins/${pluginName}`); await client?.commands?.set(plugin?.default?.data?.name, plugin?.default); - logger?.silly( + logger?.debug( `Successfully loaded plugin: ${plugin?.default?.data?.name} from ${plugin.default?.metadata?.author}` ); }); diff --git a/src/handlers/deployCommands.ts b/src/handlers/deployCommands.ts index b68f025..07d55c0 100644 --- a/src/handlers/deployCommands.ts +++ b/src/handlers/deployCommands.ts @@ -1,42 +1,54 @@ -import { devMode, bot } from "../../config.json"; +// Dependencies +import { token, clientId } from "@config/discord"; +import { devMode, guildId } from "@config/other"; + import logger from "../logger"; import fs from "fs"; import { REST } from "@discordjs/rest"; import { Routes } from "discord-api-types/v9"; export default async () => { - const commands = []; - const commandFiles = fs.readdirSync("./src/plugins"); + fs.readdir("./src/plugins", async (error: any, plugins: any) => { + if (error) { + return logger?.error(new Error(error)); + } - for (const file of commandFiles) { - // eslint-disable-next-line global-require - const command = require(`../plugins/${file}`); - commands.push(command.default.data.toJSON()); - } + const pluginList = [{} as any]; - const rest = new REST({ version: "9" }).setToken(bot?.token); + await plugins?.map(async (pluginName: any) => { + const plugin = await import(`../plugins/${pluginName}`); - await rest - .put(Routes.applicationCommands(bot?.clientId), { - body: commands, - }) - .then(async () => - logger.info("Successfully registered application commands.") - ) - .catch(async (error) => { - logger.error(error); + pluginList.push(plugin.default.data.toJSON()); + + logger?.debug( + `Successfully deployed plugin: ${plugin?.default?.data?.name} from ${plugin.default?.metadata?.author}` + ); }); - if (devMode) { + const rest = new REST({ version: "9" }).setToken(token); + await rest - .put(Routes.applicationGuildCommands(bot?.clientId, bot?.guildId), { - body: commands, + .put(Routes.applicationCommands(clientId), { + body: pluginList, }) .then(async () => - logger.info("Successfully registered guild application commands.") + logger.info("Successfully registered application commands.") ) - .catch(async (error) => { - logger.error(error); + .catch(async (err: any) => { + logger.error(err); }); - } + + if (devMode) { + await rest + .put(Routes.applicationGuildCommands(clientId, guildId), { + body: pluginList, + }) + .then(async () => + logger.info("Successfully registered guild application commands.") + ) + .catch(async (err: any) => { + logger.error(err); + }); + } + }); }; diff --git a/src/index.ts b/src/index.ts index 21f6dee..5b9c81b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,17 +1,16 @@ // Dependencies +import "tsconfig-paths/register"; // Allows using tsconfig.json paths during runtime import { Client, Intents } from "discord.js"; // discord.js -import "tsconfig-paths/register"; + +import locale from "@locale"; +import database from "@database"; +import schedules from "@schedules"; + +import events from "@handlers/events"; +import commands from "@handlers/commands"; // Configurations -import { bot } from "../config.json"; - -import database from "@root/database"; -import schedules from "./schedules"; - -// Handlers -import events from "./handlers/events"; -import commands from "./handlers/commands"; -import locale from "./handlers/locale"; +import { token } from "@config/discord"; const client = new Client({ intents: [ @@ -21,11 +20,11 @@ const client = new Client({ ], }); -database(); locale(); +database(); schedules(client); commands(client); events(client); -client?.login(bot?.token); +client?.login(token); diff --git a/src/handlers/locale.ts b/src/locale/index.ts similarity index 100% rename from src/handlers/locale.ts rename to src/locale/index.ts diff --git a/src/plugins/credits/modules/gift/index.ts b/src/plugins/credits/modules/gift/index.ts index 7cd8852..d003435 100644 --- a/src/plugins/credits/modules/gift/index.ts +++ b/src/plugins/credits/modules/gift/index.ts @@ -214,7 +214,7 @@ export default { ], }) .catch(async () => - logger.verbose(`Can not send DM to user ${optionUser?.id}`) + logger.debug(`Can not send DM to user ${optionUser?.id}`) ); // Send debug message diff --git a/src/plugins/credits/modules/work/index.ts b/src/plugins/credits/modules/work/index.ts index 072ea19..26504c3 100644 --- a/src/plugins/credits/modules/work/index.ts +++ b/src/plugins/credits/modules/work/index.ts @@ -54,7 +54,7 @@ export default { userDB.credits += creditsEarned; await userDB?.save()?.then(async () => { - logger?.verbose(`Credits added to user: ${user?.id}`); + logger?.debug(`Credits added to user: ${user?.id}`); return interaction.editReply({ embeds: [ @@ -78,7 +78,7 @@ export default { }); setTimeout(async () => { - logger?.verbose( + logger?.debug( `Guild: ${guild?.id} User: ${ user?.id } has not worked within the last ${ diff --git a/src/plugins/manage/groups/counters/modules/delete/index.ts b/src/plugins/manage/groups/counters/modules/delete/index.ts index 9aba20c..ff4d2a8 100644 --- a/src/plugins/manage/groups/counters/modules/delete/index.ts +++ b/src/plugins/manage/groups/counters/modules/delete/index.ts @@ -69,7 +69,7 @@ export default { }); }); - logger?.verbose( + logger?.debug( `Guild: ${guild?.id} User: ${user?.id} removed ${discordChannel?.id} as a counter.` ); }, diff --git a/src/plugins/manage/groups/credits/modules/give/index.ts b/src/plugins/manage/groups/credits/modules/give/index.ts index a945928..f945f05 100644 --- a/src/plugins/manage/groups/credits/modules/give/index.ts +++ b/src/plugins/manage/groups/credits/modules/give/index.ts @@ -130,7 +130,7 @@ export default { // Save toUser await toUser?.save()?.then(async () => { - logger?.verbose( + logger?.debug( `Guild: ${guild?.id} User: ${user?.id} gave ${ discordReceiver?.id } ${pluralize(creditAmount, "credit")}.` diff --git a/src/plugins/manage/groups/credits/modules/set/index.ts b/src/plugins/manage/groups/credits/modules/set/index.ts index 8bda707..7ded2a3 100644 --- a/src/plugins/manage/groups/credits/modules/set/index.ts +++ b/src/plugins/manage/groups/credits/modules/set/index.ts @@ -118,7 +118,7 @@ export default { // Save toUser await toUser?.save()?.then(async () => { - logger?.verbose( + logger?.debug( `Guild: ${guild?.id} User: ${user?.id} set ${ discordUser?.id } to ${pluralize(creditAmount, "credit")}.` diff --git a/src/plugins/manage/groups/credits/modules/take/index.ts b/src/plugins/manage/groups/credits/modules/take/index.ts index 9baf0fb..75ba407 100644 --- a/src/plugins/manage/groups/credits/modules/take/index.ts +++ b/src/plugins/manage/groups/credits/modules/take/index.ts @@ -136,7 +136,7 @@ export default { // Save toUser await toUser?.save()?.then(async () => { - logger?.verbose( + logger?.debug( `Guild: ${guild?.id} User: ${user?.id} set ${ optionUser?.id } to ${pluralize(optionAmount, "credit")}.` diff --git a/src/schedules/index.ts b/src/schedules/index.ts index daa65c3..8d5590a 100644 --- a/src/schedules/index.ts +++ b/src/schedules/index.ts @@ -1,8 +1,11 @@ +// Dependencies +import { Client } from "discord.js"; import schedule from "node-schedule"; -import logger from "../logger"; -import { Client } from "discord.js"; -import shopRoles from "./jobs/shopRoles"; +import logger from "@logger"; + +// Jobs +import shopRoles from "@root/schedules/jobs/shopRoles"; export default async (client: Client) => { const expression = "*/5 * * * *"; diff --git a/src/schedules/jobs/shopRoles.ts b/src/schedules/jobs/shopRoles.ts index 32ac40c..37ced37 100644 --- a/src/schedules/jobs/shopRoles.ts +++ b/src/schedules/jobs/shopRoles.ts @@ -1,32 +1,34 @@ +// Dependencies import { Client } from "discord.js"; -import logger from "../../logger"; +import logger from "@logger"; -import users from "../../database/schemas/user"; -import shopRoleSchema from "../../database/schemas/shopRole"; -import guilds from "../../database/schemas/guild"; +// Schemas +import userSchema from "@schemas/user"; +import shopRoleSchema from "@schemas/shopRole"; +import guildSchema from "@schemas/guild"; export default async (client: Client) => { - shopRoleSchema.find().then(async (shopRoles: any) => { - shopRoles.map(async (shopRole: any) => { + await shopRoleSchema?.find()?.then(async (shopRoles: any) => { + shopRoles?.map(async (shopRole: any) => { const payed = new Date(shopRole?.lastPayed); const oneHourAfterPayed = payed?.setHours(payed?.getHours() + 1); if (new Date() > new Date(oneHourAfterPayed)) { - logger.silly( + logger.debug( `Role: ${shopRole?.roleId} Expires: ${ new Date() < new Date(oneHourAfterPayed) } Last Payed: ${shopRole?.lastPayed}` ); // Get guild object - const guild = await guilds?.findOne({ + const guild = await guildSchema?.findOne({ guildId: shopRole?.guildId, }); if (guild === null) return; - const userDB = await users?.findOne({ + const userDB = await userSchema?.findOne({ userId: shopRole?.userId, guildId: shopRole?.guildId, }); @@ -41,7 +43,7 @@ export default async (client: Client) => { shopRoleSchema ?.deleteOne({ _id: shopRole?._id }) ?.then(async () => - logger?.verbose(`Removed ${shopRole?._id} from collection.`) + logger?.debug(`Removed ${shopRole?._id} from collection.`) ); return rMember?.roles?.remove(`${shopRole?.roleId}`); diff --git a/src/tools/index.ts b/src/tools/index.ts deleted file mode 100644 index 5d97e15..0000000 --- a/src/tools/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -import helpers from "@root/helpers"; -import config from "../../config.json"; -import schemas from "../database/schemas"; - -export default { helpers, config, schemas }; diff --git a/src/types/common/discord.d.ts b/src/types/common/discord.d.ts index 30bae32..1e4926f 100644 --- a/src/types/common/discord.d.ts +++ b/src/types/common/discord.d.ts @@ -1,5 +1,5 @@ -import { Collection, Client as DJSClient } from 'discord.js'; -declare module 'discord.js' { +import { Collection, Client as DJSClient } from "discord.js"; +declare module "discord.js" { export interface Client extends DJSClient { commands: Collection; } diff --git a/tsconfig.json b/tsconfig.json index 49af458..fb7f3a2 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -20,7 +20,13 @@ "@interface/*": ["Interfaces/*"], "@root/*": ["*"], "@config/*": ["config/*"], - "@logger": ["logger"] + "@logger": ["logger"], + "@database": ["database"], + "@schedules": ["schedules"], + "@handlers/*": ["handlers/*"], + "@helpers/*": ["helpers/*"], + "@locale": ["locale"], + "@schemas/*": ["database/schemas/*"] } }, "include": ["./src"],