diff --git a/src/database/index.ts b/src/database/index.ts index 9c62259..7d59bd4 100644 --- a/src/database/index.ts +++ b/src/database/index.ts @@ -8,12 +8,13 @@ import logger from "@logger"; import { url } from "@config/database"; export default async () => { - await mongoose - .connect(url) - ?.then(async () => { - logger.info("Successfully connected to MongoDB!"); - }) - ?.catch(async () => { - logger.error("Error whilst connecting to MongoDB!"); - }); + mongoose.connect(url).then(async (connection: any) => { + logger?.info(`Connected to database: ${connection.connection.name}`); + }); + mongoose.connection.on("error", (error: any) => { + logger?.error(error); + }); + mongoose.connection.on("warn", (warning: any) => { + logger?.warn(warning); + }); }; diff --git a/src/events/guildCreate/index.ts b/src/events/guildCreate/index.ts index dfa4c7e..a55d9d5 100644 --- a/src/events/guildCreate/index.ts +++ b/src/events/guildCreate/index.ts @@ -4,12 +4,15 @@ import { Guild } from "discord.js"; // Dependencies import updatePresence from "@helpers/updatePresence"; import fetchGuild from "@helpers/fetchGuild"; +import logger from "@logger"; export default { name: "guildCreate", async execute(guild: Guild) { const { client } = guild; + logger?.verbose(`Added to guild: ${guild.name} (${guild.id})`); + await fetchGuild(guild); await updatePresence(client); }, diff --git a/src/events/guildDelete/index.ts b/src/events/guildDelete/index.ts index 241a6ba..9a0ceec 100644 --- a/src/events/guildDelete/index.ts +++ b/src/events/guildDelete/index.ts @@ -4,12 +4,15 @@ import { Guild } from "discord.js"; // Dependencies import updatePresence from "@helpers/updatePresence"; import dropGuild from "@helpers/dropGuild"; +import logger from "@logger"; export default { name: "guildDelete", async execute(guild: Guild) { const { client } = guild; + logger?.verbose(`Deleted from guild: ${guild.name} (${guild.id})`); + await dropGuild(guild); await updatePresence(client); }, diff --git a/src/events/guildMemberAdd/index.ts b/src/events/guildMemberAdd/index.ts index 8412463..c3c2808 100644 --- a/src/events/guildMemberAdd/index.ts +++ b/src/events/guildMemberAdd/index.ts @@ -4,12 +4,17 @@ import { GuildMember } from "discord.js"; // Dependencies import updatePresence from "@helpers/updatePresence"; import fetchUser from "@helpers/fetchUser"; +import logger from "@logger"; export default { name: "guildMemberAdd", async execute(member: GuildMember) { const { client, user, guild } = member; + logger?.verbose( + `New member: ${user.tag} (${user.id}) added to guild: ${guild.name} (${guild.id})` + ); + await fetchUser(user, guild); await updatePresence(client); }, diff --git a/src/events/guildMemberRemove/index.ts b/src/events/guildMemberRemove/index.ts index 5f4f6fb..24ae581 100644 --- a/src/events/guildMemberRemove/index.ts +++ b/src/events/guildMemberRemove/index.ts @@ -4,12 +4,17 @@ import { GuildMember } from "discord.js"; // Dependencies import updatePresence from "@helpers/updatePresence"; import dropUser from "@helpers/dropUser"; +import logger from "@logger"; export default { name: "guildMemberRemove", async execute(member: GuildMember) { const { client, user, guild } = member; + logger?.verbose( + `Removed member: ${user.tag} (${user.id}) from guild: ${guild.name} (${guild.id})` + ); + await dropUser(user, guild); await updatePresence(client); }, diff --git a/src/events/interactionCreate/components/isCommand.ts b/src/events/interactionCreate/components/isCommand.ts index ed347fa..ac1e19d 100644 --- a/src/events/interactionCreate/components/isCommand.ts +++ b/src/events/interactionCreate/components/isCommand.ts @@ -5,8 +5,6 @@ import logger from "@logger"; import { errorColor, footerText, footerIcon } from "@config/embed"; -import guildSchema from "@schemas/guild"; - export default async (interaction: CommandInteraction) => { if (!interaction.isCommand()) return; @@ -15,39 +13,24 @@ export default async (interaction: CommandInteraction) => { const currentCommand = client.commands.get(commandName); if (!currentCommand) return; - // If command do not exist - - // Create guild if it does not exist already - await guildSchema.findOne( - { guildId: guild?.id }, - { new: true, upsert: true } - ); - - // Defer reply await interaction.deferReply({ ephemeral: true }); await currentCommand .execute(interaction) .then(async () => { - return logger.debug( - `Guild: ${guild?.id} (${guild?.name}) User: ${user?.tag} executed ${commandName}` + return logger?.verbose( + `Command: ${commandName} executed in guild: ${guild?.name} (${guild?.id}) by user: ${user?.tag} (${user?.id})` ); }) .catch(async (error: any) => { - console.log(error); - - logger.error( - `Guild: ${guild?.id} (${guild?.name}) User: ${user?.tag} There was an error executing the command: ${commandName}` - ); - - logger.error(error); + logger?.error(error); return interaction.editReply({ embeds: [ new MessageEmbed() .setTitle("Error") .setDescription( - `There was an error executing the command: **${currentCommand.data.name}**.` + `There was an error executing the command: **${currentCommand?.data?.name}**.` ) .setColor(errorColor) .setTimestamp(new Date()) diff --git a/src/events/interactionCreate/index.ts b/src/events/interactionCreate/index.ts index e16ef00..e93d10a 100644 --- a/src/events/interactionCreate/index.ts +++ b/src/events/interactionCreate/index.ts @@ -3,10 +3,17 @@ import { CommandInteraction } from "discord.js"; // Dependencies import isCommand from "@root/events/interactionCreate/components/isCommand"; +import logger from "@logger"; export default { name: "interactionCreate", async execute(interaction: CommandInteraction) { + const { guild, id } = interaction; + + logger?.verbose( + `New interaction: ${id} in guild: ${guild?.name} (${guild?.id})` + ); + await isCommand(interaction); }, }; diff --git a/src/events/messageCreate/modules/counters.ts b/src/events/messageCreate/modules/counters.ts index 27883f3..857992a 100644 --- a/src/events/messageCreate/modules/counters.ts +++ b/src/events/messageCreate/modules/counters.ts @@ -1,31 +1,44 @@ -import counters from "../../../database/schemas/counter"; - import { Message } from "discord.js"; +import logger from "@logger"; + +import counterSchema from "@schemas/counter"; + export default async (message: Message) => { const { guild, channel, content } = message; - // Get counter object - const counter = await counters.findOne({ + if (channel?.type !== "GUILD_TEXT") return; + + const counter = await counterSchema.findOne({ guildId: guild?.id, channelId: channel.id, }); - // If counter for the message channel - if (counter) { - // If message content is not strictly the same as counter word - if (content !== counter.word) { - // Delete the message - await message.delete(); - } else { - // Add 1 to the counter object - await counters.findOneAndUpdate( - { - guildId: guild?.id, - channelId: channel.id, - }, - { $inc: { counter: 1 } } - ); - } + if (counter === null) return; + + logger?.verbose( + `Channel: ${channel.name} (${channel.id}) is an active counter channel` + ); + + if (content !== counter.word) { + logger?.verbose(`Message: ${content} is not the counter word`); + return message.delete(); } + + logger?.verbose(`Message: ${content} is the counter word`); + + await counterSchema + .findOneAndUpdate( + { + guildId: guild?.id, + channelId: channel.id, + }, + { $inc: { counter: 1 } } + ) + .then(async () => { + logger?.verbose(`Counter incremented`); + }) + .catch(async () => { + logger?.error(`Failed to increment counter`); + }); }; diff --git a/src/events/messageCreate/modules/credits.ts b/src/events/messageCreate/modules/credits.ts index 3c33ad6..d736b69 100644 --- a/src/events/messageCreate/modules/credits.ts +++ b/src/events/messageCreate/modules/credits.ts @@ -2,69 +2,50 @@ import logger from "../../../logger"; import timeouts from "../../../database/schemas/timeout"; import { Message } from "discord.js"; export default async (guildDB: any, userDB: any, message: Message) => { - const { guild, author, channel, content } = message; + const { guild, author, content } = message; - // If message length is below guild minimum length if (content.length < guildDB.credits.minimumLength) return; - // Check if user has a timeout const isTimeout = await timeouts.findOne({ + guildId: guild?.id, + userId: author?.id, + timeoutId: "2022-03-15-17-42", + }); + + if (isTimeout) { + return logger?.verbose( + `User: ${author?.tag} (${author?.id}) in guild: ${guild?.name} (${guild?.id}) is on timeout for credits` + ); + } + + userDB.credits += guildDB.credits.rate; + + await userDB + .save() + .then(async () => { + return logger?.verbose( + `User: ${author?.tag} (${author?.id}) in guild: ${guild?.name} (${guild?.id})credits incremented` + ); + }) + .catch(async (error: any) => { + return logger?.error(error); + }); + + await timeouts.create({ guildId: guild?.id, userId: author.id, timeoutId: "2022-03-15-17-42", }); - // If user is not on timeout - if (!isTimeout) { - // Add credits to user + setTimeout(async () => { + logger?.verbose( + `User: ${author?.tag} (${author?.id}) in guild: ${guild?.name} (${guild?.id}) timeout removed for points` + ); - userDB.credits += guildDB.credits.rate; - - await userDB - .save() - .then(async () => { - // Send debug message - await logger.debug( - `Guild: ${guild?.id} User: ${author.id} Channel: ${channel.id} credits add ${guildDB.credits.rate} balance: ${userDB.credits}` - ); - }) - .catch(async (e: any) => { - // Send error message - await logger.error(e); - }); - - // Create a timeout for the user - await timeouts.create({ + await timeouts.deleteOne({ guildId: guild?.id, - userId: author.id, + userId: author?.id, timeoutId: "2022-03-15-17-42", }); - - setTimeout(async () => { - // Send debug message - await logger.debug( - `Guild: ${guild?.id} User: ${author.id} Channel: ${ - channel.id - } has not talked within last ${ - guildDB.credits.timeout / 1000 - } seconds, credits can be given` - ); - - // When timeout is out, remove it from the database - await timeouts.deleteOne({ - guildId: guild?.id, - userId: author.id, - timeoutId: "2022-03-15-17-42", - }); - }, guildDB.credits.timeout); - } else { - // Send debug message - await logger.debug( - `Guild: ${guild?.id} User: ${author.id} Channel: ${ - channel.id - } has talked within last ${ - guildDB.credits.timeout / 1000 - } seconds, no credits given` - ); - } + }, guildDB.credits.timeout); }; diff --git a/src/events/messageCreate/modules/points.ts b/src/events/messageCreate/modules/points.ts index 3530ed8..d00336a 100644 --- a/src/events/messageCreate/modules/points.ts +++ b/src/events/messageCreate/modules/points.ts @@ -3,68 +3,50 @@ import timeouts from "../../../database/schemas/timeout"; import { Message } from "discord.js"; export default async (guildDB: any, userDB: any, message: Message) => { - const { author, guild, channel, content } = message; + const { author, guild, content } = message; - // If message length is below guild minimum length if (content.length < guildDB.points.minimumLength) return; - // Check if user has a timeout const isTimeout = await timeouts.findOne({ guildId: guild?.id, userId: author.id, timeoutId: "2022-03-15-17-41", }); - // If user is not on timeout - if (!isTimeout) { - // Add points to user - userDB.points += guildDB.points.rate; + if (isTimeout) { + return logger?.verbose( + `User: ${author.tag} (${author.id}) in guild: ${guild?.name} (${guild?.id}) is on timeout for points` + ); + } - await userDB - .save() - .then(async () => { - // Send debug message - await logger.debug( - `Guild: ${guild?.id} User: ${author.id} Channel: ${channel.id} points add: ${guildDB.points.rate} balance: ${userDB.points}` - ); - }) - .catch(async (e: any) => { - // Send error message - await logger.error(e); - }); + userDB.points += guildDB.points.rate; - // Create a timeout for the user - await timeouts.create({ + await userDB + .save() + .then(async () => { + return logger?.verbose( + `User: ${author.tag} (${author.id}) in guild: ${guild?.name} (${guild?.id}) points incremented` + ); + }) + .catch(async (error: any) => { + logger?.error(error); + }); + + await timeouts.create({ + guildId: guild?.id, + userId: author.id, + timeoutId: "2022-03-15-17-41", + }); + + setTimeout(async () => { + logger?.verbose( + `User: ${author.tag} (${author.id}) in guild: ${guild?.name} (${guild?.id}) timeout removed for points` + ); + + await timeouts.deleteOne({ guildId: guild?.id, userId: author.id, timeoutId: "2022-03-15-17-41", }); - - setTimeout(async () => { - // Send debug message - await logger.debug( - `Guild: ${guild?.id} User: ${author.id} Channel: ${ - channel.id - } has not talked within last ${ - guildDB.points.timeout / 1000 - } seconds, points can be given` - ); - - // When timeout is out, remove it from the database - await timeouts.deleteOne({ - guildId: guild?.id, - userId: author.id, - timeoutId: "2022-03-15-17-41", - }); - }, guildDB.points.timeout); - } else { - // Send debug message - await logger.debug( - `Guild: ${guild?.id} User: ${author.id} Channel: ${ - channel.id - } has talked within last ${ - guildDB.points.timeout / 1000 - } seconds, no points given` - ); - } + }, guildDB.points.timeout); }; diff --git a/src/events/messageUpdate/index.ts b/src/events/messageUpdate/index.ts index 2a38a73..52547b5 100644 --- a/src/events/messageUpdate/index.ts +++ b/src/events/messageUpdate/index.ts @@ -1,18 +1,21 @@ // Dependencies import { Message } from "discord.js"; -import logger from "../../logger"; +import logger from "@logger"; // Modules import counter from "./modules/counter"; export default { name: "messageUpdate", - async execute(oldMessage: Message, newMessage: Message) { - const { author } = newMessage; + async execute(_oldMessage: Message, newMessage: Message) { + const { author, guild } = newMessage; - logger.debug({ oldMessage, newMessage }); + logger?.verbose( + `Message update event fired by ${author.tag} (${author.id}) in guild: ${guild?.name} (${guild?.id})` + ); - if (author?.bot) return; + if (author?.bot) + return logger?.verbose(`Message update event fired by bot`); await counter(newMessage); }, diff --git a/src/events/messageUpdate/modules/counter.ts b/src/events/messageUpdate/modules/counter.ts index d330b4e..9c65ab3 100644 --- a/src/events/messageUpdate/modules/counter.ts +++ b/src/events/messageUpdate/modules/counter.ts @@ -2,8 +2,8 @@ import { Message } from "discord.js"; // Models -import counterSchema from "../../../database/schemas/counter"; -import logger from "../../../logger"; +import counterSchema from "@schemas/counter"; +import logger from "@logger"; export default async (message: Message) => { const { guild, channel, author, content } = message; @@ -13,16 +13,23 @@ export default async (message: Message) => { channelId: channel?.id, }); - if (counter === null) return; + if (counter === null) + return logger?.verbose( + `No counter found for guild: ${guild?.name} (${guild?.id})` + ); const { word } = counter; - if (content === word) return; + if (content === word) + return logger?.verbose( + `User: ${author?.tag} (${author?.id}) in guild: ${guild?.name} (${guild?.id}) said the counter word: ${word}` + ); await message ?.delete() ?.then(async () => { await channel?.send(`${author} said **${word}**.`); + logger?.verbose(`${author} said ${word} in ${channel}`); }) - ?.catch(async (error) => { - logger.error(new Error(error)); + ?.catch(async (error: any) => { + logger?.error(error); }); }; diff --git a/src/events/ready/index.ts b/src/events/ready/index.ts index 6de258b..d39f97f 100644 --- a/src/events/ready/index.ts +++ b/src/events/ready/index.ts @@ -11,14 +11,16 @@ export default { name: "ready", once: true, async execute(client: Client) { - logger.info(`Successfully logged into discord user: ${client?.user?.tag}!`); + logger?.info(`${client.user?.tag} (${client.user?.id}) is ready`); + await updatePresence(client); await devMode(client); await deployCommands(); - const guilds = client.guilds.cache; - guilds.map(async (guild) => { - logger.debug({ name: guild.name, members: guild.memberCount }); + client?.guilds?.cache?.forEach((guild) => { + logger?.info( + `${client.user?.tag} (${client.user?.id}) is in guild: ${guild.name} (${guild.id})` + ); }); }, }; diff --git a/src/handlers/commands.ts b/src/handlers/commands.ts index 4645c10..415ec15 100644 --- a/src/handlers/commands.ts +++ b/src/handlers/commands.ts @@ -8,7 +8,7 @@ export default async (client: Client) => { fs.readdir("./src/plugins", async (error: any, plugins: any) => { if (error) { - return logger?.error(new Error(error)); + return logger?.error(`Error reading plugins: ${error}`); } await Promise.all( @@ -19,9 +19,8 @@ export default async (client: Client) => { plugin?.default?.data?.name, plugin?.default ); - logger?.debug( - `Successfully loaded plugin: ${plugin?.default?.data?.name} from ${plugin.default?.metadata?.author}` - ); + + logger?.verbose(`Loaded plugin: ${pluginName}`); }) ); }); diff --git a/src/handlers/deployCommands.ts b/src/handlers/deployCommands.ts index d58e5af..65d4627 100644 --- a/src/handlers/deployCommands.ts +++ b/src/handlers/deployCommands.ts @@ -21,9 +21,7 @@ export default async () => { pluginList.push(plugin.default.data.toJSON()); - logger?.debug( - `Successfully deployed plugin: ${plugin?.default?.data?.name} from ${plugin.default?.metadata?.author}` - ); + logger?.verbose(`Loaded plugin: ${pluginName} for deployment`); }) ); @@ -34,7 +32,7 @@ export default async () => { body: pluginList, }) .then(async () => { - logger.info("Successfully registered application commands."); + logger?.info(`Successfully deployed plugins to Discord`); }) .catch(async (err: any) => { logger.error(err); @@ -46,7 +44,7 @@ export default async () => { body: pluginList, }) .then(async () => - logger.info("Successfully registered guild application commands.") + logger?.info(`Successfully deployed guild plugins to Discord`) ) .catch(async (err: any) => { logger.error(err); diff --git a/src/handlers/events.ts b/src/handlers/events.ts index 0f0d891..f72010a 100644 --- a/src/handlers/events.ts +++ b/src/handlers/events.ts @@ -1,5 +1,6 @@ import fs from "fs"; // fs import { Client } from "discord.js"; // discord.js +import logger from "@logger"; export default async (client: Client) => { const eventFiles = fs.readdirSync("./src/events"); @@ -10,10 +11,12 @@ export default async (client: Client) => { client.once(event.default.name, (...args) => event.default.execute(...args) ); + logger?.verbose(`Loaded event: ${event.default.name}`); } else { client.on(event.default.name, (...args) => event.default.execute(...args) ); + logger?.verbose(`Loaded event: ${event.default.name}`); } } }; diff --git a/src/helpers/dbGuildFix.ts b/src/helpers/dbGuildFix.ts deleted file mode 100644 index e51b89e..0000000 --- a/src/helpers/dbGuildFix.ts +++ /dev/null @@ -1,24 +0,0 @@ -// TODO This file will make sure that all guilds always has at least one entry in all collections with "guildId" - -import apis from "../database/schemas/api"; -import guilds from "../database/schemas/guild"; - -import logger from "../logger"; -import { Guild } from "discord.js"; - -export default async (guild: Guild) => { - const api = await apis.findOne({ guildId: guild.id }); - const guildData = await guilds.findOne({ guildId: guild.id }); - if (!api) { - apis.create({ guildId: guild.id }); - logger.debug(`Guild: ${guild.id} added api collection`); - } else { - logger.debug(`Guild: ${guild.id} already in api collection`); - } - if (!guildData) { - guilds.create({ guildId: guild.id }); - logger.debug(`Guild: ${guild.id} added guild collection`); - } else { - logger.debug(`Guild: ${guild.id} already in guild collection`); - } -}; diff --git a/src/helpers/dbMemberFix.ts b/src/helpers/dbMemberFix.ts deleted file mode 100644 index e432226..0000000 --- a/src/helpers/dbMemberFix.ts +++ /dev/null @@ -1,34 +0,0 @@ -import users from "../database/schemas/user"; -import logger from "../logger"; -import { Guild, User } from "discord.js"; - -export default async (user: User, guild: Guild) => { - const userData = await users.findOne({ userId: user.id, guildId: guild.id }); - if (!userData) { - users - .create({ userId: user.id, guildId: guild.id }) - .then(async () => { - await logger.debug(`User: ${user.id} added user collection`); - }) - .catch(async (e) => { - await logger.error( - `User: ${user.id} failed to added user collection ${e}` - ); - }); - } else { - logger.debug(`User: ${user.id} already in user collection`); - } - - // HOW TO ITERATE - // - // const guilds = client.guilds.cache; - // await guilds.map(async (guild) => { - // await guild.members.fetch().then(async (members) => { - // await members.forEach(async (member) => { - // const { user } = member; - // dbMemberFix(user, guild); - // }); - // }); - // await dbGuildFix(guild); - // }); -}; diff --git a/src/helpers/devMode.ts b/src/helpers/devMode.ts index 708481b..6695799 100644 --- a/src/helpers/devMode.ts +++ b/src/helpers/devMode.ts @@ -8,8 +8,12 @@ import { devMode, guildId } from "@config/other"; export default async (client: Client) => { if (!devMode) { - client?.application?.commands?.set([], guildId).then(async () => { - logger.verbose(`Removed all guild based commands from ${guildId}`); + return client?.application?.commands?.set([], guildId).then(async () => { + return logger?.verbose( + `Development commands disabled for guild: ${guildId}` + ); }); } + + return logger?.verbose(`Development commands enabled for guild: ${guildId}`); }; diff --git a/src/helpers/dropGuild.ts b/src/helpers/dropGuild.ts index 70e099b..fc17d0a 100644 --- a/src/helpers/dropGuild.ts +++ b/src/helpers/dropGuild.ts @@ -1,61 +1,74 @@ -import guilds from "../database/schemas/guild"; -import users from "../database/schemas/user"; -import apis from "../database/schemas/api"; -import counters from "../database/schemas/counter"; -import shopRoles from "../database/schemas/shopRole"; -import timeouts from "../database/schemas/timeout"; +import guildSchema from "@schemas/guild"; +import userSchema from "@schemas/user"; +import apiSchema from "@schemas/api"; +import counterSchema from "@schemas/counter"; +import shopRoleSchema from "@schemas/shopRole"; +import timeoutSchema from "@schemas/timeout"; -import logger from "../logger"; +import logger from "@logger"; import { Guild } from "discord.js"; export default async (guild: Guild) => { - guilds + await guildSchema .deleteMany({ guildId: guild.id }) .then(async () => { - logger.debug(`Successfully deleted guild: ${guild.id}`); + return logger?.verbose(`Deleted guild: ${guild.id}`); }) - .catch(async (e) => { - logger.error(`Failed to delete guild: ${guild.id} ${e}`); + .catch(async (error) => { + logger?.error(`Error deleting guild: ${guild.id} - ${error}`); }); - users + + await userSchema .deleteMany({ guildId: guild.id }) .then(async () => { - logger.debug(`Successfully deleted guild: ${guild.id}'s users`); + logger?.verbose(`Deleted users for guild: ${guild.id} from database`); }) - .catch(async (e) => { - logger.error(`Failed to delete guild: ${guild.id}'s users ${e}`); + .catch(async (error) => { + logger?.error(`Error deleting users for guild: ${guild.id} - ${error}`); }); - apis + + await apiSchema .deleteMany({ guildId: guild.id }) .then(async () => { - logger.debug(`Successfully deleted guild: ${guild.id}'s apis`); + logger?.verbose(`Deleted apis for guild: ${guild.id} from database`); }) - .catch(async (e) => { - logger.error(`Failed to delete guild: ${guild.id}'s apis ${e}`); + .catch(async (error) => { + logger?.error(`Error deleting apis for guild: ${guild.id} - ${error}`); }); - counters + + await counterSchema .deleteMany({ guildId: guild.id }) .then(async () => { - logger.debug(`Successfully deleted guild: ${guild.id}'s counters`); + logger?.verbose(`Deleted counters for guild: ${guild.id} from database`); }) - .catch(async (e) => { - logger.error(`Failed to delete guild: ${guild.id}'s counters ${e}`); + .catch(async (error) => { + logger?.error( + `Error deleting counters for guild: ${guild.id} - ${error}` + ); }); - shopRoles + + await shopRoleSchema .deleteMany({ guildId: guild.id }) .then(async () => { - logger.debug(`Successfully deleted guild: ${guild.id}'s shop roles`); + logger?.verbose( + `Deleted shop roles for guild: ${guild.id} from database` + ); }) - .catch(async (e) => { - logger.error(`Failed to delete guild: ${guild.id}'s shop roles ${e}`); + .catch(async (error) => { + logger?.error( + `Error deleting shop roles for guild: ${guild.id} - ${error}` + ); }); - timeouts + + await timeoutSchema .deleteMany({ guildId: guild.id }) .then(async () => { - logger.debug(`Successfully deleted guild: ${guild.id}'s timeouts`); + logger?.verbose(`Deleted timeouts for guild: ${guild.id} from database`); }) - .catch(async (e) => { - logger.error(`Failed to delete guild: ${guild.id}'s timeouts ${e}`); + .catch(async (error) => { + logger?.error( + `Error deleting timeouts for guild: ${guild.id} - ${error}` + ); }); }; diff --git a/src/helpers/dropUser.ts b/src/helpers/dropUser.ts index 09b6e95..cb47db9 100644 --- a/src/helpers/dropUser.ts +++ b/src/helpers/dropUser.ts @@ -1,13 +1,18 @@ -import users from "../database/schemas/user"; +import userSchema from "@schemas/user"; -import logger from "../logger"; +import logger from "@logger"; import { Guild, User } from "discord.js"; export default async (user: User, guild: Guild) => { - await users + await userSchema .deleteOne({ userId: user?.id, guildId: guild?.id }) - .then(async () => - logger.debug(`Guild: ${guild?.id} User: ${user?.id} deleted successfully`) - ); + .then(async () => { + logger?.verbose(`Deleted user: ${user?.id} from guild: ${guild?.id}`); + }) + .catch(async (error) => { + logger?.error( + `Error deleting user: ${user?.id} from guild: ${guild?.id} - ${error}` + ); + }); }; diff --git a/src/helpers/fetchGuild.ts b/src/helpers/fetchGuild.ts index 9424e93..6b9c439 100644 --- a/src/helpers/fetchGuild.ts +++ b/src/helpers/fetchGuild.ts @@ -2,10 +2,10 @@ import { Guild } from "discord.js"; // Models -import guildSchema from "../database/schemas/guild"; +import guildSchema from "@schemas/guild"; // Handlers -import logger from "../logger"; +import logger from "@logger"; // Function export default async (guild: Guild) => { @@ -16,12 +16,10 @@ export default async (guild: Guild) => { await newGuildObj .save() .then(async () => { - logger.debug( - `Guild: ${guild.id} has successfully been added to the database.` - ); + logger?.verbose(`Created guild: ${guild.id}`); }) - .catch(async (err: any) => { - logger.error(err); + .catch(async (error) => { + logger?.error(`Error creating guild: ${guild.id} - ${error}`); }); return newGuildObj; diff --git a/src/helpers/fetchUser.ts b/src/helpers/fetchUser.ts index b9d21b9..98cc927 100644 --- a/src/helpers/fetchUser.ts +++ b/src/helpers/fetchUser.ts @@ -2,10 +2,10 @@ import { Guild, User } from "discord.js"; // Models -import userSchema from "../database/schemas/user"; +import userSchema from "@schemas/user"; // Handlers -import logger from "../logger"; +import logger from "@logger"; // Function export default async (user: User, guild: Guild) => { @@ -22,12 +22,12 @@ export default async (user: User, guild: Guild) => { await newUserObj .save() .then(async () => { - logger.debug( - `Member: ${user.id} has successfully been added to the database.` - ); + logger?.verbose(`Created user: ${user.id} for guild: ${guild.id}`); }) - .catch(async (err: any) => { - logger.error(err); + .catch(async (error) => { + logger?.error( + `Error creating user: ${user.id} for guild: ${guild.id} - ${error}` + ); }); return newUserObj; diff --git a/src/helpers/index.ts b/src/helpers/index.ts deleted file mode 100644 index 93be57e..0000000 --- a/src/helpers/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -import pluralize from "./pluralize"; - -export default { pluralize }; diff --git a/src/helpers/pluralize.ts b/src/helpers/pluralize.ts index 0bed6ba..c255427 100644 --- a/src/helpers/pluralize.ts +++ b/src/helpers/pluralize.ts @@ -1,2 +1,7 @@ -export default (count: number, noun: string, suffix?: string) => - `${count} ${noun}${count !== 1 ? suffix || "s" : ""}`; +import logger from "@root/logger"; + +export default (count: number, noun: string, suffix?: string) => { + const result = `${count} ${noun}${count !== 1 ? suffix || "s" : ""}`; + logger?.verbose(`Pluralized ${count} to ${result}`); + return result; +}; diff --git a/src/helpers/saveUser.ts b/src/helpers/saveUser.ts index 01c7684..cb1045b 100644 --- a/src/helpers/saveUser.ts +++ b/src/helpers/saveUser.ts @@ -18,22 +18,22 @@ export default async function saveUser(data: any, data2: any) { ); // 100 - 1000 random Number generator data.save((_: any) => _ - ? logger.error( + ? logger?.error( `ERROR Occurred while saving data (saveUser) \n${"=".repeat( 50 )}\n${`${_}\n${"=".repeat(50)}`}` ) - : "No Error" + : logger?.verbose(`Saved user: ${data.id} (saveUser)`) ); if (data2) { data2.save((_: any) => _ - ? logger.error( + ? logger?.error( `ERROR Occurred while saving data (saveUser) \n${"=".repeat( 50 )}\n${`${_}\n${"=".repeat(50)}`}` ) - : "No Error" + : logger?.verbose(`Saved user: ${data2.id} (saveUser)`) ); } }, diff --git a/src/helpers/sleep.ts b/src/helpers/sleep.ts index ced6bf6..bd209e1 100644 --- a/src/helpers/sleep.ts +++ b/src/helpers/sleep.ts @@ -1,5 +1,8 @@ +import logger from "@logger"; + export default function sleep(milliseconds: any) { return new Promise((resolve) => { setTimeout(resolve, milliseconds); + logger?.verbose(`Sleeping for ${milliseconds} milliseconds`); }); } diff --git a/src/helpers/updatePresence.ts b/src/helpers/updatePresence.ts index 4b90b79..b44682b 100644 --- a/src/helpers/updatePresence.ts +++ b/src/helpers/updatePresence.ts @@ -1,13 +1,14 @@ // Dependencies import { Client } from "discord.js"; +import logger from "@logger"; // Function export default async (client: Client) => { - // Set client status + const status = `${client?.guilds?.cache?.size} guilds.`; + client?.user?.setPresence({ - activities: [ - { type: "WATCHING", name: `${client?.guilds?.cache?.size} guilds` }, - ], + activities: [{ type: "WATCHING", name: status }], status: "online", }); + logger?.verbose(`Updated client presence to: ${status}`); }; diff --git a/src/locale/index.ts b/src/locale/index.ts index f4195f4..4749232 100644 --- a/src/locale/index.ts +++ b/src/locale/index.ts @@ -1,135 +1,143 @@ import i18next from "i18next"; +import logger from "@logger"; export default async () => { - await i18next.init({ - lng: "en", // if you're using a language detector, do not define the lng option - // debug: true, - fallbackLng: "en", - resources: { - en: { - general: { not_available: "Not Available" }, - commands: { - credits: { - general: { - credits_one: "{{count}} credit", - credits_other: "{{count}} credits", + await i18next + .init({ + lng: "en", // if you're using a language detector, do not define the lng option + // debug: true, + fallbackLng: "en", + resources: { + en: { + general: { not_available: "Not Available" }, + commands: { + credits: { + general: { + credits_one: "{{count}} credit", + credits_other: "{{count}} credits", + }, + addons: { + balance: { embed: { title: "Credits" } }, + gift: { embed: { title: "Gift" } }, + }, }, - addons: { - balance: { embed: { title: "Credits" } }, - gift: { embed: { title: "Gift" } }, - }, - }, - reputation: { - addons: { - give: { - version01: { - embed: { - title: ":medal: Reputation", - description: - "You have given reputation within the last day, you can not repute now!", + reputation: { + addons: { + give: { + version01: { + embed: { + title: ":medal: Reputation", + description: + "You have given reputation within the last day, you can not repute now!", + }, }, - }, - version02: { - embed: { - title: ":medal: Reputation", - description: - "You have given {{user}} a {{type}} reputation!", + version02: { + embed: { + title: ":medal: Reputation", + description: + "You have given {{user}} a {{type}} reputation!", + }, }, - }, - version03: { - embed: { - title: ":medal: Reputation", - description: "You can not repute yourself.", + version03: { + embed: { + title: ":medal: Reputation", + description: "You can not repute yourself.", + }, }, }, }, }, - }, - profile: { - addons: { - view: { - embed: { - title: "Profile", - reputation: "Reputation (Global)", - level: "Level (Guild)", - points: "Points (Guild)", - credits: "Credits (Guild)", - language_code: "Language Code (Global)", + profile: { + addons: { + view: { + embed: { + title: "Profile", + reputation: "Reputation (Global)", + level: "Level (Guild)", + points: "Points (Guild)", + credits: "Credits (Guild)", + language_code: "Language Code (Global)", + }, }, - }, - settings: { - embed: { - title: "Profile", - description: "Following settings is set", - fields: { language: "Language" }, + settings: { + embed: { + title: "Profile", + description: "Following settings is set", + fields: { language: "Language" }, + }, }, }, }, }, }, - }, - sv: { - general: { not_available: "Otillgänglig" }, - commands: { - credits: { - general: { - credits_one: "{{count}} krona", - credits_other: "{{count}} kronor", + sv: { + general: { not_available: "Otillgänglig" }, + commands: { + credits: { + general: { + credits_one: "{{count}} krona", + credits_other: "{{count}} kronor", + }, + addons: { + balance: { embed: { title: "Krediter" } }, + gift: { embed: { title: "Gåva" } }, + }, }, - addons: { - balance: { embed: { title: "Krediter" } }, - gift: { embed: { title: "Gåva" } }, - }, - }, - reputation: { - addons: { - give: { - version01: { - embed: { - title: ":medal: Omdöme", - description: - "Du har redan gett omdöme inom den senaste dagen, du kan inte ge ett omdöme just nu!", + reputation: { + addons: { + give: { + version01: { + embed: { + title: ":medal: Omdöme", + description: + "Du har redan gett omdöme inom den senaste dagen, du kan inte ge ett omdöme just nu!", + }, }, - }, - version02: { - embed: { - title: ":medal: Omdöme", - description: "Du har gett {{user}} ett {{type}} omdöme!", + version02: { + embed: { + title: ":medal: Omdöme", + description: "Du har gett {{user}} ett {{type}} omdöme!", + }, }, - }, - version03: { - embed: { - title: ":medal: Omdöme", - description: "Du kan inte ge dig själv ett omdöme.", + version03: { + embed: { + title: ":medal: Omdöme", + description: "Du kan inte ge dig själv ett omdöme.", + }, }, }, }, }, - }, - profile: { - addons: { - view: { - embed: { - title: "Profil", - reputation: "Omdöme (Globalt)", - level: "Nivå (Server)", - points: "Poäng (Server)", - credits: "Krediter (Server)", - language_code: "Språkkod (Globalt)", + profile: { + addons: { + view: { + embed: { + title: "Profil", + reputation: "Omdöme (Globalt)", + level: "Nivå (Server)", + points: "Poäng (Server)", + credits: "Krediter (Server)", + language_code: "Språkkod (Globalt)", + }, }, - }, - settings: { - embed: { - title: "Profil", - description: "Följande inställningar är satta", - fields: { language: "Språk" }, + settings: { + embed: { + title: "Profil", + description: "Följande inställningar är satta", + fields: { language: "Språk" }, + }, }, }, }, }, }, }, - }, - }); + }) + .then(async () => { + logger?.verbose(`i18next initialized`); + }) + .catch(async (error) => { + logger?.error(`i18next failed to initialize: ${error}`); + }); }; diff --git a/src/plugins/counters/index.ts b/src/plugins/counters/index.ts index 7a5a5df..4da895c 100644 --- a/src/plugins/counters/index.ts +++ b/src/plugins/counters/index.ts @@ -2,19 +2,24 @@ import { CommandInteraction } from "discord.js"; import { SlashCommandBuilder } from "@discordjs/builders"; +import logger from "@logger"; + import modules from "@root/plugins/counters/modules"; export default { metadata: { author: "Zyner" }, data: new SlashCommandBuilder() .setName("counters") - .setDescription("Manage counters.") + .setDescription("View guild counters") .addSubcommand(modules.view.data), async execute(interaction: CommandInteraction) { const { options } = interaction; if (options?.getSubcommand() === "view") { + logger?.verbose(`Executing view subcommand`); return modules.view.execute(interaction); } + + logger?.verbose(`Unknown subcommand ${options?.getSubcommand()}`); }, }; diff --git a/src/plugins/counters/modules/view/index.ts b/src/plugins/counters/modules/view/index.ts index 3e3cf8f..e7635c2 100644 --- a/src/plugins/counters/modules/view/index.ts +++ b/src/plugins/counters/modules/view/index.ts @@ -17,11 +17,13 @@ export default { data: (command: SlashCommandSubcommandBuilder) => { return command .setName("view") - .setDescription("View a counter's count.") + .setDescription(`View a guild counter`) .addChannelOption((option) => option .setName("channel") - .setDescription("The counter channel you want to view.") + .setDescription( + `The channel that contains the counter you want to view` + ) .setRequired(true) .addChannelType(ChannelType.GuildText as number) ); @@ -41,7 +43,7 @@ export default { embeds: [ new MessageEmbed() .setTitle("[:1234:] Counters (View)") - .setDescription(`${discordChannel} is not a counting channel!`) + .setDescription(`No counter found for channel ${discordChannel}!`) .setTimestamp(new Date()) .setColor(errorColor) .setFooter({ @@ -57,7 +59,7 @@ export default { new MessageEmbed() .setTitle("[:1234:] Counters (View)") .setDescription( - `${discordChannel} is currently at number ${counter?.counter}.` + `Viewing counter for channel ${discordChannel} with count ${counter.counter}.` ) .setTimestamp(new Date()) .setColor(successColor) diff --git a/src/plugins/credits/index.ts b/src/plugins/credits/index.ts index 05e0c9a..4566feb 100644 --- a/src/plugins/credits/index.ts +++ b/src/plugins/credits/index.ts @@ -2,6 +2,8 @@ import { SlashCommandBuilder } from "@discordjs/builders"; import { CommandInteraction } from "discord.js"; +import logger from "@logger"; + // Modules import modules from "@root/plugins/credits/modules"; @@ -18,19 +20,25 @@ export default { const { options } = interaction; if (options?.getSubcommand() === "balance") { + logger?.verbose(`Executing balance subcommand`); return modules.balance.execute(interaction); } if (options?.getSubcommand() === "gift") { + logger?.verbose(`Executing gift subcommand`); return modules.gift.execute(interaction); } if (options?.getSubcommand() === "top") { + logger?.verbose(`Executing top command`); return modules.top.execute(interaction); } if (options?.getSubcommand() === "work") { + logger?.verbose(`Executing work command`); return modules.work.execute(interaction); } + + logger?.verbose(`Unknown subcommand ${options?.getSubcommand()}`); }, }; diff --git a/src/plugins/credits/modules/balance/index.ts b/src/plugins/credits/modules/balance/index.ts index ee45681..f3b2e19 100644 --- a/src/plugins/credits/modules/balance/index.ts +++ b/src/plugins/credits/modules/balance/index.ts @@ -2,6 +2,8 @@ import { CommandInteraction, MessageEmbed } from "discord.js"; import { SlashCommandSubcommandBuilder } from "@discordjs/builders"; +import logger from "@logger"; + // Configurations import { errorColor, @@ -19,13 +21,13 @@ export default { return ( command .setName("balance") - .setDescription("Check a user's balance.") + .setDescription(`View a user's balance`) // User .addUserOption((option) => option .setName("user") - .setDescription("The user whose balance you want to check.") + .setDescription(`The user whose balance you want to view`) ) ); }, @@ -35,11 +37,13 @@ export default { const discordUser = options?.getUser("user"); if (guild === null) { + logger?.verbose(`Guild is null`); + return interaction?.editReply({ embeds: [ new MessageEmbed() .setTitle("[:dollar:] Credits (Balance)") - .setDescription(`We can not find your guild!`) + .setDescription(`You can only use this command in a guild!`) .setTimestamp(new Date()) .setColor(errorColor) .setFooter({ text: footerText, iconURL: footerIcon }), @@ -50,13 +54,13 @@ export default { const userObj = await fetchUser(discordUser || user, guild); if (userObj === null) { + logger?.verbose(`User not found`); + return interaction?.editReply({ embeds: [ new MessageEmbed() .setTitle("[:dollar:] Credits (Balance)") - .setDescription( - `We can not find ${discordUser || "you"} in our database!` - ) + .setDescription(`Could not find user ${discordUser || user}`) .setTimestamp(new Date()) .setColor(errorColor) .setFooter({ text: footerText, iconURL: footerIcon }), @@ -65,15 +69,14 @@ export default { } if (userObj.credits === null) { + logger?.verbose(`User has no credits`); + return interaction?.editReply({ embeds: [ new MessageEmbed() .setTitle("[:dollar:] Credits (Balance)") - .setDescription( - `We can not find credits for ${ - discordUser || "you" - } in our database!` - ) + .setDescription(`${userObj} has no credits!`) + .setDescription(`${discordUser || user} has no credits!`) .setTimestamp(new Date()) .setColor(errorColor) .setFooter({ text: footerText, iconURL: footerIcon }), @@ -81,15 +84,17 @@ export default { }); } + logger?.verbose(`Found user ${discordUser || user}`); + return interaction?.editReply({ embeds: [ new MessageEmbed() .setTitle("[:dollar:] Credits (Balance)") .setDescription( - `${discordUser || "You"} have ${pluralize( + `${userObj} has ${userObj.credits} ${pluralize( userObj.credits, - "credit" - )}.` + `credit` + )}!` ) .setTimestamp(new Date()) .setColor(successColor) diff --git a/src/plugins/credits/modules/gift/index.ts b/src/plugins/credits/modules/gift/index.ts index a083313..2ce6a62 100644 --- a/src/plugins/credits/modules/gift/index.ts +++ b/src/plugins/credits/modules/gift/index.ts @@ -10,14 +10,13 @@ import { } from "@config/embed"; // Handlers -import logger from "../../../../logger"; +import logger from "@logger"; // Helpers -import saveUser from "../../../../helpers/saveUser"; -import pluralize from "../../../../helpers/pluralize"; +import saveUser from "@helpers/saveUser"; // Models -import fetchUser from "../../../../helpers/fetchUser"; +import fetchUser from "@helpers/fetchUser"; import { SlashCommandSubcommandBuilder } from "@discordjs/builders"; // Function @@ -25,17 +24,17 @@ export default { data: (command: SlashCommandSubcommandBuilder) => { return command .setName("gift") - .setDescription("Gift someone credits from your credits.") + .setDescription(`Gift a user credits`) .addUserOption((option) => option .setName("user") - .setDescription("The user you want to pay.") + .setDescription("The user you want to gift credits to.") .setRequired(true) ) .addIntegerOption((option) => option .setName("amount") - .setDescription("The amount you will pay.") + .setDescription("The amount of credits you want to gift.") .setRequired(true) ) .addStringOption((option) => @@ -50,6 +49,8 @@ export default { const optionReason = options?.getString("reason"); if (guild === null) { + logger?.verbose(`Guild is null`); + return interaction.editReply({ embeds: [ new MessageEmbed() @@ -63,6 +64,8 @@ export default { } if (optionUser === null) { + logger?.verbose(`User not found`); + return interaction.editReply({ embeds: [ new MessageEmbed() @@ -82,6 +85,8 @@ export default { const toUserDB = await fetchUser(optionUser, guild); if (fromUserDB === null) { + logger?.verbose(`User not found`); + return interaction.editReply({ embeds: [ new MessageEmbed() @@ -97,6 +102,8 @@ export default { } if (toUserDB === null) { + logger?.verbose(`User not found`); + return interaction.editReply({ embeds: [ new MessageEmbed() @@ -113,6 +120,8 @@ export default { // If receiver is same as sender if (optionUser?.id === user?.id) { + logger?.verbose(`User is same as sender`); + return interaction.editReply({ embeds: [ new MessageEmbed() @@ -127,6 +136,8 @@ export default { // If amount is null if (optionAmount === null) { + logger?.verbose(`Amount is null`); + return interaction.editReply({ embeds: [ new MessageEmbed() @@ -141,6 +152,8 @@ export default { // If amount is zero or below if (optionAmount <= 0) { + logger?.verbose(`Amount is zero or below`); + return interaction.editReply({ embeds: [ new MessageEmbed() @@ -155,6 +168,8 @@ export default { // If user has below gifting amount if (fromUserDB?.credits < optionAmount) { + logger?.verbose(`User has below gifting amount`); + return interaction.editReply({ embeds: [ new MessageEmbed() @@ -171,6 +186,8 @@ export default { // If toUserDB has no credits if (toUserDB === null) { + logger?.verbose(`User has no credits`); + return interaction.editReply({ embeds: [ new MessageEmbed() @@ -203,28 +220,23 @@ export default { new MessageEmbed() .setTitle("[:dollar:] Credits (Gift)") .setDescription( - `You received ${pluralize( - optionAmount, - "credit" - )} from ${user}${ + `You have received ${optionAmount} credits from ${ + user?.tag + } with reason ${ optionReason ? ` with reason: ${optionReason}` : "" - }. Your new credits is ${pluralize( - toUserDB?.credits, - "credit" - )}.` + }!` ) .setTimestamp(new Date()) .setColor(successColor) .setFooter({ text: footerText, iconURL: footerIcon }), ], }) - .catch(async () => - logger.debug(`Can not send DM to user ${optionUser?.id}`) + .catch(async (error) => + logger?.error(`[Gift] Error sending DM to user: ${error}`) ); - // Send debug message - logger.debug( - `Guild: ${guild?.id} User: ${user?.id} gift sent from: ${user?.id} to: ${optionUser?.id}` + logger?.verbose( + `[Gift] Successfully gifted ${optionAmount} credits to ${optionUser?.tag}` ); return interaction.editReply({ @@ -232,12 +244,7 @@ export default { new MessageEmbed() .setTitle("[:dollar:] Credits (Gift)") .setDescription( - `You sent ${pluralize(optionAmount, "credit")} to ${optionUser}${ - optionReason ? ` with reason: ${optionReason}` : "" - }. Your new credits is ${pluralize( - fromUserDB?.credits, - "credit" - )}.` + `Successfully gifted ${optionAmount} credits to ${optionUser?.tag}!` ) .setTimestamp(new Date()) .setColor(successColor) diff --git a/src/plugins/credits/modules/top/index.ts b/src/plugins/credits/modules/top/index.ts index 2cd1ced..c27f4df 100644 --- a/src/plugins/credits/modules/top/index.ts +++ b/src/plugins/credits/modules/top/index.ts @@ -12,7 +12,7 @@ import pluralize from "@helpers/pluralize"; export default { data: (command: SlashCommandSubcommandBuilder) => { - return command.setName("top").setDescription("Check the top balance."); + return command.setName("top").setDescription(`View the top users`); }, execute: async (interaction: CommandInteraction) => { // Get all users in the guild @@ -29,19 +29,16 @@ export default { // Create entry object const entry = (x: any, index: number) => - `**Top ${index + 1}** - <@${x?.userId}> ${pluralize( - x?.credits, - "credit" - )}`; + `${index + 1}. <@${x?.userId}> - ${pluralize(x?.credits, "credit")}`; return interaction.editReply({ embeds: [ new MessageEmbed() .setTitle("[:dollar:] Credits (Top)") .setDescription( - `Below are the top ten. + `Top 10 users with the most credits. - ${topTen?.map((x, index) => entry(x, index))?.join("\n")}` + ${topTen.map(entry).join("\n")}` ) .setTimestamp(new Date()) .setColor(successColor) diff --git a/src/plugins/credits/modules/work/index.ts b/src/plugins/credits/modules/work/index.ts index 7b9a7eb..2ffb20d 100644 --- a/src/plugins/credits/modules/work/index.ts +++ b/src/plugins/credits/modules/work/index.ts @@ -13,13 +13,12 @@ import logger from "@logger"; import timeoutSchema from "@schemas/timeout"; // Helpers -import pluralize from "@helpers/pluralize"; import fetchUser from "@helpers/fetchUser"; import fetchGuild from "@helpers/fetchGuild"; export default { data: (command: SlashCommandSubcommandBuilder) => { - return command.setName("work").setDescription("Work for credits."); + return command.setName("work").setDescription(`Work to earn credits`); }, execute: async (interaction: CommandInteraction) => { // Destructure member @@ -35,77 +34,22 @@ export default { timeoutId: "2022-03-15-19-16", }); - if (guild === null) return; + if (guild === null) { + return logger?.verbose(`Guild is null`); + } const guildDB = await fetchGuild(guild); // If user is not on timeout - if (!isTimeout) { - const creditsEarned = chance.integer({ - min: 0, - max: guildDB?.credits?.workRate, - }); - - const userDB = await fetchUser(user, guild); - - if (userDB === null) return; - - userDB.credits += creditsEarned; - - await userDB?.save()?.then(async () => { - logger?.debug(`Credits added to user: ${user?.id}`); - - return interaction.editReply({ - embeds: [ - new MessageEmbed() - .setTitle("[:dollar:] Credits (Work)") - .setDescription( - `You have earned ${pluralize(creditsEarned, "credit")}.` - ) - .setTimestamp(new Date()) - .setColor(successColor) - .setFooter({ text: footerText, iconURL: footerIcon }), - ], - }); - }); - - // Create a timeout for the user - await timeoutSchema?.create({ - guildId: guild?.id, - userId: user?.id, - timeoutId: "2022-03-15-19-16", - }); - - setTimeout(async () => { - logger?.debug( - `Guild: ${guild?.id} User: ${ - user?.id - } has not worked within the last ${ - guildDB?.credits?.workTimeout / 1000 - } seconds, work can be done` - ); - - // When timeout is out, remove it from the database - await timeoutSchema?.deleteOne({ - guildId: guild?.id, - userId: user?.id, - timeoutId: "2022-03-15-19-16", - }); - }, guildDB?.credits?.workTimeout); - } else { - // Send debug message - logger?.debug( - `Guild: ${guild?.id} User: ${user?.id} has worked within last day, no work can be done` - ); + if (isTimeout) { + logger?.verbose(`User ${user?.id} is on timeout`); return interaction.editReply({ embeds: [ new MessageEmbed() .setTitle("[:dollar:] Credits (Work)") .setDescription( - `You have worked within the last ${ - guildDB?.credits?.workTimeout / 1000 - } seconds, you can not work now!` + `You can not work while on timeout, please wait ${guildDB?.credits.workTimeout} seconds.` ) .setTimestamp(new Date()) .setColor(successColor) @@ -113,5 +57,53 @@ export default { ], }); } + + const creditsEarned = chance.integer({ + min: 0, + max: guildDB?.credits?.workRate, + }); + + const userDB = await fetchUser(user, guild); + + if (userDB === null) { + return logger?.verbose(`User not found`); + } + + userDB.credits += creditsEarned; + + await userDB?.save()?.then(async () => { + logger?.verbose( + `User ${userDB?.userId} worked and earned ${creditsEarned} credits` + ); + + return interaction.editReply({ + embeds: [ + new MessageEmbed() + .setTitle("[:dollar:] Credits (Work)") + .setDescription(`You worked and earned ${creditsEarned} credits`) + .setTimestamp(new Date()) + .setColor(successColor) + .setFooter({ text: footerText, iconURL: footerIcon }), + ], + }); + }); + + // Create a timeout for the user + await timeoutSchema?.create({ + guildId: guild?.id, + userId: user?.id, + timeoutId: "2022-03-15-19-16", + }); + + setTimeout(async () => { + logger?.verbose(`Removing timeout for user ${user?.id}`); + + // When timeout is out, remove it from the database + await timeoutSchema?.deleteOne({ + guildId: guild?.id, + userId: user?.id, + timeoutId: "2022-03-15-19-16", + }); + }, guildDB?.credits?.workTimeout); }, }; diff --git a/src/plugins/manage/groups/counters/index.ts b/src/plugins/manage/groups/counters/index.ts index f60e671..dc3c255 100644 --- a/src/plugins/manage/groups/counters/index.ts +++ b/src/plugins/manage/groups/counters/index.ts @@ -2,6 +2,8 @@ import { SlashCommandSubcommandGroupBuilder } from "@discordjs/builders"; import { CommandInteraction } from "discord.js"; +import logger from "@logger"; + // Modules import moduleCreate from "./modules/create"; import moduleDelete from "./modules/delete"; @@ -11,7 +13,7 @@ export default { data: (group: SlashCommandSubcommandGroupBuilder) => { return group .setName("counters") - .setDescription("Manage your guild's counters.") + .setDescription("Manage guild counters.") .addSubcommand(moduleCreate.data) .addSubcommand(moduleDelete.data); }, @@ -19,11 +21,17 @@ export default { const { options } = interaction; if (options?.getSubcommand() === "create") { + logger?.verbose(`Executing create subcommand`); + return moduleCreate.execute(interaction); } if (options?.getSubcommand() === "delete") { + logger?.verbose(`Executing delete subcommand`); + return moduleDelete.execute(interaction); } + + logger?.verbose(`Unknown subcommand ${options?.getSubcommand()}`); }, }; diff --git a/src/plugins/manage/groups/counters/modules/create/index.ts b/src/plugins/manage/groups/counters/modules/create/index.ts index 43c55a3..32c83fb 100644 --- a/src/plugins/manage/groups/counters/modules/create/index.ts +++ b/src/plugins/manage/groups/counters/modules/create/index.ts @@ -15,7 +15,7 @@ import { import logger from "@logger"; // Models -import counterSchema from "../../../../../../database/schemas/counter"; +import counterSchema from "@schemas/counter"; // Function export default { @@ -26,24 +26,24 @@ export default { .addChannelOption((option) => option .setName("channel") - .setDescription("The channel you want to add a counter to.") + .setDescription("The channel to send the counter to.") .setRequired(true) .addChannelType(ChannelType.GuildText as number) ) .addStringOption((option) => option .setName("word") - .setDescription("The word you want to count.") + .setDescription("The word to use for the counter.") .setRequired(true) ) .addNumberOption((option) => option .setName("start") - .setDescription("The count that the counter will start at.") + .setDescription("The starting value of the counter.") ); }, execute: async (interaction: CommandInteraction) => { - const { options, guild, user } = interaction; + const { options, guild } = interaction; const discordChannel = options?.getChannel("channel"); const countingWord = options?.getString("word"); @@ -59,9 +59,7 @@ export default { embeds: [ new MessageEmbed() .setTitle("[:toolbox:] Manage - Counters (Create)") - .setDescription( - `${discordChannel} is already a counting channel, currently it's counting ${counter.word}!` - ) + .setDescription(`A counter already exists for this channel.`) .setTimestamp(new Date()) .setColor(errorColor) .setFooter({ text: footerText, iconURL: footerIcon }), @@ -77,19 +75,13 @@ export default { counter: startValue || 0, }) .then(async () => { - logger?.debug( - `Guild: ${guild?.id} User: ${user?.id} added ${discordChannel?.id} as a counter using word "${countingWord}" for counting.` - ); + logger?.verbose(`Created counter`); return interaction?.editReply({ embeds: [ new MessageEmbed() .setTitle("[:toolbox:] Manage - Counters (Create)") - .setDescription( - `${discordChannel} is now counting when hearing word ${countingWord} and it starts at number ${ - startValue || 0 - }.` - ) + .setDescription(`Created counter for ${discordChannel}`) .setTimestamp(new Date()) .setColor(successColor) .setFooter({ text: footerText, iconURL: footerIcon }), diff --git a/src/plugins/manage/groups/counters/modules/delete/index.ts b/src/plugins/manage/groups/counters/modules/delete/index.ts index d9d76bf..67bd222 100644 --- a/src/plugins/manage/groups/counters/modules/delete/index.ts +++ b/src/plugins/manage/groups/counters/modules/delete/index.ts @@ -13,7 +13,7 @@ import { import logger from "@logger"; // Models -import counterSchema from "../../../../../../database/schemas/counter"; +import counterSchema from "@schemas/counter"; import { SlashCommandSubcommandBuilder } from "@discordjs/builders"; import { ChannelType } from "discord-api-types/v10"; @@ -22,17 +22,17 @@ export default { data: (command: SlashCommandSubcommandBuilder) => { return command .setName("delete") - .setDescription("Delete a counter from your guild.") + .setDescription(`Delete a counter from your guild.`) .addChannelOption((option) => option .setName("channel") - .setDescription("The channel that you want to delete a counter from.") + .setDescription("The channel to delete the counter from.") .setRequired(true) .addChannelType(ChannelType.GuildText as number) ); }, execute: async (interaction: CommandInteraction) => { - const { options, guild, user } = interaction; + const { options, guild } = interaction; const discordChannel = options?.getChannel("channel"); @@ -42,11 +42,13 @@ export default { }); if (counter === null) { + logger?.verbose(`Counter is null`); + return interaction?.editReply({ embeds: [ new MessageEmbed() .setTitle("[:toolbox:] Manage - Counters (Delete)") - .setDescription(`${discordChannel} is not a counting channel!`) + .setDescription(`The counter for this channel does not exist.`) .setTimestamp(new Date()) .setColor(errorColor) .setFooter({ text: footerText, iconURL: footerIcon }), @@ -60,22 +62,21 @@ export default { channelId: discordChannel?.id, }) ?.then(async () => { + logger?.verbose(`Counter deleted`); + return interaction?.editReply({ embeds: [ new MessageEmbed() .setTitle("[:toolbox:] Manage - Counters (Delete)") - .setDescription( - `${discordChannel} is no longer an counting channel.` - ) + .setDescription(`The counter for this channel has been deleted.`) .setTimestamp(new Date()) .setColor(successColor) .setFooter({ text: footerText, iconURL: footerIcon }), ], }); + }) + .catch(async (error) => { + logger?.error(`Error deleting counter: ${error}`); }); - - logger?.debug( - `Guild: ${guild?.id} User: ${user?.id} removed ${discordChannel?.id} as a counter.` - ); }, }; diff --git a/src/plugins/manage/groups/credits/index.ts b/src/plugins/manage/groups/credits/index.ts index 3072c56..9209f8a 100644 --- a/src/plugins/manage/groups/credits/index.ts +++ b/src/plugins/manage/groups/credits/index.ts @@ -2,6 +2,8 @@ import { CommandInteraction } from "discord.js"; import { SlashCommandSubcommandGroupBuilder } from "@discordjs/builders"; +import logger from "@logger"; + // Modules import moduleGive from "./modules/give"; import moduleSet from "./modules/set"; @@ -13,7 +15,7 @@ export default { data: (group: SlashCommandSubcommandGroupBuilder) => { return group .setName("credits") - .setDescription("Manage guild member's credits.") + .setDescription("Manage the credits of a user.") .addSubcommand(moduleGive.data) .addSubcommand(moduleSet.data) .addSubcommand(moduleTake.data) @@ -23,19 +25,29 @@ export default { const { options } = interaction; if (options?.getSubcommand() === "give") { + logger?.verbose(`Executing give subcommand`); + return moduleGive.execute(interaction); } if (options?.getSubcommand() === "set") { + logger?.verbose(`Executing set subcommand`); + return moduleSet.execute(interaction); } if (options?.getSubcommand() === "take") { + logger?.verbose(`Executing take subcommand`); + return moduleTake.execute(interaction); } if (options?.getSubcommand() === "transfer") { + logger?.verbose(`Executing transfer subcommand`); + return moduleTransfer.execute(interaction); } + + logger?.verbose(`No subcommand found`); }, }; diff --git a/src/plugins/manage/groups/credits/modules/give/index.ts b/src/plugins/manage/groups/credits/modules/give/index.ts index 02dca8c..2345852 100644 --- a/src/plugins/manage/groups/credits/modules/give/index.ts +++ b/src/plugins/manage/groups/credits/modules/give/index.ts @@ -24,34 +24,36 @@ export default { data: (command: SlashCommandSubcommandBuilder) => { return command .setName("give") - .setDescription("Give credits to a user") + .setDescription("Give credits to a user.") .addUserOption((option) => option .setName("user") - .setDescription("The user you want to pay.") + .setDescription("The user to give credits to.") .setRequired(true) ) .addIntegerOption((option) => option .setName("amount") - .setDescription("The amount you will pay.") + .setDescription(`The amount of credits to give.`) .setRequired(true) ); }, execute: async (interaction: CommandInteraction) => { // Destructure - const { guild, user, options } = interaction; + const { guild, options } = interaction; const discordReceiver = options?.getUser("user"); const creditAmount = options?.getInteger("amount"); // If amount option is null if (creditAmount === null) { + logger?.verbose(`Amount is null`); + return interaction?.editReply({ embeds: [ new MessageEmbed() .setTitle("[:toolbox:] Manage - Credits (Give)") - .setDescription(`We could not read your requested amount!`) + .setDescription(`You must provide an amount.`) .setTimestamp(new Date()) .setColor(errorColor) .setFooter({ text: footerText, iconURL: footerIcon }), @@ -61,11 +63,13 @@ export default { // If amount is zero or below if (creditAmount <= 0) { + logger?.verbose(`Amount is zero or below`); + return interaction?.editReply({ embeds: [ new MessageEmbed() .setTitle("[:toolbox:] Manage - Credits (Give)") - .setDescription(`You can not give zero credits or below!`) + .setDescription(`You must provide an amount greater than zero.`) .setTimestamp(new Date()) .setColor(errorColor) .setFooter({ text: footerText, iconURL: footerIcon }), @@ -74,11 +78,13 @@ export default { } if (discordReceiver === null) { + logger?.verbose(`Discord receiver is null`); + return interaction?.editReply({ embeds: [ new MessageEmbed() .setTitle("[:toolbox:] Manage - Credits (Give)") - .setDescription(`We could not read receiver user!`) + .setDescription(`You must provide a user.`) .setTimestamp(new Date()) .setColor(errorColor) .setFooter({ text: footerText, iconURL: footerIcon }), @@ -86,11 +92,13 @@ export default { }); } if (guild === null) { + logger?.verbose(`Guild is null`); + return interaction?.editReply({ embeds: [ new MessageEmbed() .setTitle("[:toolbox:] Manage - Credits (Give)") - .setDescription(`We could not read your guild!`) + .setDescription(`You must be in a guild.`) .setTimestamp(new Date()) .setColor(errorColor) .setFooter({ text: footerText, iconURL: footerIcon }), @@ -101,13 +109,13 @@ export default { const toUser = await fetchUser(discordReceiver, guild); if (toUser === null) { + logger?.verbose(`To user is null`); + return interaction?.editReply({ embeds: [ new MessageEmbed() .setTitle("[:toolbox:] Manage - Credits (Give)") - .setDescription( - `We could not read your receiver user from our database!` - ) + .setDescription(`The user you provided could not be found.`) .setTimestamp(new Date()) .setColor(errorColor) .setFooter({ text: footerText, iconURL: footerIcon }), @@ -120,9 +128,7 @@ export default { embeds: [ new MessageEmbed() .setTitle("[:toolbox:] Manage - Credits (Give)") - .setDescription( - `We could not find credits for ${discordReceiver} in our database!` - ) + .setDescription(`The user you provided does not have any credits.`) .setTimestamp(new Date()) .setColor(errorColor) .setFooter({ text: footerText, iconURL: footerIcon }), @@ -135,21 +141,14 @@ export default { // Save toUser await toUser?.save()?.then(async () => { - logger?.debug( - `Guild: ${guild?.id} User: ${user?.id} gave ${ - discordReceiver?.id - } ${pluralize(creditAmount, "credit")}.` - ); + logger?.verbose(`Saved toUser`); return interaction?.editReply({ embeds: [ new MessageEmbed() .setTitle("[:toolbox:] Manage - Credits (Give)") .setDescription( - `We have given ${discordReceiver}, ${pluralize( - creditAmount, - "credit" - )}.` + `Successfully gave ${pluralize(creditAmount, "credit")}` ) .setTimestamp(new Date()) .setColor(successColor) diff --git a/src/plugins/manage/groups/credits/modules/set/index.ts b/src/plugins/manage/groups/credits/modules/set/index.ts index 0b3daa6..53103a4 100644 --- a/src/plugins/manage/groups/credits/modules/set/index.ts +++ b/src/plugins/manage/groups/credits/modules/set/index.ts @@ -13,7 +13,6 @@ import { import logger from "@logger"; // Helpers -import pluralize from "@helpers/pluralize"; // Models import fetchUser from "@helpers/fetchUser"; @@ -24,33 +23,35 @@ export default { data: (command: SlashCommandSubcommandBuilder) => { return command .setName("set") - .setDescription("Set credits to a user") + .setDescription("Set the amount of credits a user has.") .addUserOption((option) => option .setName("user") - .setDescription("The user you want to set credits on.") + .setDescription("The user to set the amount of credits for.") .setRequired(true) ) .addIntegerOption((option) => option .setName("amount") - .setDescription("The amount you will set.") + .setDescription(`The amount of credits to set.`) .setRequired(true) ); }, execute: async (interaction: CommandInteraction) => { - const { options, user, guild } = interaction; + const { options, guild } = interaction; const discordUser = options.getUser("user"); const creditAmount = options.getInteger("amount"); // If amount is null if (creditAmount === null) { + logger?.verbose(`Amount is null`); + return interaction?.editReply({ embeds: [ new MessageEmbed() .setTitle("[:toolbox:] Manage - Credits (Set)") - .setDescription(`We could not read your requested amount!`) + .setDescription(`You must provide an amount.`) .setTimestamp(new Date()) .setColor(errorColor) .setFooter({ text: footerText, iconURL: footerIcon }), @@ -59,11 +60,13 @@ export default { } if (discordUser === null) { + logger?.verbose(`User is null`); + return interaction?.editReply({ embeds: [ new MessageEmbed() .setTitle("[:toolbox:] Manage - Credits (Set)") - .setDescription(`We could not read your requested user!`) + .setDescription(`You must provide a user.`) .setTimestamp(new Date()) .setColor(errorColor) .setFooter({ text: footerText, iconURL: footerIcon }), @@ -71,11 +74,13 @@ export default { }); } if (guild === null) { + logger?.verbose(`Guild is null`); + return interaction?.editReply({ embeds: [ new MessageEmbed() .setTitle("[:toolbox:] Manage - Credits (Set)") - .setDescription(`We could not read your guild!`) + .setDescription(`You must provide a guild.`) .setTimestamp(new Date()) .setColor(errorColor) .setFooter({ text: footerText, iconURL: footerIcon }), @@ -88,13 +93,13 @@ export default { // If toUser does not exist if (toUser === null) { + logger?.verbose(`User does not exist`); + return interaction?.editReply({ embeds: [ new MessageEmbed() .setTitle("[:toolbox:] Manage - Credits (Set)") - .setDescription( - `We could not read your requested user from our database!` - ) + .setDescription(`The user you provided does not exist.`) .setTimestamp(new Date()) .setColor(errorColor) .setFooter({ text: footerText, iconURL: footerIcon }), @@ -104,13 +109,13 @@ export default { // If toUser.credits does not exist if (toUser?.credits === null) { + logger?.verbose(`User does not have any credits`); + return interaction?.editReply({ embeds: [ new MessageEmbed() .setTitle("[:toolbox:] Manage - Credits (Set)") - .setDescription( - `We could not find credits for ${discordUser} in our database!` - ) + .setDescription(`The user you provided does not have any credits.`) .setTimestamp(new Date()) .setColor(errorColor) .setFooter({ text: footerText, iconURL: footerIcon }), @@ -123,21 +128,14 @@ export default { // Save toUser await toUser?.save()?.then(async () => { - logger?.debug( - `Guild: ${guild?.id} User: ${user?.id} set ${ - discordUser?.id - } to ${pluralize(creditAmount, "credit")}.` - ); + logger?.verbose(`Saved user`); return interaction?.editReply({ embeds: [ new MessageEmbed() .setTitle("[:toolbox:] Manage - Credits (Set)") .setDescription( - `We have set ${discordUser} to ${pluralize( - creditAmount, - "credit" - )}.` + `Set **${discordUser}**'s credits to **${creditAmount}**.` ) .setTimestamp(new Date()) .setColor(successColor) diff --git a/src/plugins/manage/groups/credits/modules/take/index.ts b/src/plugins/manage/groups/credits/modules/take/index.ts index 34688f8..40e74bb 100644 --- a/src/plugins/manage/groups/credits/modules/take/index.ts +++ b/src/plugins/manage/groups/credits/modules/take/index.ts @@ -24,23 +24,23 @@ export default { data: (command: SlashCommandSubcommandBuilder) => { return command .setName("take") - .setDescription("Take credits from a user") + .setDescription("Take credits from a user.") .addUserOption((option) => option .setName("user") - .setDescription("The user you want to take credits from.") + .setDescription("The user to take credits from.") .setRequired(true) ) .addIntegerOption((option) => option .setName("amount") - .setDescription("The amount you will take.") + .setDescription(`The amount of credits to take.`) .setRequired(true) ); }, execute: async (interaction: CommandInteraction) => { // Destructure - const { guild, user, options } = interaction; + const { guild, options } = interaction; // User option const optionUser = options?.getUser("user"); @@ -50,11 +50,13 @@ export default { // If amount is null if (optionAmount === null) { + logger?.verbose(`Amount is null`); + return interaction?.editReply({ embeds: [ new MessageEmbed() .setTitle("[:toolbox:] Manage - Credits (Take)") - .setDescription(`We could not read your requested amount!`) + .setDescription(`You must provide an amount.`) .setTimestamp(new Date()) .setColor(errorColor) .setFooter({ text: footerText, iconURL: footerIcon }), @@ -64,11 +66,13 @@ export default { // If amount is zero or below if (optionAmount <= 0) { + logger?.verbose(`Amount is zero or below`); + return interaction?.editReply({ embeds: [ new MessageEmbed() .setTitle("[:toolbox:] Manage - Credits (Take)") - .setDescription(`We could not take zero credits or below!`) + .setDescription(`You must provide an amount greater than zero.`) .setTimestamp(new Date()) .setColor(errorColor) .setFooter({ text: footerText, iconURL: footerIcon }), @@ -77,11 +81,13 @@ export default { } if (optionUser === null) { + logger?.verbose(`Discord receiver is null`); + return interaction?.editReply({ embeds: [ new MessageEmbed() .setTitle("[:toolbox:] Manage - Credits (Take)") - .setDescription(`We could not read your requested user!`) + .setDescription(`You must provide a user.`) .setTimestamp(new Date()) .setColor(errorColor) .setFooter({ text: footerText, iconURL: footerIcon }), @@ -89,11 +95,13 @@ export default { }); } if (guild === null) { + logger?.verbose(`Guild is null`); + return interaction?.editReply({ embeds: [ new MessageEmbed() .setTitle("[:toolbox:] Manage - Credits (Take)") - .setDescription(`We could not read your guild!`) + .setDescription(`You must be in a guild.`) .setTimestamp(new Date()) .setColor(errorColor) .setFooter({ text: footerText, iconURL: footerIcon }), @@ -106,13 +114,13 @@ export default { // If toUser does not exist if (toUser === null) { + logger?.verbose(`ToUser is null`); + return interaction?.editReply({ embeds: [ new MessageEmbed() .setTitle("[:toolbox:] Manage - Credits (Take)") - .setDescription( - `We could not read your requested user from our database!` - ) + .setDescription(`The user you provided does not exist.`) .setTimestamp(new Date()) .setColor(errorColor) .setFooter({ text: footerText, iconURL: footerIcon }), @@ -122,13 +130,13 @@ export default { // If toUser.credits does not exist if (toUser?.credits === null) { + logger?.verbose(`ToUser.credits is null`); + return interaction?.editReply({ embeds: [ new MessageEmbed() .setTitle("[:toolbox:] Manage - Credits (Take)") - .setDescription( - `We could not find credits for ${optionUser} in our database!` - ) + .setDescription(`The user you provided does not have credits.`) .setTimestamp(new Date()) .setColor(errorColor) .setFooter({ text: footerText, iconURL: footerIcon }), @@ -141,21 +149,14 @@ export default { // Save toUser await toUser?.save()?.then(async () => { - logger?.debug( - `Guild: ${guild?.id} User: ${user?.id} set ${ - optionUser?.id - } to ${pluralize(optionAmount, "credit")}.` - ); + logger?.verbose(`Saved toUser`); return interaction?.editReply({ embeds: [ new MessageEmbed() .setTitle("[:toolbox:] Manage - Credits (Take)") .setDescription( - `We have taken ${pluralize( - optionAmount, - "credit" - )} from ${optionUser}.` + `Took ${pluralize(optionAmount, "credit")} from ${optionUser}.` ) .setTimestamp(new Date()) .setColor(successColor) diff --git a/src/plugins/manage/groups/credits/modules/transfer/index.ts b/src/plugins/manage/groups/credits/modules/transfer/index.ts index f5a0d02..0dbd07d 100644 --- a/src/plugins/manage/groups/credits/modules/transfer/index.ts +++ b/src/plugins/manage/groups/credits/modules/transfer/index.ts @@ -13,7 +13,6 @@ import { import logger from "@logger"; // Helpers -import pluralize from "@helpers/pluralize"; import saveUser from "@helpers/saveUser"; // Models @@ -25,29 +24,29 @@ export default { data: (command: SlashCommandSubcommandBuilder) => { return command .setName("transfer") - .setDescription("Transfer credits from a user to another user.") + .setDescription("Transfer credits from one user to another.") .addUserOption((option) => option .setName("from") - .setDescription("The user you want to take credits from.") + .setDescription("The user to transfer credits from.") .setRequired(true) ) .addUserOption((option) => option .setName("to") - .setDescription("The user you want to give credits to.") + .setDescription("The user to transfer credits to.") .setRequired(true) ) .addIntegerOption((option) => option .setName("amount") - .setDescription("The amount you will transfer.") + .setDescription(`The amount of credits to transfer.`) .setRequired(true) ); }, execute: async (interaction: CommandInteraction) => { // Destructure member - const { guild, options, user } = interaction; + const { guild, options } = interaction; // Get options const optionFromUser = options?.getUser("from"); @@ -56,11 +55,13 @@ export default { // If amount is null if (optionAmount === null) { + logger?.verbose(`Amount is null`); + return interaction?.editReply({ embeds: [ new MessageEmbed() .setTitle("[:toolbox:] Manage - Credits (Transfer)") - .setDescription(`We could not read your requested amount!`) + .setDescription(`You must provide an amount.`) .setTimestamp(new Date()) .setColor(errorColor) .setFooter({ text: footerText, iconURL: footerIcon }), @@ -69,11 +70,13 @@ export default { } if (guild === null) { + logger?.verbose(`Guild is null`); + return interaction?.editReply({ embeds: [ new MessageEmbed() .setTitle("[:toolbox:] Manage - Credits (Transfer)") - .setDescription(`We could not read your guild!`) + .setDescription(`You must be in a guild.`) .setTimestamp(new Date()) .setColor(errorColor) .setFooter({ text: footerText, iconURL: footerIcon }), @@ -81,11 +84,13 @@ export default { }); } if (optionFromUser === null) { + logger?.verbose(`From user is null`); + return interaction?.editReply({ embeds: [ new MessageEmbed() .setTitle("[:toolbox:] Manage - Credits (Transfer)") - .setDescription(`We could not read your requested from user!`) + .setDescription(`You must provide a user to transfer from.`) .setTimestamp(new Date()) .setColor(errorColor) .setFooter({ text: footerText, iconURL: footerIcon }), @@ -93,11 +98,13 @@ export default { }); } if (optionToUser === null) { + logger?.verbose(`To user is null`); + return interaction?.editReply({ embeds: [ new MessageEmbed() .setTitle("[:toolbox:] Manage - Credits (Transfer)") - .setDescription(`We could not read your requested to user!`) + .setDescription(`You must provide a user to transfer to.`) .setTimestamp(new Date()) .setColor(errorColor) .setFooter({ text: footerText, iconURL: footerIcon }), @@ -113,12 +120,14 @@ export default { // If toUser does not exist if (fromUser === null) { + logger?.verbose(`From user does not exist`); + return interaction?.editReply({ embeds: [ new MessageEmbed() .setTitle("[:toolbox:] Manage - Credits (Transfer)") .setDescription( - `We could not read your requested from user from our database!` + `The user you provided to transfer from does not exist.` ) .setTimestamp(new Date()) .setColor(errorColor) @@ -129,12 +138,14 @@ export default { // If toUser.credits does not exist if (!fromUser?.credits) { + logger?.verbose(`From user does not have credits`); + return interaction?.editReply({ embeds: [ new MessageEmbed() .setTitle("[:toolbox:] Manage - Credits (Transfer)") .setDescription( - `We could not find credits for ${optionFromUser} in our database!` + `The user you provided to transfer from does not have credits.` ) .setTimestamp(new Date()) .setColor(errorColor) @@ -145,12 +156,14 @@ export default { // If toUser does not exist if (toUser === null) { + logger?.verbose(`To user does not exist`); + return interaction?.editReply({ embeds: [ new MessageEmbed() .setTitle("[:toolbox:] Manage - Credits (Transfer)") .setDescription( - `We could not read your requested to user from our database!` + `The user you provided to transfer to does not exist.` ) .setTimestamp(new Date()) .setColor(errorColor) @@ -161,12 +174,14 @@ export default { // If toUser.credits does not exist if (toUser?.credits === null) { + logger?.verbose(`To user does not have credits`); + return interaction?.editReply({ embeds: [ new MessageEmbed() .setTitle("[:toolbox:] Manage - Credits (Transfer)") .setDescription( - `We could not find credits for ${optionToUser} in our database!` + `The user you provided to transfer to does not have credits.` ) .setTimestamp(new Date()) .setColor(errorColor) @@ -183,23 +198,13 @@ export default { // Save users await saveUser(fromUser, toUser)?.then(async () => { - logger?.debug( - `Guild: ${guild?.id} User: ${user?.id} transferred ${pluralize( - optionAmount, - "credit" - )} from ${optionFromUser?.id} to ${optionToUser?.id}.` - ); + logger?.verbose(`Saved users`); return interaction?.editReply({ embeds: [ new MessageEmbed() .setTitle("[:toolbox:] Manage - Credits (Transfer)") - .setDescription( - `We have sent ${pluralize( - optionAmount, - "credit" - )} from ${optionFromUser} to ${optionToUser}.` - ) + .setDescription(`Transferred ${optionAmount} credits.`) .addFields( { name: `${optionFromUser?.username} Balance`, diff --git a/src/plugins/manage/index.ts b/src/plugins/manage/index.ts index 37b195e..32d066d 100644 --- a/src/plugins/manage/index.ts +++ b/src/plugins/manage/index.ts @@ -8,13 +8,14 @@ import { errorColor, footerText, footerIcon } from "@config/embed"; // Groups import credits from "./groups/credits"; import counters from "./groups/counters"; +import logger from "@logger"; // Function export default { metadata: { author: "Zyner" }, data: new SlashCommandBuilder() .setName("manage") - .setDescription("Manage your guild.") + .setDescription("Manage the bot.") .addSubcommandGroup(counters.data) .addSubcommandGroup(credits.data), @@ -28,7 +29,7 @@ export default { embeds: [ new MessageEmbed() .setTitle("[:toolbox:] Manage") - .setDescription(`You do not have permission to manage this!`) + .setDescription(`You do not have the permission to manage the bot.`) .setTimestamp(new Date()) .setColor(errorColor) .setFooter({ text: footerText, iconURL: footerIcon }), @@ -37,11 +38,17 @@ export default { } if (options?.getSubcommandGroup() === "credits") { + logger?.verbose(`Subcommand group is credits`); + return credits.execute(interaction); } if (options?.getSubcommandGroup() === "counters") { + logger?.verbose(`Subcommand group is counters`); + return counters.execute(interaction); } + + logger?.verbose(`Subcommand group is not credits or counters`); }, }; diff --git a/src/plugins/profile/index.ts b/src/plugins/profile/index.ts index 647a4f4..a255a7a 100644 --- a/src/plugins/profile/index.ts +++ b/src/plugins/profile/index.ts @@ -6,7 +6,7 @@ import { CommandInteraction } from "discord.js"; import view from "./modules/view"; // Handlers -import logger from "../../logger"; +import logger from "@logger"; // Function export default { @@ -25,20 +25,14 @@ export default { ) ), async execute(interaction: CommandInteraction) { - // Destructure - const { options, guild, user, commandName } = interaction; + const { options } = interaction; - // Module - View if (options?.getSubcommand() === "view") { - // Execute Module - View + logger?.verbose(`Executing view subcommand`); + return view(interaction); } - // Send debug message - return logger?.debug( - `Guild: ${guild?.id} User: ${ - user?.id - } executed /${commandName} ${options?.getSubcommandGroup()} ${options?.getSubcommand()}` - ); + logger?.verbose(`No subcommand found`); }, }; diff --git a/src/plugins/profile/modules/view.ts b/src/plugins/profile/modules/view.ts index d5d05bf..6e05df5 100644 --- a/src/plugins/profile/modules/view.ts +++ b/src/plugins/profile/modules/view.ts @@ -7,6 +7,8 @@ import { successColor, footerText, footerIcon } from "@config/embed"; // Models import fetchUser from "@helpers/fetchUser"; +import logger from "@logger"; + // Function export default async (interaction: CommandInteraction) => { // Destructure @@ -20,7 +22,9 @@ export default async (interaction: CommandInteraction) => { `${target ? target?.id : user?.id}` ); - if (guild === null) return; + if (guild === null) { + return logger?.verbose(`Guild is null`); + } // User Information const userObj = await fetchUser(discordUser, guild); diff --git a/src/plugins/reputation/index.ts b/src/plugins/reputation/index.ts index 61517c6..6e4de17 100644 --- a/src/plugins/reputation/index.ts +++ b/src/plugins/reputation/index.ts @@ -13,41 +13,17 @@ export default { metadata: { author: "Zyner" }, data: new SlashCommandBuilder() .setName("reputation") - .setDescription("Give reputation.") - .addSubcommand((subcommand) => - subcommand - .setName("give") - .setDescription("Give reputation to a user") - .addUserOption((option) => - option - .setName("target") - .setDescription("The user you want to repute.") - .setRequired(true) - ) - .addStringOption((option) => - option - .setName("type") - .setDescription("What type of reputation you want to repute") - .setRequired(true) - .addChoice("Positive", "positive") - .addChoice("Negative", "negative") - ) - ), + .setDescription("Manage reputation.") + .addSubcommand(give.data), async execute(interaction: CommandInteraction) { - // Destructure - const { options, guild, user, commandName } = interaction; + const { options } = interaction; - // Module - Give if (options?.getSubcommand() === "give") { - // Execute Module - Give - await give(interaction); + logger?.verbose(`Executing give subcommand`); + + await give.execute(interaction); } - // Send debug message - return logger?.debug( - `Guild: ${guild?.id} User: ${ - user?.id - } executed /${commandName} ${options?.getSubcommandGroup()} ${options?.getSubcommand()}` - ); + logger?.verbose(`No subcommand found`); }, }; diff --git a/src/plugins/reputation/modules/give.ts b/src/plugins/reputation/modules/give.ts index 56b3d1f..4da08db 100644 --- a/src/plugins/reputation/modules/give.ts +++ b/src/plugins/reputation/modules/give.ts @@ -17,123 +17,145 @@ import logger from "@logger"; // Models import timeoutSchema from "@schemas/timeout"; import fetchUser from "@helpers/fetchUser"; +import { SlashCommandSubcommandBuilder } from "@discordjs/builders"; // Function -export default async (interaction: CommandInteraction) => { - // Destructure - const { options, user, guild } = interaction; +export default { + data: (command: SlashCommandSubcommandBuilder) => { + return command + .setName("give") + .setDescription("Give reputation to a user") + .addUserOption((option) => + option + .setName("target") + .setDescription("The user you want to repute.") + .setRequired(true) + ) + .addStringOption((option) => + option + .setName("type") + .setDescription("What type of reputation you want to repute") + .setRequired(true) + .addChoice("Positive", "positive") + .addChoice("Negative", "negative") + ); + }, + execute: async (interaction: CommandInteraction) => { + // Destructure + const { options, user, guild } = interaction; - // Target option - const optionTarget = options?.getUser("target"); + // Target option + const optionTarget = options?.getUser("target"); - // Type information - const optionType = options?.getString("type"); + // Type information + const optionType = options?.getString("type"); - if (guild === null) return; + if (guild === null) { + return logger?.verbose(`Guild is null`); + } - // User information - const userObj = await fetchUser(user, guild); + // User information + const userObj = await fetchUser(user, guild); - if (userObj === null) return; + if (userObj === null) { + return logger?.verbose(`User is null`); + } - // Check if user has a timeout - const isTimeout = await timeoutSchema?.findOne({ - guildId: guild?.id, - userId: user?.id, - timeoutId: "2022-04-10-16-42", - }); + // Check if user has a timeout + const isTimeout = await timeoutSchema?.findOne({ + guildId: guild?.id, + userId: user?.id, + timeoutId: "2022-04-10-16-42", + }); + + // If user is not on timeout + if (isTimeout) { + logger?.verbose(`User is on timeout`); + + return interaction?.editReply({ + embeds: [ + { + title: ":loudspeaker: Reputation [Give]", + description: `You cannot give reputation while on timeout, please wait ${timeout} seconds.`, + timestamp: new Date(), + color: errorColor, + footer: { + iconURL: footerIcon, + text: footerText, + }, + }, + ], + }); + } - // If user is not on timeout - if (!isTimeout) { // Do not allow self reputation if (optionTarget?.id === user?.id) { - // Embed object - const embed = { - title: ":loudspeaker: Reputation [Give]", - description: "You can not repute yourself.", - timestamp: new Date(), - color: errorColor, - footer: { - iconURL: footerIcon, - text: footerText, - }, - }; + logger?.verbose(`User is trying to give reputation to self`); - // Return interaction reply - return interaction?.editReply({ embeds: [embed] }); + return interaction?.editReply({ + embeds: [ + { + title: ":loudspeaker: Reputation [Give]", + description: `You cannot give reputation to yourself.`, + timestamp: new Date(), + color: errorColor, + footer: { + iconURL: footerIcon, + text: footerText, + }, + }, + ], + }); } // If type is positive if (optionType === "positive") { + logger?.verbose(`User is giving positive reputation`); + userObj.reputation += 1; } // If type is negative else if (optionType === "negative") { + logger?.verbose(`User is giving negative reputation`); + userObj.reputation -= 1; } // Save user await userObj?.save()?.then(async () => { - // Embed object - const embed = { - title: ":loudspeaker: Reputation [Give]", - description: `You have given ${optionTarget} a ${optionType} reputation!`, - timestamp: new Date(), - color: successColor, - footer: { - iconURL: footerIcon, - text: footerText, - }, - }; + logger?.verbose(`User reputation has been updated`); - // Log debug message - logger?.debug( - `Guild: ${guild?.id} User: ${user?.id} has given ${optionTarget?.id} a ${optionType} reputation.` - ); - - // Create a timeout for the user await timeoutSchema?.create({ guildId: guild?.id, userId: user?.id, timeoutId: "2022-04-10-16-42", }); - // Return interaction reply - return interaction?.editReply({ embeds: [embed] }); + + return interaction?.editReply({ + embeds: [ + { + title: ":loudspeaker: Reputation [Give]", + description: `You have given reputation to ${optionTarget}`, + timestamp: new Date(), + color: successColor, + footer: { + iconURL: footerIcon, + text: footerText, + }, + }, + ], + }); }); setTimeout(async () => { - // send debug message - logger?.debug( - `Guild: ${guild?.id} User: ${user?.id} has not repute within last ${timeout} seconds, reputation can be given` - ); + logger?.verbose(`Removing timeout`); - // When timeout is out, remove it from the database await timeoutSchema?.deleteOne({ guildId: guild?.id, userId: user?.id, timeoutId: "2022-04-10-16-42", }); }, timeout); - } else { - // Create embed object - const embed = { - title: ":loudspeaker: Reputation [Give]", - description: `You have given reputation within the last ${timeout} seconds, you can not repute now!`, - timestamp: new Date(), - color: errorColor, - footer: { - iconURL: footerIcon, - text: footerText, - }, - }; - - // Log debug message - logger?.debug( - `Guild: ${guild?.id} User: ${user?.id} has repute within last ${timeout} seconds, no reputation can be given` - ); - - // Return interaction reply - return interaction?.editReply({ embeds: [embed] }); - } + }, }; diff --git a/src/plugins/settings/guild/index.ts b/src/plugins/settings/guild/index.ts index 8beecfd..c19e701 100644 --- a/src/plugins/settings/guild/index.ts +++ b/src/plugins/settings/guild/index.ts @@ -5,7 +5,7 @@ import { Permissions, CommandInteraction } from "discord.js"; import { errorColor, footerText, footerIcon } from "@config/embed"; // Handlers -import logger from "../../../logger"; +import logger from "@logger"; // Modules import pterodactyl from "./modules/pterodactyl"; @@ -18,57 +18,49 @@ export default { data: (group: SlashCommandSubcommandGroupBuilder) => { return group .setName("guild") - .setDescription("Manage guild settings.") + .setDescription("Guild settings.") .addSubcommand(pterodactyl.data) .addSubcommand(credits.data) .addSubcommand(points.data); }, execute: async (interaction: CommandInteraction) => { // Destructure member - const { memberPermissions, options, commandName, user, guild } = - interaction; + const { memberPermissions, options } = interaction; // Check permission if (!memberPermissions?.has(Permissions?.FLAGS?.MANAGE_GUILD)) { - // Create embed object - const embed = { - title: ":tools: Settings - Guild", - color: errorColor, - description: "You do not have permission to manage this!", - timestamp: new Date(), - footer: { - iconURL: footerIcon as string, - text: footerText as string, - }, - }; + logger?.verbose(`User does not have permission to execute command.`); - // Return interaction reply - return interaction?.editReply({ embeds: [embed] }); + return interaction?.editReply({ + embeds: [ + { + title: ":tools: Settings - Guild", + color: errorColor, + description: "You do not have permission to use this command.", + timestamp: new Date(), + footer: { + iconURL: footerIcon as string, + text: footerText as string, + }, + }, + ], + }); } - // Module - Pterodactyl if (options?.getSubcommand() === "pterodactyl") { - // Execute Module - Pterodactyl + logger?.verbose(`Executing pterodactyl subcommand`); + return pterodactyl.execute(interaction); - } + } else if (options?.getSubcommand() === "credits") { + logger?.verbose(`Executing credits subcommand`); - // Module - Credits - else if (options?.getSubcommand() === "credits") { - // Execute Module - Credits return credits.execute(interaction); - } + } else if (options?.getSubcommand() === "points") { + logger?.verbose(`Executing points subcommand`); - // Module - Points - else if (options?.getSubcommand() === "points") { - // Execute Module - Points return points.execute(interaction); } - // Send debug message - return logger?.debug( - `Guild: ${guild?.id} User: ${ - user?.id - } executed /${commandName} ${options?.getSubcommandGroup()} ${options?.getSubcommand()}` - ); + logger?.verbose(`No subcommand found`); }, }; diff --git a/src/plugins/settings/guild/modules/credits.ts b/src/plugins/settings/guild/modules/credits.ts index dd38971..f7bd893 100644 --- a/src/plugins/settings/guild/modules/credits.ts +++ b/src/plugins/settings/guild/modules/credits.ts @@ -16,7 +16,7 @@ export default { data: (command: SlashCommandSubcommandBuilder) => { return command .setName("credits") - .setDescription("Credits") + .setDescription(`Credits`) .addBooleanOption((option) => option.setName("status").setDescription("Should credits be enabled?") ) @@ -36,17 +36,17 @@ export default { .addNumberOption((option) => option .setName("work-timeout") - .setDescription("Timeout between work schedules (milliseconds).") + .setDescription("Timeout between work schedules (seconds).") ) .addNumberOption((option) => option .setName("timeout") - .setDescription("Timeout between earning credits (milliseconds).") + .setDescription("Timeout between earning credits (seconds).") ); }, execute: async (interaction: CommandInteraction) => { // Destructure member - const { guild, user, options } = interaction; + const { guild, options } = interaction; // Get options const status = options?.getBoolean("status"); @@ -61,7 +61,9 @@ export default { guildId: guild?.id, }); - if (guildDB === null) return; + if (guildDB === null) { + return logger?.verbose(`Guild is null`); + } // Modify values guildDB.credits.status = @@ -78,57 +80,54 @@ export default { // Save guild await guildDB?.save()?.then(async () => { - // Embed object - const embed = { - title: ":tools: Settings - Guild [Credits]", - description: "Following settings is set!", - color: successColor, - fields: [ + logger?.verbose(`Guild saved`); + + return interaction?.editReply({ + embeds: [ { - name: "🤖 Status", - value: `${guildDB?.credits?.status}`, - inline: true, - }, - { - name: "📈 Rate", - value: `${guildDB?.credits?.rate}`, - inline: true, - }, - { - name: "📈 Work Rate", - value: `${guildDB?.credits?.workRate}`, - inline: true, - }, - { - name: "🔨 Minimum Length", - value: `${guildDB?.credits?.minimumLength}`, - inline: true, - }, - { - name: "⏰ Timeout", - value: `${guildDB?.credits?.timeout}`, - inline: true, - }, - { - name: "⏰ Work Timeout", - value: `${guildDB?.credits?.workTimeout}`, - inline: true, + title: ":tools: Settings - Guild [Credits]", + description: `Credits settings updated.`, + color: successColor, + fields: [ + { + name: "🤖 Status", + value: `${guildDB?.credits?.status}`, + inline: true, + }, + { + name: "📈 Rate", + value: `${guildDB?.credits?.rate}`, + inline: true, + }, + { + name: "📈 Work Rate", + value: `${guildDB?.credits?.workRate}`, + inline: true, + }, + { + name: "🔨 Minimum Length", + value: `${guildDB?.credits?.minimumLength}`, + inline: true, + }, + { + name: "⏰ Timeout", + value: `${guildDB?.credits?.timeout}`, + inline: true, + }, + { + name: "⏰ Work Timeout", + value: `${guildDB?.credits?.workTimeout}`, + inline: true, + }, + ], + timestamp: new Date(), + footer: { + iconURL: footerIcon, + text: footerText, + }, }, ], - timestamp: new Date(), - footer: { - iconURL: footerIcon, - text: footerText, - }, - }; - - // Send debug message - logger?.debug( - `Guild: ${guild?.id} User: ${user.id} has changed credit details.` - ); - - // Return interaction reply - return interaction?.editReply({ embeds: [embed] }); + }); }); }, }; diff --git a/src/plugins/settings/guild/modules/points.ts b/src/plugins/settings/guild/modules/points.ts index b9ef0b1..f484f22 100644 --- a/src/plugins/settings/guild/modules/points.ts +++ b/src/plugins/settings/guild/modules/points.ts @@ -5,10 +5,10 @@ import { CommandInteraction } from "discord.js"; import { successColor, footerText, footerIcon } from "@config/embed"; // Handlers -import logger from "../../../../logger"; +import logger from "@logger"; // Models -import guildSchema from "../../../../database/schemas/guild"; +import guildSchema from "@schemas/guild"; import { SlashCommandSubcommandBuilder } from "@discordjs/builders"; // Function @@ -36,7 +36,7 @@ export default { }, execute: async (interaction: CommandInteraction) => { // Destructure member - const { options, guild, user } = interaction; + const { options, guild } = interaction; // Get options const status = options?.getBoolean("status"); @@ -49,7 +49,9 @@ export default { guildId: guild?.id, }); - if (guildDB === null) return; + if (guildDB === null) { + return logger?.verbose(`Guild not found in database.`); + } // Modify values guildDB.points.status = status !== null ? status : guildDB?.points?.status; @@ -61,47 +63,44 @@ export default { // Save guild await guildDB?.save()?.then(async () => { - // Create embed object - const embed = { - title: ":hammer: Settings - Guild [Points]", - description: "Following settings is set!", - color: successColor, - fields: [ + logger?.verbose(`Guild points updated.`); + + return interaction?.editReply({ + embeds: [ { - name: "🤖 Status", - value: `${guildDB?.points?.status}`, - inline: true, - }, - { - name: "📈 Rate", - value: `${guildDB?.points?.rate}`, - inline: true, - }, - { - name: "🔨 Minimum Length", - value: `${guildDB?.points?.minimumLength}`, - inline: true, - }, - { - name: "⏰ Timeout", - value: `${guildDB?.points?.timeout}`, - inline: true, + title: ":hammer: Settings - Guild [Points]", + description: `Points settings updated.`, + color: successColor, + fields: [ + { + name: "🤖 Status", + value: `${guildDB?.points?.status}`, + inline: true, + }, + { + name: "📈 Rate", + value: `${guildDB?.points?.rate}`, + inline: true, + }, + { + name: "🔨 Minimum Length", + value: `${guildDB?.points?.minimumLength}`, + inline: true, + }, + { + name: "⏰ Timeout", + value: `${guildDB?.points?.timeout}`, + inline: true, + }, + ], + timestamp: new Date(), + footer: { + iconURL: footerIcon, + text: footerText, + }, }, ], - timestamp: new Date(), - footer: { - iconURL: footerIcon, - text: footerText, - }, - }; - - // Send debug message - logger?.debug( - `Guild: ${guild?.id} User: ${user?.id} has changed credit details.` - ); - - // Return interaction reply - return interaction?.editReply({ embeds: [embed] }); + }); }); }, }; diff --git a/src/plugins/settings/guild/modules/pterodactyl.ts b/src/plugins/settings/guild/modules/pterodactyl.ts index d25bfe3..14b0bf4 100644 --- a/src/plugins/settings/guild/modules/pterodactyl.ts +++ b/src/plugins/settings/guild/modules/pterodactyl.ts @@ -5,11 +5,11 @@ import { CommandInteraction } from "discord.js"; import { successColor, footerText, footerIcon } from "@config/embed"; // Handlers -import logger from "../../../../logger"; +import logger from "@logger"; // Models -import apiSchema from "../../../../database/schemas/api"; -import encryption from "../../../../handlers/encryption"; +import apiSchema from "@schemas/api"; +import encryption from "@handlers/encryption"; import { SlashCommandSubcommandBuilder } from "@discordjs/builders"; // Function @@ -19,18 +19,21 @@ export default { .setName("pterodactyl") .setDescription("Controlpanel.gg") .addStringOption((option) => - option.setName("url").setDescription("The api url").setRequired(true) + option + .setName("url") + .setDescription(`Controlpanel.gg URL`) + .setRequired(true) ) .addStringOption((option) => option .setName("token") - .setDescription("The api token") + .setDescription(`Controlpanel.gg Token`) .setRequired(true) ); }, execute: async (interaction: CommandInteraction) => { // Destructure member - const { options, guild, user } = interaction; + const { options, guild } = interaction; // Get options const url = options?.getString("url"); @@ -44,25 +47,22 @@ export default { { new: true, upsert: true } ) .then(async () => { - // Embed object - const embed = { - title: ":hammer: Settings - Guild [Pterodactyl]", - color: successColor, - description: "Pterodactyl settings is saved!", - timestamp: new Date(), - footer: { - iconURL: footerIcon as string, - text: footerText as string, - }, - }; + logger?.verbose(`Updated API credentials.`); - // Send debug message - logger?.debug( - `Guild: ${guild?.id} User: ${user?.id} has changed api credentials.` - ); - - // Return interaction reply - return interaction?.editReply({ embeds: [embed] }); + return interaction?.editReply({ + embeds: [ + { + title: ":hammer: Settings - Guild [Pterodactyl]", + color: successColor, + description: `Successfully updated API credentials.`, + timestamp: new Date(), + footer: { + iconURL: footerIcon, + text: footerText, + }, + }, + ], + }); }); }, }; diff --git a/src/plugins/settings/index.ts b/src/plugins/settings/index.ts index 0ccb54d..682fc30 100644 --- a/src/plugins/settings/index.ts +++ b/src/plugins/settings/index.ts @@ -7,7 +7,7 @@ import guildGroup from "./guild"; import userGroup from "./user"; // Handlers -import logger from "../../logger"; +import logger from "@logger"; // Function export default { @@ -19,25 +19,20 @@ export default { .addSubcommandGroup(userGroup.data), async execute(interaction: CommandInteraction) { - // Destructure - const { options, commandName, user, guild } = interaction; + const { options } = interaction; - // Group - Guild if (options.getSubcommandGroup() === "guild") { - // Execute Group - Guild - await guildGroup.execute(interaction); - } - // Group - User - else if (options.getSubcommandGroup() === "user") { - // Execute Group - User - await userGroup.execute(interaction); + logger.verbose(`Executing guild subcommand`); + + return guildGroup.execute(interaction); } - // Send debug message - return logger?.debug( - `Guild: ${guild?.id} User: ${ - user?.id - } executed /${commandName} ${options?.getSubcommandGroup()} ${options?.getSubcommand()}` - ); + if (options.getSubcommandGroup() === "user") { + logger.verbose(`Executing user subcommand`); + + return userGroup.execute(interaction); + } + + logger.verbose(`No subcommand group found`); }, }; diff --git a/src/plugins/settings/user/index.ts b/src/plugins/settings/user/index.ts index e325780..e3c572f 100644 --- a/src/plugins/settings/user/index.ts +++ b/src/plugins/settings/user/index.ts @@ -3,7 +3,7 @@ import { SlashCommandSubcommandGroupBuilder } from "@discordjs/builders"; import { CommandInteraction } from "discord.js"; // Handlers -import logger from "../../../logger"; +import logger from "@logger"; // Modules import appearance from "./modules/appearance"; @@ -13,35 +13,29 @@ export default { data: (group: SlashCommandSubcommandGroupBuilder) => { return group .setName("user") - .setDescription("Manage user settings.") + .setDescription("User settings.") .addSubcommand((command) => command .setName("appearance") - .setDescription("Manage your appearance") + .setDescription("User appearance settings.") .addStringOption((option) => option .setName("language") - .setDescription("Configure your language") + .setDescription("Set the language.") .addChoice("English", "en") .addChoice("Swedish", "sv") ) ); }, execute: async (interaction: CommandInteraction) => { - // Destructure member - const { guild, user, options, commandName } = interaction; + const { options } = interaction; - // Module - Appearance if (options?.getSubcommand() === "appearance") { - // Execute Module - Appearance + logger?.verbose(`Executing appearance subcommand`); + await appearance(interaction); } - // Send debug message - return logger?.debug( - `Guild: ${guild?.id} User: ${ - user?.id - } executed /${commandName} ${options?.getSubcommandGroup()} ${options?.getSubcommand()}` - ); + logger?.verbose(`No subcommand found`); }, }; diff --git a/src/plugins/settings/user/modules/appearance.ts b/src/plugins/settings/user/modules/appearance.ts index ee02a2d..bf0a4eb 100644 --- a/src/plugins/settings/user/modules/appearance.ts +++ b/src/plugins/settings/user/modules/appearance.ts @@ -5,10 +5,10 @@ import { CommandInteraction } from "discord.js"; import { successColor, footerText, footerIcon } from "@config/embed"; // Handlers -import logger from "../../../../logger"; +import logger from "@logger"; // Models -import fetchUser from "../../../../helpers/fetchUser"; +import fetchUser from "@helpers/fetchUser"; // Function export default async (interaction: CommandInteraction) => { @@ -18,43 +18,44 @@ export default async (interaction: CommandInteraction) => { // Get options const language = options?.getString("language"); - if (guild === null) return; + if (guild === null) { + return logger?.verbose(`Guild is null`); + } // Get user object const userDB = await fetchUser(user, guild); - if (userDB === null) return; + if (userDB === null) { + return logger?.verbose(`User is null`); + } // Modify values userDB.language = language !== null ? language : userDB?.language; // Save guild await userDB?.save()?.then(async () => { - // Embed object - const embed = { - title: ":hammer: Settings - User [Appearance]", - description: "Following settings is set!", - color: successColor, - fields: [ + logger?.verbose(`Updated user language.`); + + return interaction?.editReply({ + embeds: [ { - name: "🏳️‍🌈 Language", - value: `${userDB?.language}`, - inline: true, + title: ":hammer: Settings - User [Appearance]", + description: "Successfully updated user settings.", + color: successColor, + fields: [ + { + name: "🏳️‍🌈 Language", + value: `${userDB?.language}`, + inline: true, + }, + ], + timestamp: new Date(), + footer: { + iconURL: footerIcon, + text: footerText, + }, }, ], - timestamp: new Date(), - footer: { - iconURL: footerIcon, - text: footerText, - }, - }; - - // Send debug message - logger?.debug( - `Guild: ${guild?.id} User: ${user?.id} has changed appearance settings.` - ); - - // Return interaction reply - return interaction?.editReply({ embeds: [embed] }); + }); }); }; diff --git a/src/plugins/shop/index.ts b/src/plugins/shop/index.ts index c601eac..7d222a8 100644 --- a/src/plugins/shop/index.ts +++ b/src/plugins/shop/index.ts @@ -16,70 +16,24 @@ export default { metadata: { author: "Zyner" }, data: new SlashCommandBuilder() .setName("shop") - .setDescription("Purchase some items using your credits.") - .addSubcommand((subcommand) => - subcommand - .setName("pterodactyl") - .setDescription("Buy pterodactyl power.") - .addIntegerOption((option) => - option - .setName("amount") - .setDescription("How much credits you want to withdraw.") - ) - ) - .addSubcommandGroup((group) => - group - .setName("roles") - .setDescription("Manage custom roles.") - .addSubcommand((command) => - command - .setName("buy") - .setDescription("Buy a custom role") - .addStringOption((option) => - option - .setName("name") - .setDescription("Name of the role you wish to purchase.") - ) - .addStringOption((option) => - option - .setName("color") - .setDescription( - "Color of the role you wish to purchase (For example RED or BLUE or GREEN)." - ) - ) - ) - .addSubcommand((command) => - command - .setName("cancel") - .setDescription("Cancel a custom role") - .addRoleOption((option) => - option - .setName("role") - .setDescription("Name of the role you wish to cancel.") - ) - ) - ), + .setDescription("Shop for credits and custom roles.") + .addSubcommand(pterodactyl.data) + .addSubcommandGroup(roles.data), async execute(interaction: CommandInteraction) { - // Destructure - const { options, commandName, user, guild } = interaction; + const { options } = interaction; - // Module - Pterodactyl if (options?.getSubcommand() === "pterodactyl") { - // Execute Module - Pterodactyl - return pterodactyl(interaction); + logger.verbose(`Executing pterodactyl subcommand`); + + return pterodactyl.execute(interaction); } - // Group - Roles - else if (options?.getSubcommandGroup() === "roles") { - // Execute Group - Roles - return roles(interaction); + if (options?.getSubcommandGroup() === "roles") { + logger?.verbose(`Subcommand group is roles`); + + return roles.execute(interaction); } - // Send debug message - return logger?.debug( - `Guild: ${guild?.id} User: ${ - user?.id - } executed /${commandName} ${options?.getSubcommandGroup()} ${options?.getSubcommand()}` - ); + logger?.verbose(`No subcommand found.`); }, }; diff --git a/src/plugins/shop/modules/pterodactyl.ts b/src/plugins/shop/modules/pterodactyl.ts index c523a8f..01cd120 100644 --- a/src/plugins/shop/modules/pterodactyl.ts +++ b/src/plugins/shop/modules/pterodactyl.ts @@ -21,225 +21,261 @@ import pluralize from "@helpers/pluralize"; // Models import apiSchema from "@schemas/api"; import fetchUser from "@helpers/fetchUser"; +import { SlashCommandSubcommandBuilder } from "@discordjs/builders"; // Function -export default async (interaction: CommandInteraction) => { - const { options, guild, user, client } = interaction; +export default { + data: (command: SlashCommandSubcommandBuilder) => { + return command + .setName("pterodactyl") + .setDescription("Buy pterodactyl power.") + .addIntegerOption((option) => + option + .setName("amount") + .setDescription("How much credits you want to withdraw.") + ); + }, + execute: async (interaction: CommandInteraction) => { + const { options, guild, user, client } = interaction; - // Get options - const optionAmount = options?.getInteger("amount"); + // Get options + const optionAmount = options?.getInteger("amount"); - // If amount is null - if (optionAmount === null) { - // Embed object - const embed = { - title: ":dollar: Credits [Gift]", - description: "We could not read your requested amount.", - color: errorColor, - timestamp: new Date(), - footer: { - iconURL: footerIcon, - text: footerText, - }, - }; + // If amount is null + if (optionAmount === null) { + logger?.verbose(`Amount is null.`); - // Send interaction reply - return interaction?.editReply({ embeds: [embed] }); - } - - if (guild === null) return; - - // Get user object - const userDB = await fetchUser(user, guild); - - if (userDB === null) return; - - // Get DM user object - const dmUser = client?.users?.cache?.get(user?.id); - - // Stop if amount or user credits is below 100 - if ((optionAmount || userDB?.credits) < 100) { - const embed = { - title: ":shopping_cart: Shop [Pterodactyl]", - description: `You **can't** withdraw for __Pterodactyl__ below **100**.`, - color: errorColor, - fields: [ - { - name: "Your balance", - value: `${pluralize(userDB?.credits, "credit")}`, - }, - ], - timestamp: new Date(), - footer: { - iconURL: footerIcon, - text: footerText, - }, - }; - return interaction?.editReply({ embeds: [embed] }); - } - - // Stop if amount or user credits is above 1.000.000 - if ((optionAmount || userDB?.credits) > 1000000) { - const embed = { - title: ":shopping_cart: Shop [Pterodactyl]", - description: `You **can't** withdraw for __Pterodactyl__ above **1.000.000**.`, - color: errorColor, - fields: [ - { - name: "Your balance", - value: `${pluralize(userDB?.credits, "credit")}`, - }, - ], - timestamp: new Date(), - footer: { - iconURL: footerIcon, - text: footerText, - }, - }; - return interaction?.editReply({ embeds: [embed] }); - } - - // Stop if user credits is below amount - if (userDB?.credits < optionAmount) { - const embed = { - title: ":shopping_cart: Shop [Pterodactyl]", - description: `You have **insufficient** credits.`, - color: errorColor, - fields: [ - { - name: "Your balance", - value: `${pluralize(userDB?.credits, "credit")}`, - }, - ], - timestamp: new Date(), - footer: { - iconURL: footerIcon, - text: footerText, - }, - }; - return interaction?.editReply({ embeds: [embed] }); - } - - // Generate a unique voucher for the user - const code = uuidv4(); - - // Get api object - const apiCredentials = await apiSchema?.findOne({ - guildId: guild?.id, - }); - - // Create a api instance - const api = axios?.create({ - baseURL: apiCredentials?.url, - headers: { - Authorization: `Bearer ${encryption.decrypt(apiCredentials?.token)}`, - }, - }); - - // Get shop URL - const shopUrl = apiCredentials?.url?.replace("/api", "/store"); - - // Make API request - await api - - // Make a post request to the API - ?.post("vouchers", { - uses: 1, - code, - credits: optionAmount || userDB?.credits, - memo: `${interaction?.createdTimestamp} - ${interaction?.user?.id}`, - }) - - // If successful - ?.then(async () => { - // Create DM embed object - const dmEmbed = { - title: ":shopping_cart: Shop [Pterodactyl]", - description: `Redeem this voucher [here](${shopUrl})!`, - fields: [ - { name: "Code", value: `${code}`, inline: true }, + return interaction?.editReply({ + embeds: [ { - name: "Credits", - value: `${optionAmount || userDB?.credits}`, - inline: true, - }, - ], - color: successColor, - timestamp: new Date(), - footer: { - iconURL: footerIcon, - text: footerText, - }, - }; - - // Create interaction embed object - const interactionEmbed = { - title: ":shopping_cart: Shop [Pterodactyl]", - description: "I have sent you the code in DM!", - color: successColor, - timestamp: new Date(), - footer: { - iconURL: footerIcon, - text: footerText, - }, - }; - - // Withdraw amount from user credits - userDB.credits -= optionAmount || userDB?.credits; - - // Save new credits - await userDB - ?.save() - // If successful - ?.then(async () => { - // Send debug message - logger?.debug( - `User: ${user?.username} redeemed: ${pluralize( - optionAmount, - "credit" - )}` - ); - - // Send DM message - await dmUser?.send({ embeds: [dmEmbed] }); - - // Send interaction reply - await interaction?.editReply({ - embeds: [interactionEmbed], - }); - }) - - // If error occurs - .catch(async (e: any) => { - logger?.error(e); - const embed = { - title: ":shopping_cart: Shop [Pterodactyl]", - description: - "Something went wrong while saving your credits, please try again later.", + title: ":dollar: Credits [Gift]", + description: "We could not read your requested amount.", color: errorColor, timestamp: new Date(), footer: { iconURL: footerIcon, text: footerText, }, - }; - return interaction?.editReply({ embeds: [embed] }); - }); - }) + }, + ], + }); + } - // If error occurs - .catch(async (e) => { - logger?.error(e); - const embed = { - title: ":shopping_cart: Shop [Pterodactyl]", - description: "Something went wrong, please try again later.", - color: errorColor, - timestamp: new Date(), - footer: { - iconURL: footerIcon, - text: footerText, - }, - }; - return interaction?.editReply({ embeds: [embed] }); + if (guild === null) { + return logger?.verbose(`Guild is null`); + } + + // Get user object + const userDB = await fetchUser(user, guild); + + if (userDB === null) { + return logger?.verbose(`User is null`); + } + + // Get DM user object + const dmUser = client?.users?.cache?.get(user?.id); + + // Stop if amount or user credits is below 100 + if ((optionAmount || userDB?.credits) < 100) { + logger?.verbose(`Amount or user credits is below 100.`); + + return interaction?.editReply({ + embeds: [ + { + title: ":shopping_cart: Shop [Pterodactyl]", + description: `You **can't** withdraw for __Pterodactyl__ below **100**.`, + color: errorColor, + fields: [ + { + name: "Your balance", + value: `${pluralize(userDB?.credits, "credit")}`, + }, + ], + timestamp: new Date(), + footer: { + iconURL: footerIcon, + text: footerText, + }, + }, + ], + }); + } + + // Stop if amount or user credits is above 1.000.000 + if ((optionAmount || userDB?.credits) > 1000000) { + logger?.verbose(`Amount or user credits is above 1.000.000.`); + + return interaction?.editReply({ + embeds: [ + { + title: ":shopping_cart: Shop [Pterodactyl]", + description: + "You **can't** withdraw for __Pterodactyl__ above **1.000.000**.", + color: errorColor, + fields: [ + { + name: "Your balance", + value: `${pluralize(userDB?.credits, "credit")}`, + }, + ], + timestamp: new Date(), + footer: { + iconURL: footerIcon, + text: footerText, + }, + }, + ], + }); + } + + // Stop if user credits is below amount + if (userDB?.credits < optionAmount) { + logger?.verbose(`User credits is below amount.`); + + return interaction?.editReply({ + embeds: [ + { + title: ":shopping_cart: Shop [Pterodactyl]", + description: `You have **insufficient** credits.`, + color: errorColor, + fields: [ + { + name: "Your balance", + value: `${pluralize(userDB?.credits, "credit")}`, + }, + ], + timestamp: new Date(), + footer: { + iconURL: footerIcon, + text: footerText, + }, + }, + ], + }); + } + + // Generate a unique voucher for the user + const code = uuidv4(); + + // Get api object + const apiCredentials = await apiSchema?.findOne({ + guildId: guild?.id, }); + + // Create a api instance + const api = axios?.create({ + baseURL: apiCredentials?.url, + headers: { + Authorization: `Bearer ${encryption.decrypt(apiCredentials?.token)}`, + }, + }); + + // Get shop URL + const shopUrl = apiCredentials?.url?.replace("/api", "/store"); + + // Make API request + await api + + // Make a post request to the API + ?.post("vouchers", { + uses: 1, + code, + credits: optionAmount || userDB?.credits, + memo: `${interaction?.createdTimestamp} - ${interaction?.user?.id}`, + }) + + // If successful + ?.then(async () => { + logger?.verbose(`Successfully created voucher.`); + + // Withdraw amount from user credits + userDB.credits -= optionAmount || userDB?.credits; + + // Save new credits + await userDB + ?.save() + // If successful + ?.then(async () => { + logger?.verbose(`Successfully saved new credits.`); + + await dmUser?.send({ + embeds: [ + { + title: ":shopping_cart: Shop [Pterodactyl]", + description: `Redeem this voucher [here](${shopUrl})!`, + fields: [ + { name: "Code", value: `${code}`, inline: true }, + { + name: "Credits", + value: `${optionAmount || userDB?.credits}`, + inline: true, + }, + ], + color: successColor, + timestamp: new Date(), + footer: { + iconURL: footerIcon, + text: footerText, + }, + }, + ], + }); + + return interaction?.editReply({ + embeds: [ + { + title: ":shopping_cart: Shop [Pterodactyl]", + description: "I have sent you the code in DM!", + color: successColor, + timestamp: new Date(), + footer: { + iconURL: footerIcon, + text: footerText, + }, + }, + ], + }); + }) + + // If error occurs + .catch(async (error) => { + logger?.verbose(`Error saving new credits. - ${error}`); + + return interaction?.editReply({ + embeds: [ + { + title: ":shopping_cart: Shop [Pterodactyl]", + description: "Something went wrong.", + color: errorColor, + timestamp: new Date(), + footer: { + iconURL: footerIcon, + text: footerText, + }, + }, + ], + }); + }); + }) + + // If error occurs + .catch(async (error: any) => { + logger?.verbose(`Error creating voucher. - ${error}`); + + return interaction?.editReply({ + embeds: [ + { + title: ":shopping_cart: Shop [Pterodactyl]", + description: "Something went wrong.", + color: errorColor, + timestamp: new Date(), + footer: { + iconURL: footerIcon, + text: footerText, + }, + }, + ], + }); + }); + }, }; diff --git a/src/plugins/shop/roles/index.ts b/src/plugins/shop/roles/index.ts index 42b5b45..7672f51 100644 --- a/src/plugins/shop/roles/index.ts +++ b/src/plugins/shop/roles/index.ts @@ -1,4 +1,5 @@ // Dependencies +import { SlashCommandSubcommandGroupBuilder } from "@discordjs/builders"; import { CommandInteraction } from "discord.js"; // Handlers @@ -9,26 +10,27 @@ import buy from "./modules/buy"; import cancel from "./modules/cancel"; // Function -export default async (interaction: CommandInteraction) => { - // Destructure member - const { options, commandName, guild, user } = interaction; +export default { + data: (group: SlashCommandSubcommandGroupBuilder) => { + return group + .setName("roles") + .setDescription("Shop for custom roles.") + .addSubcommand(buy.data) + .addSubcommand(cancel.data); + }, + execute: async (interaction: CommandInteraction) => { + const { options } = interaction; - // Module - Buy - if (options?.getSubcommand() === "buy") { - // Execute Module - Buy - await buy(interaction); - } + if (options?.getSubcommand() === "buy") { + logger.verbose(`Executing buy subcommand`); - // Module - Cancel - if (options?.getSubcommand() === "cancel") { - // Execute Module - Cancel - await cancel(interaction); - } + await buy.execute(interaction); + } - // Send debug message - return logger?.debug( - `Guild: ${guild?.id} User: ${ - user?.id - } executed /${commandName} ${options?.getSubcommandGroup()} ${options?.getSubcommand()}` - ); + if (options?.getSubcommand() === "cancel") { + logger.verbose(`Executing cancel subcommand`); + + await cancel.execute(interaction); + } + }, }; diff --git a/src/plugins/shop/roles/modules/buy.ts b/src/plugins/shop/roles/modules/buy.ts index 238f4e6..0baf7ed 100644 --- a/src/plugins/shop/roles/modules/buy.ts +++ b/src/plugins/shop/roles/modules/buy.ts @@ -16,88 +16,126 @@ import { import shopRolesSchema from "@schemas/shopRole"; import guildSchema from "@schemas/guild"; +import logger from "@logger"; + // Helpers import pluralize from "@helpers/pluralize"; import fetchUser from "@helpers/fetchUser"; +import { SlashCommandSubcommandBuilder } from "@discordjs/builders"; // Function -export default async (interaction: CommandInteraction) => { - const { options, guild, user, member } = interaction; +export default { + data: (command: SlashCommandSubcommandBuilder) => { + return command + .setName("buy") + .setDescription("Buy a custom role.") + .addStringOption((option) => + option + .setName("name") + .setDescription("Name of the role you wish to buy.") + ) + .addStringOption((option) => + option + .setName("color") + .setDescription("Color of the role you wish to buy.") + ); + }, + execute: async (interaction: CommandInteraction) => { + const { options, guild, user, member } = interaction; - const optionName = options?.getString("name"); - const optionColor = options?.getString("color"); + const optionName = options?.getString("name"); + const optionColor = options?.getString("color"); - // If amount is null - if (optionName === null) { - // Embed object - const embed = { - title: ":dollar: Shop - Roles [Buy]", - description: "We could not read your requested name.", - color: errorColor, - timestamp: new Date(), - footer: { - iconURL: footerIcon, - text: footerText, - }, - }; + // If amount is null + if (optionName === null) { + logger?.verbose(`Name is null.`); - // Send interaction reply - return interaction?.editReply({ embeds: [embed] }); - } - - await guild?.roles - .create({ - name: optionName, - color: optionColor as ColorResolvable, - reason: `${user?.id} bought from shop`, - }) - .then(async (role) => { - // Get guild object - const guildDB = await guildSchema?.findOne({ - guildId: guild?.id, - }); - - const userDB = await fetchUser(user, guild); - - if (userDB === null) return; - if (guildDB === null) return; - if (guildDB.shop === null) return; - - const { pricePerHour } = guildDB.shop.roles; - - userDB.credits -= pricePerHour; - - await userDB?.save(); - - await shopRolesSchema?.create({ - roleId: role?.id, - userId: user?.id, - guildId: guild?.id, - pricePerHour, - lastPayed: new Date(), - }); - - await (member?.roles as GuildMemberRoleManager)?.add(role?.id); - - const embed = { - title: ":shopping_cart: Shop - Roles [Buy]", - description: `You have bought ${role?.name} for ${guildDB?.shop?.roles?.pricePerHour} per hour.`, - color: successColor, - fields: [ + return interaction?.editReply({ + embeds: [ { - name: "Your balance", - value: `${pluralize(userDB?.credits, "credit")}`, + title: ":dollar: Shop - Roles [Buy]", + description: "We could not read your requested name.", + color: errorColor, + timestamp: new Date(), + footer: { + iconURL: footerIcon, + text: footerText, + }, }, ], - timestamp: new Date(), - footer: { - iconURL: footerIcon, - text: footerText, - }, - }; - return interaction?.editReply({ - embeds: [embed], }); - }) - .catch(console.error); + } + + await guild?.roles + .create({ + name: optionName, + color: optionColor as ColorResolvable, + reason: `${user?.id} bought from shop`, + }) + .then(async (role) => { + // Get guild object + const guildDB = await guildSchema?.findOne({ + guildId: guild?.id, + }); + + const userDB = await fetchUser(user, guild); + + if (userDB === null) { + return logger?.verbose(`User is null`); + } + + if (guildDB === null) { + return logger?.verbose(`Guild is null`); + } + + if (guildDB.shop === null) { + return logger?.verbose(`Shop is null`); + } + + const { pricePerHour } = guildDB.shop.roles; + + userDB.credits -= pricePerHour; + + await userDB?.save(); + + await shopRolesSchema?.create({ + roleId: role?.id, + userId: user?.id, + guildId: guild?.id, + pricePerHour, + lastPayed: new Date(), + }); + + await (member?.roles as GuildMemberRoleManager)?.add(role?.id); + + logger?.verbose(`Role ${role?.name} was bought by ${user?.tag}`); + + return interaction?.editReply({ + embeds: [ + { + title: ":shopping_cart: Shop - Roles [Buy]", + description: `You bought **${optionName}** for **${pluralize( + pricePerHour, + "credit" + )}**.`, + color: successColor, + fields: [ + { + name: "Your balance", + value: `${pluralize(userDB?.credits, "credit")}`, + }, + ], + timestamp: new Date(), + footer: { + iconURL: footerIcon, + text: footerText, + }, + }, + ], + }); + }) + .catch(async (error) => { + return logger?.verbose(`Role could not be created. ${error}`); + }); + }, }; diff --git a/src/plugins/shop/roles/modules/cancel.ts b/src/plugins/shop/roles/modules/cancel.ts index 3e8479c..359d79c 100644 --- a/src/plugins/shop/roles/modules/cancel.ts +++ b/src/plugins/shop/roles/modules/cancel.ts @@ -11,41 +11,55 @@ import { // Models import shopRolesSchema from "@schemas/shopRole"; +import logger from "@logger"; + // Helpers import pluralize from "@helpers/pluralize"; import fetchUser from "@helpers/fetchUser"; +import { SlashCommandSubcommandBuilder } from "@discordjs/builders"; // Function -export default async (interaction: CommandInteraction) => { - const { options, guild, user, member } = interaction; +export default { + data: (command: SlashCommandSubcommandBuilder) => { + return command + .setName("cancel") + .setDescription("Cancel a purchase.") + .addRoleOption((option) => + option.setName("role").setDescription("Role you wish to cancel.") + ); + }, + execute: async (interaction: CommandInteraction) => { + const { options, guild, user, member } = interaction; - const optionRole = options.getRole("role"); + const optionRole = options.getRole("role"); - // If amount is null - if (optionRole === null) { - // Embed object - const embed = { - title: ":dollar: Shop - Roles [Cancel]", - description: "We could not read your requested role.", - color: errorColor, - timestamp: new Date(), - footer: { - iconURL: footerIcon, - text: footerText, - }, - }; + if (optionRole === null) { + logger?.verbose(`Role is null.`); - // Send interaction reply - return interaction?.editReply({ embeds: [embed] }); - } + return interaction?.editReply({ + embeds: [ + { + title: ":dollar: Shop - Roles [Cancel]", + description: "We could not read your requested role.", + color: errorColor, + timestamp: new Date(), + footer: { + iconURL: footerIcon, + text: footerText, + }, + }, + ], + }); + } - const roleExist = await shopRolesSchema?.findOne({ - guildId: guild?.id, - userId: user?.id, - roleId: optionRole?.id, - }); + const roleExist = await shopRolesSchema?.findOne({ + guildId: guild?.id, + userId: user?.id, + roleId: optionRole?.id, + }); + + if (roleExist === null) return; - if (roleExist) { await (member?.roles as GuildMemberRoleManager)?.remove(optionRole?.id); await guild?.roles @@ -53,7 +67,9 @@ export default async (interaction: CommandInteraction) => { .then(async () => { const userDB = await fetchUser(user, guild); - if (userDB === null) return; + if (userDB === null) { + return logger?.verbose(`User is null`); + } await shopRolesSchema?.deleteOne({ roleId: optionRole?.id, @@ -61,26 +77,29 @@ export default async (interaction: CommandInteraction) => { guildId: guild?.id, }); - const embed = { - title: ":shopping_cart: Shop - Roles [Cancel]", - description: `You have canceled ${optionRole.name}.`, - color: successColor, - fields: [ + return interaction?.editReply({ + embeds: [ { - name: "Your balance", - value: `${pluralize(userDB?.credits, "credit")}`, + title: ":shopping_cart: Shop - Roles [Cancel]", + description: `You have canceled ${optionRole.name}.`, + color: successColor, + fields: [ + { + name: "Your balance", + value: `${pluralize(userDB?.credits, "credit")}`, + }, + ], + timestamp: new Date(), + footer: { + iconURL: footerIcon, + text: footerText, + }, }, ], - timestamp: new Date(), - footer: { - iconURL: footerIcon, - text: footerText, - }, - }; - return interaction?.editReply({ - embeds: [embed], }); }) - .catch(console.error); - } + .catch(async (error) => { + return logger?.verbose(`Role could not be deleted. ${error}`); + }); + }, }; diff --git a/src/plugins/utilities/index.ts b/src/plugins/utilities/index.ts index 65fccdb..23c43c3 100644 --- a/src/plugins/utilities/index.ts +++ b/src/plugins/utilities/index.ts @@ -16,50 +16,30 @@ export default { data: new SlashCommandBuilder() .setName("utilities") .setDescription("Common utilities.") - .addSubcommand((subcommand) => - subcommand - .setName("lookup") - .setDescription( - "Lookup a domain or ip. (Request sent over HTTP, proceed with caution!)" - ) - .addStringOption((option) => - option - .setName("query") - .setDescription("The query you want to look up.") - .setRequired(true) - ) - ) - .addSubcommand((subcommand) => - subcommand.setName("about").setDescription("About this bot!)") - ) - .addSubcommand((subcommand) => - subcommand.setName("stats").setDescription("Check bot statistics!)") - ), + .addSubcommand(lookup.data) + .addSubcommand(about.data) + .addSubcommand(stats.data), async execute(interaction: CommandInteraction) { - // Destructure - const { options, guild, user, commandName } = interaction; + const { options } = interaction; - // Module - Lookup if (options?.getSubcommand() === "lookup") { - // Execute Module - Lookup - return lookup(interaction); - } - // Module - About - else if (options?.getSubcommand() === "about") { - // Execute Module - About - return about(interaction); - } - // Module - Stats - else if (options?.getSubcommand() === "stats") { - // Execute Module - Stats - return stats(interaction); + logger.verbose(`Executing lookup subcommand`); + + return lookup.execute(interaction); } - // Send debug message - return logger?.debug( - `Guild: ${guild?.id} User: ${ - user?.id - } executed /${commandName} ${options?.getSubcommandGroup()} ${options?.getSubcommand()}` - ); + if (options?.getSubcommand() === "about") { + logger.verbose(`Executing about subcommand`); + + return about.execute(interaction); + } + + if (options?.getSubcommand() === "stats") { + logger.verbose(`Executing stats subcommand`); + + return stats.execute(interaction); + } + + logger.verbose(`No subcommand found.`); }, }; diff --git a/src/plugins/utilities/modules/about.ts b/src/plugins/utilities/modules/about.ts index afce531..f618149 100644 --- a/src/plugins/utilities/modules/about.ts +++ b/src/plugins/utilities/modules/about.ts @@ -5,22 +5,28 @@ import { CommandInteraction } from "discord.js"; import { successColor, footerText, footerIcon } from "@config/embed"; import { hosterName, hosterUrl } from "@config/other"; +import { SlashCommandSubcommandBuilder } from "@discordjs/builders"; // Function -export default async (interaction: CommandInteraction) => { - const interactionEmbed = { - title: ":hammer: Utilities [About]", - description: `This bot is hosted by ${ - hosterUrl ? `[${hosterName}](${hosterUrl})` : `${hosterName}` - }, the bot is developed by [Zyner](https://github.com/ZynerOrg)! +export default { + data: (command: SlashCommandSubcommandBuilder) => { + return command.setName("about").setDescription("About this bot!)"); + }, + execute: async (interaction: CommandInteraction) => { + const interactionEmbed = { + title: ":hammer: Utilities [About]", + description: `This bot is hosted by ${ + hosterUrl ? `[${hosterName}](${hosterUrl})` : `${hosterName}` + }, the bot is developed by [Zyner](https://github.com/ZynerOrg)! If you are interested in contributing, then just [fork it](https://github.com/ZynerOrg/xyter) yourself, we :heart: Open Source.`, - color: successColor, - timestamp: new Date(), - footer: { - iconURL: footerIcon, - text: footerText, - }, - }; - interaction?.editReply({ embeds: [interactionEmbed] }); + color: successColor, + timestamp: new Date(), + footer: { + iconURL: footerIcon, + text: footerText, + }, + }; + interaction?.editReply({ embeds: [interactionEmbed] }); + }, }; diff --git a/src/plugins/utilities/modules/lookup.ts b/src/plugins/utilities/modules/lookup.ts index 23d3661..6175418 100644 --- a/src/plugins/utilities/modules/lookup.ts +++ b/src/plugins/utilities/modules/lookup.ts @@ -10,108 +10,125 @@ import { footerIcon, } from "@config/embed"; +import { SlashCommandSubcommandBuilder } from "@discordjs/builders"; + // Handlers -import logger from "../../../logger"; +import logger from "@logger"; // Function -export default async (interaction: CommandInteraction) => { - const { options } = interaction; - // Get lookup query - const query = options?.getString("query"); +export default { + data: (command: SlashCommandSubcommandBuilder) => { + return command + .setName("lookup") + .setDescription( + "Lookup a domain or ip. (Request sent over HTTP, proceed with caution!)" + ) + .addStringOption((option) => + option + .setName("query") + .setDescription("The query you want to look up.") + .setRequired(true) + ); + }, + execute: async (interaction: CommandInteraction) => { + const { options } = interaction; + // Get lookup query + const query = options?.getString("query"); - // Make API request - await axios - // Make a get request - ?.get(`http://ip-api.com/json/${query}`) + // Make API request + await axios + // Make a get request + ?.get(`http://ip-api.com/json/${query}`) - // If successful - ?.then(async (res) => { - // If query failed - if (res?.data?.status === "fail") { - // Create embed object - const embed = { - title: ":hammer: Utilities - Lookup", - description: `${res?.data?.message}: ${res?.data?.query}`, - color: errorColor, - timestamp: new Date(), - footer: { - iconURL: footerIcon, - text: footerText, - }, - }; + // If successful + ?.then(async (res) => { + // If query failed + if (res?.data?.status === "fail") { + // Create embed object + const embed = { + title: ":hammer: Utilities - Lookup", + description: `${res?.data?.message}: ${res?.data?.query}`, + color: errorColor, + timestamp: new Date(), + footer: { + iconURL: footerIcon, + text: footerText, + }, + }; - // Send interaction reply - await interaction?.editReply({ embeds: [embed] }); - } + // Send interaction reply + await interaction?.editReply({ embeds: [embed] }); + } - // If query is successful - else if (res?.data?.status === "success") { - // Create embed object - const embed = { - title: ":hammer: Utilities - Lookup", - fields: [ - { - name: "AS", - value: `${res?.data?.as || "Not available"}`, + // If query is successful + else if (res?.data?.status === "success") { + // Create embed object + const embed = { + title: ":hammer: Utilities - Lookup", + fields: [ + { + name: "AS", + value: `${res?.data?.as || "Not available"}`, + }, + { + name: "Country", + value: `${res?.data?.country || "Not available"}`, + }, + { + name: "Country Code", + value: `${res?.data?.countryCode || "Not available"}`, + }, + { + name: "Region", + value: `${res?.data?.region || "Not available"}`, + }, + { + name: "Region Name", + value: `${res?.data?.regionName || "Not available"}`, + }, + { + name: "City", + value: `${res?.data?.city || "Not available"}`, + }, + { + name: "ZIP Code", + value: `${res?.data?.zip || "Not available"}`, + }, + { + name: "Latitude", + value: `${res?.data?.lat || "Not available"}`, + }, + { + name: "Longitude", + value: `${res?.data?.lon || "Not available"}`, + }, + { + name: "Timezone", + value: `${res?.data?.timezone || "Not available"}`, + }, + { + name: "ISP", + value: `${res?.data?.isp || "Not available"}`, + }, + { + name: "Organization", + value: `${res?.data?.org || "Not available"}`, + }, + ], + color: successColor, + timestamp: new Date(), + footer: { + iconURL: footerIcon, + text: footerText, }, - { - name: "Country", - value: `${res?.data?.country || "Not available"}`, - }, - { - name: "Country Code", - value: `${res?.data?.countryCode || "Not available"}`, - }, - { - name: "Region", - value: `${res?.data?.region || "Not available"}`, - }, - { - name: "Region Name", - value: `${res?.data?.regionName || "Not available"}`, - }, - { - name: "City", - value: `${res?.data?.city || "Not available"}`, - }, - { - name: "ZIP Code", - value: `${res?.data?.zip || "Not available"}`, - }, - { - name: "Latitude", - value: `${res?.data?.lat || "Not available"}`, - }, - { - name: "Longitude", - value: `${res?.data?.lon || "Not available"}`, - }, - { - name: "Timezone", - value: `${res?.data?.timezone || "Not available"}`, - }, - { - name: "ISP", - value: `${res?.data?.isp || "Not available"}`, - }, - { - name: "Organization", - value: `${res?.data?.org || "Not available"}`, - }, - ], - color: successColor, - timestamp: new Date(), - footer: { - iconURL: footerIcon, - text: footerText, - }, - }; + }; - // Send interaction reply - await interaction?.editReply({ embeds: [embed] }); - } - }) - .catch(async (e) => { - logger?.error(e); - }); + // Send interaction reply + await interaction?.editReply({ embeds: [embed] }); + } + }) + .catch(async (e) => { + logger?.error(e); + }); + }, }; diff --git a/src/plugins/utilities/modules/stats.ts b/src/plugins/utilities/modules/stats.ts index ce95724..277f670 100644 --- a/src/plugins/utilities/modules/stats.ts +++ b/src/plugins/utilities/modules/stats.ts @@ -1,57 +1,63 @@ import { successColor, footerText, footerIcon } from "@config/embed"; +import { SlashCommandSubcommandBuilder } from "@discordjs/builders"; import { CommandInteraction } from "discord.js"; -export default async (interaction: CommandInteraction) => { - const { client } = interaction; - if (client?.uptime === null) return; - let totalSeconds = client?.uptime / 1000; - const days = Math?.floor(totalSeconds / 86400); - totalSeconds %= 86400; - const hours = Math?.floor(totalSeconds / 3600); - totalSeconds %= 3600; - const minutes = Math?.floor(totalSeconds / 60); - const seconds = Math?.floor(totalSeconds % 60); +export default { + data: (command: SlashCommandSubcommandBuilder) => { + return command.setName("stats").setDescription("Check bot statistics!)"); + }, + execute: async (interaction: CommandInteraction) => { + const { client } = interaction; + if (client?.uptime === null) return; + let totalSeconds = client?.uptime / 1000; + const days = Math?.floor(totalSeconds / 86400); + totalSeconds %= 86400; + const hours = Math?.floor(totalSeconds / 3600); + totalSeconds %= 3600; + const minutes = Math?.floor(totalSeconds / 60); + const seconds = Math?.floor(totalSeconds % 60); - const uptime = `${days} days, ${hours} hours, ${minutes} minutes and ${seconds} seconds`; + const uptime = `${days} days, ${hours} hours, ${minutes} minutes and ${seconds} seconds`; - const interactionEmbed = { - title: ":hammer: Utilities - Stats", - description: "Below you can see a list of statistics about the bot.", - fields: [ - { - name: "⏰ Latency", - value: `${Date?.now() - interaction?.createdTimestamp} ms`, - inline: true, + const interactionEmbed = { + title: ":hammer: Utilities - Stats", + description: "Below you can see a list of statistics about the bot.", + fields: [ + { + name: "⏰ Latency", + value: `${Date?.now() - interaction?.createdTimestamp} ms`, + inline: true, + }, + { + name: "⏰ API Latency", + value: `${Math?.round(client?.ws?.ping)} ms`, + inline: true, + }, + { + name: "⏰ Uptime", + value: `${uptime}`, + inline: false, + }, + { + name: "📈 Guilds", + value: `${client?.guilds?.cache?.size}`, + inline: true, + }, + { + name: "📈 Users (non-unique)", + value: `${client?.guilds?.cache?.reduce( + (acc, guild) => acc + guild?.memberCount, + 0 + )}`, + inline: true, + }, + ], + color: successColor, + timestamp: new Date(), + footer: { + iconURL: footerIcon, + text: footerText, }, - { - name: "⏰ API Latency", - value: `${Math?.round(client?.ws?.ping)} ms`, - inline: true, - }, - { - name: "⏰ Uptime", - value: `${uptime}`, - inline: false, - }, - { - name: "📈 Guilds", - value: `${client?.guilds?.cache?.size}`, - inline: true, - }, - { - name: "📈 Users (non-unique)", - value: `${client?.guilds?.cache?.reduce( - (acc, guild) => acc + guild?.memberCount, - 0 - )}`, - inline: true, - }, - ], - color: successColor, - timestamp: new Date(), - footer: { - iconURL: footerIcon, - text: footerText, - }, - }; - interaction?.editReply({ embeds: [interactionEmbed] }); + }; + interaction?.editReply({ embeds: [interactionEmbed] }); + }, }; diff --git a/src/schedules/index.ts b/src/schedules/index.ts index 8d5590a..ce563e7 100644 --- a/src/schedules/index.ts +++ b/src/schedules/index.ts @@ -11,8 +11,7 @@ export default async (client: Client) => { const expression = "*/5 * * * *"; schedule.scheduleJob(expression, async () => { - logger.verbose(`Checking schedules! (${expression})`); + logger?.verbose("Running shop roles job."); await shopRoles(client); }); - logger.info("Successfully started schedule engine!"); }; diff --git a/src/schedules/jobs/shopRoles.ts b/src/schedules/jobs/shopRoles.ts index 37ced37..239b484 100644 --- a/src/schedules/jobs/shopRoles.ts +++ b/src/schedules/jobs/shopRoles.ts @@ -16,11 +16,7 @@ export default async (client: Client) => { const oneHourAfterPayed = payed?.setHours(payed?.getHours() + 1); if (new Date() > new Date(oneHourAfterPayed)) { - logger.debug( - `Role: ${shopRole?.roleId} Expires: ${ - new Date() < new Date(oneHourAfterPayed) - } Last Payed: ${shopRole?.lastPayed}` - ); + logger?.verbose(`Shop role ${shopRole?.name} is expired.`); // Get guild object const guild = await guildSchema?.findOne({ @@ -43,8 +39,11 @@ export default async (client: Client) => { shopRoleSchema ?.deleteOne({ _id: shopRole?._id }) ?.then(async () => - logger?.debug(`Removed ${shopRole?._id} from collection.`) - ); + logger?.verbose(`Shop role ${shopRole?.roleId} was deleted.`) + ) + .catch(async (error) => { + return logger?.error(error); + }); return rMember?.roles?.remove(`${shopRole?.roleId}`); }