diff --git a/src/commands/credits/index.ts b/src/commands/credits/index.ts index dca9c4d..614f72b 100644 --- a/src/commands/credits/index.ts +++ b/src/commands/credits/index.ts @@ -2,89 +2,38 @@ import { SlashCommandBuilder } from "@discordjs/builders"; import { CommandInteraction } from "discord.js"; -// Handlers -import logger from "../../handlers/logger"; - // Modules -import balance from "./modules/balance"; -import gift from "./modules/gift"; -import top from "./modules/top"; -import work from "./modules/work"; +import moduleBalance from "./modules/balance"; +import moduleGift from "./modules/gift"; +import moduleTop from "./modules/top"; +import moduleWork from "./modules/work"; // Function export default { data: new SlashCommandBuilder() .setName("credits") .setDescription("Manage your credits.") - .addSubcommand((subcommand) => - subcommand - .setName("balance") - .setDescription("Check a user's balance.") - .addUserOption((option) => - option - .setName("user") - .setDescription("The user whose balance you want to check.") - .setRequired(false) - ) - ) - .addSubcommand((subcommand) => - subcommand - .setName("gift") - .setDescription("Gift someone credits from your credits.") - .addUserOption((option) => - option - .setName("user") - .setDescription("The user you want to pay.") - .setRequired(true) - ) - .addIntegerOption((option) => - option - .setName("amount") - .setDescription("The amount you will pay.") - .setRequired(true) - ) - .addStringOption((option) => - option.setName("reason").setDescription("Your reason.") - ) - ) - .addSubcommand((subcommand) => - subcommand.setName("top").setDescription("Check the top balance.") - ) - .addSubcommand((subcommand) => - subcommand.setName("work").setDescription("Work for credits.") - ), + .addSubcommand(moduleBalance.data) + .addSubcommand(moduleGift.data) + .addSubcommand(moduleTop.data) + .addSubcommand(moduleWork.data), async execute(interaction: CommandInteraction) { - const { options, user, guild, commandName } = interaction; + const { options } = interaction; - // Module - Balance if (options?.getSubcommand() === "balance") { - // Execute Module - Balance - return balance(interaction); + return moduleBalance.execute(interaction); } - // Module - Gift - else if (options?.getSubcommand() === "gift") { - // Execute Module - Gift - return gift(interaction); + if (options?.getSubcommand() === "gift") { + return moduleGift.execute(interaction); } - // Module - Top - else if (options?.getSubcommand() === "top") { - // Execute Module - Top - return top(interaction); + if (options?.getSubcommand() === "top") { + return moduleTop.execute(interaction); } - // Module - Work - else if (options?.getSubcommand() === "work") { - // Execute Module - Work - return work(interaction); + if (options?.getSubcommand() === "work") { + return moduleWork.execute(interaction); } - - // Send debug message - return logger?.debug( - `Guild: ${guild?.id} User: ${ - user?.id - } executed /${commandName} ${options?.getSubcommandGroup()} ${options?.getSubcommand()}` - ); }, }; diff --git a/src/commands/credits/modules/balance.ts b/src/commands/credits/modules/balance.ts deleted file mode 100644 index 7292fe1..0000000 --- a/src/commands/credits/modules/balance.ts +++ /dev/null @@ -1,82 +0,0 @@ -// Dependencies -import { CommandInteraction, ColorResolvable } from "discord.js"; - -// Configurations -import config from "../../../../config.json"; - -// Helpers -import pluralize from "../../../helpers/pluralize"; - -// Models -import fetchUser from "../../../helpers/fetchUser"; - -// Function -export default async (interaction: CommandInteraction) => { - // Destructure - const { options, user, guild } = interaction; - - // User option - const optionUser = options?.getUser("user"); - - if (guild === null) return; - - // Get credit object - const userDB = await fetchUser(optionUser || user, guild); - - // If userDB does not exist - if (userDB === null) { - // Embed object - const embed = { - title: ":dollar: Credits [Balance]" as string, - description: `We can not find ${ - optionUser || "you" - } in our database.` as string, - color: config?.colors?.error as ColorResolvable, - timestamp: new Date(), - footer: { - iconURL: config?.footer?.icon as string, - text: config?.footer?.text as string, - }, - }; - - // Return interaction reply - return interaction?.editReply({ embeds: [embed] }); - } - - // If userDB.credits does not exist - if (userDB.credits === null) { - // Embed object - const embed = { - title: ":dollar: Credits [Balance]" as string, - description: `We can not find credits for ${ - optionUser || "you" - } in our database.` as string, - color: config?.colors?.error as ColorResolvable, - timestamp: new Date(), - footer: { - iconURL: config?.footer?.icon as string, - text: config?.footer?.text as string, - }, - }; - - // Return interaction reply - return interaction?.editReply({ embeds: [embed] }); - } else { - // Embed object - const embed = { - title: ":dollar: Credits [Balance]" as string, - description: `${ - optionUser ? `${optionUser} has` : "You have" - } ${pluralize(userDB.credits, "credit")}.` as string, - color: config?.colors?.success as ColorResolvable, - timestamp: new Date(), - footer: { - iconURL: config?.footer?.icon as string, - text: config?.footer?.text as string, - }, - }; - - // Return interaction reply - return interaction?.editReply({ embeds: [embed] }); - } -}; diff --git a/src/commands/credits/modules/balance/index.ts b/src/commands/credits/modules/balance/index.ts new file mode 100644 index 0000000..f35814c --- /dev/null +++ b/src/commands/credits/modules/balance/index.ts @@ -0,0 +1,89 @@ +// Dependencies +import { CommandInteraction, ColorResolvable, MessageEmbed } from "discord.js"; + +// Configurations +import { colors, footer } from "../../../../../config.json"; + +// Helpers +import pluralize from "../../../../helpers/pluralize"; + +// Models +import fetchUser from "../../../../helpers/fetchUser"; +import { SlashCommandSubcommandBuilder } from "@discordjs/builders"; + +// Function +export default { + data: (command: SlashCommandSubcommandBuilder) => { + return command + .setName("balance") + .setDescription("Check a user's balance.") + .addUserOption((option) => + option + .setName("user") + .setDescription("The user whose balance you want to check.") + .setRequired(false) + ); + }, + execute: async (interaction: CommandInteraction) => { + // Destructure + const { options, user, guild } = interaction; + + // User option + const optionUser = options?.getUser("user"); + + if (guild === null) return; + + // Get credit object + const userObj = await fetchUser(optionUser || user, guild); + + // If userObj does not exist + if (userObj === null) { + return interaction?.editReply({ + embeds: [ + new MessageEmbed() + .setTitle("[:dollar:] Credits (Balance)") + .setDescription( + `We can not find ${optionUser || "you"} in our database!` + ) + .setTimestamp(new Date()) + .setColor(colors?.error as ColorResolvable) + .setFooter({ text: footer?.text, iconURL: footer?.icon }), + ], + }); + } + + // If userObj.credits does not exist + if (userObj.credits === null) { + return interaction?.editReply({ + embeds: [ + new MessageEmbed() + .setTitle("[:dollar:] Credits (Balance)") + .setDescription( + `We can not find credits for ${ + optionUser || "you" + } in our database!` + ) + .setTimestamp(new Date()) + .setColor(colors?.error as ColorResolvable) + .setFooter({ text: footer?.text, iconURL: footer?.icon }), + ], + }); + } + + return interaction?.editReply({ + embeds: [ + new MessageEmbed() + .setTitle("[:dollar:] Credits (Balance)") + .setDescription( + `${optionUser || "You"} have ${pluralize( + userObj.credits, + "credit" + )}.` + ) + .setTimestamp(new Date()) + .setColor(colors?.success as ColorResolvable) + .setFooter({ text: footer?.text, iconURL: footer?.icon }), + ], + }); + }, +}; diff --git a/src/commands/credits/modules/gift.ts b/src/commands/credits/modules/gift.ts deleted file mode 100644 index 0da9093..0000000 --- a/src/commands/credits/modules/gift.ts +++ /dev/null @@ -1,196 +0,0 @@ -// Dependencies -import { CommandInteraction, ColorResolvable } from "discord.js"; - -// Configurations -import config from "../../../../config.json"; - -// Handlers -import logger from "../../../handlers/logger"; - -// Helpers -import saveUser from "../../../helpers/saveUser"; -import pluralize from "../../../helpers/pluralize"; - -// Models -import fetchUser from "../../../helpers/fetchUser"; - -// Function -export default async (interaction: CommandInteraction) => { - // Destructure - const { options, user, guild, client } = interaction; - - // User option - const optionUser = options?.getUser("user"); - - // Amount option - const optionAmount = options?.getInteger("amount"); - - // Reason option - const optionReason = options?.getString("reason"); - - if (guild === null) return; - if (optionUser === null) return; - - // Get fromUserDB object - const fromUserDB = await fetchUser(user, guild); - - // Get toUserDB object - const toUserDB = await fetchUser(optionUser, guild); - - if (fromUserDB === null) return; - if (toUserDB === null) return; - - // If receiver is same as sender - if (optionUser?.id === user?.id) { - // Create embed object - const embed = { - title: ":dollar: Credits [Gift]" as string, - description: "You can't pay yourself." as string, - color: config?.colors?.error as ColorResolvable, - timestamp: new Date(), - footer: { - iconURL: config?.footer?.icon as string, - text: config?.footer?.text as string, - }, - }; - - // Return interaction reply - return interaction?.editReply({ embeds: [embed] }); - } - - // If amount is null - if (optionAmount === null) { - // Embed object - const embed = { - title: ":dollar: Credits [Gift]" as string, - description: "We could not read your requested amount." as string, - color: config?.colors?.error as ColorResolvable, - timestamp: new Date(), - footer: { - iconURL: config?.footer?.icon as string, - text: config?.footer?.text as string, - }, - }; - - // Send interaction reply - return interaction?.editReply({ embeds: [embed] }); - } - - // If amount is zero or below - if (optionAmount <= 0) { - // Embed object - const embed = { - title: ":dollar: Credits [Gift]" as string, - description: "You can't pay zero or below." as string, - color: config?.colors?.error as ColorResolvable, - timestamp: new Date(), - footer: { - iconURL: config?.footer?.icon as string, - text: config?.footer?.text as string, - }, - }; - - // Return interaction reply - return interaction?.editReply({ embeds: [embed] }); - } - - // If user has below gifting amount - if (fromUserDB?.credits < optionAmount) { - // Embed object - const embed = { - title: ":dollar: Credits [Gift]" as string, - description: - `You have insufficient credits. Your credits is ${fromUserDB?.credits}` as string, - color: config?.colors?.error as ColorResolvable, - timestamp: new Date(), - footer: { - iconURL: config?.footer?.icon as string, - text: config?.footer?.text as string, - }, - }; - - // Return interaction reply - return interaction?.editReply({ embeds: [embed] }); - } - - // If toUserDB has no credits - if (!toUserDB) { - // Embed object - const embed = { - title: ":dollar: Credits [Gift]" as string, - description: - `That user has no credits, I can not gift credits to ${optionUser}` as string, - color: config?.colors?.error as ColorResolvable, - timestamp: new Date(), - footer: { - iconURL: config?.footer?.icon as string, - text: config?.footer?.text as string, - }, - }; - - // Send interaction reply - return interaction?.editReply({ embeds: [embed] }); - } - - // Withdraw amount from fromUserDB - fromUserDB.credits -= optionAmount; - - // Deposit amount to toUserDB - toUserDB.credits += optionAmount; - - // Save users - await saveUser(fromUserDB, toUserDB)?.then(async () => { - // Interaction embed object - const interactionEmbed = { - title: ":dollar: Credits [Gift]", - description: `You sent ${pluralize( - optionAmount, - "credit" - )} to ${optionUser}${ - optionReason ? ` with reason: ${optionReason}` : "" - }. Your new credits is ${pluralize(fromUserDB?.credits, "credit")}.`, - color: config?.colors?.success as ColorResolvable, - timestamp: new Date(), - footer: { - iconURL: config?.footer?.icon as string, - text: config?.footer?.text as string, - }, - }; - - // DM embed object - const dmEmbed = { - title: ":dollar: Credits [Gift]" as string, - description: `You received ${pluralize( - optionAmount, - "credit" - )} from ${user}${ - optionReason ? ` with reason: ${optionReason}` : "" - }. Your new credits is ${pluralize( - toUserDB?.credits, - "credit" - )}.` as string, - color: config?.colors?.success as ColorResolvable, - timestamp: new Date(), - footer: { - iconURL: config?.footer?.icon as string, - text: config?.footer?.text as string, - }, - }; - - // Get DM user object - const dmUser = client?.users?.cache?.get(interaction?.user?.id); - - // Send DM to user - await dmUser?.send({ embeds: [dmEmbed] }); - - // Send debug message - logger.debug( - `Guild: ${guild?.id} User: ${user?.id} gift sent from: ${user?.id} to: ${optionUser?.id}` - ); - - // Send interaction reply - return interaction.editReply({ - embeds: [interactionEmbed], - }); - }); -}; diff --git a/src/commands/credits/modules/gift/index.ts b/src/commands/credits/modules/gift/index.ts new file mode 100644 index 0000000..a680fa7 --- /dev/null +++ b/src/commands/credits/modules/gift/index.ts @@ -0,0 +1,244 @@ +// Dependencies +import { CommandInteraction, ColorResolvable, MessageEmbed } from "discord.js"; + +// Configurations +import { colors, footer } from "../../../../../config.json"; + +// Handlers +import logger from "../../../../logger"; + +// Helpers +import saveUser from "../../../../helpers/saveUser"; +import pluralize from "../../../../helpers/pluralize"; + +// Models +import fetchUser from "../../../../helpers/fetchUser"; +import { SlashCommandSubcommandBuilder } from "@discordjs/builders"; + +// Function +export default { + data: (command: SlashCommandSubcommandBuilder) => { + return command + .setName("gift") + .setDescription("Gift someone credits from your credits.") + .addUserOption((option) => + option + .setName("user") + .setDescription("The user you want to pay.") + .setRequired(true) + ) + .addIntegerOption((option) => + option + .setName("amount") + .setDescription("The amount you will pay.") + .setRequired(true) + ) + .addStringOption((option) => + option.setName("reason").setDescription("Your reason.") + ); + }, + execute: async (interaction: CommandInteraction) => { + const { options, user, guild, client } = interaction; + + const optionUser = options?.getUser("user"); + const optionAmount = options?.getInteger("amount"); + const optionReason = options?.getString("reason"); + + if (guild === null) { + return interaction.editReply({ + embeds: [ + new MessageEmbed() + .setTitle("[:dollar:] Credits (Gift)") + .setDescription(`We can not find your guild!`) + .setTimestamp(new Date()) + .setColor(colors?.error as ColorResolvable) + .setFooter({ text: footer?.text, iconURL: footer?.icon }), + ], + }); + } + + if (optionUser === null) { + return interaction.editReply({ + embeds: [ + new MessageEmbed() + .setTitle("[:dollar:] Credits (Gift)") + .setDescription(`We can not find your requested user!`) + .setTimestamp(new Date()) + .setColor(colors?.error as ColorResolvable) + .setFooter({ text: footer?.text, iconURL: footer?.icon }), + ], + }); + } + + // Get fromUserDB object + const fromUserDB = await fetchUser(user, guild); + + // Get toUserDB object + const toUserDB = await fetchUser(optionUser, guild); + + if (fromUserDB === null) { + return interaction.editReply({ + embeds: [ + new MessageEmbed() + .setTitle("[:dollar:] Credits (Gift)") + .setDescription( + `We can not find your requested from user in our database!` + ) + .setTimestamp(new Date()) + .setColor(colors?.error as ColorResolvable) + .setFooter({ text: footer?.text, iconURL: footer?.icon }), + ], + }); + } + + if (toUserDB === null) { + return interaction.editReply({ + embeds: [ + new MessageEmbed() + .setTitle("[:dollar:] Credits (Gift)") + .setDescription( + `We can not find your requested to user in our database!` + ) + .setTimestamp(new Date()) + .setColor(colors?.error as ColorResolvable) + .setFooter({ text: footer?.text, iconURL: footer?.icon }), + ], + }); + } + + // If receiver is same as sender + if (optionUser?.id === user?.id) { + return interaction.editReply({ + embeds: [ + new MessageEmbed() + .setTitle("[:dollar:] Credits (Gift)") + .setDescription(`You can not pay yourself!`) + .setTimestamp(new Date()) + .setColor(colors?.error as ColorResolvable) + .setFooter({ text: footer?.text, iconURL: footer?.icon }), + ], + }); + } + + // If amount is null + if (optionAmount === null) { + return interaction.editReply({ + embeds: [ + new MessageEmbed() + .setTitle("[:dollar:] Credits (Gift)") + .setDescription(`We could not read your requested amount!`) + .setTimestamp(new Date()) + .setColor(colors?.error as ColorResolvable) + .setFooter({ text: footer?.text, iconURL: footer?.icon }), + ], + }); + } + + // If amount is zero or below + if (optionAmount <= 0) { + return interaction.editReply({ + embeds: [ + new MessageEmbed() + .setTitle("[:dollar:] Credits (Gift)") + .setDescription(`You can't gift zero or below!`) + .setTimestamp(new Date()) + .setColor(colors?.error as ColorResolvable) + .setFooter({ text: footer?.text, iconURL: footer?.icon }), + ], + }); + } + + // If user has below gifting amount + if (fromUserDB?.credits < optionAmount) { + return interaction.editReply({ + embeds: [ + new MessageEmbed() + .setTitle("[:dollar:] Credits (Gift)") + .setDescription( + `You have insufficient credits. Your balance is ${fromUserDB?.credits}!` + ) + .setTimestamp(new Date()) + .setColor(colors?.error as ColorResolvable) + .setFooter({ text: footer?.text, iconURL: footer?.icon }), + ], + }); + } + + // If toUserDB has no credits + if (toUserDB === null) { + return interaction.editReply({ + embeds: [ + new MessageEmbed() + .setTitle("[:dollar:] Credits (Gift)") + .setDescription( + `We can not find your requested to user in our database!` + ) + .setTimestamp(new Date()) + .setColor(colors?.error as ColorResolvable) + .setFooter({ text: footer?.text, iconURL: footer?.icon }), + ], + }); + } + + // Withdraw amount from fromUserDB + fromUserDB.credits -= optionAmount; + + // Deposit amount to toUserDB + toUserDB.credits += optionAmount; + + // Save users + await saveUser(fromUserDB, toUserDB)?.then(async () => { + // Get DM user object + const dmUser = client?.users?.cache?.get(optionUser?.id); + + // Send DM to user + await dmUser + ?.send({ + embeds: [ + new MessageEmbed() + .setTitle("[:dollar:] Credits (Gift)") + .setDescription( + `You received ${pluralize( + optionAmount, + "credit" + )} from ${user}${ + optionReason ? ` with reason: ${optionReason}` : "" + }. Your new credits is ${pluralize( + toUserDB?.credits, + "credit" + )}.` + ) + .setTimestamp(new Date()) + .setColor(colors?.success as ColorResolvable) + .setFooter({ text: footer?.text, iconURL: footer?.icon }), + ], + }) + .catch(async () => + logger.verbose(`Can not send DM to user ${optionUser?.id}`) + ); + + // Send debug message + logger.debug( + `Guild: ${guild?.id} User: ${user?.id} gift sent from: ${user?.id} to: ${optionUser?.id}` + ); + + return interaction.editReply({ + embeds: [ + 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" + )}.` + ) + .setTimestamp(new Date()) + .setColor(colors?.success as ColorResolvable) + .setFooter({ text: footer?.text, iconURL: footer?.icon }), + ], + }); + }); + }, +}; diff --git a/src/commands/credits/modules/top.ts b/src/commands/credits/modules/top.ts deleted file mode 100644 index 043da6d..0000000 --- a/src/commands/credits/modules/top.ts +++ /dev/null @@ -1,47 +0,0 @@ -// Dependencies -import { CommandInteraction, ColorResolvable } from "discord.js"; - -// Configurations -import config from "../../../../config.json"; - -// Models -import userSchema from "../../../database/schemas/user"; - -// helpers -import pluralize from "../../../helpers/pluralize"; - -// Function -export default async (interaction: CommandInteraction) => { - // Get all users in the guild - - const usersDB = await userSchema.find({ guildId: interaction?.guild?.id }); - - const topTen = usersDB - - // Sort them after credits amount (ascending) - .sort((a, b) => (a?.credits > b?.credits ? -1 : 1)) - - // Return the top 10 - .slice(0, 10); - - // Create entry object - const entry = (x: any, index: number) => - `**Top ${index + 1}** - <@${x?.userId}> ${pluralize(x?.credits, "credit")}`; - - // Create embed object - const embed = { - title: ":dollar: Credits [Top]" as string, - description: `Below are the top ten.\n${topTen - ?.map((x, index) => entry(x, index)) - ?.join("\n")}` as string, - color: config?.colors?.success as ColorResolvable, - timestamp: new Date(), - footer: { - iconURL: config?.footer?.icon as string, - text: config?.footer?.text as string, - }, - }; - - // Return interaction reply - return interaction?.editReply({ embeds: [embed] }); -}; diff --git a/src/commands/credits/modules/top/index.ts b/src/commands/credits/modules/top/index.ts new file mode 100644 index 0000000..968594d --- /dev/null +++ b/src/commands/credits/modules/top/index.ts @@ -0,0 +1,54 @@ +// Dependencies +import { SlashCommandSubcommandBuilder } from "@discordjs/builders"; +import { CommandInteraction, ColorResolvable, MessageEmbed } from "discord.js"; + +// Configurations +import { colors, footer } from "../../../../../config.json"; + +// Models +import userSchema from "../../../../database/schemas/user"; + +// helpers +import pluralize from "../../../../helpers/pluralize"; + +// Function +export default { + data: (command: SlashCommandSubcommandBuilder) => { + return command.setName("top").setDescription("Check the top balance."); + }, + execute: async (interaction: CommandInteraction) => { + // Get all users in the guild + + const usersDB = await userSchema.find({ guildId: interaction?.guild?.id }); + + const topTen = usersDB + + // Sort them after credits amount (ascending) + .sort((a, b) => (a?.credits > b?.credits ? -1 : 1)) + + // Return the top 10 + .slice(0, 10); + + // Create entry object + const entry = (x: any, index: number) => + `**Top ${index + 1}** - <@${x?.userId}> ${pluralize( + x?.credits, + "credit" + )}`; + + return interaction.editReply({ + embeds: [ + new MessageEmbed() + .setTitle("[:dollar:] Credits (Top)") + .setDescription( + `Below are the top ten. + + ${topTen?.map((x, index) => entry(x, index))?.join("\n")}` + ) + .setTimestamp(new Date()) + .setColor(colors?.success as ColorResolvable) + .setFooter({ text: footer?.text, iconURL: footer?.icon }), + ], + }); + }, +}; diff --git a/src/commands/credits/modules/work.ts b/src/commands/credits/modules/work.ts deleted file mode 100644 index faf66fe..0000000 --- a/src/commands/credits/modules/work.ts +++ /dev/null @@ -1,119 +0,0 @@ -// Dependencies -import { CommandInteraction, ColorResolvable } from "discord.js"; -import Chance from "chance"; - -// Configurations -import config from "../../../../config.json"; - -// Handlers -import logger from "../../../handlers/logger"; - -// Models -import timeouts from "../../../database/schemas/timeout"; - -// Helpers -import pluralize from "../../../helpers/pluralize"; -import fetchUser from "../../../helpers/fetchUser"; -import fetchGuild from "../../../helpers/fetchGuild"; - -// Function -export default async (interaction: CommandInteraction) => { - // Destructure member - const { guild, user } = interaction; - - // Chance module - const chance = new Chance(); - - // Check if user has a timeout - const isTimeout = await timeouts?.findOne({ - guildId: guild?.id, - userId: user?.id, - timeoutId: "2022-03-15-19-16", - }); - - if (guild === null) return; - - 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 () => { - // Send debug message - logger?.debug(`Credits added to user: ${user?.id}`); - - // Create embed object - const embed = { - title: ":dollar: Credits [Work]" as string, - description: `You have earned ${pluralize( - creditsEarned, - "credit" - )}` as string, - color: config?.colors?.success as ColorResolvable, - timestamp: new Date(), - footer: { - iconURL: config?.footer?.icon as string, - text: config?.footer?.text as string, - }, - }; - - // Send interaction reply - return interaction?.editReply({ embeds: [embed] }); - }); - - // Create a timeout for the user - await timeouts?.create({ - guildId: guild?.id, - userId: user?.id, - timeoutId: "2022-03-15-19-16", - }); - - setTimeout(async () => { - // Send debug message - 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 timeouts?.deleteOne({ - guildId: guild?.id, - userId: user?.id, - timeoutId: "2022-03-15-19-16", - }); - }, guildDB?.credits?.workTimeout); - } else { - // Create embed object - const embed = { - title: ":dollar: Credits [Work]" as string, - description: `You have worked within the last ${ - guildDB?.credits?.workTimeout / 1000 - } seconds, you can not work now!` as string, - timestamp: new Date(), - color: config?.colors?.error as ColorResolvable, - footer: { - iconURL: config?.footer?.icon as string, - text: config?.footer?.text as string, - }, - }; - - // Send debug message - logger?.debug( - `Guild: ${guild?.id} User: ${user?.id} has worked within last day, no work can be done` - ); - - // Return interaction reply - return interaction?.editReply({ embeds: [embed] }); - } -}; diff --git a/src/commands/credits/modules/work/index.ts b/src/commands/credits/modules/work/index.ts new file mode 100644 index 0000000..49d51ad --- /dev/null +++ b/src/commands/credits/modules/work/index.ts @@ -0,0 +1,118 @@ +// Dependencies +import { CommandInteraction, ColorResolvable, MessageEmbed } from "discord.js"; +import Chance from "chance"; + +// Configurations +import { colors, footer } from "../../../../../config.json"; + +// Handlers +import logger from "../../../../logger"; + +// Models +import timeouts from "../../../../database/schemas/timeout"; + +// Helpers +import pluralize from "../../../../helpers/pluralize"; +import fetchUser from "../../../../helpers/fetchUser"; +import fetchGuild from "../../../../helpers/fetchGuild"; +import { SlashCommandSubcommandBuilder } from "@discordjs/builders"; + +// Function +export default { + data: (command: SlashCommandSubcommandBuilder) => { + return command.setName("work").setDescription("Work for credits."); + }, + execute: async (interaction: CommandInteraction) => { + // Destructure member + const { guild, user } = interaction; + + // Chance module + const chance = new Chance(); + + // Check if user has a timeout + const isTimeout = await timeouts?.findOne({ + guildId: guild?.id, + userId: user?.id, + timeoutId: "2022-03-15-19-16", + }); + + if (guild === null) return; + + 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?.verbose(`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(colors?.success as ColorResolvable) + .setFooter({ text: footer?.text, iconURL: footer?.icon }), + ], + }); + }); + + // Create a timeout for the user + await timeouts?.create({ + guildId: guild?.id, + userId: user?.id, + timeoutId: "2022-03-15-19-16", + }); + + setTimeout(async () => { + logger?.verbose( + `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 timeouts?.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` + ); + + 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!` + ) + .setTimestamp(new Date()) + .setColor(colors?.success as ColorResolvable) + .setFooter({ text: footer?.text, iconURL: footer?.icon }), + ], + }); + } + }, +}; diff --git a/src/events/interactionCreate/index.ts b/src/events/interactionCreate/index.ts index 3349123..ed09f93 100644 --- a/src/events/interactionCreate/index.ts +++ b/src/events/interactionCreate/index.ts @@ -28,12 +28,10 @@ export default { // Execute command await command.execute(interaction); - const { commandName, user, options } = interaction; + const { commandName, user } = interaction; - logger?.verbose( - `Guild: ${guild?.id} User: ${ - user?.id - } executed /${commandName} ${options?.getSubcommandGroup()} ${options?.getSubcommand()}` + return logger?.verbose( + `Guild: ${guild?.id} User: ${user?.tag} executed ${commandName}` ); } catch (e) { // Send debug message