From 672abc44bd506d11bf8349b514553268f43ce24d Mon Sep 17 00:00:00 2001 From: Vermium Sifell Date: Thu, 26 Jan 2023 14:40:01 +0100 Subject: [PATCH] More refactoring --- .cspell/custom-dictionary-workspace.txt | 3 +- package-lock.json | 24 ++++++ package.json | 2 + .../config/subcommands/audits/index.ts | 4 +- src/commands/config/subcommands/cpgg/index.ts | 4 +- .../config/subcommands/credits/index.ts | 4 +- .../embeds/components/getValues/index.ts | 4 +- .../config/subcommands/embeds/index.ts | 2 +- .../config/subcommands/points/index.ts | 6 +- src/commands/config/subcommands/shop/index.ts | 6 +- .../config/subcommands/welcome/index.ts | 6 +- .../counters/subcommands/view/index.ts | 4 +- .../credits/subcommands/balance/index.ts | 4 +- .../credits/subcommands/gift/index.ts | 8 +- src/commands/credits/subcommands/top/index.ts | 4 +- .../credits/subcommands/work/index.ts | 12 ++- src/commands/dns/subcommands/lookup/index.ts | 4 +- src/commands/fun/subcommands/meme/index.ts | 4 +- .../groups/counters/subcommands/add/index.ts | 6 +- .../counters/subcommands/remove/index.ts | 6 +- .../groups/credits/subcommands/give/index.ts | 12 +-- .../credits/subcommands/giveaway/index.ts | 6 +- .../groups/credits/subcommands/set/index.ts | 6 +- .../groups/credits/subcommands/take/index.ts | 9 +- .../credits/subcommands/transfer/index.ts | 8 +- .../moderation/subcommands/prune/index.ts | 4 +- .../reputation/subcommands/check/index.ts | 6 +- .../reputation/subcommands/repute/index.ts | 6 +- src/commands/shop/groups/roles/index.ts | 2 +- .../groups/roles/subcommands/buy/index.ts | 12 +-- .../groups/roles/subcommands/cancel/index.ts | 9 +- src/commands/shop/subcommands/cpgg/index.ts | 6 +- src/commands/utils/modules/about/index.ts | 4 +- src/commands/utils/modules/avatar/index.ts | 4 +- src/events/guildCreate/index.ts | 45 +--------- src/events/guildDelete/index.ts | 37 +++------ src/events/guildMemberAdd/audits.ts | 32 ------- .../components/sendAuditEntry.ts | 30 +++++++ .../components/sendJoinMessage.ts | 50 +++++++++++ src/events/guildMemberAdd/index.ts | 57 +++---------- src/events/guildMemberAdd/joinMessage.ts | 52 ------------ src/events/guildMemberRemove/audits.ts | 41 --------- .../components/sendAuditEntry.ts | 39 +++++++++ .../components/sendLeaveMessage.ts | 46 ++++++++++ src/events/guildMemberRemove/index.ts | 39 +++++---- src/events/guildMemberRemove/leaveMessage.ts | 48 ----------- src/events/interactionCreate/audits.ts | 40 --------- .../components/sendAuditEntry.ts | 38 +++++++++ .../handlers/button/index.ts | 2 +- .../handlers/chatInputCommand/index.ts | 2 +- src/events/interactionCreate/index.ts | 12 ++- .../index.ts => components/earnCredits.ts} | 17 ++-- .../messageCreate/components/updateCounter.ts | 83 +++++++++++++++++++ src/events/messageCreate/index.ts | 10 +-- .../messageCreate/modules/counters/index.ts | 67 --------------- .../messageCreate/modules/points/index.ts | 65 --------------- src/events/messageDelete/audits.ts | 53 ------------ .../components/sendAuditEntry.ts | 51 ++++++++++++ .../messageDelete/components/updateCounter.ts | 48 +++++++++++ src/events/messageDelete/index.ts | 8 +- src/events/messageDelete/modules/counter.ts | 42 ---------- src/events/messageUpdate/audits.ts | 70 ---------------- .../components/sendAuditEntry.ts | 68 +++++++++++++++ .../messageUpdate/components/updateCounter.ts | 73 ++++++++++++++++ src/events/messageUpdate/index.ts | 20 +---- src/events/messageUpdate/modules/counter.ts | 43 ---------- src/events/ready/index.ts | 2 +- src/handlers/deferReply/index.ts | 27 ------ src/handlers/{database/index.ts => prisma.ts} | 4 +- .../{command/index.ts => registerCommands.ts} | 10 +-- .../{event/index.ts => registerEvents.ts} | 13 ++- .../{schedule/index.ts => scheduleJobs.ts} | 13 ++- src/handlers/updatePresence/index.ts | 34 -------- src/index.ts | 25 ++---- src/{schedules => jobs}/cooldowns/index.ts | 2 +- src/{schedules => jobs}/shop/index.ts | 0 .../modules/roles/components/dueForPayment.ts | 0 .../roles/components/overDueForPayment.ts | 2 +- .../shop/modules/roles/index.ts | 2 +- src/jobs/updatePresence.ts | 11 +++ src/middlewares/cooldown/index.ts | 2 +- src/modules/credits/validateTransaction.ts | 2 +- 82 files changed, 761 insertions(+), 927 deletions(-) delete mode 100644 src/events/guildMemberAdd/audits.ts create mode 100644 src/events/guildMemberAdd/components/sendAuditEntry.ts create mode 100644 src/events/guildMemberAdd/components/sendJoinMessage.ts delete mode 100644 src/events/guildMemberAdd/joinMessage.ts delete mode 100644 src/events/guildMemberRemove/audits.ts create mode 100644 src/events/guildMemberRemove/components/sendAuditEntry.ts create mode 100644 src/events/guildMemberRemove/components/sendLeaveMessage.ts delete mode 100644 src/events/guildMemberRemove/leaveMessage.ts delete mode 100644 src/events/interactionCreate/audits.ts create mode 100644 src/events/interactionCreate/components/sendAuditEntry.ts rename src/events/messageCreate/{modules/credits/index.ts => components/earnCredits.ts} (55%) create mode 100644 src/events/messageCreate/components/updateCounter.ts delete mode 100644 src/events/messageCreate/modules/counters/index.ts delete mode 100644 src/events/messageCreate/modules/points/index.ts delete mode 100644 src/events/messageDelete/audits.ts create mode 100644 src/events/messageDelete/components/sendAuditEntry.ts create mode 100644 src/events/messageDelete/components/updateCounter.ts delete mode 100644 src/events/messageDelete/modules/counter.ts delete mode 100644 src/events/messageUpdate/audits.ts create mode 100644 src/events/messageUpdate/components/sendAuditEntry.ts create mode 100644 src/events/messageUpdate/components/updateCounter.ts delete mode 100644 src/events/messageUpdate/modules/counter.ts delete mode 100644 src/handlers/deferReply/index.ts rename src/handlers/{database/index.ts => prisma.ts} (87%) rename src/handlers/{command/index.ts => registerCommands.ts} (77%) rename src/handlers/{event/index.ts => registerEvents.ts} (71%) rename src/handlers/{schedule/index.ts => scheduleJobs.ts} (76%) delete mode 100644 src/handlers/updatePresence/index.ts rename src/{schedules => jobs}/cooldowns/index.ts (95%) rename src/{schedules => jobs}/shop/index.ts (100%) rename src/{schedules => jobs}/shop/modules/roles/components/dueForPayment.ts (100%) rename src/{schedules => jobs}/shop/modules/roles/components/overDueForPayment.ts (98%) rename src/{schedules => jobs}/shop/modules/roles/index.ts (93%) create mode 100644 src/jobs/updatePresence.ts diff --git a/.cspell/custom-dictionary-workspace.txt b/.cspell/custom-dictionary-workspace.txt index f5e0cc5..a4c2a17 100644 --- a/.cspell/custom-dictionary-workspace.txt +++ b/.cspell/custom-dictionary-workspace.txt @@ -5,9 +5,9 @@ cpgg dagen discordjs Följande +Gåva gett Globalt -Gåva hoster inom inställningar @@ -33,5 +33,6 @@ Språkkod upsert uuidv Vermium +voca xyter Zyner diff --git a/package-lock.json b/package-lock.json index a45a571..3a0d832 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,6 +19,7 @@ "node-schedule": "^2.1.0", "typescript": "^4.9.4", "uuid": "^9.0.0", + "voca": "^1.4.0", "winston": "^3.8.2", "winston-daily-rotate-file": "^4.7.1" }, @@ -28,6 +29,7 @@ "@types/chance": "1.1.3", "@types/node-schedule": "2.1.0", "@types/uuid": "9.0.0", + "@types/voca": "^1.4.2", "@typescript-eslint/eslint-plugin": "^5.46.1", "@typescript-eslint/parser": "^5.46.1", "eslint": "^8.29.0", @@ -777,6 +779,12 @@ "integrity": "sha512-kr90f+ERiQtKWMz5rP32ltJ/BtULDI5RVO0uavn1HQUOwjx0R1h0rnDYNL0CepF1zL5bSY6FISAfd9tOdDhU5Q==", "dev": true }, + "node_modules/@types/voca": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@types/voca/-/voca-1.4.2.tgz", + "integrity": "sha512-Vmw8euGSdVlcDV69LoixtuervYUim5u6Vgp41PNxrHVGIo4vxSKMhW0I9MmBKbk3gtveNFzdHIVzyW1DpECzYw==", + "dev": true + }, "node_modules/@types/ws": { "version": "8.5.3", "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.3.tgz", @@ -9714,6 +9722,11 @@ "spdx-expression-parse": "^3.0.0" } }, + "node_modules/voca": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/voca/-/voca-1.4.0.tgz", + "integrity": "sha512-8Xz4H3vhYRGbFupLtl6dHwMx0ojUcjt0HYkqZ9oBCfipd/5mD7Md58m2/dq7uPuZU/0T3Gb1m66KS9jn+I+14Q==" + }, "node_modules/webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", @@ -10584,6 +10597,12 @@ "integrity": "sha512-kr90f+ERiQtKWMz5rP32ltJ/BtULDI5RVO0uavn1HQUOwjx0R1h0rnDYNL0CepF1zL5bSY6FISAfd9tOdDhU5Q==", "dev": true }, + "@types/voca": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@types/voca/-/voca-1.4.2.tgz", + "integrity": "sha512-Vmw8euGSdVlcDV69LoixtuervYUim5u6Vgp41PNxrHVGIo4vxSKMhW0I9MmBKbk3gtveNFzdHIVzyW1DpECzYw==", + "dev": true + }, "@types/ws": { "version": "8.5.3", "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.3.tgz", @@ -16982,6 +17001,11 @@ "spdx-expression-parse": "^3.0.0" } }, + "voca": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/voca/-/voca-1.4.0.tgz", + "integrity": "sha512-8Xz4H3vhYRGbFupLtl6dHwMx0ojUcjt0HYkqZ9oBCfipd/5mD7Md58m2/dq7uPuZU/0T3Gb1m66KS9jn+I+14Q==" + }, "webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", diff --git a/package.json b/package.json index 8cd6f05..6e4b0fd 100644 --- a/package.json +++ b/package.json @@ -44,6 +44,7 @@ "node-schedule": "^2.1.0", "typescript": "^4.9.4", "uuid": "^9.0.0", + "voca": "^1.4.0", "winston": "^3.8.2", "winston-daily-rotate-file": "^4.7.1" }, @@ -53,6 +54,7 @@ "@types/chance": "1.1.3", "@types/node-schedule": "2.1.0", "@types/uuid": "9.0.0", + "@types/voca": "^1.4.2", "@typescript-eslint/eslint-plugin": "^5.46.1", "@typescript-eslint/parser": "^5.46.1", "eslint": "^8.29.0", diff --git a/src/commands/config/subcommands/audits/index.ts b/src/commands/config/subcommands/audits/index.ts index 1a93c30..d3cf964 100644 --- a/src/commands/config/subcommands/audits/index.ts +++ b/src/commands/config/subcommands/audits/index.ts @@ -5,10 +5,10 @@ import { PermissionsBitField, SlashCommandSubcommandBuilder, } from "discord.js"; -import prisma from "../../../../handlers/database"; -import deferReply from "../../../../handlers/deferReply"; +import prisma from "../../../../handlers/prisma"; import { success as embedSuccess } from "../../../../helpers/baseEmbeds"; import checkPermission from "../../../../helpers/checkPermission"; +import deferReply from "../../../../helpers/deferReply"; import logger from "../../../../middlewares/logger"; export const builder = (command: SlashCommandSubcommandBuilder) => { diff --git a/src/commands/config/subcommands/cpgg/index.ts b/src/commands/config/subcommands/cpgg/index.ts index edda2c8..bb75932 100644 --- a/src/commands/config/subcommands/cpgg/index.ts +++ b/src/commands/config/subcommands/cpgg/index.ts @@ -3,10 +3,10 @@ import { PermissionsBitField, SlashCommandSubcommandBuilder, } from "discord.js"; -import prisma from "../../../../handlers/database"; -import deferReply from "../../../../handlers/deferReply"; +import prisma from "../../../../handlers/prisma"; import { success as embedSuccess } from "../../../../helpers/baseEmbeds"; import checkPermission from "../../../../helpers/checkPermission"; +import deferReply from "../../../../helpers/deferReply"; import encryption from "../../../../helpers/encryption"; import logger from "../../../../middlewares/logger"; diff --git a/src/commands/config/subcommands/credits/index.ts b/src/commands/config/subcommands/credits/index.ts index 1d81cac..6b4887f 100644 --- a/src/commands/config/subcommands/credits/index.ts +++ b/src/commands/config/subcommands/credits/index.ts @@ -3,10 +3,10 @@ import { PermissionsBitField, SlashCommandSubcommandBuilder, } from "discord.js"; -import prisma from "../../../../handlers/database"; -import deferReply from "../../../../handlers/deferReply"; +import prisma from "../../../../handlers/prisma"; import { success as embedSuccess } from "../../../../helpers/baseEmbeds"; import checkPermission from "../../../../helpers/checkPermission"; +import deferReply from "../../../../helpers/deferReply"; import logger from "../../../../middlewares/logger"; export const builder = (command: SlashCommandSubcommandBuilder) => { diff --git a/src/commands/config/subcommands/embeds/components/getValues/index.ts b/src/commands/config/subcommands/embeds/components/getValues/index.ts index 1a68813..11f82b3 100644 --- a/src/commands/config/subcommands/embeds/components/getValues/index.ts +++ b/src/commands/config/subcommands/embeds/components/getValues/index.ts @@ -1,6 +1,6 @@ import { ChatInputCommandInteraction, ColorResolvable } from "discord.js"; -import prisma from "../../../../../../handlers/database"; -import getEmbedConfig from "../../../../../../helpers/getEmbedData"; +import prisma from "../../../../../../handlers/prisma"; +import getEmbedConfig from "../../../../../../helpers/getEmbedConfig"; import logger from "../../../../../../middlewares/logger"; export default async (interaction: ChatInputCommandInteraction) => { diff --git a/src/commands/config/subcommands/embeds/index.ts b/src/commands/config/subcommands/embeds/index.ts index f861b70..88d7cff 100644 --- a/src/commands/config/subcommands/embeds/index.ts +++ b/src/commands/config/subcommands/embeds/index.ts @@ -5,8 +5,8 @@ import { SlashCommandSubcommandBuilder, } from "discord.js"; -import deferReply from "../../../../handlers/deferReply"; import checkPermission from "../../../../helpers/checkPermission"; +import deferReply from "../../../../helpers/deferReply"; import getValues from "./components/getValues"; export const builder = (command: SlashCommandSubcommandBuilder) => { diff --git a/src/commands/config/subcommands/points/index.ts b/src/commands/config/subcommands/points/index.ts index efcf161..ac7e802 100644 --- a/src/commands/config/subcommands/points/index.ts +++ b/src/commands/config/subcommands/points/index.ts @@ -4,10 +4,10 @@ import { PermissionsBitField, SlashCommandSubcommandBuilder, } from "discord.js"; -import prisma from "../../../../handlers/database"; -import deferReply from "../../../../handlers/deferReply"; +import prisma from "../../../../handlers/prisma"; import checkPermission from "../../../../helpers/checkPermission"; -import getEmbedConfig from "../../../../helpers/getEmbedData"; +import deferReply from "../../../../helpers/deferReply"; +import getEmbedConfig from "../../../../helpers/getEmbedConfig"; import logger from "../../../../middlewares/logger"; export const builder = (command: SlashCommandSubcommandBuilder) => { diff --git a/src/commands/config/subcommands/shop/index.ts b/src/commands/config/subcommands/shop/index.ts index a3eebb4..da2d2ac 100644 --- a/src/commands/config/subcommands/shop/index.ts +++ b/src/commands/config/subcommands/shop/index.ts @@ -4,10 +4,10 @@ import { PermissionsBitField, SlashCommandSubcommandBuilder, } from "discord.js"; -import prisma from "../../../../handlers/database"; -import deferReply from "../../../../handlers/deferReply"; +import prisma from "../../../../handlers/prisma"; import checkPermission from "../../../../helpers/checkPermission"; -import getEmbedConfig from "../../../../helpers/getEmbedData"; +import deferReply from "../../../../helpers/deferReply"; +import getEmbedConfig from "../../../../helpers/getEmbedConfig"; import logger from "../../../../middlewares/logger"; export const builder = (command: SlashCommandSubcommandBuilder) => { diff --git a/src/commands/config/subcommands/welcome/index.ts b/src/commands/config/subcommands/welcome/index.ts index 4b4f77a..48bf43b 100644 --- a/src/commands/config/subcommands/welcome/index.ts +++ b/src/commands/config/subcommands/welcome/index.ts @@ -5,10 +5,10 @@ import { PermissionsBitField, SlashCommandSubcommandBuilder, } from "discord.js"; -import prisma from "../../../../handlers/database"; -import deferReply from "../../../../handlers/deferReply"; +import prisma from "../../../../handlers/prisma"; import checkPermission from "../../../../helpers/checkPermission"; -import getEmbedConfig from "../../../../helpers/getEmbedData"; +import deferReply from "../../../../helpers/deferReply"; +import getEmbedConfig from "../../../../helpers/getEmbedConfig"; import logger from "../../../../middlewares/logger"; export const builder = (command: SlashCommandSubcommandBuilder) => { diff --git a/src/commands/counters/subcommands/view/index.ts b/src/commands/counters/subcommands/view/index.ts index 9a6fb11..566bd2d 100644 --- a/src/commands/counters/subcommands/view/index.ts +++ b/src/commands/counters/subcommands/view/index.ts @@ -4,9 +4,9 @@ import { SlashCommandSubcommandBuilder, } from "discord.js"; -import prisma from "../../../../handlers/database"; -import deferReply from "../../../../handlers/deferReply"; +import prisma from "../../../../handlers/prisma"; import { success as BaseEmbedSuccess } from "../../../../helpers/baseEmbeds"; +import deferReply from "../../../../helpers/deferReply"; // 1. Create builder function. export const builder = (command: SlashCommandSubcommandBuilder) => { diff --git a/src/commands/credits/subcommands/balance/index.ts b/src/commands/credits/subcommands/balance/index.ts index acd7ab8..fb45ebc 100644 --- a/src/commands/credits/subcommands/balance/index.ts +++ b/src/commands/credits/subcommands/balance/index.ts @@ -1,8 +1,8 @@ import { CommandInteraction, SlashCommandSubcommandBuilder } from "discord.js"; -import prisma from "../../../../handlers/database"; -import deferReply from "../../../../handlers/deferReply"; +import prisma from "../../../../handlers/prisma"; import { success as BaseEmbedSuccess } from "../../../../helpers/baseEmbeds"; +import deferReply from "../../../../helpers/deferReply"; import upsertGuildMember from "../../../../helpers/upsertGuildMember"; import logger from "../../../../middlewares/logger"; diff --git a/src/commands/credits/subcommands/gift/index.ts b/src/commands/credits/subcommands/gift/index.ts index ee209ee..2a1812b 100644 --- a/src/commands/credits/subcommands/gift/index.ts +++ b/src/commands/credits/subcommands/gift/index.ts @@ -2,13 +2,13 @@ import { ChatInputCommandInteraction, SlashCommandSubcommandBuilder, } from "discord.js"; -import prisma from "../../../../handlers/database"; +import prisma from "../../../../handlers/prisma"; -import deferReply from "../../../../handlers/deferReply"; import { success as BaseEmbedSuccess } from "../../../../helpers/baseEmbeds"; -import creditsTransfer from "../../../../helpers/credits/transfer"; +import deferReply from "../../../../helpers/deferReply"; import upsertGuildMember from "../../../../helpers/upsertGuildMember"; import logger from "../../../../middlewares/logger"; +import economy from "../../../../modules/credits"; // 1. Export a builder function. export const builder = (command: SlashCommandSubcommandBuilder) => { @@ -63,7 +63,7 @@ export const execute = async (interaction: ChatInputCommandInteraction) => { await upsertGuildMember(guild, user); // 5. Start an transaction of the credits. - await creditsTransfer(guild, user, account, credits); + await economy.transfer(guild, user, account, credits); const receiverGuildMember = await prisma.guildMemberCredit.upsert({ where: { diff --git a/src/commands/credits/subcommands/top/index.ts b/src/commands/credits/subcommands/top/index.ts index 4461130..7d13575 100644 --- a/src/commands/credits/subcommands/top/index.ts +++ b/src/commands/credits/subcommands/top/index.ts @@ -5,9 +5,9 @@ import { userMention, } from "discord.js"; -import prisma from "../../../../handlers/database"; -import deferReply from "../../../../handlers/deferReply"; +import prisma from "../../../../handlers/prisma"; import { success as BaseEmbedSuccess } from "../../../../helpers/baseEmbeds"; +import deferReply from "../../../../helpers/deferReply"; import upsertGuildMember from "../../../../helpers/upsertGuildMember"; import logger from "../../../../middlewares/logger"; diff --git a/src/commands/credits/subcommands/work/index.ts b/src/commands/credits/subcommands/work/index.ts index 985140b..09dfe8c 100644 --- a/src/commands/credits/subcommands/work/index.ts +++ b/src/commands/credits/subcommands/work/index.ts @@ -1,13 +1,13 @@ import Chance from "chance"; import { CommandInteraction, SlashCommandSubcommandBuilder } from "discord.js"; -import prisma from "../../../../handlers/database"; -import deferReply from "../../../../handlers/deferReply"; +import prisma from "../../../../handlers/prisma"; import { success as BaseEmbedSuccess } from "../../../../helpers/baseEmbeds"; -import creditsGive from "../../../../helpers/credits/give"; +import deferReply from "../../../../helpers/deferReply"; import upsertGuildMember from "../../../../helpers/upsertGuildMember"; import cooldown from "../../../../middlewares/cooldown"; import logger from "../../../../middlewares/logger"; +import economy from "../../../../modules/credits"; // 1. Export a builder function. export const builder = (command: SlashCommandSubcommandBuilder) => { @@ -54,7 +54,11 @@ export const execute = async (interaction: CommandInteraction) => { max: createGuild.workRate, }); - const upsertGuildMemberResult = await creditsGive(guild, user, creditsEarned); + const upsertGuildMemberResult = await economy.give( + guild, + user, + creditsEarned + ); // 8. Send embed. await interaction.editReply({ diff --git a/src/commands/dns/subcommands/lookup/index.ts b/src/commands/dns/subcommands/lookup/index.ts index e67b1a2..38ef20d 100644 --- a/src/commands/dns/subcommands/lookup/index.ts +++ b/src/commands/dns/subcommands/lookup/index.ts @@ -4,8 +4,8 @@ import { EmbedBuilder, SlashCommandSubcommandBuilder, } from "discord.js"; -import deferReply from "../../../../handlers/deferReply"; -import getEmbedConfig from "../../../../helpers/getEmbedData"; +import deferReply from "../../../../helpers/deferReply"; +import getEmbedConfig from "../../../../helpers/getEmbedConfig"; export const builder = (command: SlashCommandSubcommandBuilder) => { return command diff --git a/src/commands/fun/subcommands/meme/index.ts b/src/commands/fun/subcommands/meme/index.ts index 394d2c9..ca71bbe 100644 --- a/src/commands/fun/subcommands/meme/index.ts +++ b/src/commands/fun/subcommands/meme/index.ts @@ -7,8 +7,8 @@ import { EmbedBuilder, SlashCommandSubcommandBuilder, } from "discord.js"; -import deferReply from "../../../../handlers/deferReply"; -import getEmbedConfig from "../../../../helpers/getEmbedData"; +import deferReply from "../../../../helpers/deferReply"; +import getEmbedConfig from "../../../../helpers/getEmbedConfig"; import cooldown from "../../../../middlewares/cooldown"; export const builder = (command: SlashCommandSubcommandBuilder) => { diff --git a/src/commands/manage/groups/counters/subcommands/add/index.ts b/src/commands/manage/groups/counters/subcommands/add/index.ts index a20e48c..95b54ed 100644 --- a/src/commands/manage/groups/counters/subcommands/add/index.ts +++ b/src/commands/manage/groups/counters/subcommands/add/index.ts @@ -6,11 +6,11 @@ import { PermissionsBitField, SlashCommandSubcommandBuilder, } from "discord.js"; -import deferReply from "../../../../../../handlers/deferReply"; import checkPermission from "../../../../../../helpers/checkPermission"; +import deferReply from "../../../../../../helpers/deferReply"; // Configurations -import prisma from "../../../../../../handlers/database"; -import getEmbedConfig from "../../../../../../helpers/getEmbedData"; +import prisma from "../../../../../../handlers/prisma"; +import getEmbedConfig from "../../../../../../helpers/getEmbedConfig"; import logger from "../../../../../../middlewares/logger"; // Function diff --git a/src/commands/manage/groups/counters/subcommands/remove/index.ts b/src/commands/manage/groups/counters/subcommands/remove/index.ts index a022b59..33d1d5f 100644 --- a/src/commands/manage/groups/counters/subcommands/remove/index.ts +++ b/src/commands/manage/groups/counters/subcommands/remove/index.ts @@ -7,11 +7,11 @@ import { PermissionsBitField, SlashCommandSubcommandBuilder, } from "discord.js"; -import deferReply from "../../../../../../handlers/deferReply"; import checkPermission from "../../../../../../helpers/checkPermission"; +import deferReply from "../../../../../../helpers/deferReply"; // Configurations -import prisma from "../../../../../../handlers/database"; -import getEmbedConfig from "../../../../../../helpers/getEmbedData"; +import prisma from "../../../../../../handlers/prisma"; +import getEmbedConfig from "../../../../../../helpers/getEmbedConfig"; // Function export const builder = (command: SlashCommandSubcommandBuilder) => { diff --git a/src/commands/manage/groups/credits/subcommands/give/index.ts b/src/commands/manage/groups/credits/subcommands/give/index.ts index 5596e5b..0e63e0f 100644 --- a/src/commands/manage/groups/credits/subcommands/give/index.ts +++ b/src/commands/manage/groups/credits/subcommands/give/index.ts @@ -5,14 +5,12 @@ import { SlashCommandSubcommandBuilder, } from "discord.js"; // Configurations -// Helpers../../../../../../../helpers/userData -import pluralize from "../../../../../../helpers/pluralize"; // Models // Handlers -import deferReply from "../../../../../../handlers/deferReply"; import { success as baseEmbedSuccess } from "../../../../../../helpers/baseEmbeds"; import checkPermission from "../../../../../../helpers/checkPermission"; -import creditsGive from "../../../../../../helpers/credits/give"; +import deferReply from "../../../../../../helpers/deferReply"; +import economy from "../../../../../../modules/credits"; export const builder = (command: SlashCommandSubcommandBuilder) => { return command @@ -57,14 +55,12 @@ export const execute = async (interaction: ChatInputCommandInteraction) => { const embedSuccess = await baseEmbedSuccess(guild, "[:toolbox:] Give"); // 6. Give the credits. - await creditsGive(guild, discordReceiver, creditsAmount); + await economy.give(guild, discordReceiver, creditsAmount); // 7. Send embed. return await interaction.editReply({ embeds: [ - embedSuccess.setDescription( - `Successfully gave ${pluralize(creditsAmount, "credit")}` - ), + embedSuccess.setDescription(`Successfully gave ${creditsAmount} credits`), ], }); }; diff --git a/src/commands/manage/groups/credits/subcommands/giveaway/index.ts b/src/commands/manage/groups/credits/subcommands/giveaway/index.ts index 5d884c2..bcc1ff1 100644 --- a/src/commands/manage/groups/credits/subcommands/giveaway/index.ts +++ b/src/commands/manage/groups/credits/subcommands/giveaway/index.ts @@ -13,10 +13,10 @@ import { import { v4 as uuidv4 } from "uuid"; import encryption from "../../../../../../helpers/encryption"; // Configurations -import prisma from "../../../../../../handlers/database"; -import deferReply from "../../../../../../handlers/deferReply"; +import prisma from "../../../../../../handlers/prisma"; import checkPermission from "../../../../../../helpers/checkPermission"; -import getEmbedConfig from "../../../../../../helpers/getEmbedData"; +import deferReply from "../../../../../../helpers/deferReply"; +import getEmbedConfig from "../../../../../../helpers/getEmbedConfig"; import logger from "../../../../../../middlewares/logger"; // Function diff --git a/src/commands/manage/groups/credits/subcommands/set/index.ts b/src/commands/manage/groups/credits/subcommands/set/index.ts index fc12cae..058f416 100644 --- a/src/commands/manage/groups/credits/subcommands/set/index.ts +++ b/src/commands/manage/groups/credits/subcommands/set/index.ts @@ -7,10 +7,10 @@ import { SlashCommandSubcommandBuilder, } from "discord.js"; -import deferReply from "../../../../../../handlers/deferReply"; import { success as baseEmbedSuccess } from "../../../../../../helpers/baseEmbeds"; import checkPermission from "../../../../../../helpers/checkPermission"; -import creditsSet from "../../../../../../helpers/credits/set"; +import deferReply from "../../../../../../helpers/deferReply"; +import economy from "../../../../../../modules/credits"; export const builder = (command: SlashCommandSubcommandBuilder) => { return command @@ -49,7 +49,7 @@ export const execute = async (interaction: ChatInputCommandInteraction) => { if (!discordUser) throw new Error("User is not specified"); // 5. Set the credits. - await creditsSet(guild, discordUser, creditAmount); + await economy.set(guild, discordUser, creditAmount); // 6. Create base embeds. const embedSuccess = await baseEmbedSuccess(guild, "[:toolbox:] Set"); diff --git a/src/commands/manage/groups/credits/subcommands/take/index.ts b/src/commands/manage/groups/credits/subcommands/take/index.ts index 835176a..0906fbe 100644 --- a/src/commands/manage/groups/credits/subcommands/take/index.ts +++ b/src/commands/manage/groups/credits/subcommands/take/index.ts @@ -6,11 +6,10 @@ import { SlashCommandSubcommandBuilder, } from "discord.js"; -import deferReply from "../../../../../../handlers/deferReply"; import { success as baseEmbedSuccess } from "../../../../../../helpers/baseEmbeds"; import checkPermission from "../../../../../../helpers/checkPermission"; -import creditsTake from "../../../../../../helpers/credits/take"; -import pluralize from "../../../../../../helpers/pluralize"; +import deferReply from "../../../../../../helpers/deferReply"; +import economy from "../../../../../../modules/credits"; export const builder = (command: SlashCommandSubcommandBuilder) => { return command @@ -52,13 +51,13 @@ export const execute = async (interaction: ChatInputCommandInteraction) => { const embedSuccess = await baseEmbedSuccess(guild, "[:toolbox:] Take"); // 6. Take the credits. - await creditsTake(guild, discordReceiver, optionAmount); + await economy.take(guild, discordReceiver, optionAmount); // 7. Send embed. return await interaction.editReply({ embeds: [ embedSuccess.setDescription( - `Took ${pluralize(optionAmount, "credit")} from ${discordReceiver}.` + `Took ${optionAmount} credits from ${discordReceiver}.` ), ], }); diff --git a/src/commands/manage/groups/credits/subcommands/transfer/index.ts b/src/commands/manage/groups/credits/subcommands/transfer/index.ts index be8b1ef..c66af43 100644 --- a/src/commands/manage/groups/credits/subcommands/transfer/index.ts +++ b/src/commands/manage/groups/credits/subcommands/transfer/index.ts @@ -6,11 +6,11 @@ import { PermissionsBitField, SlashCommandSubcommandBuilder, } from "discord.js"; -import creditsTransfer from "../../../../../../helpers/credits/transfer"; // Configurations -import deferReply from "../../../../../../handlers/deferReply"; import checkPermission from "../../../../../../helpers/checkPermission"; -import getEmbedConfig from "../../../../../../helpers/getEmbedData"; +import deferReply from "../../../../../../helpers/deferReply"; +import getEmbedConfig from "../../../../../../helpers/getEmbedConfig"; +import economy from "../../../../../../modules/credits"; // Function export const builder = (command: SlashCommandSubcommandBuilder) => { @@ -64,7 +64,7 @@ export const execute = async (interaction: ChatInputCommandInteraction) => { if (!optionToUser) throw new Error("You must provide a user to transfer to."); - await creditsTransfer(guild, optionFromUser, optionToUser, optionAmount); + await economy.transfer(guild, optionFromUser, optionToUser, optionAmount); return interaction?.editReply({ embeds: [ diff --git a/src/commands/moderation/subcommands/prune/index.ts b/src/commands/moderation/subcommands/prune/index.ts index 59d47d1..97e783b 100644 --- a/src/commands/moderation/subcommands/prune/index.ts +++ b/src/commands/moderation/subcommands/prune/index.ts @@ -6,10 +6,10 @@ import { PermissionsBitField, SlashCommandSubcommandBuilder, } from "discord.js"; -import deferReply from "../../../../handlers/deferReply"; import checkPermission from "../../../../helpers/checkPermission"; +import deferReply from "../../../../helpers/deferReply"; // Configurations -import getEmbedConfig from "../../../../helpers/getEmbedData"; +import getEmbedConfig from "../../../../helpers/getEmbedConfig"; // Function export const builder = (command: SlashCommandSubcommandBuilder) => { diff --git a/src/commands/reputation/subcommands/check/index.ts b/src/commands/reputation/subcommands/check/index.ts index e628634..f50e713 100644 --- a/src/commands/reputation/subcommands/check/index.ts +++ b/src/commands/reputation/subcommands/check/index.ts @@ -3,9 +3,9 @@ import { EmbedBuilder, SlashCommandSubcommandBuilder, } from "discord.js"; -import prisma from "../../../../handlers/database"; -import deferReply from "../../../../handlers/deferReply"; -import getEmbedConfig from "../../../../helpers/getEmbedData"; +import prisma from "../../../../handlers/prisma"; +import deferReply from "../../../../helpers/deferReply"; +import getEmbedConfig from "../../../../helpers/getEmbedConfig"; import logger from "../../../../middlewares/logger"; export const builder = (command: SlashCommandSubcommandBuilder) => { diff --git a/src/commands/reputation/subcommands/repute/index.ts b/src/commands/reputation/subcommands/repute/index.ts index b7d78ba..9f9f5f2 100644 --- a/src/commands/reputation/subcommands/repute/index.ts +++ b/src/commands/reputation/subcommands/repute/index.ts @@ -3,12 +3,12 @@ import { EmbedBuilder, SlashCommandSubcommandBuilder, } from "discord.js"; -import getEmbedConfig from "../../../../helpers/getEmbedData"; +import getEmbedConfig from "../../../../helpers/getEmbedConfig"; import logger from "../../../../middlewares/logger"; import noSelfReputation from "./components/noSelfReputation"; -import prisma from "../../../../handlers/database"; -import deferReply from "../../../../handlers/deferReply"; +import prisma from "../../../../handlers/prisma"; +import deferReply from "../../../../helpers/deferReply"; import cooldown from "../../../../middlewares/cooldown"; export const builder = (command: SlashCommandSubcommandBuilder) => { diff --git a/src/commands/shop/groups/roles/index.ts b/src/commands/shop/groups/roles/index.ts index 5615773..c9d7f2a 100644 --- a/src/commands/shop/groups/roles/index.ts +++ b/src/commands/shop/groups/roles/index.ts @@ -16,7 +16,7 @@ import { execute as CancelExecute, } from "./subcommands/cancel"; -import prisma from "../../../../handlers/database"; +import prisma from "../../../../handlers/prisma"; export const builder = (group: SlashCommandSubcommandGroupBuilder) => { return ( diff --git a/src/commands/shop/groups/roles/subcommands/buy/index.ts b/src/commands/shop/groups/roles/subcommands/buy/index.ts index 7554656..c85fe50 100644 --- a/src/commands/shop/groups/roles/subcommands/buy/index.ts +++ b/src/commands/shop/groups/roles/subcommands/buy/index.ts @@ -7,15 +7,14 @@ import { GuildMemberRoleManager, SlashCommandSubcommandBuilder, } from "discord.js"; -import deferReply from "../../../../../../handlers/deferReply"; -import getEmbedData from "../../../../../../helpers/getEmbedData"; +import deferReply from "../../../../../../helpers/deferReply"; +import getEmbedData from "../../../../../../helpers/getEmbedConfig"; import logger from "../../../../../../middlewares/logger"; // Configurations // import fetchUser from "../../../../../../helpers/userData"; // Models -import prisma from "../../../../../../handlers/database"; -import pluralize from "../../../../../../helpers/pluralize"; +import prisma from "../../../../../../handlers/prisma"; // Function export const builder = (command: SlashCommandSubcommandBuilder) => { @@ -184,10 +183,7 @@ export const execute = async (interaction: ChatInputCommandInteraction) => { const interactionEmbed = new EmbedBuilder() .setTitle("[:shopping_cart:] Buy") .setDescription( - `You bought **${optionName}** for **${pluralize( - pricePerHour, - "credit" - )}**.` + `You bought **${optionName}** for **${pricePerHour} credits**.` ) .setTimestamp() .setColor(successColor) diff --git a/src/commands/shop/groups/roles/subcommands/cancel/index.ts b/src/commands/shop/groups/roles/subcommands/cancel/index.ts index 704cb2b..4e30e51 100644 --- a/src/commands/shop/groups/roles/subcommands/cancel/index.ts +++ b/src/commands/shop/groups/roles/subcommands/cancel/index.ts @@ -8,14 +8,13 @@ import { } from "discord.js"; // Configurations // Models -import deferReply from "../../../../../../handlers/deferReply"; +import deferReply from "../../../../../../helpers/deferReply"; import logger from "../../../../../../middlewares/logger"; // Configurations // Models -import prisma from "../../../../../../handlers/database"; -import getEmbedData from "../../../../../../helpers/getEmbedData"; -import pluralize from "../../../../../../helpers/pluralize"; +import prisma from "../../../../../../handlers/prisma"; +import getEmbedData from "../../../../../../helpers/getEmbedConfig"; // Function export const builder = (command: SlashCommandSubcommandBuilder) => { @@ -109,7 +108,7 @@ export const execute = async (interaction: ChatInputCommandInteraction) => { .setColor(successColor) .addFields({ name: "Your balance", - value: `${pluralize(createGuildMember.balance, "credit")}`, + value: `${createGuildMember.balance} credits`, }) .setFooter({ text: footerText, iconURL: footerIcon }); return interaction?.editReply({ diff --git a/src/commands/shop/subcommands/cpgg/index.ts b/src/commands/shop/subcommands/cpgg/index.ts index f453a04..3c9ed82 100644 --- a/src/commands/shop/subcommands/cpgg/index.ts +++ b/src/commands/shop/subcommands/cpgg/index.ts @@ -9,10 +9,10 @@ import { SlashCommandSubcommandBuilder, } from "discord.js"; import { v4 as uuidv4 } from "uuid"; -import prisma from "../../../../handlers/database"; -import deferReply from "../../../../handlers/deferReply"; +import prisma from "../../../../handlers/prisma"; +import deferReply from "../../../../helpers/deferReply"; import encryption from "../../../../helpers/encryption"; -import getEmbedData from "../../../../helpers/getEmbedData"; +import getEmbedData from "../../../../helpers/getEmbedConfig"; import logger from "../../../../middlewares/logger"; export const builder = (command: SlashCommandSubcommandBuilder) => { diff --git a/src/commands/utils/modules/about/index.ts b/src/commands/utils/modules/about/index.ts index 13a9b87..d4ee9ed 100644 --- a/src/commands/utils/modules/about/index.ts +++ b/src/commands/utils/modules/about/index.ts @@ -9,9 +9,9 @@ import { EmbedBuilder, SlashCommandSubcommandBuilder, } from "discord.js"; -import deferReply from "../../../../handlers/deferReply"; +import deferReply from "../../../../helpers/deferReply"; // Configurations -import getEmbedConfig from "../../../../helpers/getEmbedData"; +import getEmbedConfig from "../../../../helpers/getEmbedConfig"; // Function export const builder = (command: SlashCommandSubcommandBuilder) => { diff --git a/src/commands/utils/modules/avatar/index.ts b/src/commands/utils/modules/avatar/index.ts index 9dc6966..ee9d380 100644 --- a/src/commands/utils/modules/avatar/index.ts +++ b/src/commands/utils/modules/avatar/index.ts @@ -3,8 +3,8 @@ import { EmbedBuilder, SlashCommandSubcommandBuilder, } from "discord.js"; -import deferReply from "../../../../handlers/deferReply"; -import getEmbedConfig from "../../../../helpers/getEmbedData"; +import deferReply from "../../../../helpers/deferReply"; +import getEmbedConfig from "../../../../helpers/getEmbedConfig"; export const builder = (command: SlashCommandSubcommandBuilder) => { return command diff --git a/src/events/guildCreate/index.ts b/src/events/guildCreate/index.ts index 42653b0..8f26481 100644 --- a/src/events/guildCreate/index.ts +++ b/src/events/guildCreate/index.ts @@ -1,51 +1,12 @@ import { Guild } from "discord.js"; -import prisma from "../../handlers/database"; -import updatePresence from "../../handlers/updatePresence"; +import upsertGuildMember from "../../helpers/upsertGuildMember"; import { IEventOptions } from "../../interfaces/EventOptions"; -import logger from "../../middlewares/logger"; export const options: IEventOptions = { type: "on", }; -// Execute the function export const execute = async (guild: Guild) => { - const { client } = guild; - - updatePresence(client); - - // Create guildMember object - const createGuildMember = await prisma.guildMember.upsert({ - where: { - userId_guildId: { - userId: guild.ownerId, - guildId: guild.id, - }, - }, - update: {}, - create: { - user: { - connectOrCreate: { - create: { - id: guild.ownerId, - }, - where: { - id: guild.ownerId, - }, - }, - }, - guild: { - connectOrCreate: { - create: { - id: guild.id, - }, - where: { - id: guild.id, - }, - }, - }, - }, - }); - - logger.silly(createGuildMember); + const guildMember = await guild.fetchOwner(); + await upsertGuildMember(guild, guildMember.user); }; diff --git a/src/events/guildDelete/index.ts b/src/events/guildDelete/index.ts index 3bac8bd..1d592b9 100644 --- a/src/events/guildDelete/index.ts +++ b/src/events/guildDelete/index.ts @@ -1,9 +1,7 @@ // 3rd party dependencies import { Guild } from "discord.js"; -import prisma from "../../handlers/database"; -import updatePresence from "../../handlers/updatePresence"; +import prisma from "../../handlers/prisma"; import { IEventOptions } from "../../interfaces/EventOptions"; -import logger from "../../middlewares/logger"; export const options: IEventOptions = { type: "on", @@ -11,27 +9,16 @@ export const options: IEventOptions = { // Execute the function export const execute = async (guild: Guild) => { - const { client } = guild; - - updatePresence(client); - - // Delete guildMember objects - const deleteGuildMembers = prisma.guildMember.deleteMany({ - where: { - guildId: guild.id, - }, + return await prisma.$transaction(async (tx) => { + tx.guildMember.deleteMany({ + where: { + guildId: guild.id, + }, + }); + tx.guild.deleteMany({ + where: { + id: guild.id, + }, + }); }); - - // Delete guild object - const deleteGuild = prisma.guild.deleteMany({ - where: { - id: guild.id, - }, - }); - - // The transaction runs synchronously so deleteUsers must run last. - await prisma.$transaction([deleteGuildMembers, deleteGuild]); - - logger.silly(deleteGuildMembers); - logger.silly(deleteGuild); }; diff --git a/src/events/guildMemberAdd/audits.ts b/src/events/guildMemberAdd/audits.ts deleted file mode 100644 index a99961d..0000000 --- a/src/events/guildMemberAdd/audits.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { formatDistanceToNow } from "date-fns"; -import { EmbedBuilder, GuildMember } from "discord.js"; -import auditLogger from "../../helpers/auditLogger"; -import capitalizeFirstLetter from "../../helpers/capitalizeFirstLetter"; - -export default { - execute: async (member: GuildMember) => { - const { guild } = member; - - const embed = new EmbedBuilder() - .setAuthor({ - name: "Member Joined", - iconURL: member.displayAvatarURL(), - }) - .addFields([ - { - name: "User", - value: `${member.user} (${member.user.tag})`, - inline: true, - }, - { - name: "Created", - value: `${capitalizeFirstLetter( - formatDistanceToNow(member.user.createdAt, { addSuffix: true }) - )}`, - inline: true, - }, - ]); - - await auditLogger(guild, embed); - }, -}; diff --git a/src/events/guildMemberAdd/components/sendAuditEntry.ts b/src/events/guildMemberAdd/components/sendAuditEntry.ts new file mode 100644 index 0000000..db2bea4 --- /dev/null +++ b/src/events/guildMemberAdd/components/sendAuditEntry.ts @@ -0,0 +1,30 @@ +import { formatDistanceToNow } from "date-fns"; +import { EmbedBuilder, GuildMember } from "discord.js"; +import voca from "voca"; +import auditLogger from "../../../helpers/sendAuditLog"; + +export default async (member: GuildMember) => { + const { guild } = member; + + const embed = new EmbedBuilder() + .setAuthor({ + name: "Member Joined", + iconURL: member.displayAvatarURL(), + }) + .addFields([ + { + name: "User", + value: `${member.user} (${member.user.tag})`, + inline: true, + }, + { + name: "Created", + value: `${voca.capitalize( + formatDistanceToNow(member.user.createdAt, { addSuffix: true }) + )}`, + inline: true, + }, + ]); + + await auditLogger(guild, embed); +}; diff --git a/src/events/guildMemberAdd/components/sendJoinMessage.ts b/src/events/guildMemberAdd/components/sendJoinMessage.ts new file mode 100644 index 0000000..5ff9c36 --- /dev/null +++ b/src/events/guildMemberAdd/components/sendJoinMessage.ts @@ -0,0 +1,50 @@ +import { ChannelType, EmbedBuilder, GuildMember } from "discord.js"; +import prisma from "../../../handlers/prisma"; +import getEmbedConfig from "../../../helpers/getEmbedConfig"; +import logger from "../../../middlewares/logger"; + +export default async (member: GuildMember) => { + const { footerText, footerIcon, successColor } = await getEmbedConfig( + member.guild + ); + + const getGuildConfigWelcome = await prisma.guildConfigWelcome.findUnique({ + where: { id: member.guild.id }, + }); + + if (!getGuildConfigWelcome) { + logger.verbose("Guild not found"); + return; + } + + const { client } = member; + + if (getGuildConfigWelcome.status !== true) return; + if (!getGuildConfigWelcome.joinChannelId) return; + + const channel = client.channels.cache.get( + `${getGuildConfigWelcome.joinChannelId}` + ); + + if (!channel) throw new Error("Channel not found"); + if (channel.type !== ChannelType.GuildText) + throw new Error("Channel is not a text channel"); + + channel.send({ + embeds: [ + new EmbedBuilder() + .setColor(successColor) + .setTitle(`${member.user.username} has joined the server!`) + .setThumbnail(member.user.displayAvatarURL()) + .setDescription( + getGuildConfigWelcome.joinChannelMessage || + "Configure a join message in the `/settings guild welcome`." + ) + .setTimestamp() + .setFooter({ + text: footerText, + iconURL: footerIcon, + }), + ], + }); +}; diff --git a/src/events/guildMemberAdd/index.ts b/src/events/guildMemberAdd/index.ts index fc71e62..ab3ed5e 100644 --- a/src/events/guildMemberAdd/index.ts +++ b/src/events/guildMemberAdd/index.ts @@ -1,11 +1,10 @@ // 3rd party dependencies import { GuildMember } from "discord.js"; -import prisma from "../../handlers/database"; -import updatePresence from "../../handlers/updatePresence"; +import upsertGuildMember from "../../helpers/upsertGuildMember"; import { IEventOptions } from "../../interfaces/EventOptions"; import logger from "../../middlewares/logger"; -import audits from "./audits"; -import joinMessage from "./joinMessage"; +import sendAuditEntry from "./components/sendAuditEntry"; +import sendJoinMessage from "./components/sendJoinMessage"; export const options: IEventOptions = { type: "on", @@ -13,48 +12,16 @@ export const options: IEventOptions = { // Execute the function export const execute = async (member: GuildMember) => { - const { client, user, guild } = member; + const { user, guild } = member; - logger.silly( - `New member: ${user.tag} (${user.id}) added to guild: ${guild.name} (${guild.id})` - ); - - await audits.execute(member); - await joinMessage.execute(member); - updatePresence(client); - - // Create guildMember object - const createGuildMember = await prisma.guildMember.upsert({ - where: { - userId_guildId: { - userId: user.id, - guildId: guild.id, - }, - }, - update: {}, - create: { - user: { - connectOrCreate: { - create: { - id: user.id, - }, - where: { - id: user.id, - }, - }, - }, - guild: { - connectOrCreate: { - create: { - id: guild.id, - }, - where: { - id: guild.id, - }, - }, - }, - }, + logger.verbose({ + message: `User: ${user.tag} (${user.id}) joined guild: ${guild.name} (${guild.id})`, + guild, + user, }); - logger.silly(createGuildMember); + await sendAuditEntry(member); + await sendJoinMessage(member); + + await upsertGuildMember(guild, user); }; diff --git a/src/events/guildMemberAdd/joinMessage.ts b/src/events/guildMemberAdd/joinMessage.ts deleted file mode 100644 index 007c67f..0000000 --- a/src/events/guildMemberAdd/joinMessage.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { ChannelType, EmbedBuilder, GuildMember } from "discord.js"; -import prisma from "../../handlers/database"; -import getEmbedConfig from "../../helpers/getEmbedData"; -import logger from "../../middlewares/logger"; - -export default { - execute: async (member: GuildMember) => { - const { footerText, footerIcon, successColor } = await getEmbedConfig( - member.guild - ); - - const getGuildConfigWelcome = await prisma.guildConfigWelcome.findUnique({ - where: { id: member.guild.id }, - }); - - if (!getGuildConfigWelcome) { - logger.verbose("Guild not found"); - return; - } - - const { client } = member; - - if (getGuildConfigWelcome.status !== true) return; - if (!getGuildConfigWelcome.joinChannelId) return; - - const channel = client.channels.cache.get( - `${getGuildConfigWelcome.joinChannelId}` - ); - - if (!channel) throw new Error("Channel not found"); - if (channel.type !== ChannelType.GuildText) - throw new Error("Channel is not a text channel"); - - channel.send({ - embeds: [ - new EmbedBuilder() - .setColor(successColor) - .setTitle(`${member.user.username} has joined the server!`) - .setThumbnail(member.user.displayAvatarURL()) - .setDescription( - getGuildConfigWelcome.joinChannelMessage || - "Configure a join message in the `/settings guild welcome`." - ) - .setTimestamp() - .setFooter({ - text: footerText, - iconURL: footerIcon, - }), - ], - }); - }, -}; diff --git a/src/events/guildMemberRemove/audits.ts b/src/events/guildMemberRemove/audits.ts deleted file mode 100644 index f84397c..0000000 --- a/src/events/guildMemberRemove/audits.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { formatDistanceToNow } from "date-fns"; -import { EmbedBuilder, GuildMember } from "discord.js"; -import auditLogger from "../../helpers/auditLogger"; -import capitalizeFirstLetter from "../../helpers/capitalizeFirstLetter"; - -export default { - execute: async (member: GuildMember) => { - const { guild } = member; - - if (!member.joinedAt) throw new Error("Can not find joined date"); - - const embed = new EmbedBuilder() - .setAuthor({ - name: "Member Left", - iconURL: member.displayAvatarURL(), - }) - .addFields([ - { - name: "User", - value: `${member.user} (${member.user.tag})`, - inline: true, - }, - { - name: "Member since", - value: `${capitalizeFirstLetter( - formatDistanceToNow(member.joinedAt, { addSuffix: true }) - )}`, - inline: true, - }, - { - name: "Created", - value: `${capitalizeFirstLetter( - formatDistanceToNow(member.user.createdAt, { addSuffix: true }) - )}`, - inline: true, - }, - ]); - - await auditLogger(guild, embed); - }, -}; diff --git a/src/events/guildMemberRemove/components/sendAuditEntry.ts b/src/events/guildMemberRemove/components/sendAuditEntry.ts new file mode 100644 index 0000000..909f575 --- /dev/null +++ b/src/events/guildMemberRemove/components/sendAuditEntry.ts @@ -0,0 +1,39 @@ +import { formatDistanceToNow } from "date-fns"; +import { EmbedBuilder, GuildMember } from "discord.js"; +import voca from "voca"; +import auditLogger from "../../../helpers/sendAuditLog"; + +export default async (member: GuildMember) => { + const { guild } = member; + + if (!member.joinedAt) throw new Error("Can not find joined date"); + + const embed = new EmbedBuilder() + .setAuthor({ + name: "Member Left", + iconURL: member.displayAvatarURL(), + }) + .addFields([ + { + name: "User", + value: `${member.user} (${member.user.tag})`, + inline: true, + }, + { + name: "Member since", + value: `${voca.capitalize( + formatDistanceToNow(member.joinedAt, { addSuffix: true }) + )}`, + inline: true, + }, + { + name: "Created", + value: `${voca.capitalize( + formatDistanceToNow(member.user.createdAt, { addSuffix: true }) + )}`, + inline: true, + }, + ]); + + await auditLogger(guild, embed); +}; diff --git a/src/events/guildMemberRemove/components/sendLeaveMessage.ts b/src/events/guildMemberRemove/components/sendLeaveMessage.ts new file mode 100644 index 0000000..3487a6a --- /dev/null +++ b/src/events/guildMemberRemove/components/sendLeaveMessage.ts @@ -0,0 +1,46 @@ +import { ChannelType, EmbedBuilder, GuildMember } from "discord.js"; +import prisma from "../../../handlers/prisma"; +import getEmbedConfig from "../../../helpers/getEmbedConfig"; + +export default async (member: GuildMember) => { + const { footerText, footerIcon, errorColor } = await getEmbedConfig( + member.guild + ); + + const getGuildConfigWelcome = await prisma.guildConfigWelcome.findUnique({ + where: { id: member.guild.id }, + }); + + if (!getGuildConfigWelcome) throw new Error("Guild not found"); + + const { client } = member; + + if (getGuildConfigWelcome.status !== true) return; + if (!getGuildConfigWelcome.leaveChannelId) return; + + const channel = client.channels.cache.get( + `${getGuildConfigWelcome.leaveChannelId}` + ); + + if (!channel) throw new Error("Channel not found"); + if (channel.type !== ChannelType.GuildText) + throw new Error("Channel is not a text channel"); + + channel.send({ + embeds: [ + new EmbedBuilder() + .setColor(errorColor) + .setTitle(`${member.user.username} has left the server!`) + .setThumbnail(member.user.displayAvatarURL()) + .setDescription( + getGuildConfigWelcome.leaveChannelMessage || + "Configure a leave message in the `/settings guild welcome`." + ) + .setTimestamp() + .setFooter({ + text: footerText, + iconURL: footerIcon, + }), + ], + }); +}; diff --git a/src/events/guildMemberRemove/index.ts b/src/events/guildMemberRemove/index.ts index bbe61ad..9b04e4b 100644 --- a/src/events/guildMemberRemove/index.ts +++ b/src/events/guildMemberRemove/index.ts @@ -1,11 +1,10 @@ // 3rd party dependencies import { GuildMember } from "discord.js"; -import prisma from "../../handlers/database"; -import updatePresence from "../../handlers/updatePresence"; +import prisma from "../../handlers/prisma"; import { IEventOptions } from "../../interfaces/EventOptions"; import logger from "../../middlewares/logger"; -import audits from "./audits"; -import leaveMessage from "./leaveMessage"; +import sendAuditEntry from "./components/sendAuditEntry"; +import sendLeaveMessage from "./components/sendLeaveMessage"; export const options: IEventOptions = { type: "on", @@ -13,23 +12,23 @@ export const options: IEventOptions = { // Execute the function export const execute = async (member: GuildMember) => { - const { client, user, guild } = member; + const { user, guild } = member; - logger?.silly( - `Removed member: ${user.tag} (${user.id}) from guild: ${guild.name} (${guild.id})` - ); - - await audits.execute(member); - await leaveMessage.execute(member); - updatePresence(client); - - // Delete guildMember object - const deleteGuildMember = await prisma.guildMember.deleteMany({ - where: { - userId: user.id, - guildId: guild.id, - }, + logger.verbose({ + message: `User: ${user.tag} (${user.id}) left guild: ${guild.name} (${guild.id})`, + guild, + user, }); - logger.silly(deleteGuildMember); + await sendAuditEntry(member); + await sendLeaveMessage(member); + + await prisma.guildMember.delete({ + where: { + userId_guildId: { + userId: user.id, + guildId: guild.id, + }, + }, + }); }; diff --git a/src/events/guildMemberRemove/leaveMessage.ts b/src/events/guildMemberRemove/leaveMessage.ts deleted file mode 100644 index 4fb52e0..0000000 --- a/src/events/guildMemberRemove/leaveMessage.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { ChannelType, EmbedBuilder, GuildMember } from "discord.js"; -import prisma from "../../handlers/database"; -import getEmbedConfig from "../../helpers/getEmbedData"; - -export default { - execute: async (member: GuildMember) => { - const { footerText, footerIcon, errorColor } = await getEmbedConfig( - member.guild - ); - - const getGuildConfigWelcome = await prisma.guildConfigWelcome.findUnique({ - where: { id: member.guild.id }, - }); - - if (!getGuildConfigWelcome) throw new Error("Guild not found"); - - const { client } = member; - - if (getGuildConfigWelcome.status !== true) return; - if (!getGuildConfigWelcome.leaveChannelId) return; - - const channel = client.channels.cache.get( - `${getGuildConfigWelcome.leaveChannelId}` - ); - - if (!channel) throw new Error("Channel not found"); - if (channel.type !== ChannelType.GuildText) - throw new Error("Channel is not a text channel"); - - channel.send({ - embeds: [ - new EmbedBuilder() - .setColor(errorColor) - .setTitle(`${member.user.username} has left the server!`) - .setThumbnail(member.user.displayAvatarURL()) - .setDescription( - getGuildConfigWelcome.leaveChannelMessage || - "Configure a leave message in the `/settings guild welcome`." - ) - .setTimestamp() - .setFooter({ - text: footerText, - iconURL: footerIcon, - }), - ], - }); - }, -}; diff --git a/src/events/interactionCreate/audits.ts b/src/events/interactionCreate/audits.ts deleted file mode 100644 index 5f3a37f..0000000 --- a/src/events/interactionCreate/audits.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { BaseInteraction, EmbedBuilder } from "discord.js"; -import auditLogger from "../../helpers/auditLogger"; - -export default { - execute: async (interaction: BaseInteraction) => { - const { guild, user } = interaction; - if (!guild) throw new Error("Guild unavailable"); - if (!user) throw new Error("User unavailable"); - - const embed = new EmbedBuilder() - .setAuthor({ - name: "Interaction Created", - iconURL: user.displayAvatarURL(), - }) - .addFields([ - { - name: "ID", - value: `${interaction.id}`, - inline: true, - }, - { - name: "Type", - value: `${interaction.type}`, - inline: true, - }, - { - name: "User ID", - value: `${interaction.user} (${interaction.user.tag})`, - inline: true, - }, - { - name: "Channel", - value: `${interaction.channel}`, - inline: true, - }, - ]); - - await auditLogger(guild, embed); - }, -}; diff --git a/src/events/interactionCreate/components/sendAuditEntry.ts b/src/events/interactionCreate/components/sendAuditEntry.ts new file mode 100644 index 0000000..57c52a6 --- /dev/null +++ b/src/events/interactionCreate/components/sendAuditEntry.ts @@ -0,0 +1,38 @@ +import { BaseInteraction, EmbedBuilder } from "discord.js"; +import auditLogger from "../../../helpers/sendAuditLog"; + +export default async (interaction: BaseInteraction) => { + const { guild, user } = interaction; + if (!guild) throw new Error("Guild unavailable"); + if (!user) throw new Error("User unavailable"); + + const embed = new EmbedBuilder() + .setAuthor({ + name: "Interaction Created", + iconURL: user.displayAvatarURL(), + }) + .addFields([ + { + name: "ID", + value: `${interaction.id}`, + inline: true, + }, + { + name: "Type", + value: `${interaction.type}`, + inline: true, + }, + { + name: "User ID", + value: `${interaction.user} (${interaction.user.tag})`, + inline: true, + }, + { + name: "Channel", + value: `${interaction.channel}`, + inline: true, + }, + ]); + + await auditLogger(guild, embed); +}; diff --git a/src/events/interactionCreate/handlers/button/index.ts b/src/events/interactionCreate/handlers/button/index.ts index 092b5dd..92aaa69 100644 --- a/src/events/interactionCreate/handlers/button/index.ts +++ b/src/events/interactionCreate/handlers/button/index.ts @@ -5,7 +5,7 @@ import { ButtonStyle, EmbedBuilder, } from "discord.js"; -import getEmbedData from "../../../../helpers/getEmbedData"; +import getEmbedData from "../../../../helpers/getEmbedConfig"; export default async (interaction: ButtonInteraction) => { const { errorColor, footerText, footerIcon } = await getEmbedData( diff --git a/src/events/interactionCreate/handlers/chatInputCommand/index.ts b/src/events/interactionCreate/handlers/chatInputCommand/index.ts index 0f24744..825d5a6 100644 --- a/src/events/interactionCreate/handlers/chatInputCommand/index.ts +++ b/src/events/interactionCreate/handlers/chatInputCommand/index.ts @@ -5,7 +5,7 @@ import { ChatInputCommandInteraction, EmbedBuilder, } from "discord.js"; -import getEmbedData from "../../../../helpers/getEmbedData"; +import getEmbedData from "../../../../helpers/getEmbedConfig"; export default async (interaction: ChatInputCommandInteraction) => { const { errorColor, footerText, footerIcon } = await getEmbedData( diff --git a/src/events/interactionCreate/index.ts b/src/events/interactionCreate/index.ts index 86a21c5..da3f09e 100644 --- a/src/events/interactionCreate/index.ts +++ b/src/events/interactionCreate/index.ts @@ -2,7 +2,7 @@ import { BaseInteraction, InteractionType } from "discord.js"; import upsertGuildMember from "../../helpers/upsertGuildMember"; import { IEventOptions } from "../../interfaces/EventOptions"; import logger from "../../middlewares/logger"; -import audits from "./audits"; +import sendAuditEntry from "./components/sendAuditEntry"; import button from "./handlers/button"; import chatInputCommand from "./handlers/chatInputCommand"; @@ -11,9 +11,15 @@ export const options: IEventOptions = { }; export const execute = async (interaction: BaseInteraction) => { - logger.silly({ interaction }); const { guild, user } = interaction; + logger.verbose({ + message: `New interaction created: ${interaction.id} by: ${user.tag} (${user.id})`, + interaction, + guild, + user, + }); + if (guild) { await upsertGuildMember(guild, user); } @@ -36,5 +42,5 @@ export const execute = async (interaction: BaseInteraction) => { throw new Error("Unknown interaction type"); } - await audits.execute(interaction); + await sendAuditEntry(interaction); }; diff --git a/src/events/messageCreate/modules/credits/index.ts b/src/events/messageCreate/components/earnCredits.ts similarity index 55% rename from src/events/messageCreate/modules/credits/index.ts rename to src/events/messageCreate/components/earnCredits.ts index b8a7051..7636eea 100644 --- a/src/events/messageCreate/modules/credits/index.ts +++ b/src/events/messageCreate/components/earnCredits.ts @@ -1,8 +1,7 @@ import { ChannelType, Message } from "discord.js"; -import prisma from "../../../../handlers/database"; -import creditsGive from "../../../../helpers/credits/give"; -import cooldown from "../../../../middlewares/cooldown"; -import logger from "../../../../middlewares/logger"; +import prisma from "../../../handlers/prisma"; +import cooldown from "../../../middlewares/cooldown"; +import economy from "../../../modules/credits"; export default async (message: Message) => { const { guild, author, content, channel } = message; @@ -11,7 +10,7 @@ export default async (message: Message) => { if (author.bot) return; if (channel.type !== ChannelType.GuildText) return; - const upsertGuildConfigCredits = await prisma.guildConfigCredits.upsert({ + const creditsConfig = await prisma.guildConfigCredits.upsert({ where: { id: guild.id, }, @@ -33,17 +32,15 @@ export default async (message: Message) => { }, }); - logger.silly(upsertGuildConfigCredits); - - if (content.length < upsertGuildConfigCredits.minimumLength) return; + if (content.length < creditsConfig.minimumLength) return; await cooldown( guild, author, "event-messageCreate-credits", - upsertGuildConfigCredits.timeout, + creditsConfig.timeout, true ); - await creditsGive(guild, author, upsertGuildConfigCredits.rate); + await economy.give(guild, author, creditsConfig.rate); }; diff --git a/src/events/messageCreate/components/updateCounter.ts b/src/events/messageCreate/components/updateCounter.ts new file mode 100644 index 0000000..7e147d7 --- /dev/null +++ b/src/events/messageCreate/components/updateCounter.ts @@ -0,0 +1,83 @@ +import { ChannelType, Message } from "discord.js"; +import prisma from "../../../handlers/prisma"; +import logger from "../../../middlewares/logger"; + +export default async (message: Message) => { + const { guild, author, content, channel } = message; + + if (!guild) return; + if (author.bot) return; + if (channel?.type !== ChannelType.GuildText) return; + + const counter = await prisma.guildCounters.findUnique({ + where: { + guildId_channelId: { + guildId: guild.id, + channelId: channel.id, + }, + }, + }); + + if (!counter) { + logger.debug({ + message: `Channel: ${channel.name} (${channel.id}) in guild: ${guild.name} (${guild.id}) has no counter`, + channel, + guild, + counter, + }); + return; + } + + const messages = await message.channel.messages.fetch({ limit: 2 }); + const lastMessage = messages.last(); + if (!lastMessage) { + logger.error({ + message: `Failed to get last message in channel: ${channel.name} (${channel.id}) in guild ${guild.name} (${guild.id})`, + channel, + guild, + messages, + counter, + }); + return; + } + + if (lastMessage.author.id === author.id && channel.id === counter.channelId) { + logger.verbose({ + message: `Message sent by user: ${author.tag} (${author.id}) ${author.username} was deleted since nobody else wrote in the counter channel since last message`, + author, + channel, + lastMessage, + counter, + }); + + await message.delete(); + return; + } + + if (content !== counter.triggerWord) { + logger.verbose({ + message: `Message sent by user: ${author.tag} (${author.id}) ${author.username} was deleted since it did not match the trigger word: ${counter.triggerWord}`, + author, + channel, + lastMessage, + counter, + }); + + await message.delete(); + return; + } + + await prisma.guildCounters.update({ + where: { + guildId_channelId: { + guildId: guild.id, + channelId: channel.id, + }, + }, + data: { + count: { + increment: 1, + }, + }, + }); +}; diff --git a/src/events/messageCreate/index.ts b/src/events/messageCreate/index.ts index 627d353..9b189a9 100644 --- a/src/events/messageCreate/index.ts +++ b/src/events/messageCreate/index.ts @@ -1,15 +1,13 @@ import { Message } from "discord.js"; import { IEventOptions } from "../../interfaces/EventOptions"; -import countersExecute from "./modules/counters"; -import creditsExecute from "./modules/credits"; -import pointsExecute from "./modules/points"; +import earnCredits from "./components/earnCredits"; +import updateCounter from "./components/updateCounter"; export const options: IEventOptions = { type: "on", }; export const execute = async (message: Message) => { - await creditsExecute(message); - await pointsExecute(message); - await countersExecute(message); + await earnCredits(message); + await updateCounter(message); }; diff --git a/src/events/messageCreate/modules/counters/index.ts b/src/events/messageCreate/modules/counters/index.ts deleted file mode 100644 index 8fe8664..0000000 --- a/src/events/messageCreate/modules/counters/index.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { ChannelType, Message } from "discord.js"; -import prisma from "../../../../handlers/database"; -import logger from "../../../../middlewares/logger"; - -export default async (message: Message) => { - const { guild, author, content, channel } = message; - - if (!guild) return; - if (author.bot) return; - if (channel?.type !== ChannelType.GuildText) return; - - const messages = await message.channel.messages.fetch({ limit: 2 }); - const lastMessage = messages.last(); - - const channelCounter = await prisma.guildCounters.findUnique({ - where: { - guildId_channelId: { - guildId: guild.id, - channelId: channel.id, - }, - }, - }); - - if (!channelCounter) { - logger.debug("No counters found in channel."); - return; - } - - if ( - lastMessage?.author.id === author.id && - channel.id === channelCounter.channelId - ) { - logger.silly( - `${author.username} sent the last message therefor not allowing again.` - ); - await message.delete(); - return; - } - - if (content !== channelCounter.triggerWord) { - logger.silly( - `Counter word ${channelCounter.triggerWord} does not match message ${content}` - ); - - await message.delete(); - return; - } - - const updateGuildCounter = await prisma.guildCounters.update({ - where: { - guildId_channelId: { - guildId: guild.id, - channelId: channel.id, - }, - }, - data: { - count: { - increment: 1, - }, - }, - }); - - logger.silly(updateGuildCounter); - - if (!updateGuildCounter) - logger.error(`Failed to update counter - ${updateGuildCounter}`); -}; diff --git a/src/events/messageCreate/modules/points/index.ts b/src/events/messageCreate/modules/points/index.ts deleted file mode 100644 index 713d177..0000000 --- a/src/events/messageCreate/modules/points/index.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { ChannelType, Message } from "discord.js"; -import prisma from "../../../../handlers/database"; -import cooldown from "../../../../middlewares/cooldown"; -import logger from "../../../../middlewares/logger"; - -export default async (message: Message) => { - const { guild, author, content, channel } = message; - - if (!guild) return; - if (author.bot) return; - if (channel.type !== ChannelType.GuildText) return; - - const upsertGuildConfigPoints = await prisma.guildConfigPoints.upsert({ - where: { - id: guild.id, - }, - update: {}, - create: { - guild: { - connectOrCreate: { - create: { - id: guild.id, - }, - where: { - id: guild.id, - }, - }, - }, - }, - include: { - guild: true, - }, - }); - - logger.silly(upsertGuildConfigPoints); - - if (content.length < upsertGuildConfigPoints.minimumLength) return; - - await cooldown( - guild, - author, - "event-messageCreate-points", - upsertGuildConfigPoints.timeout, - true - ); - - const updateGuildMember = await prisma.guildMember.update({ - where: { - userId_guildId: { - userId: author.id, - guildId: guild.id, - }, - }, - data: { - pointsEarned: { - increment: upsertGuildConfigPoints.rate, - }, - }, - }); - - logger.silly(updateGuildMember); - - if (!updateGuildMember) - throw new Error("Failed to update guildMember object"); -}; diff --git a/src/events/messageDelete/audits.ts b/src/events/messageDelete/audits.ts deleted file mode 100644 index 092a937..0000000 --- a/src/events/messageDelete/audits.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { formatDistanceToNow } from "date-fns"; -import { EmbedBuilder, Message } from "discord.js"; -import auditLogger from "../../helpers/auditLogger"; -import capitalizeFirstLetter from "../../helpers/capitalizeFirstLetter"; - -export default { - execute: async (message: Message) => { - const { guild, member } = message; - if (!guild) throw new Error("Guild unavailable"); - if (!member) throw new Error("Member unavailable"); - - if (!member.joinedAt) throw new Error("Can not find member joined at"); - - const embed = new EmbedBuilder() - .setAuthor({ - name: "Message Deleted", - iconURL: message.author.displayAvatarURL(), - }) - .addFields([ - { - name: "User", - value: `${message.author} (${message.author.tag})`, - inline: true, - }, - { - name: "Member since", - value: `${capitalizeFirstLetter( - formatDistanceToNow(member.joinedAt, { - addSuffix: true, - }) - )}`, - inline: true, - }, - { - name: "Created", - value: `${capitalizeFirstLetter( - formatDistanceToNow(message.author.createdAt, { addSuffix: true }) - )}`, - inline: true, - }, - { - name: "Content", - value: `${ - message.content.length <= 1024 - ? message.content - : "Length is above 1024, this is a [limit by Discord](https://discord.com/developers/docs/resources/channel#embed-object-embed-limits), we are working on an solution to this problem." - }`, - }, - ]); - - await auditLogger(guild, embed); - }, -}; diff --git a/src/events/messageDelete/components/sendAuditEntry.ts b/src/events/messageDelete/components/sendAuditEntry.ts new file mode 100644 index 0000000..5e808b1 --- /dev/null +++ b/src/events/messageDelete/components/sendAuditEntry.ts @@ -0,0 +1,51 @@ +import { formatDistanceToNow } from "date-fns"; +import { EmbedBuilder, Message } from "discord.js"; +import voca from "voca"; +import auditLogger from "../../../helpers/sendAuditLog"; + +export default async (message: Message) => { + const { guild, member } = message; + if (!guild) throw new Error("Guild unavailable"); + if (!member) throw new Error("Member unavailable"); + + if (!member.joinedAt) throw new Error("Can not find member joined at"); + + const embed = new EmbedBuilder() + .setAuthor({ + name: "Message Deleted", + iconURL: message.author.displayAvatarURL(), + }) + .addFields([ + { + name: "User", + value: `${message.author} (${message.author.tag})`, + inline: true, + }, + { + name: "Member since", + value: `${voca.capitalize( + formatDistanceToNow(member.joinedAt, { + addSuffix: true, + }) + )}`, + inline: true, + }, + { + name: "Created", + value: `${voca.capitalize( + formatDistanceToNow(message.author.createdAt, { addSuffix: true }) + )}`, + inline: true, + }, + { + name: "Content", + value: `${ + message.content.length <= 1024 + ? message.content + : "Length is above 1024, this is a [limit by Discord](https://discord.com/developers/docs/resources/channel#embed-object-embed-limits), we are working on an solution to this problem." + }`, + }, + ]); + + await auditLogger(guild, embed); +}; diff --git a/src/events/messageDelete/components/updateCounter.ts b/src/events/messageDelete/components/updateCounter.ts new file mode 100644 index 0000000..9535c06 --- /dev/null +++ b/src/events/messageDelete/components/updateCounter.ts @@ -0,0 +1,48 @@ +import { ChannelType, Message } from "discord.js"; +import prisma from "../../../handlers/prisma"; +import logger from "../../../middlewares/logger"; + +export default async (message: Message) => { + const { guild, channel, author } = message; + + if (!guild) return; + if (author.bot) return; + if (channel?.type !== ChannelType.GuildText) return; + + const counter = await prisma.guildCounters.findUnique({ + where: { + guildId_channelId: { + guildId: guild.id, + channelId: channel.id, + }, + }, + }); + + if (!counter) { + logger.debug({ + message: `Channel: ${channel.name} (${channel.id}) in guild: ${guild.name} (${guild.id}) has no counter`, + channel, + guild, + counter, + }); + return; + } + + const messages = await message.channel.messages.fetch({ limit: 2 }); + const lastMessage = messages.last(); + if (!lastMessage) { + logger.error({ + message: `Failed to get last message in channel: ${channel.name} (${channel.id}) in guild ${guild.name} (${guild.id})`, + channel, + guild, + messages, + counter, + }); + return; + } + + await channel.send( + `${author} deleted his message saying: **${counter.triggerWord}**.` + ); + return; +}; diff --git a/src/events/messageDelete/index.ts b/src/events/messageDelete/index.ts index 53ccb2d..f43baac 100644 --- a/src/events/messageDelete/index.ts +++ b/src/events/messageDelete/index.ts @@ -1,7 +1,7 @@ import { Message } from "discord.js"; import { IEventOptions } from "../../interfaces/EventOptions"; -import audits from "./audits"; -import counter from "./modules/counter"; +import sendAuditEntry from "./components/sendAuditEntry"; +import updateCounter from "./components/updateCounter"; export const options: IEventOptions = { type: "on", @@ -9,6 +9,6 @@ export const options: IEventOptions = { // Execute the function export const execute = async (message: Message) => { - await audits.execute(message); - await counter(message); + await sendAuditEntry(message); + await updateCounter(message); }; diff --git a/src/events/messageDelete/modules/counter.ts b/src/events/messageDelete/modules/counter.ts deleted file mode 100644 index 1cd1bd9..0000000 --- a/src/events/messageDelete/modules/counter.ts +++ /dev/null @@ -1,42 +0,0 @@ -// Dependencies -import { Message } from "discord.js"; -// Models -import prisma from "../../../handlers/database"; -import logger from "../../../middlewares/logger"; - -export default async (message: Message) => { - const { guild, channel, author, content } = message; - - if (!guild) throw new Error("Guild not found"); - if (!channel) throw new Error("Channel not found"); - - const channelCounter = await prisma.guildCounters.findUnique({ - where: { - guildId_channelId: { - guildId: guild.id, - channelId: channel.id, - }, - }, - }); - - if (!channelCounter) return logger.debug("No counter found in channel."); - - const messages = await message.channel.messages.fetch({ limit: 1 }); - const lastMessage = messages.last(); - - if (!lastMessage) return false; - - if (content !== channelCounter.triggerWord) - return logger.silly("Message do not include the trigger word"); - - if (lastMessage.author.id === message.author.id) - return logger.debug("Same author as last message"); - - logger?.silly(`${author} said ${channelCounter.triggerWord} in ${channel}`); - logger?.silly( - `User: ${author?.tag} (${author?.id}) in guild: ${guild?.name} (${guild?.id}) said the counter word: ${channelCounter.triggerWord}` - ); - return await channel.send( - `${author} said **${channelCounter.triggerWord}**.` - ); -}; diff --git a/src/events/messageUpdate/audits.ts b/src/events/messageUpdate/audits.ts deleted file mode 100644 index 44b3754..0000000 --- a/src/events/messageUpdate/audits.ts +++ /dev/null @@ -1,70 +0,0 @@ -/* eslint-disable no-loops/no-loops */ -import { formatDistanceToNow } from "date-fns"; -import { EmbedBuilder, Message } from "discord.js"; -import auditLogger from "../../helpers/auditLogger"; -import capitalizeFirstLetter from "../../helpers/capitalizeFirstLetter"; - -export default { - execute: async (oldMessage: Message, newMessage: Message) => { - const { guild, member } = newMessage; - if (!guild) throw new Error("Guild unavailable"); - if (!member) throw new Error("Member unavailable"); - - if (!member.joinedAt) throw new Error("Can not find member joined at"); - - // Do not send audit log when an message contains an link and that links creates an embed - if (!newMessage.editedTimestamp) return; - - // Do not send audit log if oldMessage content is not found - if (!oldMessage.content) return; - - const embed = new EmbedBuilder() - .setAuthor({ - name: "Message Updated", - iconURL: newMessage.author.displayAvatarURL(), - }) - .addFields([ - { - name: "User", - value: `${newMessage.author} (${newMessage.author.tag})`, - inline: true, - }, - { - name: "Member since", - value: `${capitalizeFirstLetter( - formatDistanceToNow(member.joinedAt, { - addSuffix: true, - }) - )}`, - inline: true, - }, - { - name: "Created", - value: `${capitalizeFirstLetter( - formatDistanceToNow(newMessage.author.createdAt, { - addSuffix: true, - }) - )}`, - inline: true, - }, - { - name: "Before edited", - value: `${ - oldMessage.content.length <= 1024 - ? oldMessage.content - : "Length is above 1024, this is a [limit by Discord](https://discord.com/developers/docs/resources/channel#embed-object-embed-limits), we are working on an solution to this problem." - }`, - }, - { - name: "After edited", - value: `${ - newMessage.content.length <= 1024 - ? newMessage.content - : "Length is above 1024, this is a [limit by Discord](https://discord.com/developers/docs/resources/channel#embed-object-embed-limits), we are working on an solution to this problem." - }`, - }, - ]); - - await auditLogger(guild, embed); - }, -}; diff --git a/src/events/messageUpdate/components/sendAuditEntry.ts b/src/events/messageUpdate/components/sendAuditEntry.ts new file mode 100644 index 0000000..65b6179 --- /dev/null +++ b/src/events/messageUpdate/components/sendAuditEntry.ts @@ -0,0 +1,68 @@ +/* eslint-disable no-loops/no-loops */ +import { formatDistanceToNow } from "date-fns"; +import { EmbedBuilder, Message } from "discord.js"; +import voca from "voca"; +import auditLogger from "../../../helpers/sendAuditLog"; + +export default async (oldMessage: Message, newMessage: Message) => { + const { guild, member } = newMessage; + if (!guild) throw new Error("Guild unavailable"); + if (!member) throw new Error("Member unavailable"); + + if (!member.joinedAt) throw new Error("Can not find member joined at"); + + // Do not send audit log when an message contains an link and that links creates an embed + if (!newMessage.editedTimestamp) return; + + // Do not send audit log if oldMessage content is not found + if (!oldMessage.content) return; + + const embed = new EmbedBuilder() + .setAuthor({ + name: "Message Updated", + iconURL: newMessage.author.displayAvatarURL(), + }) + .addFields([ + { + name: "User", + value: `${newMessage.author} (${newMessage.author.tag})`, + inline: true, + }, + { + name: "Member since", + value: `${voca.capitalize( + formatDistanceToNow(member.joinedAt, { + addSuffix: true, + }) + )}`, + inline: true, + }, + { + name: "Created", + value: `${voca.capitalize( + formatDistanceToNow(newMessage.author.createdAt, { + addSuffix: true, + }) + )}`, + inline: true, + }, + { + name: "Before edited", + value: `${ + oldMessage.content.length <= 1024 + ? oldMessage.content + : "Length is above 1024, this is a [limit by Discord](https://discord.com/developers/docs/resources/channel#embed-object-embed-limits), we are working on an solution to this problem." + }`, + }, + { + name: "After edited", + value: `${ + newMessage.content.length <= 1024 + ? newMessage.content + : "Length is above 1024, this is a [limit by Discord](https://discord.com/developers/docs/resources/channel#embed-object-embed-limits), we are working on an solution to this problem." + }`, + }, + ]); + + await auditLogger(guild, embed); +}; diff --git a/src/events/messageUpdate/components/updateCounter.ts b/src/events/messageUpdate/components/updateCounter.ts new file mode 100644 index 0000000..6ae113b --- /dev/null +++ b/src/events/messageUpdate/components/updateCounter.ts @@ -0,0 +1,73 @@ +import { ChannelType, Message } from "discord.js"; +import prisma from "../../../handlers/prisma"; +import logger from "../../../middlewares/logger"; + +export default async (message: Message) => { + const { guild, author, content, channel } = message; + + if (!guild) return; + if (author.bot) return; + if (channel?.type !== ChannelType.GuildText) return; + + const counter = await prisma.guildCounters.findUnique({ + where: { + guildId_channelId: { + guildId: guild.id, + channelId: channel.id, + }, + }, + }); + + if (!counter) { + logger.debug({ + message: `Channel: ${channel.name} (${channel.id}) in guild: ${guild.name} (${guild.id}) has no counter`, + channel, + guild, + counter, + }); + return; + } + + const messages = await message.channel.messages.fetch({ limit: 2 }); + const lastMessage = messages.last(); + if (!lastMessage) { + logger.error({ + message: `Failed to get last message in channel: ${channel.name} (${channel.id}) in guild ${guild.name} (${guild.id})`, + channel, + guild, + messages, + counter, + }); + return; + } + + if (lastMessage.author.id === author.id && channel.id === counter.channelId) { + logger.verbose({ + message: `Message sent by user: ${author.tag} (${author.id}) ${author.username} was deleted since nobody else wrote in the counter channel since last message`, + author, + channel, + lastMessage, + counter, + }); + + await message.delete(); + return; + } + + if (content !== counter.triggerWord) { + logger.verbose({ + message: `Message sent by user: ${author.tag} (${author.id}) ${author.username} was deleted since it did not match the trigger word: ${counter.triggerWord}`, + author, + channel, + lastMessage, + counter, + }); + + await message.delete().then(async () => { + await channel.send( + `${author}'s message was deleted, before edited it said: **${counter.triggerWord}**.` + ); + }); + return; + } +}; diff --git a/src/events/messageUpdate/index.ts b/src/events/messageUpdate/index.ts index b017359..0f287e7 100644 --- a/src/events/messageUpdate/index.ts +++ b/src/events/messageUpdate/index.ts @@ -1,25 +1,13 @@ -// Dependencies import { Message } from "discord.js"; - -// Modules -import counter from "./modules/counter"; - import { IEventOptions } from "../../interfaces/EventOptions"; -import audits from "./audits"; +import sendAuditEntry from "./components/sendAuditEntry"; +import updateCounter from "./components/updateCounter"; export const options: IEventOptions = { type: "on", }; -// Execute the function export const execute = async (oldMessage: Message, newMessage: Message) => { - const { author } = newMessage; - - await audits.execute(oldMessage, newMessage); - - if (author.bot) return; - - await counter(newMessage); - - return; + await sendAuditEntry(oldMessage, newMessage); + await updateCounter(newMessage); }; diff --git a/src/events/messageUpdate/modules/counter.ts b/src/events/messageUpdate/modules/counter.ts deleted file mode 100644 index cbc844c..0000000 --- a/src/events/messageUpdate/modules/counter.ts +++ /dev/null @@ -1,43 +0,0 @@ -// Dependencies -import { Message } from "discord.js"; -// Models -import prisma from "../../../handlers/database"; -import logger from "../../../middlewares/logger"; - -export default async (message: Message) => { - const { guild, channel, author, content } = message; - - if (!guild) throw new Error("Guild not found"); - - if (!channel) throw new Error("Channel not found"); - - const channelCounter = await prisma.guildCounters.findUnique({ - where: { - guildId_channelId: { - guildId: guild.id, - channelId: channel.id, - }, - }, - }); - - if (!channelCounter) return logger.debug("No counters found in channel."); - - if (content === channelCounter.triggerWord) - return logger?.silly( - `User: ${author?.tag} (${author?.id}) in guild: ${guild?.name} (${guild?.id}) said the counter word: ${channelCounter.triggerWord}` - ); - - await message - .delete() - .then(async () => { - logger?.silly( - `${author} said ${channelCounter.triggerWord} in ${channel}` - ); - await channel?.send(`${author} said **${channelCounter.triggerWord}**.`); - }) - .catch((error) => { - return logger.error(error); - }); - - return true; -}; diff --git a/src/events/ready/index.ts b/src/events/ready/index.ts index 2c68a73..20f2964 100644 --- a/src/events/ready/index.ts +++ b/src/events/ready/index.ts @@ -2,7 +2,7 @@ import { Client } from "discord.js"; // Helpers import deployCommands from "../../handlers/deployCommands"; -import updatePresence from "../../handlers/updatePresence"; +import updatePresence from "../../helpers/updatePresence"; import { IEventOptions } from "../../interfaces/EventOptions"; import logger from "../../middlewares/logger"; diff --git a/src/handlers/deferReply/index.ts b/src/handlers/deferReply/index.ts deleted file mode 100644 index 92f1fb2..0000000 --- a/src/handlers/deferReply/index.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { BaseInteraction, EmbedBuilder } from "discord.js"; -import getEmbedData from "../../helpers/getEmbedData"; - -export default async (interaction: BaseInteraction, ephemeral: boolean) => { - if (!interaction.isRepliable()) - throw new Error(`Cannot reply to an interaction that is not repliable`); - - await interaction.deferReply({ - ephemeral, - }); - - const embedConfig = await getEmbedData(interaction.guild); - - await interaction.editReply({ - embeds: [ - new EmbedBuilder() - .setFooter({ - text: embedConfig.footerText, - iconURL: embedConfig.footerIcon, - }) - .setTimestamp(new Date()) - .setTitle("⏳︱Your request are being processed") - .setColor(embedConfig.waitColor) - .setDescription("This might take a while, please wait..."), - ], - }); -}; diff --git a/src/handlers/database/index.ts b/src/handlers/prisma.ts similarity index 87% rename from src/handlers/database/index.ts rename to src/handlers/prisma.ts index dff0994..271a4bf 100644 --- a/src/handlers/database/index.ts +++ b/src/handlers/prisma.ts @@ -1,13 +1,11 @@ import { PrismaClient } from "@prisma/client"; -import logger from "../../middlewares/logger"; +import logger from "../middlewares/logger"; const prisma = new PrismaClient(); prisma.$use(async (params, next) => { const before = Date.now(); - const result = await next(params); - const after = Date.now(); logger.debug( diff --git a/src/handlers/command/index.ts b/src/handlers/registerCommands.ts similarity index 77% rename from src/handlers/command/index.ts rename to src/handlers/registerCommands.ts index bdde535..7dff716 100644 --- a/src/handlers/command/index.ts +++ b/src/handlers/registerCommands.ts @@ -1,17 +1,17 @@ import { Client } from "discord.js"; -import checkDirectory from "../../helpers/checkDirectory"; -import { ICommand } from "../../interfaces/Command"; -import logger from "../../middlewares/logger"; +import checkDirectory from "../helpers/readDirectory"; +import { ICommand } from "../interfaces/Command"; +import logger from "../middlewares/logger"; // Register the commands. -export const register = async (client: Client) => { +export default async (client: Client) => { const profiler = logger.startTimer(); await checkDirectory("commands").then((commandNames) => { commandNames.forEach(async (commandName) => { const commandProfiler = logger.startTimer(); - await import(`../../commands/${commandName}`) + await import(`../commands/${commandName}`) .then((command: ICommand) => { client.commands.set(command.builder.name, command); diff --git a/src/handlers/event/index.ts b/src/handlers/registerEvents.ts similarity index 71% rename from src/handlers/event/index.ts rename to src/handlers/registerEvents.ts index 751aae0..b5ed408 100644 --- a/src/handlers/event/index.ts +++ b/src/handlers/registerEvents.ts @@ -1,17 +1,14 @@ import { Client } from "discord.js"; -import checkDirectory from "../../helpers/checkDirectory"; -import { IEvent } from "../../interfaces/Event"; -import logger from "../../middlewares/logger"; +import checkDirectory from "../helpers/readDirectory"; +import { IEvent } from "../interfaces/Event"; +import logger from "../middlewares/logger"; -// Registers all available events. -export const register = async (client: Client) => { +export default async (client: Client) => { const profiler = logger.startTimer(); await checkDirectory("events").then((eventNames) => { - // Import an event. const importEvent = async (name: string) => { - await import(`../../events/${name}`).then((event: IEvent) => { - // Create a new event execute function. + await import(`../events/${name}`).then((event: IEvent) => { const eventExecutor = async (...args: Promise[]) => { await event.execute(...args); }; diff --git a/src/handlers/schedule/index.ts b/src/handlers/scheduleJobs.ts similarity index 76% rename from src/handlers/schedule/index.ts rename to src/handlers/scheduleJobs.ts index 8fcd102..c1793a7 100644 --- a/src/handlers/schedule/index.ts +++ b/src/handlers/scheduleJobs.ts @@ -1,16 +1,15 @@ import { Client } from "discord.js"; import schedule from "node-schedule"; -import checkDirectory from "../../helpers/checkDirectory"; -import { IJob } from "../../interfaces/Job"; -import logger from "../../middlewares/logger"; +import checkDirectory from "../helpers/readDirectory"; +import { IJob } from "../interfaces/Job"; +import logger from "../middlewares/logger"; -// Start all jobs that are in the schedules directory -export const start = async (client: Client) => { +export default async (client: Client) => { const profiler = logger.startTimer(); - await checkDirectory("schedules").then((jobNames) => { + await checkDirectory("jobs").then((jobNames) => { jobNames.forEach(async (jobName) => { - await import(`../../schedules/${jobName}`) + await import(`../jobs/${jobName}`) .then((job: IJob) => { schedule.scheduleJob(job.options.schedule, async () => { const jobProfiler = logger.startTimer(); diff --git a/src/handlers/updatePresence/index.ts b/src/handlers/updatePresence/index.ts deleted file mode 100644 index 5696492..0000000 --- a/src/handlers/updatePresence/index.ts +++ /dev/null @@ -1,34 +0,0 @@ -// Dependencies -import { ActivitiesOptions, ActivityType, Client } from "discord.js"; -import logger from "../../middlewares/logger"; - -// Function -export default (client: Client) => { - // 1. Destructure the client. - const { guilds, user } = client; - if (!user) throw new Error("No user found"); - - // 2. Get the total number of guilds and members. - const memberCount = guilds.cache.reduce((a, g) => a + g.memberCount, 0); - const guildCount = guilds.cache.size; - - const activities: ActivitiesOptions[] = [ - { - name: `${guildCount} servers︱${memberCount} users`, - type: ActivityType.Watching, - }, - ]; - - const activity = activities[Math.floor(Math.random() * activities.length)]; - - // 3. Set the presence. - user.setActivity(activity); - - // 4. Log the presence. - return logger.debug({ - guildCount, - memberCount, - message: `Presence updated`, - activity, - }); -}; diff --git a/src/index.ts b/src/index.ts index b58112b..98bbefb 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,12 +1,11 @@ import { Client, Collection, GatewayIntentBits } from "discord.js"; // discord.js import "dotenv/config"; -import { register as commandRegister } from "./handlers/command"; -import { register as eventRegister } from "./handlers/event"; -import { start as scheduleStart } from "./handlers/schedule"; -// Main process that starts all other sub processes -const main = async () => { - // Initiate client object +import registerCommands from "./handlers/registerCommands"; +import registerEvents from "./handlers/registerEvents"; +import scheduleJobs from "./handlers/scheduleJobs"; + +(async () => { const client = new Client({ intents: [ GatewayIntentBits.Guilds, @@ -16,17 +15,11 @@ const main = async () => { ], }); - // Create command collection client.commands = new Collection(); - // Start critical handlers - await scheduleStart(client); - await eventRegister(client); - await commandRegister(client); + await registerEvents(client); + await registerCommands(client); + await scheduleJobs(client); - // Authorize with Discord's API await client.login(process.env.DISCORD_TOKEN); -}; - -// Start main process -main(); +})(); diff --git a/src/schedules/cooldowns/index.ts b/src/jobs/cooldowns/index.ts similarity index 95% rename from src/schedules/cooldowns/index.ts rename to src/jobs/cooldowns/index.ts index c825cc9..7c1f014 100644 --- a/src/schedules/cooldowns/index.ts +++ b/src/jobs/cooldowns/index.ts @@ -1,7 +1,7 @@ /* eslint-disable no-loops/no-loops */ import { add, formatDuration, intervalToDuration, isPast } from "date-fns"; -import prisma from "../../handlers/database"; +import prisma from "../../handlers/prisma"; import logger from "../../middlewares/logger"; export const options = { diff --git a/src/schedules/shop/index.ts b/src/jobs/shop/index.ts similarity index 100% rename from src/schedules/shop/index.ts rename to src/jobs/shop/index.ts diff --git a/src/schedules/shop/modules/roles/components/dueForPayment.ts b/src/jobs/shop/modules/roles/components/dueForPayment.ts similarity index 100% rename from src/schedules/shop/modules/roles/components/dueForPayment.ts rename to src/jobs/shop/modules/roles/components/dueForPayment.ts diff --git a/src/schedules/shop/modules/roles/components/overDueForPayment.ts b/src/jobs/shop/modules/roles/components/overDueForPayment.ts similarity index 98% rename from src/schedules/shop/modules/roles/components/overDueForPayment.ts rename to src/jobs/shop/modules/roles/components/overDueForPayment.ts index 10119fc..6fff38b 100644 --- a/src/schedules/shop/modules/roles/components/overDueForPayment.ts +++ b/src/jobs/shop/modules/roles/components/overDueForPayment.ts @@ -2,7 +2,7 @@ import { Client } from "discord.js"; import logger from "../../../../../middlewares/logger"; import { GuildShopRoles } from "@prisma/client"; -import prisma from "../../../../../handlers/database"; +import prisma from "../../../../../handlers/prisma"; // Execute the component export const execute = async (client: Client, role: GuildShopRoles) => { diff --git a/src/schedules/shop/modules/roles/index.ts b/src/jobs/shop/modules/roles/index.ts similarity index 93% rename from src/schedules/shop/modules/roles/index.ts rename to src/jobs/shop/modules/roles/index.ts index 197cecd..d59481b 100644 --- a/src/schedules/shop/modules/roles/index.ts +++ b/src/jobs/shop/modules/roles/index.ts @@ -1,6 +1,6 @@ /* eslint-disable no-loops/no-loops */ import { Client } from "discord.js"; -import prisma from "../../../../handlers/database"; +import prisma from "../../../../handlers/prisma"; import { execute as dueForPaymentExecute } from "./components/dueForPayment"; import { execute as overDueForPaymentExecute } from "./components/overDueForPayment"; diff --git a/src/jobs/updatePresence.ts b/src/jobs/updatePresence.ts new file mode 100644 index 0000000..8408554 --- /dev/null +++ b/src/jobs/updatePresence.ts @@ -0,0 +1,11 @@ +import { Client } from "discord.js"; + +import updatePresence from "../helpers/updatePresence"; + +export const options = { + schedule: "*/5 * * * *", // https://crontab.guru/ +}; + +export const execute = async (client: Client) => { + updatePresence(client); +}; diff --git a/src/middlewares/cooldown/index.ts b/src/middlewares/cooldown/index.ts index c439482..09cef59 100644 --- a/src/middlewares/cooldown/index.ts +++ b/src/middlewares/cooldown/index.ts @@ -1,6 +1,6 @@ import { add, formatDuration, intervalToDuration } from "date-fns"; import { Guild, User } from "discord.js"; -import prisma from "../../handlers/database"; +import prisma from "../../handlers/prisma"; import logger from "../logger"; export default async ( diff --git a/src/modules/credits/validateTransaction.ts b/src/modules/credits/validateTransaction.ts index f56466b..de35582 100644 --- a/src/modules/credits/validateTransaction.ts +++ b/src/modules/credits/validateTransaction.ts @@ -12,6 +12,6 @@ export default (guild: Guild, user: User, amount: number) => { // 3. Verify that the user is not an bot. if (user.bot) { - throw new Error(""); + throw new Error("Bots cant participate in transactions"); } };