🎨 typescripted commands

This commit is contained in:
Axel Olausson Holtenäs 2022-04-10 17:54:36 +02:00
parent 95adb324f4
commit 1b0b9fb6bb
No known key found for this signature in database
GPG key ID: 9347A5E873995701
45 changed files with 1663 additions and 1332 deletions

View file

@ -1,47 +0,0 @@
import config from '../../../../config.json';
import logger from '../../../handlers/logger';
import counters from '../../../helpers/database/models/counterSchema';
import { CommandInteraction } from 'discord.js';
export default async (interaction: CommandInteraction) => {
try {
// Destructure member
const { member } = await interaction;
// Get options
const channel = await interaction.options.getChannel('channel');
const counter = await counters.findOne({
guildId: interaction?.guild?.id,
channelId: channel?.id,
});
if (!counter) {
// Create embed object
const embed = {
title: 'Counter - View',
description: `${channel} is not a counting channel.`,
timestamp: new Date(),
color: config.colors.error as any,
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
// Send interaction reply
return await interaction.editReply({ embeds: [embed] });
}
// Create embed object
const embed = {
title: 'Counter - View',
color: config.colors.success as any,
description: `${channel} is currently at number ${counter.counter}.`,
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
// Send interaction reply
return await interaction.editReply({ embeds: [embed] });
} catch (e) {
// Send debug message
await logger.error(e);
}
};

View file

@ -1,11 +1,17 @@
import { SlashCommandBuilder } from '@discordjs/builders';
import view from './addons/view';
// Dependencies
import { CommandInteraction } from 'discord.js';
import { SlashCommandBuilder } from '@discordjs/builders';
// Modules
import view from './modules/view';
// Handlers
import logger from '../../handlers/logger';
// Function
export default {
data: new SlashCommandBuilder()
.setName('counter')
.setName('counters')
.setDescription('Manage counters.')
.addSubcommand((subcommand) =>
subcommand
@ -19,10 +25,19 @@ export default {
)
),
async execute(interaction: CommandInteraction) {
// If subcommand is view
if (interaction.options.getSubcommand() === 'view') {
// Execute view addon
await view(interaction);
const { options, guild, user, commandName } = interaction;
// Module - View
if (options?.getSubcommand() === 'view') {
// Execute Module - View
return await view(interaction);
}
// Send debug message
return logger?.debug(
`Guild: ${guild?.id} User: ${
user?.id
} executed /${commandName} ${options?.getSubcommandGroup()} ${options?.getSubcommand()}`
);
},
};

View file

@ -0,0 +1,54 @@
// Dependencies
import { CommandInteraction, ColorResolvable } from 'discord.js';
// Configurations
import config from '../../../../config.json';
// Models
import counterSchema from '../../../helpers/database/models/counterSchema';
// Function
export default async (interaction: CommandInteraction) => {
// Destructure member
const { options, guild } = interaction;
// Get options
const optionChannel = options?.getChannel('channel');
const counter = await counterSchema?.findOne({
guildId: guild?.id,
channelId: optionChannel?.id,
});
if (!counter) {
// Create embed object
const embed = {
title: ':1234: Counters [View]' as string,
description: `${optionChannel} is not a counting channel.` as string,
timestamp: new Date() as Date,
color: config?.colors?.error as ColorResolvable,
footer: {
iconURL: config?.footer?.icon as string,
text: config?.footer?.text as string,
},
};
// Send interaction reply
return await interaction?.editReply({ embeds: [embed] });
}
// Embed object
const embed = {
title: ':1234: Counters [View]' as string,
color: config.colors.success as ColorResolvable,
description: `${optionChannel} is currently at number ${counter?.counter}.`,
timestamp: new Date() as Date,
footer: {
iconURL: config?.footer?.icon as string,
text: config?.footer?.text as string,
},
};
// Send interaction reply
return await interaction?.editReply({ embeds: [embed] });
};

View file

@ -1,68 +0,0 @@
import { CommandInteraction } from 'discord.js';
import config from '../../../../config.json';
import logger from '../../../handlers/logger';
import users from '../../../helpers/database/models/userSchema';
import creditNoun from '../../../helpers/creditNoun';
export default async (interaction: CommandInteraction) => {
// Get options
const user = await interaction.options.getUser('user');
// Get credit object
const userDB = await users.findOne({
userId: user ? user.id : interaction?.user?.id,
guildId: interaction?.guild?.id,
});
// Destructure balance
const { credits } = userDB;
// If !userDB
if (!userDB) {
// Create embed object
const embed = {
title: ':dollar: Credits - Balance',
description: `${
user ? `${user} is` : 'You are'
} not found in the database.`,
color: config.colors.error as any,
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
// Send interaction reply
return interaction.editReply({ embeds: [embed] });
}
// If !credits
if (!credits) {
// Create embed object
const embed = {
title: ':dollar: Credits - Balance',
description: `${user ? `${user} has` : 'You have'} no credits.`,
color: config.colors.success as any,
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
// Send interaction reply
return interaction.editReply({ embeds: [embed] });
}
// If credits
if (credits) {
// Create embed object
const embed = {
title: ':dollar: Credits - Balance',
description: `${user ? `${user} has` : 'You have'} ${creditNoun(
credits
)}.`,
color: config.colors.success as any,
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
// Send interaction reply
return interaction.editReply({ embeds: [embed] });
}
};

View file

@ -1,140 +0,0 @@
import config from '../../../../config.json';
import logger from '../../../handlers/logger';
import users from '../../../helpers/database/models/userSchema';
import saveUser from '../../../helpers/saveUser';
import creditNoun from '../../../helpers/creditNoun';
import { CommandInteraction } from 'discord.js';
export default async (interaction: CommandInteraction) => {
// Get options
const user = await interaction.options.getUser('user');
const amount = await interaction.options.getInteger('amount');
const reason = await interaction.options.getString('reason');
const { member } = interaction;
// Get fromUserDB object
const fromUserDB = await users.findOne({
userId: interaction?.user?.id,
guildId: interaction?.guild?.id,
});
// Get toUserDB object
const toUserDB = await users.findOne({
userId: user?.id,
guildId: interaction?.guild?.id,
});
// If receiver is same as sender
if (user?.id === interaction?.user?.id) {
// Create embed object
const embed = {
title: ':dollar: Credits - Gift',
description: "You can't pay yourself.",
color: config.colors.error as any,
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
// Send interaction reply
return interaction.editReply({ embeds: [embed] });
}
if (amount === null) return;
// If amount is zero or below
if (amount <= 0) {
// Create embed object
const embed = {
title: ':dollar: Credits - Gift',
description: "You can't pay zero or below.",
color: config.colors.error as any,
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
// Send interaction reply
return interaction.editReply({ embeds: [embed] });
}
// If user has below gifting amount
if (fromUserDB.credits < amount) {
// Create embed
const embed = {
title: ':dollar: Credits - Gift',
description: `You have insufficient credits. Your credits is ${fromUserDB.credits}`,
color: config.colors.error as any,
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
// Send interaction reply
return interaction.editReply({ embeds: [embed] });
}
// If toUserDB has no credits
if (!toUserDB) {
// Create embed object
const embed = {
title: ':dollar: Credits - Gift',
description:
'That user has no credits, I can not gift credits to the user',
color: config.colors.error as any,
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
// Send interaction reply
return interaction.editReply({ embeds: [embed] });
}
// Withdraw amount from fromUserDB
fromUserDB.credits -= amount;
// Deposit amount to toUserDB
toUserDB.credits += amount;
// Save users
await saveUser(fromUserDB, toUserDB).then(async () => {
// Create interaction embed object
const interactionEmbed = {
title: ':dollar: Credits - Gift',
description: `You sent ${creditNoun(amount)} to ${user}${
reason ? ` with reason: ${reason}` : ''
}. Your new credits is ${creditNoun(fromUserDB.credits)}.`,
color: 0x22bb33,
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
// Create DM embed object
const dmEmbed = {
title: ':dollar: Credits - Gift',
description: `You received ${creditNoun(amount)} from ${
interaction.user
}${
reason ? ` with reason: ${reason}` : ''
}. Your new credits is ${creditNoun(toUserDB.credits)}.`,
color: 0x22bb33,
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
// Get DM user object
const dmUser = await interaction.client.users.cache.get(
interaction?.user?.id
);
// Send DM to user
await dmUser?.send({ embeds: [dmEmbed] });
// Send debug message
await logger.debug(
`Guild: ${interaction?.guild?.id} User: ${interaction?.user?.id} gift sent from: ${interaction?.user?.id} to: ${user?.id}`
);
// Send interaction reply
return interaction.editReply({
embeds: [interactionEmbed],
});
});
};

View file

@ -1,6 +0,0 @@
import balance from './balance';
import gift from './gift';
import top from './top';
import work from './work';
export default { balance, gift, top, work };

View file

@ -1,35 +0,0 @@
import config from '../../../../config.json';
import users from '../../../helpers/database/models/userSchema';
import creditNoun from '../../../helpers/creditNoun';
import { CommandInteraction } from 'discord.js';
export default async (interaction: CommandInteraction) => {
// Get all users in the guild
const usersDB = await users.find({ guildId: interaction?.guild?.id });
const topTen = usersDB
// Sort them after credits amount (ascending)
.sort((a, b) => (a.credits > b.credits ? -1 : 1))
// Return the top 10
.slice(0, 10);
// Create entry object
const entry = (x: any, index: any) =>
`**Top ${index + 1}** - <@${x.userId}> ${creditNoun(x.credits)}`;
// Create embed object
const embed = {
title: ':dollar: Credits - Top',
description: `Below are the top ten.\n${topTen
.map((x, index) => entry(x, index))
.join('\n')}`,
color: config.colors.success as any,
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
// Send interaction reply
return interaction.editReply({ embeds: [embed] });
};

View file

@ -1,96 +0,0 @@
import config from '../../../../config.json';
import logger from '../../../handlers/logger';
import guilds from '../../../helpers/database/models/guildSchema';
import users from '../../../helpers/database/models/userSchema';
import timeouts from '../../../helpers/database/models/timeoutSchema';
import creditNoun from '../../../helpers/creditNoun';
import { CommandInteraction } from 'discord.js';
export default async (interaction: CommandInteraction) => {
// Destructure member
const { member } = interaction;
// Check if user has a timeout
const isTimeout = await timeouts.findOne({
guildId: interaction?.guild?.id,
userId: interaction?.user?.id,
timeoutId: '2022-03-15-19-16',
});
const guildDB = await guilds.findOne({
guildId: interaction?.guild?.id,
});
// If user is not on timeout
if (!isTimeout) {
// Make a variable of how much credits user will earn based on random multiplied with work rate
const creditsEarned = Math.floor(Math.random() * guildDB.credits.workRate);
const userDB = await users.findOne({
userId: interaction?.user?.id,
guildId: interaction?.guild?.id,
});
userDB.credits += creditsEarned;
await userDB.save().then(async () => {
// Send debug message
await logger.debug(`Credits added to user: ${interaction?.user?.id}`);
// Create embed object
const embed = {
title: ':dollar: Credits - Work',
description: `You have earned ${creditNoun(creditsEarned)}`,
color: config.colors.success as any,
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
// Send interaction reply
return interaction.editReply({ embeds: [embed] });
});
// Create a timeout for the user
await timeouts.create({
guildId: interaction?.guild?.id,
userId: interaction?.user?.id,
timeoutId: '2022-03-15-19-16',
});
setTimeout(async () => {
// Send debug message
await logger.debug(
`Guild: ${interaction?.guild?.id} User: ${
interaction?.user?.id
} has not worked within the last ${
guildDB.work.timeout / 1000
} seconds, work can be done`
);
// When timeout is out, remove it from the database
await timeouts.deleteOne({
guildId: interaction?.guild?.id,
userId: interaction?.user?.id,
timeoutId: '2022-03-15-19-16',
});
}, guildDB.credits.workTimeout);
} else {
// Create embed object
const embed = {
title: ':dollar: Credits - Work',
description: `You have worked within the last ${
guildDB.credits.workTimeout / 1000
} seconds, you can not work now!`,
timestamp: new Date(),
color: config.colors.error as any,
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
// Send interaction reply
await interaction.editReply({ embeds: [embed] });
// Send debug message
await logger.debug(
`Guild: ${interaction?.guild?.id} User: ${interaction?.user?.id} has worked within last day, no work can be done`
);
}
};

View file

@ -1,9 +1,17 @@
// Dependencies
import { SlashCommandBuilder } from '@discordjs/builders';
import balance from './addons/balance';
import gift from './addons/gift';
import top from './addons/top';
import work from './addons/work';
import { CommandInteraction } from 'discord.js';
// Handlers
import logger from '../../handlers/logger';
// Modules
import balance from './modules/balance';
import gift from './modules/gift';
import top from './modules/top';
import work from './modules/work';
// Function
export default {
data: new SlashCommandBuilder()
.setName('credits')
@ -46,28 +54,37 @@ export default {
subcommand.setName('work').setDescription('Work for credits.')
),
async execute(interaction: CommandInteraction) {
// If subcommand is balance
if (interaction.options.getSubcommand() === 'balance') {
// Execute balance addon
await balance(interaction);
const { options, user, guild, commandName } = interaction;
// Module - Balance
if (options?.getSubcommand() === 'balance') {
// Execute Module - Balance
return await balance(interaction);
}
// If subcommand is gift
else if (interaction.options.getSubcommand() === 'gift') {
// Execute gift addon
await gift(interaction);
// Module - Gift
else if (options?.getSubcommand() === 'gift') {
// Execute Module - Gift
return await gift(interaction);
}
// If subcommand is top
else if (interaction.options.getSubcommand() === 'top') {
// Execute top addon
await top(interaction);
// Module - Top
else if (options?.getSubcommand() === 'top') {
// Execute Module - Top
return await top(interaction);
}
// If subcommand is work
else if (interaction.options.getSubcommand() === 'work') {
// Execute work addon
await work(interaction);
// Module - Work
else if (options?.getSubcommand() === 'work') {
// Execute Module - Work
return await work(interaction);
}
// Send debug message
return logger?.debug(
`Guild: ${guild?.id} User: ${
user?.id
} executed /${commandName} ${options?.getSubcommandGroup()} ${options?.getSubcommand()}`
);
},
};

View file

@ -0,0 +1,83 @@
// Dependencies
import { CommandInteraction, ColorResolvable } from 'discord.js';
// Configurations
import config from '../../../../config.json';
// Helpers
import creditNoun from '../../../helpers/creditNoun';
// Models
import userSchema from '../../../helpers/database/models/userSchema';
// Function
export default async (interaction: CommandInteraction) => {
// Destructure
const { options, user, guild } = interaction;
// User option
const optionUser = options?.getUser('user');
// Get credit object
const userDB = await userSchema?.findOne({
userId: optionUser ? optionUser?.id : user?.id,
guildId: guild?.id,
});
// If userDB does not exist
if (!userDB) {
// Embed object
const embed = {
title: ':dollar: Credits [Balance]' as string,
description: `We can not find ${
optionUser || 'you'
} in our database.` as string,
color: config?.colors?.error as ColorResolvable,
timestamp: new Date() as Date,
footer: {
iconURL: config?.footer?.icon as string,
text: config?.footer?.text as string,
},
};
// Return interaction reply
return interaction?.editReply({ embeds: [embed] });
}
// If userDB.credits does not exist
if (!userDB.credits) {
// Embed object
const embed = {
title: ':dollar: Credits [Balance]' as string,
description: `We can not find credits for ${
optionUser || 'you'
} in our database.` as string,
color: config?.colors?.error as ColorResolvable,
timestamp: new Date() as Date,
footer: {
iconURL: config?.footer?.icon as string,
text: config?.footer?.text as string,
},
};
// Return interaction reply
return interaction?.editReply({ embeds: [embed] });
} else {
// Embed object
const embed = {
title: ':dollar: Credits [Balance]' as string,
description: `${
optionUser ? `${optionUser} has` : 'You have'
} ${creditNoun(userDB.credits)}.` as string,
color: config?.colors?.success as ColorResolvable,
timestamp: new Date() as Date,
footer: {
iconURL: config?.footer?.icon as string,
text: config?.footer?.text as string,
},
};
// Return interaction reply
return interaction?.editReply({ embeds: [embed] });
}
};

View file

@ -0,0 +1,187 @@
// Dependencies
import { CommandInteraction, ColorResolvable } from 'discord.js';
// Configurations
import config from '../../../../config.json';
// Handlers
import logger from '../../../handlers/logger';
// Helpers
import saveUser from '../../../helpers/saveUser';
import creditNoun from '../../../helpers/creditNoun';
// Models
import userSchema from '../../../helpers/database/models/userSchema';
// Function
export default async (interaction: CommandInteraction) => {
// Destructure
const { options, user, guild, client } = interaction;
// User option
const optionUser = options?.getUser('user');
// Amount option
const optionAmount = options?.getInteger('amount');
// Reason option
const optionReason = options?.getString('reason');
// Get fromUserDB object
const fromUserDB = await userSchema?.findOne({
userId: user?.id,
guildId: guild?.id,
});
// Get toUserDB object
const toUserDB = await userSchema?.findOne({
userId: optionUser?.id,
guildId: guild?.id,
});
// If receiver is same as sender
if (optionUser?.id === user?.id) {
// Create embed object
const embed = {
title: ':dollar: Credits [Gift]' as string,
description: "You can't pay yourself." as string,
color: config?.colors?.error as ColorResolvable,
timestamp: new Date() as Date,
footer: {
iconURL: config?.footer?.icon as string,
text: config?.footer?.text as string,
},
};
// Return interaction reply
return await interaction?.editReply({ embeds: [embed] });
}
// If amount is null
if (optionAmount === null) {
// Embed object
const embed = {
title: ':dollar: Credits [Gift]' as string,
description: 'We could not read your requested amount.' as string,
color: config?.colors?.error as ColorResolvable,
timestamp: new Date() as Date,
footer: {
iconURL: config?.footer?.icon as string,
text: config?.footer?.text as string,
},
};
// Send interaction reply
return await interaction?.editReply({ embeds: [embed] });
}
// If amount is zero or below
if (optionAmount <= 0) {
// Embed object
const embed = {
title: ':dollar: Credits [Gift]' as string,
description: "You can't pay zero or below." as string,
color: config?.colors?.error as ColorResolvable,
timestamp: new Date() as Date,
footer: {
iconURL: config?.footer?.icon as string,
text: config?.footer?.text as string,
},
};
// Return interaction reply
return await interaction?.editReply({ embeds: [embed] });
}
// If user has below gifting amount
if (fromUserDB?.credits < optionAmount) {
// Embed object
const embed = {
title: ':dollar: Credits [Gift]' as string,
description:
`You have insufficient credits. Your credits is ${fromUserDB?.credits}` as string,
color: config?.colors?.error as ColorResolvable,
timestamp: new Date() as Date,
footer: {
iconURL: config?.footer?.icon as string,
text: config?.footer?.text as string,
},
};
// Return interaction reply
return await interaction?.editReply({ embeds: [embed] });
}
// If toUserDB has no credits
if (!toUserDB) {
// Embed object
const embed = {
title: ':dollar: Credits [Gift]' as string,
description:
`That user has no credits, I can not gift credits to ${optionUser}` as string,
color: config?.colors?.error as ColorResolvable,
timestamp: new Date() as Date,
footer: {
iconURL: config?.footer?.icon as string,
text: config?.footer?.text as string,
},
};
// Send interaction reply
return await interaction?.editReply({ embeds: [embed] });
}
// Withdraw amount from fromUserDB
fromUserDB.credits -= optionAmount;
// Deposit amount to toUserDB
toUserDB.credits += optionAmount;
// Save users
await saveUser(fromUserDB, toUserDB)?.then(async () => {
// Interaction embed object
const interactionEmbed = {
title: ':dollar: Credits [Gift]',
description: `You sent ${creditNoun(optionAmount)} to ${optionUser}${
optionReason ? ` with reason: ${optionReason}` : ''
}. Your new credits is ${creditNoun(fromUserDB?.credits)}.`,
color: config?.colors?.success as ColorResolvable,
timestamp: new Date() as Date,
footer: {
iconURL: config?.footer?.icon as string,
text: config?.footer?.text as string,
},
};
// DM embed object
const dmEmbed = {
title: ':dollar: Credits [Gift]' as string,
description: `You received ${creditNoun(optionAmount)} from ${user}${
optionReason ? ` with reason: ${optionReason}` : ''
}. Your new credits is ${creditNoun(toUserDB?.credits)}.` as string,
color: config?.colors?.success as ColorResolvable,
timestamp: new Date() as Date,
footer: {
iconURL: config?.footer?.icon as string,
text: config?.footer?.text as string,
},
};
// Get DM user object
const dmUser = client?.users?.cache?.get(interaction?.user?.id);
// Send DM to user
await dmUser?.send({ embeds: [dmEmbed] });
// Send debug message
logger.debug(
`Guild: ${guild?.id} User: ${user?.id} gift sent from: ${user?.id} to: ${optionUser?.id}`
);
// Send interaction reply
return await interaction.editReply({
embeds: [interactionEmbed],
});
});
};

View file

@ -0,0 +1,47 @@
// Dependencies
import { CommandInteraction, ColorResolvable } from 'discord.js';
// Configurations
import config from '../../../../config.json';
// Models
import userSchema from '../../../helpers/database/models/userSchema';
// helpers
import creditNoun from '../../../helpers/creditNoun';
// Function
export default async (interaction: CommandInteraction) => {
// Get all users in the guild
const usersDB = await userSchema.find({ guildId: interaction?.guild?.id });
const topTen = usersDB
// Sort them after credits amount (ascending)
.sort((a, b) => (a?.credits > b?.credits ? -1 : 1))
// Return the top 10
.slice(0, 10);
// Create entry object
const entry = (x: any, index: number) =>
`**Top ${index + 1}** - <@${x?.userId}> ${creditNoun(x?.credits)}`;
// Create embed object
const embed = {
title: ':dollar: Credits [Top]' as string,
description: `Below are the top ten.\n${topTen
?.map((x, index) => entry(x, index))
?.join('\n')}` as string,
color: config?.colors?.success as ColorResolvable,
timestamp: new Date() as Date,
footer: {
iconURL: config?.footer?.icon as string,
text: config?.footer?.text as string,
},
};
// Return interaction reply
return await interaction?.editReply({ embeds: [embed] });
};

View file

@ -0,0 +1,113 @@
// Dependencies
import { CommandInteraction, ColorResolvable } from 'discord.js';
// Configurations
import config from '../../../../config.json';
// Handlers
import logger from '../../../handlers/logger';
// Models
import guildSchema from '../../../helpers/database/models/guildSchema';
import userSchema from '../../../helpers/database/models/userSchema';
import timeouts from '../../../helpers/database/models/timeoutSchema';
// Helpers
import creditNoun from '../../../helpers/creditNoun';
// Function
export default async (interaction: CommandInteraction) => {
// Destructure member
const { guild, user } = interaction;
// Check if user has a timeout
const isTimeout = await timeouts?.findOne({
guildId: guild?.id,
userId: user?.id,
timeoutId: '2022-03-15-19-16',
});
const guildDB = await guildSchema?.findOne({
guildId: guild?.id,
});
// If user is not on timeout
if (!isTimeout) {
// Make a variable of how much credits user will earn based on random multiplied with work rate
const creditsEarned = Math?.floor(
Math?.random() * guildDB?.credits?.workRate
);
const userDB = await userSchema?.findOne({
userId: user?.id,
guildId: guild?.id,
});
userDB.credits += creditsEarned;
await userDB?.save()?.then(async () => {
// Send debug message
logger?.debug(`Credits added to user: ${user?.id}`);
// Create embed object
const embed = {
title: ':dollar: Credits [Work]' as string,
description: `You have earned ${creditNoun(creditsEarned)}` as string,
color: config?.colors?.success as ColorResolvable,
timestamp: new Date() as Date,
footer: {
iconURL: config?.footer?.icon as string,
text: config?.footer?.text as string,
},
};
// Send interaction reply
return await interaction?.editReply({ embeds: [embed] });
});
// Create a timeout for the user
await timeouts?.create({
guildId: guild?.id,
userId: user?.id,
timeoutId: '2022-03-15-19-16',
});
setTimeout(async () => {
// Send debug message
logger?.debug(
`Guild: ${guild?.id} User: ${user?.id} has not worked within the last ${
guildDB?.work?.timeout / 1000
} seconds, work can be done`
);
// When timeout is out, remove it from the database
await timeouts?.deleteOne({
guildId: guild?.id,
userId: user?.id,
timeoutId: '2022-03-15-19-16',
});
}, guildDB?.credits?.workTimeout);
} else {
// Create embed object
const embed = {
title: ':dollar: Credits [Work]' as string,
description: `You have worked within the last ${
guildDB?.credits?.workTimeout / 1000
} seconds, you can not work now!` as string,
timestamp: new Date() as Date,
color: config?.colors?.error as ColorResolvable,
footer: {
iconURL: config?.footer?.icon as string,
text: config?.footer?.text as string,
},
};
// Send debug message
logger?.debug(
`Guild: ${guild?.id} User: ${user?.id} has worked within last day, no work can be done`
);
// Return interaction reply
return await interaction?.editReply({ embeds: [embed] });
}
};

View file

@ -5,6 +5,9 @@ import { CommandInteraction } from 'discord.js';
// Modules
import view from './modules/view';
// Handlers
import logger from '../../handlers/logger';
// Function
export default {
data: new SlashCommandBuilder()
@ -21,10 +24,20 @@ export default {
)
),
async execute(interaction: CommandInteraction) {
// Destructure
const { options, guild, user, commandName } = interaction;
// Module - View
if (interaction.options.getSubcommand() === 'view') {
if (options?.getSubcommand() === 'view') {
// Execute Module - View
await view(interaction);
return await view(interaction);
}
// Send debug message
return logger?.debug(
`Guild: ${guild?.id} User: ${
user?.id
} executed /${commandName} ${options?.getSubcommandGroup()} ${options?.getSubcommand()}`
);
},
};

View file

@ -1,8 +1,13 @@
import i18next from 'i18next';
// Dependencies
import { CommandInteraction, ColorResolvable } from 'discord.js';
// Configurations
import config from '../../../../config.json';
import logger from '../../../handlers/logger';
import users from '../../../helpers/database/models/userSchema';
import { CommandInteraction } from 'discord.js';
// Models
import userSchema from '../../../helpers/database/models/userSchema';
// Function
export default async (interaction: CommandInteraction) => {
// Destructure
const { client, options, user, guild } = interaction;
@ -11,12 +16,12 @@ export default async (interaction: CommandInteraction) => {
const target = options?.getUser('target');
// Discord User Information
const discordUser = await client.users.fetch(
const discordUser = await client?.users?.fetch(
`${target ? target?.id : user?.id}`
);
// User Information
const userObj = await users.findOne({
const userObj = await userSchema?.findOne({
userId: discordUser?.id,
guildId: guild?.id,
});
@ -24,41 +29,44 @@ export default async (interaction: CommandInteraction) => {
// Embed object
const embed = {
author: {
name: `${discordUser.username}#${discordUser.discriminator}`,
icon_url: discordUser.displayAvatarURL(),
name: `${discordUser?.username}#${discordUser?.discriminator}` as string,
icon_url: discordUser?.displayAvatarURL() as string,
},
color: config.colors.success as any,
color: config?.colors?.success as ColorResolvable,
fields: [
{
name: `:dollar: Credits`,
value: `${userObj.credits || 'Not found'}`,
name: `:dollar: Credits` as string,
value: `${userObj?.credits || 'Not found'}` as string,
inline: true,
},
{
name: `:squeeze_bottle: Level`,
value: `${userObj.level || 'Not found'}`,
name: `:squeeze_bottle: Level` as string,
value: `${userObj?.level || 'Not found'}` as string,
inline: true,
},
{
name: `:squeeze_bottle: Points`,
value: `${userObj.points || 'Not found'}`,
name: `:squeeze_bottle: Points` as string,
value: `${userObj?.points || 'Not found'}` as string,
inline: true,
},
{
name: `:loudspeaker: Reputation`,
value: `${userObj.reputation || 'Not found'}`,
name: `:loudspeaker: Reputation` as string,
value: `${userObj?.reputation || 'Not found'}` as string,
inline: true,
},
{
name: `:rainbow_flag: Language`,
value: `${userObj.language || 'Not found'}`,
name: `:rainbow_flag: Language` as string,
value: `${userObj?.language || 'Not found'}` as string,
inline: true,
},
],
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
timestamp: new Date() as Date,
footer: {
iconURL: config?.footer?.icon as string,
text: config?.footer?.text as string,
},
};
// Send interaction reply
return await interaction.editReply({ embeds: [embed] });
// Return interaction reply
return await interaction?.editReply({ embeds: [embed] });
};

View file

@ -5,6 +5,9 @@ import { CommandInteraction } from 'discord.js';
// Modules
import give from './modules/give';
// Handlers
import logger from '../../handlers/logger';
// Function
export default {
data: new SlashCommandBuilder()
@ -31,12 +34,19 @@ export default {
),
async execute(interaction: CommandInteraction) {
// Destructure
const { options } = interaction;
const { options, guild, user, commandName } = interaction;
// Module - Give
if (options.getSubcommand() === 'give') {
if (options?.getSubcommand() === 'give') {
// Execute Module - Give
await give(interaction);
}
// Send debug message
return logger?.debug(
`Guild: ${guild?.id} User: ${
user?.id
} executed /${commandName} ${options?.getSubcommandGroup()} ${options?.getSubcommand()}`
);
},
};

View file

@ -1,122 +1,138 @@
import i18next from 'i18next';
import { CommandInteraction } from 'discord.js';
import config from '../../../../config.json';
import logger from '../../../handlers/logger';
import users from '../../../helpers/database/models/userSchema';
import timeouts from '../../../helpers/database/models/timeoutSchema';
// Dependencies
import { CommandInteraction, ColorResolvable } from 'discord.js';
// Configurations
import config from '../../../../config.json';
// Handlers
import logger from '../../../handlers/logger';
// Models
import userSchema from '../../../helpers/database/models/userSchema';
import timeoutSchema from '../../../helpers/database/models/timeoutSchema';
// Function
export default async (interaction: CommandInteraction) => {
// Destructure
const { options, user, guild } = interaction;
// Target information
const target = options.getUser('target');
// Target option
const optionTarget = options?.getUser('target');
// Type information
const type = options.getString('type');
const optionType = options?.getString('type');
// User information
const userObj = await users.findOne({
const userObj = await userSchema?.findOne({
userId: user?.id,
guildId: guild?.id,
});
// Check if user has a timeout
const isTimeout = await timeouts.findOne({
const isTimeout = await timeoutSchema?.findOne({
guildId: guild?.id,
userId: user?.id,
timeoutId: 2,
timeoutId: '2022-04-10-16-42',
});
// If user is not on timeout
if (!isTimeout) {
// Do not allow self reputation
if (target?.id === user?.id) {
if (optionTarget?.id === user?.id) {
// Embed object
const embed = {
title: ':loudspeaker: Reputation - Give',
description: 'You can not repute yourself.',
timestamp: new Date(),
color: config.colors.error as any,
footer: { iconURL: config.footer.icon, text: config.footer.text },
title: ':loudspeaker: Reputation [Give]' as string,
description: 'You can not repute yourself.' as string,
timestamp: new Date() as Date,
color: config?.colors?.error as ColorResolvable,
footer: {
iconURL: config?.footer?.icon as string,
text: config?.footer?.text as string,
},
};
// Return interaction reply
return interaction.editReply({ embeds: [embed] });
return await interaction?.editReply({ embeds: [embed] });
}
// If type is positive
if (type === 'positive') {
if (optionType === 'positive') {
userObj.reputation += 1;
}
// If type is negative
if (type === 'negative') {
else if (optionType === 'negative') {
userObj.reputation -= 1;
}
// Save user
await userObj.save().then(async () => {
await userObj?.save()?.then(async () => {
// Embed object
const embed = {
title: ':loudspeaker: Reputation - Give',
description: `You have given ${target} a ${type} reputation!`,
timestamp: new Date(),
color: config.colors.success as any,
footer: { iconURL: config.footer.icon, text: config.footer.text },
title: ':loudspeaker: Reputation [Give]' as string,
description:
`You have given ${optionTarget} a ${optionType} reputation!` as string,
timestamp: new Date() as Date,
color: config?.colors?.success as ColorResolvable,
footer: {
iconURL: config?.footer?.icon as string,
text: config?.footer?.text as string,
},
};
// Send interaction reply
await interaction.editReply({ embeds: [embed] });
// Log debug message
logger.debug(
`Guild: ${guild?.id} User: ${user?.id} has given ${target?.id} a ${type} reputation.`
logger?.debug(
`Guild: ${guild?.id} User: ${user?.id} has given ${optionTarget?.id} a ${optionType} reputation.`
);
// Create a timeout for the user
await timeouts.create({
await timeoutSchema?.create({
guildId: guild?.id,
userId: user?.id,
timeoutId: 2,
timeoutId: '2022-04-10-16-42',
});
// Return interaction reply
return await interaction?.editReply({ embeds: [embed] });
});
setTimeout(async () => {
// send debug message
logger.debug(
logger?.debug(
`Guild: ${guild?.id} User: ${user?.id} has not repute within last ${
config.reputation.timeout / 1000
config?.reputation?.timeout / 1000
} seconds, reputation can be given`
);
// When timeout is out, remove it from the database
await timeouts.deleteOne({
await timeoutSchema?.deleteOne({
guildId: guild?.id,
userId: user?.id,
timeoutId: 2,
timeoutId: '2022-04-10-16-42',
});
}, config.reputation.timeout);
}, config?.reputation?.timeout);
} else {
// Create embed object
const embed = {
title: ':loudspeaker: Reputation - Give',
title: ':loudspeaker: Reputation [Give]' as string,
description: `You have given reputation within the last ${
config.reputation.timeout / 1000
} seconds, you can not repute now!`,
timestamp: new Date(),
color: config.colors.error as any,
footer: { iconURL: config.footer.icon, text: config.footer.text },
config?.reputation?.timeout / 1000
} seconds, you can not repute now!` as string,
timestamp: new Date() as Date,
color: config.colors.error as ColorResolvable,
footer: {
iconURL: config?.footer?.icon as string,
text: config?.footer?.text as string,
},
};
// Send interaction reply
await interaction.editReply({ embeds: [embed] });
// Log debug message
logger.debug(
logger?.debug(
`Guild: ${guild?.id} User: ${user?.id} has repute within last ${
config.reputation.timeout / 1000
config?.reputation?.timeout / 1000
} seconds, no reputation can be given`
);
// Return interaction reply
return await interaction?.editReply({ embeds: [embed] });
}
};

View file

@ -1,95 +1,97 @@
import { Permissions, CommandInteraction } from 'discord.js';
// Dependencies
import { ColorResolvable, CommandInteraction } from 'discord.js';
// Configurations
import config from '../../../../../config.json';
//Handlers
import logger from '../../../../handlers/logger';
// Database models
import guilds from '../../../../helpers/database/models/guildSchema';
// Models
import guildSchema from '../../../../helpers/database/models/guildSchema';
// Function
export default async (interaction: CommandInteraction) => {
// Destructure member
const { guild, user } = interaction;
// Check permission
if (!interaction?.memberPermissions?.has(Permissions.FLAGS.MANAGE_GUILD)) {
// Create embed object
const embed = {
title: ':hammer: Settings - Guild [Credits]',
color: config.colors.error as any,
description: `You don't have permission to manage this!`,
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
// Send interaction reply
return interaction.editReply({ embeds: [embed] });
}
const { guild, user, options } = interaction;
// Get options
const status = await interaction.options.getBoolean('status');
const rate = await interaction.options.getNumber('rate');
const timeout = await interaction.options.getNumber('timeout');
const minimumLength = await interaction.options.getNumber('minimum-length');
const workRate = await interaction.options.getNumber('work-rate');
const workTimeout = await interaction.options.getNumber('work-timeout');
const status = options?.getBoolean('status');
const rate = options?.getNumber('rate');
const timeout = options?.getNumber('timeout');
const minimumLength = options?.getNumber('minimum-length');
const workRate = options?.getNumber('work-rate');
const workTimeout = options?.getNumber('work-timeout');
// Get guild object
const guildDB = await guilds.findOne({
const guildDB = await guildSchema?.findOne({
guildId: guild?.id,
});
// Modify values
guildDB.credits.status = status !== null ? status : guildDB.credits.status;
guildDB.credits.rate = rate !== null ? rate : guildDB.credits.rate;
guildDB.credits.status = status !== null ? status : guildDB?.credits?.status;
guildDB.credits.rate = rate !== null ? rate : guildDB?.credits?.rate;
guildDB.credits.timeout =
timeout !== null ? timeout : guildDB.credits.timeout;
timeout !== null ? timeout : guildDB?.credits?.timeout;
guildDB.credits.workRate =
workRate !== null ? workRate : guildDB.credits.workRate;
workRate !== null ? workRate : guildDB?.credits?.workRate;
guildDB.credits.workTimeout =
workTimeout !== null ? workTimeout : guildDB.credits.workTimeout;
workTimeout !== null ? workTimeout : guildDB?.credits?.workTimeout;
guildDB.credits.minimumLength =
minimumLength !== null ? minimumLength : guildDB.credits.minimumLength;
minimumLength !== null ? minimumLength : guildDB?.credits?.minimumLength;
// Save guild
await guildDB.save().then(async () => {
// Create embed object
await guildDB?.save()?.then(async () => {
// Embed object
const embed = {
title: ':hammer: Settings - Guild [Credits]',
description: 'Following settings is set!',
color: config.colors.success as any,
title: ':tools: Settings - Guild [Credits]' as string,
description: 'Following settings is set!' as string,
color: config?.colors?.success as ColorResolvable,
fields: [
{ name: '🤖 Status', value: `${guildDB.credits.status}`, inline: true },
{ name: '📈 Rate', value: `${guildDB.credits.rate}`, inline: true },
{
name: '📈 Work Rate',
value: `${guildDB.credits.workRate}`,
name: '🤖 Status' as string,
value: `${guildDB?.credits?.status}` as string,
inline: true,
},
{
name: '🔨 Minimum Length',
value: `${guildDB.credits.minimumLength}`,
name: '📈 Rate' as string,
value: `${guildDB?.credits?.rate}` as string,
inline: true,
},
{
name: '⏰ Timeout',
value: `${guildDB.credits.timeout}`,
name: '📈 Work Rate' as string,
value: `${guildDB?.credits?.workRate}` as string,
inline: true,
},
{
name: '⏰ Work Timeout',
value: `${guildDB.credits.workTimeout}`,
name: '🔨 Minimum Length' as string,
value: `${guildDB?.credits?.minimumLength}` as string,
inline: true,
},
{
name: '⏰ Timeout' as string,
value: `${guildDB?.credits?.timeout}` as string,
inline: true,
},
{
name: '⏰ Work Timeout' as string,
value: `${guildDB?.credits?.workTimeout}` as string,
inline: true,
},
],
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
timestamp: new Date() as Date,
footer: {
iconURL: config?.footer?.icon as string,
text: config?.footer?.text as string,
},
};
// Send interaction reply
await interaction.editReply({ embeds: [embed] });
// Send debug message
await logger.debug(
logger?.debug(
`Guild: ${guild?.id} User: ${user.id} has changed credit details.`
);
// Return interaction reply
return await interaction?.editReply({ embeds: [embed] });
});
};

View file

@ -1,5 +0,0 @@
import pterodactyl from './pterodactyl';
import credits from './credits';
import points from './points';
export default { pterodactyl, credits, points };

View file

@ -1,79 +1,81 @@
import { Permissions, CommandInteraction } from 'discord.js';
// Dependencies
import { ColorResolvable, CommandInteraction } from 'discord.js';
// Configurations
import config from '../../../../../config.json';
// Handlers
import logger from '../../../../handlers/logger';
// Database models
import guilds from '../../../../helpers/database/models/guildSchema';
// Models
import guildSchema from '../../../../helpers/database/models/guildSchema';
// Function
export default async (interaction: CommandInteraction) => {
// Destructure member
const { member } = interaction;
// Check permission
if (!interaction?.memberPermissions?.has(Permissions.FLAGS.MANAGE_GUILD)) {
// Create embed object
const embed = {
title: ':hammer: Settings - Guild [Points]',
color: config.colors.error as any,
description: `You don't have permission to manage this!`,
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
// Send interaction reply
return interaction.editReply({ embeds: [embed] });
}
const { options, guild, user } = interaction;
// Get options
const status = await interaction.options.getBoolean('status');
const rate = await interaction.options.getNumber('rate');
const timeout = await interaction.options.getNumber('timeout');
const minimumLength = await interaction.options.getNumber('minimum-length');
const status = options?.getBoolean('status');
const rate = options?.getNumber('rate');
const timeout = options?.getNumber('timeout');
const minimumLength = options?.getNumber('minimum-length');
// Get guild object
const guildDB = await guilds.findOne({
guildId: interaction?.guild?.id,
const guildDB = await guildSchema?.findOne({
guildId: guild?.id,
});
// Modify values
guildDB.credits.status = status !== null ? status : guildDB.credits.status;
guildDB.credits.rate = rate !== null ? rate : guildDB.credits.rate;
guildDB.credits.timeout =
timeout !== null ? timeout : guildDB.credits.timeout;
guildDB.credits.minimumLength =
minimumLength !== null ? minimumLength : guildDB.credits.minimumLength;
guildDB.points.status = status !== null ? status : guildDB?.points?.status;
guildDB.points.rate = rate !== null ? rate : guildDB?.points?.rate;
guildDB.points.timeout =
timeout !== null ? timeout : guildDB?.points?.timeout;
guildDB.points.minimumLength =
minimumLength !== null ? minimumLength : guildDB?.points?.minimumLength;
// Save guild
await guildDB.save().then(async () => {
await guildDB?.save()?.then(async () => {
// Create embed object
const embed = {
title: ':hammer: Settings - Guild [Points]',
description: 'Following settings is set!',
color: config.colors.success as any,
title: ':hammer: Settings - Guild [Points]' as string,
description: 'Following settings is set!' as string,
color: config.colors.success as ColorResolvable,
fields: [
{ name: '🤖 Status', value: `${guildDB.credits.status}`, inline: true },
{ name: '📈 Rate', value: `${guildDB.credits.rate}`, inline: true },
{
name: '🔨 Minimum Length',
value: `${guildDB.credits.minimumLength}`,
name: '🤖 Status' as string,
value: `${guildDB?.points?.status}` as string,
inline: true,
},
{
name: '⏰ Timeout',
value: `${guildDB.credits.timeout}`,
name: '📈 Rate' as string,
value: `${guildDB?.points?.rate}` as string,
inline: true,
},
{
name: '🔨 Minimum Length' as string,
value: `${guildDB?.points?.minimumLength}` as string,
inline: true,
},
{
name: '⏰ Timeout' as string,
value: `${guildDB?.points?.timeout}` as string,
inline: true,
},
],
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
timestamp: new Date() as Date,
footer: {
iconURL: config?.footer?.icon as string,
text: config?.footer?.text as string,
},
};
// Send interaction reply
await interaction.editReply({ embeds: [embed] });
// Send debug message
await logger.debug(
`Guild: ${interaction?.guild?.id} User: ${interaction?.user?.id} has changed credit details.`
logger?.debug(
`Guild: ${guild?.id} User: ${user?.id} has changed credit details.`
);
// Return interaction reply
return await interaction?.editReply({ embeds: [embed] });
});
};

View file

@ -1,62 +1,50 @@
import { Permissions, CommandInteraction } from 'discord.js';
// Dependencies
import { ColorResolvable, CommandInteraction } from 'discord.js';
// Configurations
import config from '../../../../../config.json';
// Handlers
import logger from '../../../../handlers/logger';
// Database models
import apis from '../../../../helpers/database/models/apiSchema';
// Models
import apiSchema from '../../../../helpers/database/models/apiSchema';
// Function
export default async (interaction: CommandInteraction) => {
// Destructure member
const { member } = interaction;
// Check permission
if (!interaction?.memberPermissions?.has(Permissions.FLAGS.MANAGE_GUILD)) {
// Create embed object
const embed = {
title: ':hammer: Settings - Guild [Pterodactyl]',
color: config.colors.error as any,
description: 'You do not have permission to manage this!',
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
// Send interaction reply
return interaction.editReply({ embeds: [embed] });
}
const { options, guild, user } = interaction;
// Get options
const url = await interaction.options.getString('url');
const token = await interaction.options.getString('token');
const url = options?.getString('url');
const token = options?.getString('token');
// Update API credentials
await apis
.findOneAndUpdate(
{ guildId: interaction?.guild?.id },
await apiSchema
?.findOneAndUpdate(
{ guildId: guild?.id },
{ url, token },
{ new: true, upsert: true }
)
.then(async () => {
// Build embed
// Embed object
const embed = {
title: ':hammer: Settings - Guild [Pterodactyl]',
color: config.colors.success as any,
description: 'Pterodactyl settings is saved!',
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
title: ':hammer: Settings - Guild [Pterodactyl]' as string,
color: config?.colors?.success as ColorResolvable,
description: 'Pterodactyl settings is saved!' as string,
timestamp: new Date() as Date,
footer: {
iconURL: config?.footer?.icon as string,
text: config?.footer?.text as string,
},
};
// Send reply
await interaction.editReply({ embeds: [embed] });
// Send debug message
await logger.debug(
`Guild: ${interaction?.guild?.id} User: ${interaction?.user?.id} has changed api credentials.`
logger?.debug(
`Guild: ${guild?.id} User: ${user?.id} has changed api credentials.`
);
// Return interaction reply
return await interaction?.editReply({ embeds: [embed] });
});
};

View file

@ -1,53 +1,62 @@
import { Permissions, CommandInteraction } from 'discord.js';
// Dependencies
import { Permissions, ColorResolvable, CommandInteraction } from 'discord.js';
// Configurations
import config from '../../../../config.json';
// Handlers
import logger from '../../../handlers/logger';
// Modules
import pterodactyl from './addons/pterodactyl';
import credits from './addons/credits';
import points from './addons/points';
// Function
export default async (interaction: CommandInteraction) => {
// Destructure member
const { member } = interaction;
const { memberPermissions, options, commandName, user, guild } = interaction;
// Check permission
if (!interaction?.memberPermissions?.has(Permissions.FLAGS.MANAGE_GUILD)) {
if (!memberPermissions?.has(Permissions?.FLAGS?.MANAGE_GUILD)) {
// Create embed object
const embed = {
title: 'Settings - Guild',
color: config.colors.error as any,
description: 'You do not have permission to manage this!',
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
title: ':tools: Settings - Guild' as string,
color: config?.colors?.error as ColorResolvable,
description: 'You do not have permission to manage this!' as string,
timestamp: new Date() as Date,
footer: {
iconURL: config?.footer?.icon as string,
text: config?.footer?.text as string,
},
};
// Send interaction reply
await interaction.editReply({ embeds: [embed] });
// Return interaction reply
return await interaction?.editReply({ embeds: [embed] });
}
// If subcommand is pterodactyl
if (interaction.options.getSubcommand() === 'pterodactyl') {
// Execute pterodactyl addon
await pterodactyl(interaction);
// Module - Pterodactyl
if (options?.getSubcommand() === 'pterodactyl') {
// Execute Module - Pterodactyl
return await pterodactyl(interaction);
}
// If subcommand is credits
else if (interaction.options.getSubcommand() === 'credits') {
// Execute credits addon
await credits(interaction);
// Module - Credits
else if (options?.getSubcommand() === 'credits') {
// Execute Module - Credits
return await credits(interaction);
}
// If subcommand is points
else if (interaction.options.getSubcommand() === 'points') {
// Execute points addon
await points(interaction);
// Module - Points
else if (options?.getSubcommand() === 'points') {
// Execute Module - Points
return await points(interaction);
}
// Send debug message
await logger.debug(
`Guild: ${interaction?.guild?.id} User: ${
interaction?.user?.id
} executed /${
interaction.commandName
} ${interaction.options.getSubcommandGroup()} ${interaction.options.getSubcommand()}`
return logger?.debug(
`Guild: ${guild?.id} User: ${
user?.id
} executed /${commandName} ${options?.getSubcommandGroup()} ${options?.getSubcommand()}`
);
};

View file

@ -1,8 +1,15 @@
// Dependencies
import { SlashCommandBuilder } from '@discordjs/builders';
import { Permissions, CommandInteraction } from 'discord.js';
import guild from './guild';
import user from './user';
import { CommandInteraction } from 'discord.js';
// Groups
import guildGroup from './guild';
import userGroup from './user';
// Handlers
import logger from '../../handlers/logger';
// Function
export default {
data: new SlashCommandBuilder()
.setName('settings')
@ -113,15 +120,25 @@ export default {
)
),
async execute(interaction: CommandInteraction) {
// If subcommand group is guild
if (interaction.options.getSubcommandGroup() === 'guild') {
// Execute guild group
await guild(interaction);
// Destructure
const { options, commandName, user, guild } = interaction;
// Group - Guild
if (options.getSubcommandGroup() === 'guild') {
// Execute Group - Guild
await guildGroup(interaction);
}
// If subcommand group is user
else if (interaction.options.getSubcommandGroup() === 'user') {
// Execute user group
await user(interaction);
// Group - User
else if (options.getSubcommandGroup() === 'user') {
// Execute Group - User
await userGroup(interaction);
}
// Send debug message
return logger?.debug(
`Guild: ${guild?.id} User: ${
user?.id
} executed /${commandName} ${options?.getSubcommandGroup()} ${options?.getSubcommand()}`
);
},
};

View file

@ -1,49 +0,0 @@
import config from '../../../../../config.json';
import logger from '../../../../handlers/logger';
import { CommandInteraction } from 'discord.js';
// Database models
import users from '../../../../helpers/database/models/userSchema';
export default async (interaction: CommandInteraction) => {
// Destructure member
const { member } = interaction;
// Get options
const language = await interaction.options.getString('language');
// Get user object
const userDB = await users.findOne({
userId: interaction?.user?.id,
guildId: interaction?.guild?.id,
});
// Modify values
userDB.language = language !== null ? language : userDB.language;
// Save guild
await userDB.save().then(async () => {
// Create embed object
const embed = {
title: ':hammer: Settings - User [Appearance]',
description: 'Following settings is set!',
color: config.colors.success as any,
fields: [
{
name: '🏳️‍🌈 Language',
value: `${userDB.language}`,
inline: true,
},
],
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
// Send interaction reply
await interaction.editReply({ embeds: [embed] });
// Send debug message
await logger.debug(
`Guild: ${interaction?.guild?.id} User: ${interaction?.user?.id} has changed appearance settings.`
);
});
};

View file

@ -1,3 +0,0 @@
import appearance from './appearance';
export default { appearance };

View file

@ -1,24 +1,27 @@
import { Permissions, CommandInteraction } from 'discord.js';
import config from '../../../../config.json';
import logger from '../../../handlers/logger';
import appearance from './addons/appearance';
// Dependencies
import { CommandInteraction } from 'discord.js';
// Handlers
import logger from '../../../handlers/logger';
// Modules
import appearance from './modules/appearance';
// Function
export default async (interaction: CommandInteraction) => {
// Destructure member
const { member } = interaction;
const { guild, user, options, commandName } = interaction;
// If subcommand is appearance
if (interaction.options.getSubcommand() === 'appearance') {
// Execute appearance addon
// Module - Appearance
if (options?.getSubcommand() === 'appearance') {
// Execute Module - Appearance
await appearance(interaction);
}
// Send debug message
await logger.debug(
`Guild: ${interaction?.guild?.id} User: ${
interaction?.user?.id
} executed /${
interaction.commandName
} ${interaction.options.getSubcommandGroup()} ${interaction.options.getSubcommand()}`
return logger?.debug(
`Guild: ${guild?.id} User: ${
user?.id
} executed /${commandName} ${options?.getSubcommandGroup()} ${options?.getSubcommand()}`
);
};

View file

@ -0,0 +1,59 @@
// Dependencies
import { CommandInteraction, ColorResolvable } from 'discord.js';
// Configurations
import config from '../../../../../config.json';
// Handlers
import logger from '../../../../handlers/logger';
// Models
import userSchema from '../../../../helpers/database/models/userSchema';
// Function
export default async (interaction: CommandInteraction) => {
// Destructure member
const { options, user, guild } = interaction;
// Get options
const language = options?.getString('language');
// Get user object
const userDB = await userSchema?.findOne({
userId: user?.id,
guildId: guild?.id,
});
// Modify values
userDB.language = language !== null ? language : userDB?.language;
// Save guild
await userDB?.save()?.then(async () => {
// Embed object
const embed = {
title: ':hammer: Settings - User [Appearance]' as string,
description: 'Following settings is set!' as string,
color: config?.colors?.success as ColorResolvable,
fields: [
{
name: '🏳️‍🌈 Language' as string,
value: `${userDB?.language}` as string,
inline: true,
},
],
timestamp: new Date() as Date,
footer: {
iconURL: config?.footer?.icon as string,
text: config?.footer?.text as string,
},
};
// Send debug message
logger?.debug(
`Guild: ${guild?.id} User: ${user?.id} has changed appearance settings.`
);
// Return interaction reply
return await interaction?.editReply({ embeds: [embed] });
});
};

View file

@ -1,177 +0,0 @@
import { v4 as uuidv4 } from 'uuid';
import axios from 'axios';
import config from '../../../../config.json';
import logger from '../../../handlers/logger';
import apis from '../../../helpers/database/models/apiSchema';
import users from '../../../helpers/database/models/userSchema';
import creditNoun from '../../../helpers/creditNoun';
import { CommandInteraction } from 'discord.js';
export default async (interaction: CommandInteraction) => {
const { member } = interaction;
// Get options
const amount = await interaction.options.getInteger('amount');
if (amount === null) return;
// Get user object
const userDB = await users.findOne({
userId: interaction?.user?.id,
guildId: interaction?.guild?.id,
});
// Get DM user object
const dmUser = interaction.client.users.cache.get(interaction?.user?.id);
// Stop if amount or user credits is below 100
if ((amount || userDB.credits) < 100) {
const embed = {
title: ':shopping_cart: Shop - Pterodactyl',
description: `You **can't** withdraw for __Pterodactyl__ below **100**.`,
color: config.colors.error as any,
fields: [
{ name: 'Your balance', value: `${creditNoun(userDB.credits)}` },
],
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
return interaction.editReply({ embeds: [embed] });
}
// Stop if amount or user credits is above 1.000.000
if ((amount || userDB.credits) > 1000000) {
const embed = {
title: ':shopping_cart: Shop - Pterodactyl',
description: `You **can't** withdraw for __Pterodactyl__ above **1.000.000**.`,
color: config.colors.error as any,
fields: [
{ name: 'Your balance', value: `${creditNoun(userDB.credits)}` },
],
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
return interaction.editReply({ embeds: [embed] });
}
// Stop if user credits is below amount
if (userDB.credits < amount) {
const embed = {
title: ':shopping_cart: Shop - Pterodactyl',
description: `You have **insufficient** credits.`,
color: config.colors.error as any,
fields: [
{ name: 'Your balance', value: `${creditNoun(userDB.credits)}` },
],
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
return interaction.editReply({ embeds: [embed] });
}
// Generate a unique voucher for the user
const code = uuidv4();
// Get api object
const apiCredentials = await apis.findOne({
guildId: interaction?.guild?.id,
});
// Create a api instance
const api = axios.create({
baseURL: apiCredentials.url,
headers: { Authorization: `Bearer ${apiCredentials.token}` },
});
// Get shop URL
const shopUrl = apiCredentials.url.replace('/api', '/store');
// Make API request
await api
// Make a post request to the API
.post('vouchers', {
uses: 1,
code,
credits: amount || userDB.credits,
memo: `${interaction.createdTimestamp} - ${interaction?.user?.id}`,
})
// If successful
.then(async () => {
// Create DM embed object
const dmEmbed = {
title: ':shopping_cart: Shop - Pterodactyl',
description: `Redeem this voucher [here](${shopUrl})!`,
fields: [
{ name: 'Code', value: `${code}`, inline: true },
{
name: 'Credits',
value: `${amount || userDB.credits}`,
inline: true,
},
],
color: config.colors.success as any,
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
// Create interaction embed object
const interactionEmbed = {
title: ':shopping_cart: Shop - Pterodactyl',
description: 'I have sent you the code in DM!',
color: config.colors.success as any,
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
// Withdraw amount from user credits
userDB.credits -= amount || userDB.credits;
// Save new credits
await userDB
.save()
// If successful
.then(async () => {
// Send debug message
await logger.debug(
`User: ${interaction?.user?.username} redeemed: ${creditNoun(
amount
)}`
);
// Send DM message
await dmUser?.send({ embeds: [dmEmbed] });
// Send interaction reply
await interaction.editReply({
embeds: [interactionEmbed],
});
})
// If error occurs
.catch(async (e: any) => {
await logger.error(e);
const embed = {
title: ':shopping_cart: Shop - Pterodactyl',
description: 'Something went wrong, please try again later.',
color: config.colors.error as any,
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
return interaction.editReply({ embeds: [embed] });
});
})
// If error occurs
.catch(async (e) => {
await logger.error(e);
const embed = {
title: ':shopping_cart: Shop - Pterodactyl',
description: 'Something went wrong, please try again later.',
color: config.colors.error as any,
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
return interaction.editReply({ embeds: [embed] });
});
};

View file

@ -1,48 +0,0 @@
import { v4 as uuidv4 } from 'uuid';
import axios from 'axios';
import config from '../../../../config.json';
import logger from '../../../handlers/logger';
import guilds from '../../../helpers/database/models/guildSchema';
import users from '../../../helpers/database/models/userSchema';
import creditNoun from '../../../helpers/creditNoun';
import { CommandInteraction, RoleManager } from 'discord.js';
export default async (interaction: CommandInteraction) => {
const name = interaction.options.getString('name');
const { member } = interaction;
const guildDB = await guilds.findOne({ guildId: interaction?.guild?.id });
const userDB = await users.findOne({
userId: interaction?.user?.id,
guildId: interaction?.guild?.id,
});
if (name === null) return;
(interaction?.guild?.roles as RoleManager)
.create({
name,
color: 'BLUE',
reason: `${interaction?.user?.id} bought from shop`,
})
.then(async (role) => {
console.log(role);
userDB.credits -= guildDB.shop.roles.pricePerHour;
await userDB.save().then(async () => {
const embed = {
title: ':shopping_cart: Shop - Roles',
description: `You have bought ${role.name} for ${guildDB.shop.roles.pricePerHour} per hour.`,
color: config.colors.error as any,
fields: [
{ name: 'Your balance', value: `${creditNoun(userDB.credits)}` },
],
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
return interaction.editReply({
embeds: [embed],
});
});
})
.catch(console.error);
};

View file

@ -1,9 +1,17 @@
// Dependencies
import { SlashCommandBuilder } from '@discordjs/builders';
import { Permissions, CommandInteraction } from 'discord.js';
import guilds from '../../helpers/database/models/guildSchema';
import pterodactyl from './addons/pterodactyl';
import { CommandInteraction } from 'discord.js';
// Modules
import pterodactyl from './modules/pterodactyl';
// Groups
import roles from './roles';
// Handlers
import logger from '../../handlers/logger';
// Function
export default {
data: new SlashCommandBuilder()
.setName('shop')
@ -44,16 +52,26 @@ export default {
)
),
async execute(interaction: CommandInteraction) {
// If subcommand is pterodactyl
if (interaction.options.getSubcommand() === 'pterodactyl') {
// Execute pterodactyl addon
await pterodactyl(interaction);
// Destructure
const { options, commandName, user, guild } = interaction;
// Module - Pterodactyl
if (options?.getSubcommand() === 'pterodactyl') {
// Execute Module - Pterodactyl
return await pterodactyl(interaction);
}
// If subcommand group is roles
else if (interaction.options.getSubcommandGroup() === 'roles') {
// Execute roles addon
await roles(interaction);
// Group - Roles
else if (options?.getSubcommandGroup() === 'roles') {
// Execute Group - Roles
return await roles(interaction);
}
// Send debug message
return logger?.debug(
`Guild: ${guild?.id} User: ${
user?.id
} executed /${commandName} ${options?.getSubcommandGroup()} ${options?.getSubcommand()}`
);
},
};

View file

@ -0,0 +1,235 @@
// Dependencies
import { CommandInteraction, ColorResolvable } from 'discord.js';
import { v4 as uuidv4 } from 'uuid';
import axios from 'axios';
// Configurations
import config from '../../../../config.json';
// Handlers
import logger from '../../../handlers/logger';
// Helpers
import creditNoun from '../../../helpers/creditNoun';
// Models
import apiSchema from '../../../helpers/database/models/apiSchema';
import userSchema from '../../../helpers/database/models/userSchema';
// Function
export default async (interaction: CommandInteraction) => {
const { options, guild, user, client } = interaction;
// Get options
const optionAmount = options?.getInteger('amount');
// If amount is null
if (optionAmount === null) {
// Embed object
const embed = {
title: ':dollar: Credits [Gift]' as string,
description: 'We could not read your requested amount.' as string,
color: config?.colors?.error as ColorResolvable,
timestamp: new Date() as Date,
footer: {
iconURL: config?.footer?.icon as string,
text: config?.footer?.text as string,
},
};
// Send interaction reply
return await interaction?.editReply({ embeds: [embed] });
}
// Get user object
const userDB = await userSchema?.findOne({
userId: user?.id,
guildId: guild?.id,
});
// Get DM user object
const dmUser = client?.users?.cache?.get(user?.id);
// Stop if amount or user credits is below 100
if ((optionAmount || userDB?.credits) < 100) {
const embed = {
title: ':shopping_cart: Shop [Pterodactyl]' as string,
description:
`You **can't** withdraw for __Pterodactyl__ below **100**.` as string,
color: config?.colors?.error as ColorResolvable,
fields: [
{
name: 'Your balance' as string,
value: `${creditNoun(userDB?.credits)}` as string,
},
],
timestamp: new Date() as Date,
footer: {
iconURL: config?.footer?.icon as string,
text: config?.footer?.text as string,
},
};
return interaction?.editReply({ embeds: [embed] });
}
// Stop if amount or user credits is above 1.000.000
if ((optionAmount || userDB?.credits) > 1000000) {
const embed = {
title: ':shopping_cart: Shop [Pterodactyl]' as string,
description:
`You **can't** withdraw for __Pterodactyl__ above **1.000.000**.` as string,
color: config?.colors?.error as ColorResolvable,
fields: [
{
name: 'Your balance' as string,
value: `${creditNoun(userDB?.credits)}` as string,
},
],
timestamp: new Date() as Date,
footer: {
iconURL: config?.footer?.icon as string,
text: config?.footer?.text as string,
},
};
return interaction?.editReply({ embeds: [embed] });
}
// Stop if user credits is below amount
if (userDB?.credits < optionAmount) {
const embed = {
title: ':shopping_cart: Shop [Pterodactyl]' as string,
description: `You have **insufficient** credits.` as string,
color: config.colors.error as ColorResolvable,
fields: [
{
name: 'Your balance' as string,
value: `${creditNoun(userDB?.credits)}` as string,
},
],
timestamp: new Date() as Date,
footer: {
iconURL: config?.footer?.icon as string,
text: config?.footer?.text as string,
},
};
return interaction?.editReply({ embeds: [embed] });
}
// Generate a unique voucher for the user
const code = uuidv4();
// Get api object
const apiCredentials = await apiSchema?.findOne({
guildId: guild?.id,
});
// Create a api instance
const api = axios?.create({
baseURL: apiCredentials?.url,
headers: { Authorization: `Bearer ${apiCredentials?.token}` },
});
// Get shop URL
const shopUrl = apiCredentials?.url?.replace('/api', '/store');
// Make API request
await api
// Make a post request to the API
?.post('vouchers', {
uses: 1,
code,
credits: optionAmount || userDB?.credits,
memo: `${interaction?.createdTimestamp} - ${interaction?.user?.id}`,
})
// If successful
?.then(async () => {
// Create DM embed object
const dmEmbed = {
title: ':shopping_cart: Shop [Pterodactyl]' as string,
description: `Redeem this voucher [here](${shopUrl})!` as string,
fields: [
{ name: 'Code' as string, value: `${code}` as string, inline: true },
{
name: 'Credits' as string,
value: `${optionAmount || userDB?.credits}` as string,
inline: true,
},
],
color: config?.colors?.success as ColorResolvable,
timestamp: new Date() as Date,
footer: {
iconURL: config?.footer?.icon as string,
text: config?.footer?.text as string,
},
};
// Create interaction embed object
const interactionEmbed = {
title: ':shopping_cart: Shop [Pterodactyl]' as string,
description: 'I have sent you the code in DM!' as string,
color: config?.colors?.success as ColorResolvable,
timestamp: new Date() as Date,
footer: {
iconURL: config?.footer?.icon as string,
text: config?.footer?.text as string,
},
};
// Withdraw amount from user credits
userDB.credits -= optionAmount || userDB?.credits;
// Save new credits
await userDB
?.save()
// If successful
?.then(async () => {
// Send debug message
logger?.debug(
`User: ${user?.username} redeemed: ${creditNoun(optionAmount)}`
);
// Send DM message
await dmUser?.send({ embeds: [dmEmbed] });
// Send interaction reply
await interaction?.editReply({
embeds: [interactionEmbed],
});
})
// If error occurs
.catch(async (e: any) => {
logger?.error(e);
const embed = {
title: ':shopping_cart: Shop [Pterodactyl]' as string,
description:
'Something went wrong, please try again later.' as string,
color: config?.colors?.error as ColorResolvable,
timestamp: new Date() as Date,
footer: {
iconURL: config?.footer?.icon as string,
text: config?.footer?.text as string,
},
};
return interaction?.editReply({ embeds: [embed] });
});
})
// If error occurs
.catch(async (e) => {
logger?.error(e);
const embed = {
title: ':shopping_cart: Shop [Pterodactyl]' as string,
description: 'Something went wrong, please try again later.' as string,
color: config?.colors?.error as ColorResolvable,
timestamp: new Date() as Date,
footer: {
iconURL: config?.footer?.icon as string,
text: config?.footer?.text as string,
},
};
return interaction?.editReply({ embeds: [embed] });
});
};

View file

@ -1,66 +0,0 @@
import { v4 as uuidv4 } from 'uuid';
import axios from 'axios';
import config from '../../../../../config.json';
import logger from '../../../../handlers/logger';
import users from '../../../../helpers/database/models/userSchema';
import shopRoles from '../../../../helpers/database/models/shopRolesSchema';
import guilds from '../../../../helpers/database/models/guildSchema';
import creditNoun from '../../../../helpers/creditNoun';
import { CommandInteraction, GuildMemberRoleManager } from 'discord.js';
export default async (interaction: CommandInteraction) => {
const { member } = interaction;
const name = await interaction.options.getString('name');
if (name === null) return;
await interaction?.guild?.roles
.create({
name,
color: 'RED',
reason: `${interaction?.user?.id} bought from shop`,
})
.then(async (role) => {
// Get guild object
const guildDB = await guilds.findOne({
guildId: interaction?.guild?.id,
});
const userDB = await users.findOne({
userId: interaction?.user?.id,
guildId: interaction?.guild?.id,
});
const { pricePerHour } = guildDB.shop.roles;
userDB.credits -= pricePerHour;
await userDB.save();
await shopRoles.create({
roleId: role?.id,
userId: interaction?.user?.id,
guildId: interaction?.guild?.id,
pricePerHour,
lastPayed: new Date(),
});
await (interaction?.member?.roles as GuildMemberRoleManager)?.add(
role?.id
);
await shopRoles.find().then((role: any) => console.log(role));
const embed = {
title: ':shopping_cart: Shop - Roles [Buy]',
description: `You have bought ${role.name} for ${guildDB.shop.roles.pricePerHour} per hour.`,
color: config.colors.success as any,
fields: [
{ name: 'Your balance', value: `${creditNoun(userDB.credits)}` },
],
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
return interaction.editReply({
embeds: [embed],
});
})
.catch(console.error);
};

View file

@ -1,63 +0,0 @@
import { v4 as uuidv4 } from 'uuid';
import axios from 'axios';
import config from '../../../../../config.json';
import logger from '../../../../handlers/logger';
import users from '../../../../helpers/database/models/userSchema';
import shopRoles from '../../../../helpers/database/models/shopRolesSchema';
import guilds from '../../../../helpers/database/models/guildSchema';
import creditNoun from '../../../../helpers/creditNoun';
import { CommandInteraction, GuildMemberRoleManager } from 'discord.js';
export default async (interaction: CommandInteraction) => {
const { member } = interaction;
const role = await interaction.options.getRole('role');
if (role === null) return;
const roleExist = await shopRoles.find({
guildId: interaction?.guild?.id,
userId: interaction?.user?.id,
roleId: role?.id,
});
if (roleExist) {
await (interaction?.member?.roles as GuildMemberRoleManager).remove(
role?.id
);
await interaction?.guild?.roles
.delete(role?.id, `${interaction?.user?.id} canceled from shop`)
.then(async () => {
// Get guild object
const guildDB = await guilds.findOne({
guildId: interaction?.guild?.id,
});
const userDB = await users.findOne({
userId: interaction?.user?.id,
guildId: interaction?.guild?.id,
});
await shopRoles.deleteOne({
roleId: role?.id,
userId: interaction?.user?.id,
guildId: interaction?.guild?.id,
});
const embed = {
title: ':shopping_cart: Shop - Roles [Buy]',
description: `You have canceled ${role.name}.`,
color: config.colors.success as any,
fields: [
{ name: 'Your balance', value: `${creditNoun(userDB.credits)}` },
],
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
return interaction.editReply({
embeds: [embed],
});
})
.catch(console.error);
}
};

View file

@ -1,4 +0,0 @@
import buy from './buy';
import cancel from './cancel';
export default { buy, cancel };

View file

@ -1,29 +1,34 @@
import logger from '../../../handlers/logger';
import buy from './addons/buy';
import cancel from './addons/cancel';
// Dependencies
import { CommandInteraction } from 'discord.js';
// Handlers
import logger from '../../../handlers/logger';
// Modules
import buy from './modules/buy';
import cancel from './modules/cancel';
// Function
export default async (interaction: CommandInteraction) => {
// Destructure member
const { member } = interaction;
const { options, commandName, guild, user } = interaction;
// If subcommand is buy
if (interaction.options.getSubcommand() === 'buy') {
// Execute buy addon
// Module - Buy
if (options?.getSubcommand() === 'buy') {
// Execute Module - Buy
await buy(interaction);
}
// If subcommand is cancel
if (interaction.options.getSubcommand() === 'cancel') {
// Execute cancel addon
// Module - Cancel
if (options?.getSubcommand() === 'cancel') {
// Execute Module - Cancel
await cancel(interaction);
}
// Send debug message
await logger.debug(
`Guild: ${interaction?.guild?.id} User: ${
interaction?.user?.id
} executed /${
interaction.commandName
} ${interaction.options.getSubcommandGroup()} ${interaction.options.getSubcommand()}`
return logger?.debug(
`Guild: ${guild?.id} User: ${
user?.id
} executed /${commandName} ${options?.getSubcommandGroup()} ${options?.getSubcommand()}`
);
};

View file

@ -0,0 +1,99 @@
// Dependencies
import {
CommandInteraction,
ColorResolvable,
GuildMemberRoleManager,
} from 'discord.js';
// Configurations
import config from '../../../../../config.json';
// Models
import userSchema from '../../../../helpers/database/models/userSchema';
import shopRolesSchema from '../../../../helpers/database/models/shopRolesSchema';
import guildSchema from '../../../../helpers/database/models/guildSchema';
// Helpers
import creditNoun from '../../../../helpers/creditNoun';
// Function
export default async (interaction: CommandInteraction) => {
const { options, guild, user, member } = interaction;
const optionName = options?.getString('name');
// If amount is null
if (optionName === null) {
// Embed object
const embed = {
title: ':dollar: Shop - Roles [Buy]' as string,
description: 'We could not read your requested name.' as string,
color: config?.colors?.error as ColorResolvable,
timestamp: new Date() as Date,
footer: {
iconURL: config?.footer?.icon as string,
text: config?.footer?.text as string,
},
};
// Send interaction reply
return await interaction?.editReply({ embeds: [embed] });
}
await guild?.roles
.create({
name: optionName,
color: 'RED',
reason: `${user?.id} bought from shop`,
})
.then(async (role) => {
// Get guild object
const guildDB = await guildSchema?.findOne({
guildId: guild?.id,
});
const userDB = await userSchema?.findOne({
userId: user?.id,
guildId: guild?.id,
});
const { pricePerHour } = guildDB?.shop?.roles;
userDB.credits -= pricePerHour;
await userDB?.save();
await shopRolesSchema?.create({
roleId: role?.id,
userId: user?.id,
guildId: guild?.id,
pricePerHour,
lastPayed: new Date(),
});
await (member?.roles as GuildMemberRoleManager)?.add(role?.id);
await shopRolesSchema?.find()?.then((role: any) => console.log(role));
const embed = {
title: ':shopping_cart: Shop - Roles [Buy]' as string,
description:
`You have bought ${role?.name} for ${guildDB?.shop?.roles?.pricePerHour} per hour.` as string,
color: config?.colors?.success as ColorResolvable,
fields: [
{
name: 'Your balance' as string,
value: `${creditNoun(userDB?.credits)}` as string,
},
],
timestamp: new Date() as Date,
footer: {
iconURL: config?.footer?.icon as string,
text: config?.footer?.text as string,
},
};
return interaction?.editReply({
embeds: [embed],
});
})
.catch(console.error);
};

View file

@ -0,0 +1,87 @@
// Dependencies
import {
CommandInteraction,
ColorResolvable,
GuildMemberRoleManager,
} from 'discord.js';
// Configurations
import config from '../../../../../config.json';
// Models
import userSchema from '../../../../helpers/database/models/userSchema';
import shopRolesSchema from '../../../../helpers/database/models/shopRolesSchema';
// Helpers
import creditNoun from '../../../../helpers/creditNoun';
// Function
export default async (interaction: CommandInteraction) => {
const { options, guild, user, member } = interaction;
const optionRole = options.getRole('role');
// If amount is null
if (optionRole === null) {
// Embed object
const embed = {
title: ':dollar: Shop - Roles [Cancel]' as string,
description: 'We could not read your requested role.' as string,
color: config?.colors?.error as ColorResolvable,
timestamp: new Date() as Date,
footer: {
iconURL: config?.footer?.icon as string,
text: config?.footer?.text as string,
},
};
// Send interaction reply
return await interaction?.editReply({ embeds: [embed] });
}
const roleExist = await shopRolesSchema?.find({
guildId: guild?.id,
userId: user?.id,
roleId: optionRole?.id,
});
if (roleExist) {
await (member?.roles as GuildMemberRoleManager)?.remove(optionRole?.id);
await guild?.roles
.delete(optionRole?.id, `${user?.id} canceled from shop`)
.then(async () => {
const userDB = await userSchema?.findOne({
userId: user?.id,
guildId: guild?.id,
});
await shopRolesSchema?.deleteOne({
roleId: optionRole?.id,
userId: user?.id,
guildId: guild?.id,
});
const embed = {
title: ':shopping_cart: Shop - Roles [Cancel]' as string,
description: `You have canceled ${optionRole.name}.` as string,
color: config?.colors?.success as ColorResolvable,
fields: [
{
name: 'Your balance' as string,
value: `${creditNoun(userDB?.credits)}` as string,
},
],
timestamp: new Date() as Date,
footer: {
iconURL: config?.footer?.icon as string,
text: config?.footer?.text as string,
},
};
return interaction?.editReply({
embeds: [embed],
});
})
.catch(console.error);
}
};

View file

@ -1,18 +0,0 @@
import config from '../../../../config.json';
import { CommandInteraction } from 'discord.js';
export default async (interaction: CommandInteraction) => {
const interactionEmbed = {
title: ':hammer: Utilities - About',
description: `This bot is hosted by ${
config.hoster.url
? `[${config.hoster.name}](${config.hoster.url})`
: `${config.hoster.name}`
}, the bot is developed by [Zyner](https://github.com/ZynerOrg)!
If you are interested in contributing, then just [fork it](https://github.com/ZynerOrg/xyter) yourself, we :heart: Open Source.`,
color: config.colors.success as any,
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
interaction.editReply({ embeds: [interactionEmbed] });
};

View file

@ -1,5 +0,0 @@
import lookup from './lookup';
import about from './about';
import stats from './stats';
export default { lookup, about, stats };

View file

@ -1,87 +0,0 @@
import axios from 'axios';
import config from '../../../../config.json';
import logger from '../../../handlers/logger';
import { CommandInteraction } from 'discord.js';
export default async (interaction: CommandInteraction) => {
try {
// Get lookup query
const query = await interaction.options.getString('query');
// Make API request
await axios
// Make a get request
.get(`http://ip-api.com/json/${query}`)
// If successful
.then(async (res) => {
// If query failed
if (res.data.status === 'fail') {
// Create embed object
const embed = {
title: ':hammer: Utilities - Lookup',
description: `${res.data.message}: ${res.data.query}`,
color: config.colors.error as any,
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
// Send interaction reply
await interaction.editReply({ embeds: [embed] });
}
// If query is successful
else if (res.data.status === 'success') {
// Create embed object
const embed = {
title: ':hammer: Utilities - Lookup',
fields: [
{ name: 'AS', value: `${res.data.as || 'Not available'}` },
{
name: 'Country',
value: `${res.data.country || 'Not available'}`,
},
{
name: 'Country Code',
value: `${res.data.countryCode || 'Not available'}`,
},
{
name: 'Region',
value: `${res.data.region || 'Not available'}`,
},
{
name: 'Region Name',
value: `${res.data.regionName || 'Not available'}`,
},
{ name: 'City', value: `${res.data.city || 'Not available'}` },
{ name: 'ZIP Code', value: `${res.data.zip || 'Not available'}` },
{ name: 'Latitude', value: `${res.data.lat || 'Not available'}` },
{
name: 'Longitude',
value: `${res.data.lon || 'Not available'}`,
},
{
name: 'Timezone',
value: `${res.data.timezone || 'Not available'}`,
},
{ name: 'ISP', value: `${res.data.isp || 'Not available'}` },
{
name: 'Organization',
value: `${res.data.org || 'Not available'}`,
},
],
color: config.colors.success as any,
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
// Send interaction reply
await interaction.editReply({ embeds: [embed] });
}
})
.catch(async (e) => {
await logger.error(e);
});
} catch (e) {
await logger.error(e);
}
};

View file

@ -1,53 +0,0 @@
import config from '../../../../config.json';
import { CommandInteraction } from 'discord.js';
export default async (interaction: CommandInteraction) => {
if (interaction?.client?.uptime === null) return;
let totalSeconds = interaction?.client?.uptime / 1000;
const days = Math.floor(totalSeconds / 86400);
totalSeconds %= 86400;
const hours = Math.floor(totalSeconds / 3600);
totalSeconds %= 3600;
const minutes = Math.floor(totalSeconds / 60);
const seconds = Math.floor(totalSeconds % 60);
const uptime = `${days} days, ${hours} hours, ${minutes} minutes and ${seconds} seconds`;
const interactionEmbed = {
title: ':hammer: Utilities - Stats',
description: 'Below you can see a list of statistics about the bot.',
fields: [
{
name: '⏰ Latency',
value: `${Date.now() - interaction.createdTimestamp} ms`,
inline: true,
},
{
name: '⏰ API Latency',
value: `${Math.round(interaction.client.ws.ping)} ms`,
inline: true,
},
{
name: '⏰ Uptime',
value: `${uptime}`,
inline: false,
},
{
name: '📈 Guilds',
value: `${interaction.client.guilds.cache.size}`,
inline: true,
},
{
name: '📈 Users (non-unique)',
value: `${interaction.client.guilds.cache.reduce(
(acc, guild) => acc + guild.memberCount,
0
)}`,
inline: true,
},
],
color: config.colors.success as any,
timestamp: new Date(),
footer: { iconURL: config.footer.icon, text: config.footer.text },
};
interaction.editReply({ embeds: [interactionEmbed] });
};

View file

@ -1,8 +1,16 @@
// Dependencies
import { SlashCommandBuilder } from '@discordjs/builders';
import lookup from './addons/lookup';
import about from './addons/about';
import stats from './addons/stats';
import { CommandInteraction } from 'discord.js';
// Modules
import lookup from './modules/lookup';
import about from './modules/about';
import stats from './modules/stats';
// Handlers
import logger from '../../handlers/logger';
// Function
export default {
data: new SlashCommandBuilder()
.setName('utilities')
@ -27,20 +35,30 @@ export default {
subcommand.setName('stats').setDescription('Check bot statistics!)')
),
async execute(interaction: CommandInteraction) {
// If subcommand is lookup
if (interaction.options.getSubcommand() === 'lookup') {
// Execute lookup addon
await lookup(interaction);
// Destructure
const { options, guild, user, commandName } = interaction;
// Module - Lookup
if (options?.getSubcommand() === 'lookup') {
// Execute Module - Lookup
return await lookup(interaction);
}
// If subcommand is about
else if (interaction.options.getSubcommand() === 'about') {
// Execute about addon
await about(interaction);
// Module - About
else if (options?.getSubcommand() === 'about') {
// Execute Module - About
return await about(interaction);
}
// If subcommand is stats
else if (interaction.options.getSubcommand() === 'stats') {
// Execute stats addon
await stats(interaction);
// Module - Stats
else if (options?.getSubcommand() === 'stats') {
// Execute Module - Stats
return await stats(interaction);
}
// Send debug message
return logger?.debug(
`Guild: ${guild?.id} User: ${
user?.id
} executed /${commandName} ${options?.getSubcommandGroup()} ${options?.getSubcommand()}`
);
},
};

View file

@ -0,0 +1,26 @@
// Dependencies
import { CommandInteraction, ColorResolvable } from 'discord.js';
// Configurations
import config from '../../../../config.json';
// Function
export default async (interaction: CommandInteraction) => {
const interactionEmbed = {
title: ':hammer: Utilities [About]' as string,
description: `This bot is hosted by ${
config?.hoster?.url
? `[${config?.hoster?.name}](${config?.hoster?.url})`
: `${config?.hoster?.name}`
}, the bot is developed by [Zyner](https://github.com/ZynerOrg)!
If you are interested in contributing, then just [fork it](https://github.com/ZynerOrg/xyter) yourself, we :heart: Open Source.` as string,
color: config?.colors?.success as ColorResolvable,
timestamp: new Date() as Date,
footer: {
iconURL: config?.footer?.icon as string,
text: config?.footer?.text as string,
},
};
interaction?.editReply({ embeds: [interactionEmbed] });
};

View file

@ -0,0 +1,112 @@
// Dependencies
import axios from 'axios';
import { CommandInteraction, ColorResolvable } from 'discord.js';
// Configurations
import config from '../../../../config.json';
// Handlers
import logger from '../../../handlers/logger';
// Function
export default async (interaction: CommandInteraction) => {
const { options } = interaction;
// Get lookup query
const query = options?.getString('query');
// Make API request
await axios
// Make a get request
?.get(`http://ip-api.com/json/${query}`)
// If successful
?.then(async (res) => {
// If query failed
if (res?.data?.status === 'fail') {
// Create embed object
const embed = {
title: ':hammer: Utilities - Lookup' as string,
description: `${res?.data?.message}: ${res?.data?.query}` as string,
color: config?.colors?.error as ColorResolvable,
timestamp: new Date() as Date,
footer: {
iconURL: config?.footer?.icon as string,
text: config?.footer?.text as string,
},
};
// Send interaction reply
await interaction?.editReply({ embeds: [embed] });
}
// If query is successful
else if (res?.data?.status === 'success') {
// Create embed object
const embed = {
title: ':hammer: Utilities - Lookup' as string,
fields: [
{
name: 'AS' as string,
value: `${res?.data?.as || 'Not available'}` as string,
},
{
name: 'Country' as string,
value: `${res?.data?.country || 'Not available'}` as string,
},
{
name: 'Country Code' as string,
value: `${res?.data?.countryCode || 'Not available'}` as string,
},
{
name: 'Region' as string,
value: `${res?.data?.region || 'Not available'}` as string,
},
{
name: 'Region Name' as string,
value: `${res?.data?.regionName || 'Not available'}` as string,
},
{
name: 'City' as string,
value: `${res?.data?.city || 'Not available'}` as string,
},
{
name: 'ZIP Code' as string,
value: `${res?.data?.zip || 'Not available'}` as string,
},
{
name: 'Latitude' as string,
value: `${res?.data?.lat || 'Not available'}` as string,
},
{
name: 'Longitude' as string,
value: `${res?.data?.lon || 'Not available'}` as string,
},
{
name: 'Timezone' as string,
value: `${res?.data?.timezone || 'Not available'}` as string,
},
{
name: 'ISP' as string,
value: `${res?.data?.isp || 'Not available'}` as string,
},
{
name: 'Organization' as string,
value: `${res?.data?.org || 'Not available'}` as string,
},
],
color: config?.colors?.success as ColorResolvable,
timestamp: new Date() as Date,
footer: {
iconURL: config?.footer?.icon as string,
text: config?.footer?.text as string,
},
};
// Send interaction reply
await interaction?.editReply({ embeds: [embed] });
}
})
.catch(async (e) => {
logger?.error(e);
});
};

View file

@ -0,0 +1,58 @@
import config from '../../../../config.json';
import { CommandInteraction, ColorResolvable } from 'discord.js';
export default async (interaction: CommandInteraction) => {
const { client } = interaction;
if (client?.uptime === null) return;
let totalSeconds = client?.uptime / 1000;
const days = Math?.floor(totalSeconds / 86400);
totalSeconds %= 86400;
const hours = Math?.floor(totalSeconds / 3600);
totalSeconds %= 3600;
const minutes = Math?.floor(totalSeconds / 60);
const seconds = Math?.floor(totalSeconds % 60);
const uptime = `${days} days, ${hours} hours, ${minutes} minutes and ${seconds} seconds`;
const interactionEmbed = {
title: ':hammer: Utilities - Stats' as string,
description:
'Below you can see a list of statistics about the bot.' as string,
fields: [
{
name: '⏰ Latency' as string,
value: `${Date?.now() - interaction?.createdTimestamp} ms` as string,
inline: true,
},
{
name: '⏰ API Latency' as string,
value: `${Math?.round(client?.ws?.ping)} ms` as string,
inline: true,
},
{
name: '⏰ Uptime' as string,
value: `${uptime}` as string,
inline: false,
},
{
name: '📈 Guilds' as string,
value: `${client?.guilds?.cache?.size}` as string,
inline: true,
},
{
name: '📈 Users (non-unique)' as string,
value: `${client?.guilds?.cache?.reduce(
(acc, guild) => acc + guild?.memberCount,
0
)}` as string,
inline: true,
},
],
color: config?.colors?.success as ColorResolvable,
timestamp: new Date() as Date,
footer: {
iconURL: config?.footer?.icon as string,
text: config?.footer?.text as string,
},
};
interaction?.editReply({ embeds: [interactionEmbed] });
};