More refactoring

This commit is contained in:
Axel Olausson Holtenäs 2023-01-26 14:40:01 +01:00
parent aea3dfd365
commit 672abc44bd
82 changed files with 761 additions and 927 deletions

View file

@ -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

24
package-lock.json generated
View file

@ -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",

View file

@ -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",

View file

@ -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) => {

View file

@ -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";

View file

@ -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) => {

View file

@ -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) => {

View file

@ -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) => {

View file

@ -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) => {

View file

@ -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) => {

View file

@ -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) => {

View file

@ -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) => {

View file

@ -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";

View file

@ -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: {

View file

@ -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";

View file

@ -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({

View file

@ -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

View file

@ -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) => {

View file

@ -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

View file

@ -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) => {

View file

@ -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`),
],
});
};

View file

@ -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

View file

@ -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");

View file

@ -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}.`
),
],
});

View file

@ -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: [

View file

@ -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) => {

View file

@ -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) => {

View file

@ -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) => {

View file

@ -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 (

View file

@ -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)

View file

@ -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({

View file

@ -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) => {

View file

@ -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) => {

View file

@ -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

View file

@ -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);
};

View file

@ -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);
};

View file

@ -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);
},
};

View file

@ -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);
};

View file

@ -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,
}),
],
});
};

View file

@ -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);
};

View file

@ -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,
}),
],
});
},
};

View file

@ -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);
},
};

View file

@ -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);
};

View file

@ -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,
}),
],
});
};

View file

@ -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,
},
},
});
};

View file

@ -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,
}),
],
});
},
};

View file

@ -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);
},
};

View file

@ -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);
};

View file

@ -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(

View file

@ -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(

View file

@ -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);
};

View file

@ -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);
};

View file

@ -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,
},
},
});
};

View file

@ -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);
};

View file

@ -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}`);
};

View file

@ -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");
};

View file

@ -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);
},
};

View file

@ -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);
};

View file

@ -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;
};

View file

@ -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);
};

View file

@ -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}**.`
);
};

View file

@ -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);
},
};

View file

@ -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);
};

View file

@ -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;
}
};

View file

@ -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);
};

View file

@ -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;
};

View file

@ -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";

View file

@ -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..."),
],
});
};

View file

@ -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(

View file

@ -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);

View file

@ -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<void>[]) => {
await event.execute(...args);
};

View file

@ -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();

View file

@ -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,
});
};

View file

@ -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();
})();

View file

@ -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 = {

View file

@ -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) => {

View file

@ -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";

View file

@ -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);
};

View file

@ -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 (

View file

@ -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");
}
};