Merge pull request #240 from VermiumSifell/dev
Development for 2022.5.0
This commit is contained in:
commit
a7f37bbbdc
85 changed files with 1390 additions and 1206 deletions
|
@ -5,7 +5,7 @@
|
|||
"main": "src/index.ts",
|
||||
"scripts": {
|
||||
"test": "jest",
|
||||
"start": "nodemon | pino-pretty -i pid,hostname -t yyyy-mm-dd HH:MM:s",
|
||||
"start": "node .",
|
||||
"prettier-format": "prettier \"src/**/*.ts\" --write",
|
||||
"lint": "eslint ./src --ext .ts",
|
||||
"prepare": "husky install"
|
||||
|
@ -27,6 +27,7 @@
|
|||
"email": "vermium@zyner.org"
|
||||
},
|
||||
"dependencies": {
|
||||
"@crowdin/ota-client": "^0.7.0",
|
||||
"@discordjs/builders": "^0.13.0",
|
||||
"@discordjs/rest": "^0.4.0",
|
||||
"axios": "^0.27.0",
|
||||
|
@ -36,6 +37,9 @@
|
|||
"discord-api-types": "^0.33.0",
|
||||
"discord.js": "^13.6.0",
|
||||
"i18next": "^21.6.13",
|
||||
"i18next-async-backend": "^2.0.0",
|
||||
"i18next-http-backend": "^1.4.0",
|
||||
"i18next-resources-to-backend": "^1.0.0",
|
||||
"mongoose": "^6.2.3",
|
||||
"node-schedule": "^2.1.0",
|
||||
"ts-node": "^10.7.0",
|
||||
|
|
|
@ -8,13 +8,15 @@ import logger from "@logger";
|
|||
import { url } from "@config/database";
|
||||
|
||||
export default async () => {
|
||||
mongoose.connect(url).then(async (connection) => {
|
||||
logger?.info(`Connected to database: ${connection.connection.name}`);
|
||||
await mongoose.connect(url).then(async (connection) => {
|
||||
logger.info(`Connected to database: ${connection.connection.name}`);
|
||||
});
|
||||
mongoose.connection.on("error", (error) => {
|
||||
logger?.error(error);
|
||||
|
||||
mongoose.connection.on("error", async (error) => {
|
||||
logger.error(error);
|
||||
});
|
||||
mongoose.connection.on("warn", (warning) => {
|
||||
logger?.warn(warning);
|
||||
|
||||
mongoose.connection.on("warn", async (warning) => {
|
||||
logger.warn(warning);
|
||||
});
|
||||
};
|
||||
|
|
|
@ -7,7 +7,6 @@ import fetchGuild from "@helpers/fetchGuild";
|
|||
import logger from "@logger";
|
||||
|
||||
export default {
|
||||
name: "guildCreate",
|
||||
async execute(guild: Guild) {
|
||||
const { client } = guild;
|
||||
|
||||
|
@ -15,5 +14,7 @@ export default {
|
|||
|
||||
await fetchGuild(guild);
|
||||
await updatePresence(client);
|
||||
|
||||
logger.silly(`guildCreate: ${guild}`);
|
||||
},
|
||||
};
|
||||
|
|
|
@ -7,7 +7,6 @@ import dropGuild from "@helpers/dropGuild";
|
|||
import logger from "@logger";
|
||||
|
||||
export default {
|
||||
name: "guildDelete",
|
||||
async execute(guild: Guild) {
|
||||
const { client } = guild;
|
||||
|
||||
|
@ -15,5 +14,7 @@ export default {
|
|||
|
||||
await dropGuild(guild);
|
||||
await updatePresence(client);
|
||||
|
||||
logger.silly(`guildDelete: ${guild}`);
|
||||
},
|
||||
};
|
||||
|
|
|
@ -20,24 +20,35 @@ export default {
|
|||
|
||||
if (channel === null) return;
|
||||
|
||||
(channel as TextChannel).send({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setColor(successColor)
|
||||
.setAuthor({
|
||||
name: "Member Joined",
|
||||
iconURL: member.user.displayAvatarURL(),
|
||||
})
|
||||
.setDescription(`${member.user} ${member.user.tag}`)
|
||||
.addFields([
|
||||
{ name: "Account Age", value: `${member.user.createdAt}` },
|
||||
])
|
||||
.setTimestamp()
|
||||
.setFooter({
|
||||
text: footerText,
|
||||
iconURL: footerIcon,
|
||||
}),
|
||||
],
|
||||
});
|
||||
(channel as TextChannel)
|
||||
.send({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setColor(successColor)
|
||||
.setAuthor({
|
||||
name: "Member Joined",
|
||||
iconURL: member.user.displayAvatarURL(),
|
||||
})
|
||||
.setDescription(`${member.user} ${member.user.tag}`)
|
||||
.addFields([
|
||||
{ name: "Account Age", value: `${member.user.createdAt}` },
|
||||
])
|
||||
.setTimestamp()
|
||||
.setFooter({
|
||||
text: footerText,
|
||||
iconURL: footerIcon,
|
||||
}),
|
||||
],
|
||||
})
|
||||
.then(async () => {
|
||||
logger.info(
|
||||
`Audit log sent for event guildMemberAdd in guild ${member.guild.name} (${member.guild.id})`
|
||||
);
|
||||
})
|
||||
.catch(async () => {
|
||||
logger.error(
|
||||
`Audit log failed to send for event guildMemberAdd in guild ${member.guild.name} (${member.guild.id})`
|
||||
);
|
||||
});
|
||||
},
|
||||
};
|
||||
|
|
|
@ -9,7 +9,6 @@ import joinMessage from "../guildMemberAdd/joinMessage";
|
|||
import audits from "../guildMemberAdd/audits";
|
||||
|
||||
export default {
|
||||
name: "guildMemberAdd",
|
||||
async execute(member: GuildMember) {
|
||||
const { client, user, guild } = member;
|
||||
|
||||
|
|
|
@ -20,21 +20,32 @@ export default {
|
|||
|
||||
if (channel === null) return;
|
||||
|
||||
(channel as TextChannel).send({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setColor(errorColor)
|
||||
.setAuthor({
|
||||
name: "Member Left",
|
||||
iconURL: member.user.displayAvatarURL(),
|
||||
})
|
||||
.setDescription(`${member.user} ${member.user.tag}`)
|
||||
.setTimestamp()
|
||||
.setFooter({
|
||||
text: footerText,
|
||||
iconURL: footerIcon,
|
||||
}),
|
||||
],
|
||||
});
|
||||
(channel as TextChannel)
|
||||
.send({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setColor(errorColor)
|
||||
.setAuthor({
|
||||
name: "Member Left",
|
||||
iconURL: member.user.displayAvatarURL(),
|
||||
})
|
||||
.setDescription(`${member.user} ${member.user.tag}`)
|
||||
.setTimestamp()
|
||||
.setFooter({
|
||||
text: footerText,
|
||||
iconURL: footerIcon,
|
||||
}),
|
||||
],
|
||||
})
|
||||
.then(async () => {
|
||||
logger.info(
|
||||
`Audit log sent for event guildMemberRemove in guild ${member.guild.name} (${member.guild.id})`
|
||||
);
|
||||
})
|
||||
.catch(async () => {
|
||||
logger.error(
|
||||
`Audit log failed to send for event guildMemberRemove in guild ${member.guild.name} (${member.guild.id})`
|
||||
);
|
||||
});
|
||||
},
|
||||
};
|
||||
|
|
|
@ -9,7 +9,6 @@ import leaveMessage from "./leaveMessage";
|
|||
import audits from "./audits";
|
||||
|
||||
export default {
|
||||
name: "guildMemberRemove",
|
||||
async execute(member: GuildMember) {
|
||||
const { client, user, guild } = member;
|
||||
|
||||
|
|
|
@ -26,23 +26,34 @@ export default {
|
|||
|
||||
if (channel === null) return;
|
||||
|
||||
(channel as TextChannel).send({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setColor(successColor)
|
||||
.setDescription(
|
||||
`
|
||||
(channel as TextChannel)
|
||||
.send({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setColor(successColor)
|
||||
.setDescription(
|
||||
`
|
||||
**Interaction created by** ${interaction.user.username} **in** ${interaction.channel}
|
||||
`
|
||||
)
|
||||
.setThumbnail(interaction.user.displayAvatarURL())
|
||||
.addFields([{ name: "Event", value: "interactionCreate" }])
|
||||
.setTimestamp()
|
||||
.setFooter({
|
||||
text: footerText,
|
||||
iconURL: footerIcon,
|
||||
}),
|
||||
],
|
||||
});
|
||||
)
|
||||
.setThumbnail(interaction.user.displayAvatarURL())
|
||||
.addFields([{ name: "Event", value: "interactionCreate" }])
|
||||
.setTimestamp()
|
||||
.setFooter({
|
||||
text: footerText,
|
||||
iconURL: footerIcon,
|
||||
}),
|
||||
],
|
||||
})
|
||||
.then(async () => {
|
||||
logger.info(
|
||||
`Audit log sent for event interactionCreate in guild ${interaction?.guild?.name} (${interaction?.guild?.id})`
|
||||
);
|
||||
})
|
||||
.catch(async () => {
|
||||
logger.error(
|
||||
`Audit log failed to send for event interactionCreate in guild ${interaction?.guild?.name} (${interaction?.guild?.id})`
|
||||
);
|
||||
});
|
||||
},
|
||||
};
|
||||
|
|
|
@ -4,16 +4,83 @@ import { CommandInteraction, MessageEmbed } from "discord.js";
|
|||
import logger from "@logger";
|
||||
|
||||
import { errorColor, footerText, footerIcon } from "@config/embed";
|
||||
import i18next from "i18next";
|
||||
import deferReply from "@root/helpers/deferReply";
|
||||
import getCommandMeta from "@root/helpers/getCommandMeta";
|
||||
|
||||
export default async (interaction: CommandInteraction) => {
|
||||
if (!interaction.isCommand()) return;
|
||||
|
||||
const { client, guild, commandName, user } = interaction;
|
||||
const { client, guild, commandName, user, memberPermissions } = interaction;
|
||||
|
||||
const currentCommand = client.commands.get(commandName);
|
||||
if (!currentCommand) return;
|
||||
|
||||
await interaction.deferReply({ ephemeral: true });
|
||||
if (currentCommand == null) {
|
||||
logger.silly(`Command ${commandName} not found`);
|
||||
}
|
||||
|
||||
const meta = await getCommandMeta(interaction, currentCommand);
|
||||
|
||||
await deferReply(interaction, meta.ephemeral || false);
|
||||
|
||||
if (
|
||||
meta.permissions &&
|
||||
meta.guildOnly &&
|
||||
!memberPermissions?.has(meta.permissions)
|
||||
) {
|
||||
return interaction?.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:toolbox:] Manage")
|
||||
.setDescription(`You do not have the permission to manage the bot.`)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(errorColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
if (meta.guildOnly) {
|
||||
if (!guild) {
|
||||
logger.verbose(`Guild is null`);
|
||||
|
||||
return interaction.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setDescription(
|
||||
i18next.t("guildOnly", {
|
||||
lng: interaction.locale,
|
||||
ns: "errors",
|
||||
})
|
||||
)
|
||||
.setColor(errorColor)
|
||||
.setTimestamp(new Date())
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
],
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (meta.dmOnly) {
|
||||
if (guild) {
|
||||
logger.verbose(`Guild exist`);
|
||||
|
||||
return interaction.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setDescription(
|
||||
i18next.t("dmOnly", {
|
||||
lng: interaction.locale,
|
||||
ns: "errors",
|
||||
})
|
||||
)
|
||||
.setColor(errorColor)
|
||||
.setTimestamp(new Date())
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
],
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
await currentCommand
|
||||
.execute(interaction)
|
||||
|
@ -23,7 +90,7 @@ export default async (interaction: CommandInteraction) => {
|
|||
);
|
||||
})
|
||||
.catch(async (error: any) => {
|
||||
logger?.error(error);
|
||||
logger?.error(`${error}`);
|
||||
|
||||
return interaction.editReply({
|
||||
embeds: [
|
||||
|
|
|
@ -7,7 +7,6 @@ import logger from "@logger";
|
|||
import audits from "./audits";
|
||||
|
||||
export default {
|
||||
name: "interactionCreate",
|
||||
async execute(interaction: CommandInteraction) {
|
||||
const { guild, id } = interaction;
|
||||
|
||||
|
|
|
@ -2,7 +2,6 @@ import { Message } from "discord.js";
|
|||
import modules from "@events/messageCreate/modules";
|
||||
|
||||
export default {
|
||||
name: "messageCreate",
|
||||
async execute(message: Message) {
|
||||
await modules.credits.execute(message);
|
||||
await modules.points.execute(message);
|
||||
|
|
|
@ -26,26 +26,37 @@ export default {
|
|||
|
||||
if (channel === null) return;
|
||||
|
||||
(channel as TextChannel).send({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setColor(successColor)
|
||||
.setAuthor({
|
||||
name: message.author.username,
|
||||
iconURL: message.author.displayAvatarURL(),
|
||||
})
|
||||
.setDescription(
|
||||
`
|
||||
(channel as TextChannel)
|
||||
.send({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setColor(successColor)
|
||||
.setAuthor({
|
||||
name: message.author.username,
|
||||
iconURL: message.author.displayAvatarURL(),
|
||||
})
|
||||
.setDescription(
|
||||
`
|
||||
**Message sent by** ${message.author} **deleted in** ${message.channel}
|
||||
${message.content}
|
||||
`
|
||||
)
|
||||
.setTimestamp()
|
||||
.setFooter({
|
||||
text: footerText,
|
||||
iconURL: footerIcon,
|
||||
}),
|
||||
],
|
||||
});
|
||||
)
|
||||
.setTimestamp()
|
||||
.setFooter({
|
||||
text: footerText,
|
||||
iconURL: footerIcon,
|
||||
}),
|
||||
],
|
||||
})
|
||||
.then(async () => {
|
||||
logger.info(
|
||||
`Audit log sent for event messageDelete in guild ${message?.guild?.name} (${message?.guild?.id})`
|
||||
);
|
||||
})
|
||||
.catch(async () => {
|
||||
logger.error(
|
||||
`Audit log failed to send for event messageDelete in guild ${message?.guild?.name} (${message?.guild?.id})`
|
||||
);
|
||||
});
|
||||
},
|
||||
};
|
||||
|
|
|
@ -3,7 +3,6 @@ import audits from "@events/messageDelete/audits";
|
|||
import counter from "./modules/counter";
|
||||
|
||||
export default {
|
||||
name: "messageDelete",
|
||||
async execute(message: Message) {
|
||||
await audits.execute(message);
|
||||
await counter(message);
|
||||
|
|
|
@ -29,25 +29,36 @@ export default {
|
|||
|
||||
if (channel === null) return;
|
||||
|
||||
(channel as TextChannel).send({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setColor(successColor)
|
||||
.setAuthor({
|
||||
name: newMessage.author.username,
|
||||
iconURL: newMessage.author.displayAvatarURL(),
|
||||
})
|
||||
.setDescription(
|
||||
`
|
||||
(channel as TextChannel)
|
||||
.send({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setColor(successColor)
|
||||
.setAuthor({
|
||||
name: newMessage.author.username,
|
||||
iconURL: newMessage.author.displayAvatarURL(),
|
||||
})
|
||||
.setDescription(
|
||||
`
|
||||
**Message edited in** ${newMessage.channel} [jump to message](https://discord.com/channels/${newMessage.guild.id}/${newMessage.channel.id}/${newMessage.id})
|
||||
`
|
||||
)
|
||||
.setTimestamp()
|
||||
.setFooter({
|
||||
text: footerText,
|
||||
iconURL: footerIcon,
|
||||
}),
|
||||
],
|
||||
});
|
||||
)
|
||||
.setTimestamp()
|
||||
.setFooter({
|
||||
text: footerText,
|
||||
iconURL: footerIcon,
|
||||
}),
|
||||
],
|
||||
})
|
||||
.then(async () => {
|
||||
logger.info(
|
||||
`Audit log sent for event messageUpdate in guild ${newMessage?.guild?.name} (${newMessage?.guild?.id})`
|
||||
);
|
||||
})
|
||||
.catch(async () => {
|
||||
logger.error(
|
||||
`Audit log failed to send for event messageUpdate in guild ${newMessage?.guild?.name} (${newMessage?.guild?.id})`
|
||||
);
|
||||
});
|
||||
},
|
||||
};
|
||||
|
|
|
@ -8,7 +8,6 @@ import counter from "./modules/counter";
|
|||
import audits from "./audits";
|
||||
|
||||
export default {
|
||||
name: "messageUpdate",
|
||||
async execute(oldMessage: Message, newMessage: Message) {
|
||||
const { author, guild } = newMessage;
|
||||
|
||||
|
|
|
@ -8,7 +8,6 @@ import deployCommands from "@handlers/deployCommands";
|
|||
import devMode from "@handlers/devMode";
|
||||
|
||||
export default {
|
||||
name: "ready",
|
||||
once: true,
|
||||
async execute(client: Client) {
|
||||
logger.info(`${client.user?.tag} (${client.user?.id}) is ready`);
|
||||
|
|
|
@ -15,19 +15,18 @@ export default async (client: Client) => {
|
|||
plugins.map(async (pluginName) => {
|
||||
const plugin = await import(`../plugins/${pluginName}`);
|
||||
|
||||
await client?.commands?.set(
|
||||
plugin?.default?.data?.name,
|
||||
plugin?.default
|
||||
await client.commands.set(
|
||||
plugin.default.data.name,
|
||||
plugin.default,
|
||||
plugin.default.meta
|
||||
);
|
||||
|
||||
logger.verbose(`Loaded plugin: ${pluginName}`);
|
||||
})
|
||||
)
|
||||
.then(async () => {
|
||||
logger.debug("Successfully loaded plugins.");
|
||||
})
|
||||
.catch(async (err) => {
|
||||
logger.error(err);
|
||||
logger.error(`${err}`);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
|
|
@ -15,12 +15,12 @@ export default async (client: Client) => {
|
|||
logger.verbose(`Loaded event: ${eventName}`);
|
||||
|
||||
if (event.once) {
|
||||
return client.once(event.default.name, async (...args) =>
|
||||
return client.once(eventName, async (...args) =>
|
||||
event.default.execute(...args)
|
||||
);
|
||||
}
|
||||
|
||||
return client.on(event.default.name, async (...args) =>
|
||||
return client.on(eventName, async (...args) =>
|
||||
event.default.execute(...args)
|
||||
);
|
||||
})
|
||||
|
|
22
src/helpers/deferReply.ts
Normal file
22
src/helpers/deferReply.ts
Normal file
|
@ -0,0 +1,22 @@
|
|||
import { CommandInteraction, MessageEmbed } from "discord.js";
|
||||
import { waitColor, footerText, footerIcon } from "@config/embed";
|
||||
|
||||
export default async (interaction: CommandInteraction, ephemeral: boolean) => {
|
||||
await interaction.deferReply({
|
||||
ephemeral,
|
||||
});
|
||||
|
||||
await interaction.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setFooter({
|
||||
text: footerText,
|
||||
iconURL: footerIcon,
|
||||
})
|
||||
.setTimestamp(new Date())
|
||||
.setTitle("Processing your request")
|
||||
.setColor(waitColor)
|
||||
.setDescription("Please wait..."),
|
||||
],
|
||||
});
|
||||
};
|
9
src/helpers/embedBuilder.ts
Normal file
9
src/helpers/embedBuilder.ts
Normal file
|
@ -0,0 +1,9 @@
|
|||
import { footerText, footerIcon } from "@config/embed";
|
||||
import { MessageEmbed } from "discord.js";
|
||||
|
||||
export default new MessageEmbed()
|
||||
.setFooter({
|
||||
text: footerText,
|
||||
iconURL: footerIcon,
|
||||
})
|
||||
.setTimestamp(new Date());
|
12
src/helpers/getCommandMeta.ts
Normal file
12
src/helpers/getCommandMeta.ts
Normal file
|
@ -0,0 +1,12 @@
|
|||
import { CommandInteraction } from "discord.js";
|
||||
|
||||
export default async (interaction: CommandInteraction, currentCommand: any) => {
|
||||
const subcommand = interaction.options.getSubcommand();
|
||||
const subcommandGroup = interaction.options.getSubcommandGroup(false);
|
||||
|
||||
if (!subcommandGroup) {
|
||||
return currentCommand.modules[subcommand].meta;
|
||||
}
|
||||
|
||||
return currentCommand.groups[subcommandGroup].modules[subcommand].meta;
|
||||
};
|
|
@ -4,7 +4,6 @@ import { token, intents } from "@config/discord";
|
|||
|
||||
import { Client } from "discord.js"; // discord.js
|
||||
|
||||
import locale from "@locale";
|
||||
import database from "@database";
|
||||
import schedules from "@schedules";
|
||||
import events from "@handlers/events";
|
||||
|
@ -15,7 +14,6 @@ async function main() {
|
|||
intents,
|
||||
});
|
||||
|
||||
await locale();
|
||||
await database();
|
||||
await schedules(client);
|
||||
|
||||
|
|
|
@ -1,205 +0,0 @@
|
|||
import i18next from "i18next";
|
||||
import logger from "@logger";
|
||||
|
||||
export default async () => {
|
||||
await i18next
|
||||
.init({
|
||||
lng: "en", // if you're using a language detector, do not define the lng option
|
||||
// debug: true,
|
||||
fallbackLng: "en",
|
||||
resources: {
|
||||
en: {
|
||||
general: { not_available: "Not Available" },
|
||||
commands: {
|
||||
credits: {
|
||||
general: {
|
||||
credits_one: "{{count}} credit",
|
||||
credits_other: "{{count}} credits",
|
||||
},
|
||||
addons: {
|
||||
balance: { embed: { title: "Credits" } },
|
||||
gift: { embed: { title: "Gift" } },
|
||||
},
|
||||
},
|
||||
reputation: {
|
||||
addons: {
|
||||
give: {
|
||||
version01: {
|
||||
embed: {
|
||||
title: ":medal: Reputation",
|
||||
description:
|
||||
"You have given reputation within the last day, you can not repute now!",
|
||||
},
|
||||
},
|
||||
version02: {
|
||||
embed: {
|
||||
title: ":medal: Reputation",
|
||||
description:
|
||||
"You have given {{user}} a {{type}} reputation!",
|
||||
},
|
||||
},
|
||||
version03: {
|
||||
embed: {
|
||||
title: ":medal: Reputation",
|
||||
description: "You can not repute yourself.",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
profile: {
|
||||
addons: {
|
||||
view: {
|
||||
embed: {
|
||||
title: "Profile",
|
||||
reputation: "Reputation (Global)",
|
||||
level: "Level (Guild)",
|
||||
points: "Points (Guild)",
|
||||
credits: "Credits (Guild)",
|
||||
language_code: "Language Code (Global)",
|
||||
},
|
||||
},
|
||||
settings: {
|
||||
embed: {
|
||||
title: "Profile",
|
||||
description: "Following settings is set",
|
||||
fields: { language: "Language" },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
sv: {
|
||||
general: { not_available: "Otillgänglig" },
|
||||
commands: {
|
||||
credits: {
|
||||
general: {
|
||||
credits_one: "{{count}} krona",
|
||||
credits_other: "{{count}} kronor",
|
||||
},
|
||||
addons: {
|
||||
balance: { embed: { title: "Krediter" } },
|
||||
gift: { embed: { title: "Gåva" } },
|
||||
},
|
||||
},
|
||||
reputation: {
|
||||
addons: {
|
||||
give: {
|
||||
version01: {
|
||||
embed: {
|
||||
title: ":medal: Omdöme",
|
||||
description:
|
||||
"Du har redan gett omdöme inom den senaste dagen, du kan inte ge ett omdöme just nu!",
|
||||
},
|
||||
},
|
||||
version02: {
|
||||
embed: {
|
||||
title: ":medal: Omdöme",
|
||||
description: "Du har gett {{user}} ett {{type}} omdöme!",
|
||||
},
|
||||
},
|
||||
version03: {
|
||||
embed: {
|
||||
title: ":medal: Omdöme",
|
||||
description: "Du kan inte ge dig själv ett omdöme.",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
profile: {
|
||||
addons: {
|
||||
view: {
|
||||
embed: {
|
||||
title: "Profil",
|
||||
reputation: "Omdöme (Globalt)",
|
||||
level: "Nivå (Server)",
|
||||
points: "Poäng (Server)",
|
||||
credits: "Krediter (Server)",
|
||||
language_code: "Språkkod (Globalt)",
|
||||
},
|
||||
},
|
||||
settings: {
|
||||
embed: {
|
||||
title: "Profil",
|
||||
description: "Följande inställningar är satta",
|
||||
fields: { language: "Språk" },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
de: {
|
||||
general: { not_available: "Nicht verfügbar" },
|
||||
commands: {
|
||||
credits: {
|
||||
general: {
|
||||
credits_one: "{{count}} Guthaben",
|
||||
credits_other: "{{count}} Guthaben",
|
||||
},
|
||||
addons: {
|
||||
balance: { embed: { title: "Guthaben" } },
|
||||
gift: { embed: { title: "Geschenk" } },
|
||||
},
|
||||
},
|
||||
reputation: {
|
||||
addons: {
|
||||
give: {
|
||||
version01: {
|
||||
embed: {
|
||||
title: ":medal: Ruf",
|
||||
description:
|
||||
"Du hast dir am letzten Tag einen Ruf verschafft, den du jetzt nicht rühmen kannst!",
|
||||
},
|
||||
},
|
||||
version02: {
|
||||
embed: {
|
||||
title: ":medal: Ruf",
|
||||
description:
|
||||
"Du hast {{user}} einen {{type}} Ruf gegeben!",
|
||||
},
|
||||
},
|
||||
version03: {
|
||||
embed: {
|
||||
title: ":medal: Ruf",
|
||||
description: "Du kannst dich nicht selbst rühmen.",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
profile: {
|
||||
addons: {
|
||||
view: {
|
||||
embed: {
|
||||
title: "Profil",
|
||||
reputation: "Ruf (Weltweit)",
|
||||
level: "Level (Gilde)",
|
||||
points: "Punkte (Gilde)",
|
||||
credits: "Guthaben (Gilde)",
|
||||
language_code: "Sprachcode (Weltweit)",
|
||||
},
|
||||
},
|
||||
settings: {
|
||||
embed: {
|
||||
title: "Profile",
|
||||
description: "Folgende Einstellungen werden vorgenommen",
|
||||
fields: { language: "Sprache" },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
.then(async () => {
|
||||
logger.debug(`i18next initialized`);
|
||||
})
|
||||
.catch(async (error) => {
|
||||
logger.error(`i18next failed to initialize: ${error}`);
|
||||
});
|
||||
};
|
|
@ -1,17 +1,18 @@
|
|||
// Dependencies
|
||||
import { CommandInteraction } from "discord.js";
|
||||
import { SlashCommandBuilder } from "@discordjs/builders";
|
||||
|
||||
import logger from "@logger";
|
||||
|
||||
import modules from "@root/plugins/counters/modules";
|
||||
import modules from "@plugins/counters/modules";
|
||||
|
||||
export default {
|
||||
metadata: { author: "Zyner" },
|
||||
modules,
|
||||
|
||||
data: new SlashCommandBuilder()
|
||||
.setName("counters")
|
||||
.setDescription("View guild counters")
|
||||
|
||||
.addSubcommand(modules.view.data),
|
||||
|
||||
async execute(interaction: CommandInteraction) {
|
||||
const { options } = interaction;
|
||||
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
import view from "./view";
|
||||
import view from "@plugins/counters/modules/view";
|
||||
|
||||
export default { view };
|
||||
|
|
|
@ -1,11 +1,3 @@
|
|||
// Dependencies
|
||||
import { CommandInteraction, MessageEmbed } from "discord.js";
|
||||
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
|
||||
import { ChannelType } from "discord-api-types/v10";
|
||||
|
||||
import counterSchema from "@schemas/counter";
|
||||
|
||||
// Configuration
|
||||
import {
|
||||
errorColor,
|
||||
successColor,
|
||||
|
@ -13,7 +5,16 @@ import {
|
|||
footerIcon,
|
||||
} from "@config/embed";
|
||||
|
||||
import { CommandInteraction, MessageEmbed } from "discord.js";
|
||||
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
|
||||
import { ChannelType } from "discord-api-types/v10";
|
||||
|
||||
import counterSchema from "@schemas/counter";
|
||||
import i18next from "i18next";
|
||||
|
||||
export default {
|
||||
meta: { guildOnly: true, ephemeral: false },
|
||||
|
||||
data: (command: SlashCommandSubcommandBuilder) => {
|
||||
return command
|
||||
.setName("view")
|
||||
|
@ -25,14 +26,28 @@ export default {
|
|||
`The channel that contains the counter you want to view`
|
||||
)
|
||||
.setRequired(true)
|
||||
.addChannelType(ChannelType.GuildText as number)
|
||||
.addChannelTypes(ChannelType.GuildText)
|
||||
);
|
||||
},
|
||||
|
||||
execute: async (interaction: CommandInteraction) => {
|
||||
const { options, guild } = interaction;
|
||||
const { options, guild, locale } = interaction;
|
||||
|
||||
const discordChannel = options?.getChannel("channel");
|
||||
|
||||
const embed = new MessageEmbed()
|
||||
.setTitle(
|
||||
i18next.t("counters:modules:view:general:title", {
|
||||
lng: locale,
|
||||
ns: "plugins",
|
||||
})
|
||||
)
|
||||
.setTimestamp(new Date())
|
||||
.setFooter({
|
||||
text: footerText,
|
||||
iconURL: footerIcon,
|
||||
});
|
||||
|
||||
const counter = await counterSchema?.findOne({
|
||||
guildId: guild?.id,
|
||||
channelId: discordChannel?.id,
|
||||
|
@ -41,32 +56,31 @@ export default {
|
|||
if (counter === null) {
|
||||
return interaction?.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:1234:] Counters (View)")
|
||||
.setDescription(`No counter found for channel ${discordChannel}!`)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(errorColor)
|
||||
.setFooter({
|
||||
text: footerText,
|
||||
iconURL: footerIcon,
|
||||
}),
|
||||
embed
|
||||
.setDescription(
|
||||
i18next.t("counters:modules:view:error01:description", {
|
||||
lng: locale,
|
||||
ns: "plugins",
|
||||
channel: discordChannel,
|
||||
})
|
||||
)
|
||||
.setColor(errorColor),
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
return interaction?.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:1234:] Counters (View)")
|
||||
embed
|
||||
.setDescription(
|
||||
`Viewing counter for channel ${discordChannel} with count ${counter.counter}.`
|
||||
i18next.t("counters:modules:view:success01:description", {
|
||||
lng: locale,
|
||||
ns: "plugins",
|
||||
channel: discordChannel,
|
||||
amount: counter.counter,
|
||||
})
|
||||
)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(successColor)
|
||||
.setFooter({
|
||||
text: footerText,
|
||||
iconURL: footerIcon,
|
||||
}),
|
||||
.setColor(successColor),
|
||||
],
|
||||
});
|
||||
},
|
||||
|
|
|
@ -1,44 +1,39 @@
|
|||
// Dependencies
|
||||
import { SlashCommandBuilder } from "@discordjs/builders";
|
||||
import { CommandInteraction } from "discord.js";
|
||||
|
||||
import logger from "@logger";
|
||||
|
||||
// Modules
|
||||
import modules from "@root/plugins/credits/modules";
|
||||
import modules from "@plugins/credits/modules";
|
||||
|
||||
export default {
|
||||
metadata: { author: "Zyner" },
|
||||
modules,
|
||||
|
||||
data: new SlashCommandBuilder()
|
||||
.setName("credits")
|
||||
.setDescription("Manage your credits.")
|
||||
|
||||
.addSubcommand(modules.balance.data)
|
||||
.addSubcommand(modules.gift.data)
|
||||
.addSubcommand(modules.top.data)
|
||||
.addSubcommand(modules.work.data),
|
||||
|
||||
async execute(interaction: CommandInteraction) {
|
||||
const { options } = interaction;
|
||||
|
||||
if (options?.getSubcommand() === "balance") {
|
||||
logger?.verbose(`Executing balance subcommand`);
|
||||
return modules.balance.execute(interaction);
|
||||
switch (options.getSubcommand()) {
|
||||
case "balance":
|
||||
await modules.balance.execute(interaction);
|
||||
break;
|
||||
case "gift":
|
||||
await modules.gift.execute(interaction);
|
||||
break;
|
||||
case "top":
|
||||
await modules.top.execute(interaction);
|
||||
break;
|
||||
case "work":
|
||||
await modules.work.execute(interaction);
|
||||
break;
|
||||
default:
|
||||
logger.verbose(`Unknown subcommand ${options.getSubcommand()}`);
|
||||
}
|
||||
|
||||
if (options?.getSubcommand() === "gift") {
|
||||
logger?.verbose(`Executing gift subcommand`);
|
||||
return modules.gift.execute(interaction);
|
||||
}
|
||||
|
||||
if (options?.getSubcommand() === "top") {
|
||||
logger?.verbose(`Executing top command`);
|
||||
return modules.top.execute(interaction);
|
||||
}
|
||||
|
||||
if (options?.getSubcommand() === "work") {
|
||||
logger?.verbose(`Executing work command`);
|
||||
return modules.work.execute(interaction);
|
||||
}
|
||||
|
||||
logger?.verbose(`Unknown subcommand ${options?.getSubcommand()}`);
|
||||
},
|
||||
};
|
||||
|
|
|
@ -1,10 +1,3 @@
|
|||
// Dependencies
|
||||
import { CommandInteraction, MessageEmbed } from "discord.js";
|
||||
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
|
||||
|
||||
import logger from "@logger";
|
||||
|
||||
// Configurations
|
||||
import {
|
||||
errorColor,
|
||||
successColor,
|
||||
|
@ -12,41 +5,53 @@ import {
|
|||
footerIcon,
|
||||
} from "@config/embed";
|
||||
|
||||
// Helpers
|
||||
import pluralize from "@helpers/pluralize";
|
||||
import i18next from "i18next";
|
||||
import { CommandInteraction, MessageEmbed } from "discord.js";
|
||||
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
|
||||
import logger from "@logger";
|
||||
|
||||
import fetchUser from "@helpers/fetchUser";
|
||||
|
||||
export default {
|
||||
meta: { guildOnly: true, ephemeral: true },
|
||||
data: (command: SlashCommandSubcommandBuilder) => {
|
||||
return (
|
||||
command
|
||||
.setName("balance")
|
||||
.setDescription(`View a user's balance`)
|
||||
|
||||
// User
|
||||
.addUserOption((option) =>
|
||||
option
|
||||
.setName("user")
|
||||
.setDescription(`The user whose balance you want to view`)
|
||||
)
|
||||
);
|
||||
return command
|
||||
.setName("balance")
|
||||
.setDescription(`View a user's balance`)
|
||||
.addUserOption((option) =>
|
||||
option
|
||||
.setName("user")
|
||||
.setDescription(`The user whose balance you want to view`)
|
||||
);
|
||||
},
|
||||
execute: async (interaction: CommandInteraction) => {
|
||||
const { options, user, guild } = interaction;
|
||||
const { options, user, guild, locale } = interaction;
|
||||
|
||||
const discordUser = options?.getUser("user");
|
||||
const discordUser = options.getUser("user");
|
||||
|
||||
const embed = new MessageEmbed()
|
||||
.setTitle(
|
||||
i18next.t("credits:modules:balance:general:title", {
|
||||
lng: locale,
|
||||
ns: "plugins",
|
||||
})
|
||||
)
|
||||
.setTimestamp(new Date())
|
||||
.setFooter({ text: footerText, iconURL: footerIcon });
|
||||
|
||||
if (guild === null) {
|
||||
logger?.verbose(`Guild is null`);
|
||||
logger.verbose(`Guild is null`);
|
||||
|
||||
return interaction?.editReply({
|
||||
return interaction.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:dollar:] Credits (Balance)")
|
||||
.setDescription(`You can only use this command in a guild!`)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(errorColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
embed
|
||||
.setDescription(
|
||||
i18next.t("guildOnly", {
|
||||
lng: locale,
|
||||
ns: "errors",
|
||||
})
|
||||
)
|
||||
.setColor(errorColor),
|
||||
],
|
||||
});
|
||||
}
|
||||
|
@ -54,50 +59,55 @@ export default {
|
|||
const userObj = await fetchUser(discordUser || user, guild);
|
||||
|
||||
if (userObj === null) {
|
||||
logger?.verbose(`User not found`);
|
||||
logger.verbose(`User not found`);
|
||||
|
||||
return interaction?.editReply({
|
||||
return interaction.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:dollar:] Credits (Balance)")
|
||||
.setDescription(`Could not find user ${discordUser || user}`)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(errorColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
embed
|
||||
.setDescription(
|
||||
i18next.t("userNotFound", {
|
||||
lng: locale,
|
||||
ns: "errors",
|
||||
user: discordUser || user,
|
||||
})
|
||||
)
|
||||
.setColor(errorColor),
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
if (userObj.credits === null) {
|
||||
logger?.verbose(`User has no credits`);
|
||||
logger.verbose(`User has no credits`);
|
||||
|
||||
return interaction?.editReply({
|
||||
return interaction.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:dollar:] Credits (Balance)")
|
||||
.setDescription(`${discordUser || user} has no credits!`)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(errorColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
embed
|
||||
.setDescription(
|
||||
i18next.t("credits:modules:balance:error01:description", {
|
||||
lng: locale,
|
||||
ns: "plugins",
|
||||
user: discordUser || user,
|
||||
})
|
||||
)
|
||||
.setColor(errorColor),
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
logger?.verbose(`Found user ${discordUser || user}`);
|
||||
logger.verbose(`Found user ${discordUser || user}`);
|
||||
|
||||
return interaction?.editReply({
|
||||
return interaction.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:dollar:] Credits (Balance)")
|
||||
embed
|
||||
.setDescription(
|
||||
`${discordUser || user} has ${pluralize(
|
||||
userObj.credits,
|
||||
`credit`
|
||||
)}!`
|
||||
i18next.t("credits:modules:balance:success01:description", {
|
||||
lng: locale,
|
||||
ns: "plugins",
|
||||
user: discordUser || user,
|
||||
amount: userObj.credits,
|
||||
})
|
||||
)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(successColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
.setColor(successColor),
|
||||
],
|
||||
});
|
||||
},
|
||||
|
|
|
@ -18,9 +18,12 @@ import saveUser from "@helpers/saveUser";
|
|||
// Models
|
||||
import fetchUser from "@helpers/fetchUser";
|
||||
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
|
||||
import i18next from "i18next";
|
||||
|
||||
// Function
|
||||
export default {
|
||||
meta: { guildOnly: true, ephemeral: true },
|
||||
|
||||
data: (command: SlashCommandSubcommandBuilder) => {
|
||||
return command
|
||||
.setName("gift")
|
||||
|
@ -42,38 +45,52 @@ export default {
|
|||
);
|
||||
},
|
||||
execute: async (interaction: CommandInteraction) => {
|
||||
const { options, user, guild, client } = interaction;
|
||||
const { options, user, guild, client, locale } = interaction;
|
||||
|
||||
const optionUser = options?.getUser("user");
|
||||
const optionAmount = options?.getInteger("amount");
|
||||
const optionReason = options?.getString("reason");
|
||||
const optionUser = options.getUser("user");
|
||||
const optionAmount = options.getInteger("amount");
|
||||
const optionReason = options.getString("reason");
|
||||
|
||||
const embed = new MessageEmbed()
|
||||
.setTitle(
|
||||
i18next.t("credits:modules:gift:general:title", {
|
||||
lng: locale,
|
||||
ns: "plugins",
|
||||
})
|
||||
)
|
||||
.setTimestamp(new Date())
|
||||
.setFooter({ text: footerText, iconURL: footerIcon });
|
||||
|
||||
if (guild === null) {
|
||||
logger?.verbose(`Guild is null`);
|
||||
logger.verbose(`Guild is null`);
|
||||
|
||||
return interaction.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:dollar:] Credits (Gift)")
|
||||
.setDescription(`We can not find your guild!`)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(errorColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
embed
|
||||
.setDescription(
|
||||
i18next.t("guildOnly", {
|
||||
lng: locale,
|
||||
ns: "errors",
|
||||
})
|
||||
)
|
||||
.setColor(errorColor),
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
if (optionUser === null) {
|
||||
logger?.verbose(`User not found`);
|
||||
logger.verbose(`User not found`);
|
||||
|
||||
return interaction.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:dollar:] Credits (Gift)")
|
||||
.setDescription(`We can not find your requested user!`)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(errorColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
embed
|
||||
.setDescription(
|
||||
i18next.t("userNotFound", {
|
||||
lng: locale,
|
||||
ns: "errors",
|
||||
})
|
||||
)
|
||||
.setColor(errorColor),
|
||||
],
|
||||
});
|
||||
}
|
||||
|
@ -85,119 +102,126 @@ export default {
|
|||
const toUserDB = await fetchUser(optionUser, guild);
|
||||
|
||||
if (fromUserDB === null) {
|
||||
logger?.verbose(`User not found`);
|
||||
logger.verbose(`User not found`);
|
||||
|
||||
return interaction.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:dollar:] Credits (Gift)")
|
||||
embed
|
||||
.setDescription(
|
||||
`We can not find your requested from user in our database!`
|
||||
i18next.t("userNotFound", {
|
||||
lng: locale,
|
||||
ns: "errors",
|
||||
})
|
||||
)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(errorColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
.setColor(errorColor),
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
if (toUserDB === null) {
|
||||
logger?.verbose(`User not found`);
|
||||
logger.verbose(`User not found`);
|
||||
|
||||
return interaction.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:dollar:] Credits (Gift)")
|
||||
embed
|
||||
.setDescription(
|
||||
`We can not find your requested to user in our database!`
|
||||
i18next.t("userNotFound", {
|
||||
lng: locale,
|
||||
ns: "errors",
|
||||
})
|
||||
)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(errorColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
.setColor(errorColor),
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
// If receiver is same as sender
|
||||
if (optionUser?.id === user?.id) {
|
||||
logger?.verbose(`User is same as sender`);
|
||||
if (optionUser.id === user.id) {
|
||||
logger.verbose(`User is same as sender`);
|
||||
|
||||
return interaction.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:dollar:] Credits (Gift)")
|
||||
.setDescription(`You can not pay yourself!`)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(errorColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
embed
|
||||
.setDescription(
|
||||
i18next.t("credits:modules:gift:error01:description", {
|
||||
lng: locale,
|
||||
ns: "plugins",
|
||||
})
|
||||
)
|
||||
.setColor(errorColor),
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
// If amount is null
|
||||
if (optionAmount === null) {
|
||||
logger?.verbose(`Amount is null`);
|
||||
logger.verbose(`Amount is null`);
|
||||
|
||||
return interaction.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:dollar:] Credits (Gift)")
|
||||
.setDescription(`We could not read your requested amount!`)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(errorColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
embed
|
||||
.setDescription(
|
||||
i18next.t("amountNotFound", {
|
||||
lng: locale,
|
||||
ns: "errors",
|
||||
})
|
||||
)
|
||||
.setColor(errorColor),
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
// If amount is zero or below
|
||||
if (optionAmount <= 0) {
|
||||
logger?.verbose(`Amount is zero or below`);
|
||||
logger.verbose(`Amount is zero or below`);
|
||||
|
||||
return interaction.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:dollar:] Credits (Gift)")
|
||||
.setDescription(`You can't gift zero or below!`)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(errorColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
embed
|
||||
.setDescription(
|
||||
i18next.t("credits:modules:gift:error02:description", {
|
||||
lng: locale,
|
||||
ns: "plugins",
|
||||
})
|
||||
)
|
||||
.setColor(errorColor),
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
// If user has below gifting amount
|
||||
if (fromUserDB?.credits < optionAmount) {
|
||||
logger?.verbose(`User has below gifting amount`);
|
||||
if (fromUserDB.credits < optionAmount) {
|
||||
logger.verbose(`User has below gifting amount`);
|
||||
|
||||
return interaction.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:dollar:] Credits (Gift)")
|
||||
embed
|
||||
.setDescription(
|
||||
`You have insufficient credits. Your balance is ${fromUserDB?.credits}!`
|
||||
i18next.t("credits:modules:gift:error03:description", {
|
||||
lng: locale,
|
||||
ns: "plugins",
|
||||
amount: fromUserDB.credits,
|
||||
})
|
||||
)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(errorColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
.setColor(errorColor),
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
// If toUserDB has no credits
|
||||
if (toUserDB === null) {
|
||||
logger?.verbose(`User has no credits`);
|
||||
logger.verbose(`User has no credits`);
|
||||
|
||||
return interaction.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:dollar:] Credits (Gift)")
|
||||
embed
|
||||
.setDescription(
|
||||
`We can not find your requested to user in our database!`
|
||||
i18next.t("userNotFound", {
|
||||
lng: locale,
|
||||
ns: "errors",
|
||||
})
|
||||
)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(errorColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
.setColor(errorColor),
|
||||
],
|
||||
});
|
||||
}
|
||||
|
@ -209,46 +233,50 @@ export default {
|
|||
toUserDB.credits += optionAmount;
|
||||
|
||||
// Save users
|
||||
await saveUser(fromUserDB, toUserDB)?.then(async () => {
|
||||
await saveUser(fromUserDB, toUserDB).then(async () => {
|
||||
// Get DM user object
|
||||
const dmUser = client?.users?.cache?.get(optionUser?.id);
|
||||
const dmUser = client.users.cache.get(optionUser.id);
|
||||
|
||||
if (dmUser == null) return;
|
||||
|
||||
// Send DM to user
|
||||
await dmUser
|
||||
?.send({
|
||||
.send({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:dollar:] Credits (Gift)")
|
||||
embed
|
||||
.setDescription(
|
||||
`You have received ${optionAmount} credits from ${
|
||||
user?.tag
|
||||
} with reason ${
|
||||
optionReason ? ` with reason: ${optionReason}` : ""
|
||||
}!`
|
||||
i18next.t("credits:modules:gift:error03:description", {
|
||||
lng: locale,
|
||||
ns: "plugins",
|
||||
user: user.tag,
|
||||
amount: optionAmount,
|
||||
reason: optionReason || "unspecified",
|
||||
})
|
||||
)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(successColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
.setColor(successColor),
|
||||
],
|
||||
})
|
||||
.catch(async (error) =>
|
||||
logger?.error(`[Gift] Error sending DM to user: ${error}`)
|
||||
logger.error(`[Gift] Error sending DM to user: ${error}`)
|
||||
);
|
||||
|
||||
logger?.verbose(
|
||||
`[Gift] Successfully gifted ${optionAmount} credits to ${optionUser?.tag}`
|
||||
logger.verbose(
|
||||
`[Gift] Successfully gifted ${optionAmount} credits to ${optionUser.tag}`
|
||||
);
|
||||
|
||||
return interaction.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:dollar:] Credits (Gift)")
|
||||
embed
|
||||
.setDescription(
|
||||
`Successfully gifted ${optionAmount} credits to ${optionUser?.tag}!`
|
||||
i18next.t("credits:modules:gift:success02:description", {
|
||||
lng: locale,
|
||||
ns: "plugins",
|
||||
user: user,
|
||||
amount: optionAmount,
|
||||
reason: optionReason || "unspecified",
|
||||
})
|
||||
)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(successColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
.setColor(successColor),
|
||||
],
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import balance from "./balance";
|
||||
import gift from "./gift";
|
||||
import top from "./top";
|
||||
import work from "./work";
|
||||
import balance from "@plugins/credits/modules/balance";
|
||||
import gift from "@plugins/credits/modules/gift";
|
||||
import top from "@plugins/credits/modules/top";
|
||||
import work from "@plugins/credits/modules/work";
|
||||
|
||||
export default { balance, gift, top, work };
|
||||
|
|
|
@ -1,48 +1,86 @@
|
|||
// Dependencies
|
||||
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
|
||||
import {
|
||||
successColor,
|
||||
errorColor,
|
||||
footerText,
|
||||
footerIcon,
|
||||
} from "@config/embed";
|
||||
|
||||
import i18next from "i18next";
|
||||
import { CommandInteraction, MessageEmbed } from "discord.js";
|
||||
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
|
||||
import logger from "@logger";
|
||||
|
||||
import userSchema from "@schemas/user";
|
||||
|
||||
// Configurations
|
||||
import { successColor, footerText, footerIcon } from "@config/embed";
|
||||
|
||||
// Helpers
|
||||
import pluralize from "@helpers/pluralize";
|
||||
import userSchema, { IUser } from "@schemas/user";
|
||||
|
||||
export default {
|
||||
meta: { guildOnly: true, ephemeral: false },
|
||||
|
||||
data: (command: SlashCommandSubcommandBuilder) => {
|
||||
return command.setName("top").setDescription(`View the top users`);
|
||||
},
|
||||
execute: async (interaction: CommandInteraction) => {
|
||||
// Get all users in the guild
|
||||
const { locale, guild } = interaction;
|
||||
|
||||
const usersDB = await userSchema.find({ guildId: interaction?.guild?.id });
|
||||
const embed = new MessageEmbed()
|
||||
.setTitle(
|
||||
i18next.t("credits:modules:top:general:title", {
|
||||
lng: locale,
|
||||
ns: "plugins",
|
||||
})
|
||||
)
|
||||
.setTimestamp(new Date())
|
||||
.setFooter({ text: footerText, iconURL: footerIcon });
|
||||
|
||||
if (guild === null) {
|
||||
logger.verbose(`Guild is null`);
|
||||
|
||||
return interaction.editReply({
|
||||
embeds: [
|
||||
embed
|
||||
.setDescription(
|
||||
i18next.t("guildOnly", {
|
||||
lng: locale,
|
||||
ns: "errors",
|
||||
})
|
||||
)
|
||||
.setColor(errorColor),
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
const usersDB = await userSchema.find({ guildId: guild.id });
|
||||
|
||||
const topTen = usersDB
|
||||
|
||||
// Sort them after credits amount (ascending)
|
||||
.sort((a, b) => (a?.credits > b?.credits ? -1 : 1))
|
||||
.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) =>
|
||||
`${index + 1}. <@${x?.userId}> - ${pluralize(x?.credits, "credit")}`;
|
||||
const entry = (x: IUser, index: number) =>
|
||||
i18next.t("credits:modules:top:entry", {
|
||||
lng: locale,
|
||||
ns: "plugins",
|
||||
index: index + 1,
|
||||
user: x.userId,
|
||||
amount: x.credits,
|
||||
});
|
||||
|
||||
return interaction.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:dollar:] Credits (Top)")
|
||||
embed
|
||||
.setDescription(
|
||||
`Top 10 users with the most credits.
|
||||
` ${i18next.t("credits:modules:top:success01:description", {
|
||||
lng: locale,
|
||||
ns: "plugins",
|
||||
})}
|
||||
|
||||
${topTen.map(entry).join("\n")}`
|
||||
${topTen.map(entry).join("\n")}
|
||||
`
|
||||
)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(successColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
.setColor(successColor),
|
||||
],
|
||||
});
|
||||
},
|
||||
|
|
|
@ -4,7 +4,12 @@ import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
|
|||
import Chance from "chance";
|
||||
|
||||
// Configurations
|
||||
import { successColor, footerText, footerIcon } from "@config/embed";
|
||||
import {
|
||||
successColor,
|
||||
errorColor,
|
||||
footerText,
|
||||
footerIcon,
|
||||
} from "@config/embed";
|
||||
|
||||
// Handlers
|
||||
import logger from "@logger";
|
||||
|
@ -15,14 +20,30 @@ import timeoutSchema from "@schemas/timeout";
|
|||
// Helpers
|
||||
import fetchUser from "@helpers/fetchUser";
|
||||
import fetchGuild from "@helpers/fetchGuild";
|
||||
import i18next from "i18next";
|
||||
|
||||
export default {
|
||||
meta: { guildOnly: true, ephemeral: true },
|
||||
|
||||
data: (command: SlashCommandSubcommandBuilder) => {
|
||||
return command.setName("work").setDescription(`Work to earn credits`);
|
||||
},
|
||||
execute: async (interaction: CommandInteraction) => {
|
||||
// Destructure member
|
||||
const { guild, user } = interaction;
|
||||
const { guild, user, locale } = interaction;
|
||||
|
||||
const embed = new MessageEmbed()
|
||||
.setTitle(
|
||||
i18next.t("credits:modules:work:general:title", {
|
||||
lng: locale,
|
||||
ns: "plugins",
|
||||
})
|
||||
)
|
||||
.setTimestamp(new Date())
|
||||
.setFooter({
|
||||
text: footerText,
|
||||
iconURL: footerIcon,
|
||||
});
|
||||
|
||||
// Chance module
|
||||
const chance = new Chance();
|
||||
|
@ -46,14 +67,15 @@ export default {
|
|||
|
||||
return interaction.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:dollar:] Credits (Work)")
|
||||
embed
|
||||
.setDescription(
|
||||
`You can not work while on timeout, please wait ${guildDB?.credits.workTimeout} seconds.`
|
||||
i18next.t("credits:modules:work:error01:description", {
|
||||
lng: locale,
|
||||
ns: "plugins",
|
||||
time: guildDB?.credits.workTimeout,
|
||||
})
|
||||
)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(successColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
.setColor(errorColor),
|
||||
],
|
||||
});
|
||||
}
|
||||
|
@ -78,12 +100,16 @@ export default {
|
|||
|
||||
return interaction.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:dollar:] Credits (Work)")
|
||||
.setDescription(`You worked and earned ${creditsEarned} credits`)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(successColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
embed
|
||||
.setDescription(
|
||||
i18next.t("credits:modules:work:success01:description", {
|
||||
lng: locale,
|
||||
ns: "plugins",
|
||||
time: guildDB?.credits.workTimeout,
|
||||
amount: creditsEarned,
|
||||
})
|
||||
)
|
||||
.setColor(successColor),
|
||||
],
|
||||
});
|
||||
});
|
||||
|
|
27
src/plugins/fun/index.ts
Normal file
27
src/plugins/fun/index.ts
Normal file
|
@ -0,0 +1,27 @@
|
|||
import { SlashCommandBuilder } from "@discordjs/builders";
|
||||
import { CommandInteraction } from "discord.js";
|
||||
import logger from "@logger";
|
||||
|
||||
import modules from "@plugins/fun/modules";
|
||||
|
||||
export default {
|
||||
modules,
|
||||
|
||||
data: new SlashCommandBuilder()
|
||||
.setName("fun")
|
||||
.setDescription("Fun commands.")
|
||||
|
||||
.addSubcommand(modules.meme.data),
|
||||
|
||||
async execute(interaction: CommandInteraction) {
|
||||
const { options } = interaction;
|
||||
|
||||
switch (options.getSubcommand()) {
|
||||
case "meme":
|
||||
await modules.meme.execute(interaction);
|
||||
break;
|
||||
default:
|
||||
logger.verbose(`Unknown subcommand ${options.getSubcommand()}`);
|
||||
}
|
||||
},
|
||||
};
|
5
src/plugins/fun/modules/index.ts
Normal file
5
src/plugins/fun/modules/index.ts
Normal file
|
@ -0,0 +1,5 @@
|
|||
import meme from "@plugins/fun/modules/meme";
|
||||
|
||||
export default {
|
||||
meme,
|
||||
};
|
37
src/plugins/fun/modules/meme.ts
Normal file
37
src/plugins/fun/modules/meme.ts
Normal file
|
@ -0,0 +1,37 @@
|
|||
import { successColor, footerText, footerIcon } from "@config/embed";
|
||||
|
||||
import axios from "axios";
|
||||
import { CommandInteraction, MessageEmbed } from "discord.js";
|
||||
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
|
||||
import logger from "@logger";
|
||||
|
||||
export default {
|
||||
meta: { guildOnly: false, ephemeral: false },
|
||||
|
||||
data: (command: SlashCommandSubcommandBuilder) => {
|
||||
return command.setName("meme").setDescription("Get a meme from r/memes)");
|
||||
},
|
||||
execute: async (interaction: CommandInteraction) => {
|
||||
await axios
|
||||
.get("https://www.reddit.com/r/memes/random/.json")
|
||||
.then(async (res) => {
|
||||
const response = res.data[0].data.children;
|
||||
const content = response[0].data;
|
||||
|
||||
const embed = new MessageEmbed()
|
||||
.setTitle(content.title)
|
||||
.setTimestamp(new Date())
|
||||
.setImage(content.url)
|
||||
.setFooter({
|
||||
text: `👍 ${content.ups}︱👎 ${content.downs}\n${footerText}`,
|
||||
iconURL: footerIcon,
|
||||
})
|
||||
.setColor(successColor);
|
||||
|
||||
return interaction.editReply({ embeds: [embed] });
|
||||
})
|
||||
.catch((error) => {
|
||||
logger.error(`${error}`);
|
||||
});
|
||||
},
|
||||
};
|
|
@ -5,31 +5,33 @@ import { CommandInteraction } from "discord.js";
|
|||
import logger from "@logger";
|
||||
|
||||
// Modules
|
||||
import moduleCreate from "./modules/create";
|
||||
import moduleDelete from "./modules/delete";
|
||||
import modules from "./modules";
|
||||
|
||||
// Function
|
||||
export default {
|
||||
modules,
|
||||
|
||||
data: (group: SlashCommandSubcommandGroupBuilder) => {
|
||||
return group
|
||||
.setName("counters")
|
||||
.setDescription("Manage guild counters.")
|
||||
.addSubcommand(moduleCreate.data)
|
||||
.addSubcommand(moduleDelete.data);
|
||||
.addSubcommand(modules.add.data)
|
||||
.addSubcommand(modules.remove.data);
|
||||
},
|
||||
|
||||
execute: async (interaction: CommandInteraction) => {
|
||||
const { options } = interaction;
|
||||
|
||||
if (options?.getSubcommand() === "create") {
|
||||
if (options?.getSubcommand() === "add") {
|
||||
logger?.verbose(`Executing create subcommand`);
|
||||
|
||||
return moduleCreate.execute(interaction);
|
||||
return modules.add.execute(interaction);
|
||||
}
|
||||
|
||||
if (options?.getSubcommand() === "delete") {
|
||||
if (options?.getSubcommand() === "remove") {
|
||||
logger?.verbose(`Executing delete subcommand`);
|
||||
|
||||
return moduleDelete.execute(interaction);
|
||||
return modules.remove.execute(interaction);
|
||||
}
|
||||
|
||||
logger?.verbose(`Unknown subcommand ${options?.getSubcommand()}`);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Dependencies
|
||||
import { MessageEmbed, CommandInteraction } from "discord.js";
|
||||
import { MessageEmbed, CommandInteraction, Permissions } from "discord.js";
|
||||
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
|
||||
import { ChannelType } from "discord-api-types/v10";
|
||||
|
||||
|
@ -16,19 +16,26 @@ import logger from "@logger";
|
|||
|
||||
// Models
|
||||
import counterSchema from "@schemas/counter";
|
||||
import i18next from "i18next";
|
||||
|
||||
// Function
|
||||
export default {
|
||||
meta: {
|
||||
guildOnly: true,
|
||||
ephemeral: true,
|
||||
permissions: [Permissions.FLAGS.MANAGE_GUILD],
|
||||
},
|
||||
|
||||
data: (command: SlashCommandSubcommandBuilder) => {
|
||||
return command
|
||||
.setName("create")
|
||||
.setName("add")
|
||||
.setDescription("Add a counter to your guild.")
|
||||
.addChannelOption((option) =>
|
||||
option
|
||||
.setName("channel")
|
||||
.setDescription("The channel to send the counter to.")
|
||||
.setRequired(true)
|
||||
.addChannelType(ChannelType.GuildText as number)
|
||||
.addChannelTypes(ChannelType.GuildText)
|
||||
)
|
||||
.addStringOption((option) =>
|
||||
option
|
||||
|
@ -43,12 +50,22 @@ export default {
|
|||
);
|
||||
},
|
||||
execute: async (interaction: CommandInteraction) => {
|
||||
const { options, guild } = interaction;
|
||||
const { options, guild, locale } = interaction;
|
||||
|
||||
const discordChannel = options?.getChannel("channel");
|
||||
const countingWord = options?.getString("word");
|
||||
const startValue = options?.getNumber("start");
|
||||
|
||||
const embed = new MessageEmbed()
|
||||
.setTitle(
|
||||
i18next.t("manage:groups:counters:modules:add:general:title", {
|
||||
lng: locale,
|
||||
ns: "plugins",
|
||||
})
|
||||
)
|
||||
.setTimestamp(new Date())
|
||||
.setFooter({ text: footerText, iconURL: footerIcon });
|
||||
|
||||
const counter = await counterSchema?.findOne({
|
||||
guildId: guild?.id,
|
||||
channelId: discordChannel?.id,
|
||||
|
@ -57,12 +74,18 @@ export default {
|
|||
if (counter) {
|
||||
return interaction?.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:toolbox:] Manage - Counters (Create)")
|
||||
.setDescription(`A counter already exists for this channel.`)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(errorColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
embed
|
||||
.setDescription(
|
||||
i18next.t(
|
||||
"manage:groups:counters:modules:add:error01:description",
|
||||
{
|
||||
lng: locale,
|
||||
ns: "plugins",
|
||||
channel: discordChannel,
|
||||
}
|
||||
)
|
||||
)
|
||||
.setColor(errorColor),
|
||||
],
|
||||
});
|
||||
}
|
||||
|
@ -79,12 +102,18 @@ export default {
|
|||
|
||||
return interaction?.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:toolbox:] Manage - Counters (Create)")
|
||||
.setDescription(`Created counter for ${discordChannel}`)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(successColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
embed
|
||||
.setDescription(
|
||||
i18next.t(
|
||||
"manage:groups:counters:modules:create:success01:description",
|
||||
{
|
||||
lng: locale,
|
||||
ns: "plugins",
|
||||
channel: discordChannel,
|
||||
}
|
||||
)
|
||||
)
|
||||
.setColor(successColor),
|
||||
],
|
||||
});
|
||||
});
|
4
src/plugins/manage/groups/counters/modules/index.ts
Normal file
4
src/plugins/manage/groups/counters/modules/index.ts
Normal file
|
@ -0,0 +1,4 @@
|
|||
import add from "@plugins/manage/groups/counters/modules/add";
|
||||
import remove from "@plugins/manage/groups/counters/modules/remove";
|
||||
|
||||
export default { add, remove };
|
|
@ -1,5 +1,5 @@
|
|||
// Dependencies
|
||||
import { CommandInteraction, MessageEmbed } from "discord.js";
|
||||
import { CommandInteraction, MessageEmbed, Permissions } from "discord.js";
|
||||
|
||||
// Configurations
|
||||
import {
|
||||
|
@ -16,26 +16,43 @@ import logger from "@logger";
|
|||
import counterSchema from "@schemas/counter";
|
||||
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
|
||||
import { ChannelType } from "discord-api-types/v10";
|
||||
import i18next from "i18next";
|
||||
|
||||
// Function
|
||||
export default {
|
||||
meta: {
|
||||
guildOnly: true,
|
||||
ephemeral: true,
|
||||
permissions: [Permissions.FLAGS.MANAGE_GUILD],
|
||||
},
|
||||
|
||||
data: (command: SlashCommandSubcommandBuilder) => {
|
||||
return command
|
||||
.setName("delete")
|
||||
.setName("remove")
|
||||
.setDescription(`Delete a counter from your guild.`)
|
||||
.addChannelOption((option) =>
|
||||
option
|
||||
.setName("channel")
|
||||
.setDescription("The channel to delete the counter from.")
|
||||
.setRequired(true)
|
||||
.addChannelType(ChannelType.GuildText as number)
|
||||
.addChannelTypes(ChannelType.GuildText)
|
||||
);
|
||||
},
|
||||
execute: async (interaction: CommandInteraction) => {
|
||||
const { options, guild } = interaction;
|
||||
const { options, guild, locale } = interaction;
|
||||
|
||||
const discordChannel = options?.getChannel("channel");
|
||||
|
||||
const embed = new MessageEmbed()
|
||||
.setTitle(
|
||||
i18next.t("manage:groups:counters:modules:remove:general:title", {
|
||||
lng: locale,
|
||||
ns: "plugins",
|
||||
})
|
||||
)
|
||||
.setTimestamp(new Date())
|
||||
.setFooter({ text: footerText, iconURL: footerIcon });
|
||||
|
||||
const counter = await counterSchema?.findOne({
|
||||
guildId: guild?.id,
|
||||
channelId: discordChannel?.id,
|
||||
|
@ -46,12 +63,17 @@ export default {
|
|||
|
||||
return interaction?.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:toolbox:] Manage - Counters (Delete)")
|
||||
.setDescription(`The counter for this channel does not exist.`)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(errorColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
embed
|
||||
.setDescription(
|
||||
i18next.t(
|
||||
"manage:groups:counters:modules:remove:error01:description",
|
||||
{
|
||||
lng: locale,
|
||||
ns: "plugins",
|
||||
}
|
||||
)
|
||||
)
|
||||
.setColor(errorColor),
|
||||
],
|
||||
});
|
||||
}
|
||||
|
@ -66,12 +88,17 @@ export default {
|
|||
|
||||
return interaction?.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:toolbox:] Manage - Counters (Delete)")
|
||||
.setDescription(`The counter for this channel has been deleted.`)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(successColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
embed
|
||||
.setDescription(
|
||||
i18next.t(
|
||||
"manage:groups:counters:modules:remove:success01:description",
|
||||
{
|
||||
lng: locale,
|
||||
ns: "plugins",
|
||||
}
|
||||
)
|
||||
)
|
||||
.setColor(successColor),
|
||||
],
|
||||
});
|
||||
})
|
|
@ -1,53 +1,43 @@
|
|||
// Dependencies
|
||||
import { CommandInteraction } from "discord.js";
|
||||
import { SlashCommandSubcommandGroupBuilder } from "@discordjs/builders";
|
||||
|
||||
import logger from "@logger";
|
||||
|
||||
// Modules
|
||||
import moduleGive from "./modules/give";
|
||||
import moduleSet from "./modules/set";
|
||||
import moduleTake from "./modules/take";
|
||||
import moduleTransfer from "./modules/transfer";
|
||||
import modules from "./modules";
|
||||
|
||||
// Function
|
||||
export default {
|
||||
modules,
|
||||
|
||||
data: (group: SlashCommandSubcommandGroupBuilder) => {
|
||||
return group
|
||||
.setName("credits")
|
||||
.setDescription("Manage the credits of a user.")
|
||||
.addSubcommand(moduleGive.data)
|
||||
.addSubcommand(moduleSet.data)
|
||||
.addSubcommand(moduleTake.data)
|
||||
.addSubcommand(moduleTransfer.data);
|
||||
.addSubcommand(modules.give.data)
|
||||
.addSubcommand(modules.set.data)
|
||||
.addSubcommand(modules.take.data)
|
||||
.addSubcommand(modules.transfer.data);
|
||||
},
|
||||
execute: async (interaction: CommandInteraction) => {
|
||||
const { options } = interaction;
|
||||
|
||||
if (options?.getSubcommand() === "give") {
|
||||
logger?.verbose(`Executing give subcommand`);
|
||||
switch (options.getSubcommand()) {
|
||||
case "give":
|
||||
logger.verbose(`Executing give subcommand`);
|
||||
|
||||
return moduleGive.execute(interaction);
|
||||
return modules.give.execute(interaction);
|
||||
case "set":
|
||||
logger.verbose(`Executing set subcommand`);
|
||||
|
||||
return modules.set.execute(interaction);
|
||||
case "take":
|
||||
logger.verbose(`Executing take subcommand`);
|
||||
|
||||
return modules.take.execute(interaction);
|
||||
case "transfer":
|
||||
logger.verbose(`Executing transfer subcommand`);
|
||||
|
||||
return modules.transfer.execute(interaction);
|
||||
default:
|
||||
logger.verbose(`Unknown subcommand ${options.getSubcommand()}`);
|
||||
}
|
||||
|
||||
if (options?.getSubcommand() === "set") {
|
||||
logger?.verbose(`Executing set subcommand`);
|
||||
|
||||
return moduleSet.execute(interaction);
|
||||
}
|
||||
|
||||
if (options?.getSubcommand() === "take") {
|
||||
logger?.verbose(`Executing take subcommand`);
|
||||
|
||||
return moduleTake.execute(interaction);
|
||||
}
|
||||
|
||||
if (options?.getSubcommand() === "transfer") {
|
||||
logger?.verbose(`Executing transfer subcommand`);
|
||||
|
||||
return moduleTransfer.execute(interaction);
|
||||
}
|
||||
|
||||
logger?.verbose(`No subcommand found`);
|
||||
},
|
||||
};
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Dependencies
|
||||
import { CommandInteraction, MessageEmbed } from "discord.js";
|
||||
import { CommandInteraction, MessageEmbed, Permissions } from "discord.js";
|
||||
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
|
||||
|
||||
// Configurations
|
||||
|
@ -21,6 +21,12 @@ import fetchUser from "@helpers/fetchUser";
|
|||
|
||||
// Function
|
||||
export default {
|
||||
meta: {
|
||||
guildOnly: true,
|
||||
ephemeral: true,
|
||||
permissions: [Permissions.FLAGS.MANAGE_GUILD],
|
||||
},
|
||||
|
||||
data: (command: SlashCommandSubcommandBuilder) => {
|
||||
return command
|
||||
.setName("give")
|
||||
|
|
6
src/plugins/manage/groups/credits/modules/index.ts
Normal file
6
src/plugins/manage/groups/credits/modules/index.ts
Normal file
|
@ -0,0 +1,6 @@
|
|||
import give from "@plugins/manage/groups/credits/modules/give";
|
||||
import set from "@plugins/manage/groups/credits/modules/set";
|
||||
import take from "@plugins/manage/groups/credits/modules/take";
|
||||
import transfer from "@plugins/manage/groups/credits/modules/transfer";
|
||||
|
||||
export default { give, set, take, transfer };
|
|
@ -1,5 +1,5 @@
|
|||
// Dependencies
|
||||
import { CommandInteraction, MessageEmbed } from "discord.js";
|
||||
import { CommandInteraction, MessageEmbed, Permissions } from "discord.js";
|
||||
|
||||
// Configurations
|
||||
import {
|
||||
|
@ -20,6 +20,12 @@ import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
|
|||
|
||||
// Function
|
||||
export default {
|
||||
meta: {
|
||||
guildOnly: true,
|
||||
ephemeral: true,
|
||||
permissions: [Permissions.FLAGS.MANAGE_GUILD],
|
||||
},
|
||||
|
||||
data: (command: SlashCommandSubcommandBuilder) => {
|
||||
return command
|
||||
.setName("set")
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Dependencies
|
||||
import { CommandInteraction, MessageEmbed } from "discord.js";
|
||||
import { CommandInteraction, MessageEmbed, Permissions } from "discord.js";
|
||||
|
||||
// Configurations
|
||||
import {
|
||||
|
@ -21,6 +21,12 @@ import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
|
|||
|
||||
// Function
|
||||
export default {
|
||||
meta: {
|
||||
guildOnly: true,
|
||||
ephemeral: true,
|
||||
permissions: [Permissions.FLAGS.MANAGE_GUILD],
|
||||
},
|
||||
|
||||
data: (command: SlashCommandSubcommandBuilder) => {
|
||||
return command
|
||||
.setName("take")
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Dependencies
|
||||
import { CommandInteraction, MessageEmbed } from "discord.js";
|
||||
import { CommandInteraction, MessageEmbed, Permissions } from "discord.js";
|
||||
|
||||
// Configurations
|
||||
import {
|
||||
|
@ -21,6 +21,12 @@ import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
|
|||
|
||||
// Function
|
||||
export default {
|
||||
meta: {
|
||||
guildOnly: true,
|
||||
ephemeral: true,
|
||||
permissions: [Permissions.FLAGS.MANAGE_GUILD],
|
||||
},
|
||||
|
||||
data: (command: SlashCommandSubcommandBuilder) => {
|
||||
return command
|
||||
.setName("transfer")
|
||||
|
|
4
src/plugins/manage/groups/index.ts
Normal file
4
src/plugins/manage/groups/index.ts
Normal file
|
@ -0,0 +1,4 @@
|
|||
import counters from "@plugins/manage/groups/counters";
|
||||
import credits from "@plugins/manage/groups/credits";
|
||||
|
||||
export default { counters, credits };
|
|
@ -1,52 +1,35 @@
|
|||
//Dependencies
|
||||
import { SlashCommandBuilder } from "@discordjs/builders";
|
||||
import { CommandInteraction, Permissions, MessageEmbed } from "discord.js";
|
||||
|
||||
// Configurations
|
||||
import { errorColor, footerText, footerIcon } from "@config/embed";
|
||||
import { CommandInteraction } from "discord.js";
|
||||
|
||||
// Groups
|
||||
import credits from "./groups/credits";
|
||||
import counters from "./groups/counters";
|
||||
import groups from "@plugins/manage/groups";
|
||||
import logger from "@logger";
|
||||
|
||||
// Function
|
||||
export default {
|
||||
metadata: { author: "Zyner" },
|
||||
groups,
|
||||
|
||||
data: new SlashCommandBuilder()
|
||||
.setName("manage")
|
||||
.setDescription("Manage the bot.")
|
||||
.addSubcommandGroup(counters.data)
|
||||
.addSubcommandGroup(credits.data),
|
||||
.addSubcommandGroup(groups.counters.data)
|
||||
.addSubcommandGroup(groups.credits.data),
|
||||
|
||||
async execute(interaction: CommandInteraction) {
|
||||
// Destructure
|
||||
const { memberPermissions, options } = interaction;
|
||||
|
||||
// Check permission
|
||||
if (!memberPermissions?.has(Permissions?.FLAGS?.MANAGE_GUILD)) {
|
||||
return interaction?.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:toolbox:] Manage")
|
||||
.setDescription(`You do not have the permission to manage the bot.`)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(errorColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
],
|
||||
});
|
||||
}
|
||||
const { options } = interaction;
|
||||
|
||||
if (options?.getSubcommandGroup() === "credits") {
|
||||
logger?.verbose(`Subcommand group is credits`);
|
||||
|
||||
return credits.execute(interaction);
|
||||
return groups.credits.execute(interaction);
|
||||
}
|
||||
|
||||
if (options?.getSubcommandGroup() === "counters") {
|
||||
logger?.verbose(`Subcommand group is counters`);
|
||||
|
||||
return counters.execute(interaction);
|
||||
return groups.counters.execute(interaction);
|
||||
}
|
||||
|
||||
logger?.verbose(`Subcommand group is not credits or counters`);
|
||||
|
|
|
@ -3,34 +3,26 @@ import { SlashCommandBuilder } from "@discordjs/builders";
|
|||
import { CommandInteraction } from "discord.js";
|
||||
|
||||
// Modules
|
||||
import view from "./modules/view";
|
||||
import modules from "@plugins/profile/modules";
|
||||
|
||||
// Handlers
|
||||
import logger from "@logger";
|
||||
|
||||
// Function
|
||||
export default {
|
||||
metadata: { author: "Zyner" },
|
||||
modules,
|
||||
|
||||
data: new SlashCommandBuilder()
|
||||
.setName("profile")
|
||||
.setDescription("Check a profile.")
|
||||
.addSubcommand((subcommand) =>
|
||||
subcommand
|
||||
.setName("view")
|
||||
.setDescription("View a profile.")
|
||||
.addUserOption((option) =>
|
||||
option
|
||||
.setName("target")
|
||||
.setDescription("The profile you wish to view")
|
||||
)
|
||||
),
|
||||
.addSubcommand(modules.view.data),
|
||||
async execute(interaction: CommandInteraction) {
|
||||
const { options } = interaction;
|
||||
|
||||
if (options?.getSubcommand() === "view") {
|
||||
logger?.verbose(`Executing view subcommand`);
|
||||
|
||||
return view(interaction);
|
||||
return modules.view.execute(interaction);
|
||||
}
|
||||
|
||||
logger?.verbose(`No subcommand found`);
|
||||
|
|
3
src/plugins/profile/modules/index.ts
Normal file
3
src/plugins/profile/modules/index.ts
Normal file
|
@ -0,0 +1,3 @@
|
|||
import view from "@plugins/profile/modules/view";
|
||||
|
||||
export default { view };
|
|
@ -8,68 +8,82 @@ import { successColor, footerText, footerIcon } from "@config/embed";
|
|||
import fetchUser from "@helpers/fetchUser";
|
||||
|
||||
import logger from "@logger";
|
||||
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
|
||||
|
||||
// Function
|
||||
export default async (interaction: CommandInteraction) => {
|
||||
// Destructure
|
||||
const { client, options, user, guild } = interaction;
|
||||
export default {
|
||||
meta: { guildOnly: true, ephemeral: false },
|
||||
|
||||
// Target information
|
||||
const target = options?.getUser("target");
|
||||
data: (command: SlashCommandSubcommandBuilder) => {
|
||||
return command
|
||||
.setName("view")
|
||||
.setDescription("View a profile.")
|
||||
.addUserOption((option) =>
|
||||
option.setName("target").setDescription("The profile you wish to view")
|
||||
);
|
||||
},
|
||||
|
||||
// Discord User Information
|
||||
const discordUser = await client?.users?.fetch(
|
||||
`${target ? target?.id : user?.id}`
|
||||
);
|
||||
execute: async (interaction: CommandInteraction) => {
|
||||
// Destructure
|
||||
const { client, options, user, guild } = interaction;
|
||||
|
||||
if (guild === null) {
|
||||
return logger?.verbose(`Guild is null`);
|
||||
}
|
||||
// Target information
|
||||
const target = options?.getUser("target");
|
||||
|
||||
// User Information
|
||||
const userObj = await fetchUser(discordUser, guild);
|
||||
// Discord User Information
|
||||
const discordUser = await client?.users?.fetch(
|
||||
`${target ? target?.id : user?.id}`
|
||||
);
|
||||
|
||||
// Embed object
|
||||
const embed = {
|
||||
author: {
|
||||
name: `${discordUser?.username}#${discordUser?.discriminator}`,
|
||||
icon_url: discordUser?.displayAvatarURL(),
|
||||
},
|
||||
color: successColor,
|
||||
fields: [
|
||||
{
|
||||
name: `:dollar: Credits`,
|
||||
value: `${userObj?.credits || "Not found"}`,
|
||||
inline: true,
|
||||
if (guild === null) {
|
||||
return logger?.verbose(`Guild is null`);
|
||||
}
|
||||
|
||||
// User Information
|
||||
const userObj = await fetchUser(discordUser, guild);
|
||||
|
||||
// Embed object
|
||||
const embed = {
|
||||
author: {
|
||||
name: `${discordUser?.username}#${discordUser?.discriminator}`,
|
||||
icon_url: discordUser?.displayAvatarURL(),
|
||||
},
|
||||
{
|
||||
name: `:squeeze_bottle: Level`,
|
||||
value: `${userObj?.level || "Not found"}`,
|
||||
inline: true,
|
||||
color: successColor,
|
||||
fields: [
|
||||
{
|
||||
name: `:dollar: Credits`,
|
||||
value: `${userObj?.credits || "Not found"}`,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: `:squeeze_bottle: Level`,
|
||||
value: `${userObj?.level || "Not found"}`,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: `:squeeze_bottle: Points`,
|
||||
value: `${userObj?.points || "Not found"}`,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: `:loudspeaker: Reputation`,
|
||||
value: `${userObj?.reputation || "Not found"}`,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: `:rainbow_flag: Language`,
|
||||
value: `${userObj?.language || "Not found"}`,
|
||||
inline: true,
|
||||
},
|
||||
],
|
||||
timestamp: new Date(),
|
||||
footer: {
|
||||
iconURL: footerIcon,
|
||||
text: footerText,
|
||||
},
|
||||
{
|
||||
name: `:squeeze_bottle: Points`,
|
||||
value: `${userObj?.points || "Not found"}`,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: `:loudspeaker: Reputation`,
|
||||
value: `${userObj?.reputation || "Not found"}`,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: `:rainbow_flag: Language`,
|
||||
value: `${userObj?.language || "Not found"}`,
|
||||
inline: true,
|
||||
},
|
||||
],
|
||||
timestamp: new Date(),
|
||||
footer: {
|
||||
iconURL: footerIcon,
|
||||
text: footerText,
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
// Return interaction reply
|
||||
return interaction?.editReply({ embeds: [embed] });
|
||||
// Return interaction reply
|
||||
return interaction?.editReply({ embeds: [embed] });
|
||||
},
|
||||
};
|
||||
|
|
|
@ -3,25 +3,25 @@ import { SlashCommandBuilder } from "@discordjs/builders";
|
|||
import { CommandInteraction } from "discord.js";
|
||||
|
||||
// Modules
|
||||
import give from "./modules/give";
|
||||
import modules from "./modules";
|
||||
|
||||
// Handlers
|
||||
import logger from "@logger";
|
||||
|
||||
// Function
|
||||
export default {
|
||||
metadata: { author: "Zyner" },
|
||||
modules,
|
||||
data: new SlashCommandBuilder()
|
||||
.setName("reputation")
|
||||
.setDescription("Manage reputation.")
|
||||
.addSubcommand(give.data),
|
||||
.addSubcommand(modules.give.data),
|
||||
async execute(interaction: CommandInteraction) {
|
||||
const { options } = interaction;
|
||||
|
||||
if (options?.getSubcommand() === "give") {
|
||||
logger?.verbose(`Executing give subcommand`);
|
||||
|
||||
await give.execute(interaction);
|
||||
await modules.give.execute(interaction);
|
||||
}
|
||||
|
||||
logger?.verbose(`No subcommand found`);
|
||||
|
|
|
@ -21,6 +21,8 @@ import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
|
|||
|
||||
// Function
|
||||
export default {
|
||||
meta: { guildOnly: true, ephemeral: true },
|
||||
|
||||
data: (command: SlashCommandSubcommandBuilder) => {
|
||||
return command
|
||||
.setName("give")
|
||||
|
@ -36,8 +38,13 @@ export default {
|
|||
.setName("type")
|
||||
.setDescription("What type of reputation you want to repute")
|
||||
.setRequired(true)
|
||||
.addChoice("Positive", "positive")
|
||||
.addChoice("Negative", "negative")
|
||||
.addChoices(
|
||||
{ name: "Positive", value: "positive" },
|
||||
{
|
||||
name: "Negative",
|
||||
value: "negative",
|
||||
}
|
||||
)
|
||||
);
|
||||
},
|
||||
execute: async (interaction: CommandInteraction) => {
|
||||
|
|
3
src/plugins/reputation/modules/index.ts
Normal file
3
src/plugins/reputation/modules/index.ts
Normal file
|
@ -0,0 +1,3 @@
|
|||
import give from "@plugins/reputation/modules/give";
|
||||
|
||||
export default { give };
|
60
src/plugins/settings/groups/guild/index.ts
Normal file
60
src/plugins/settings/groups/guild/index.ts
Normal file
|
@ -0,0 +1,60 @@
|
|||
// Dependencies
|
||||
import { CommandInteraction } from "discord.js";
|
||||
|
||||
// Handlers
|
||||
import logger from "@logger";
|
||||
|
||||
// Modules
|
||||
import modules from "./modules";
|
||||
|
||||
import { SlashCommandSubcommandGroupBuilder } from "@discordjs/builders";
|
||||
|
||||
// Function
|
||||
export default {
|
||||
modules,
|
||||
|
||||
data: (group: SlashCommandSubcommandGroupBuilder) => {
|
||||
return group
|
||||
.setName("guild")
|
||||
.setDescription("Guild settings.")
|
||||
.addSubcommand(modules.pterodactyl.data)
|
||||
.addSubcommand(modules.credits.data)
|
||||
.addSubcommand(modules.points.data)
|
||||
.addSubcommand(modules.welcome.data)
|
||||
.addSubcommand(modules.audits.data)
|
||||
.addSubcommand(modules.shop.data);
|
||||
},
|
||||
execute: async (interaction: CommandInteraction) => {
|
||||
// Destructure member
|
||||
const { options } = interaction;
|
||||
|
||||
switch (options?.getSubcommand()) {
|
||||
case "pterodactyl":
|
||||
logger?.verbose(`Subcommand is pterodactyl`);
|
||||
|
||||
return modules.pterodactyl.execute(interaction);
|
||||
case "credits":
|
||||
logger?.verbose(`Subcommand is credits`);
|
||||
|
||||
return modules.credits.execute(interaction);
|
||||
case "points":
|
||||
logger?.verbose(`Subcommand is points`);
|
||||
|
||||
return modules.points.execute(interaction);
|
||||
case "welcome":
|
||||
logger?.verbose(`Subcommand is welcome`);
|
||||
|
||||
return modules.welcome.execute(interaction);
|
||||
case "audits":
|
||||
logger?.verbose(`Subcommand is audits`);
|
||||
|
||||
return modules.audits.execute(interaction);
|
||||
case "shop":
|
||||
logger?.verbose(`Subcommand is shop`);
|
||||
|
||||
return modules.shop.execute(interaction);
|
||||
default:
|
||||
logger?.verbose(`Subcommand is not found`);
|
||||
}
|
||||
},
|
||||
};
|
|
@ -1,5 +1,5 @@
|
|||
// Dependencies
|
||||
import { CommandInteraction } from "discord.js";
|
||||
import { CommandInteraction, Permissions } from "discord.js";
|
||||
|
||||
// Configurations
|
||||
import { successColor, footerText, footerIcon } from "@config/embed";
|
||||
|
@ -14,6 +14,12 @@ import { ChannelType } from "discord-api-types/v10";
|
|||
|
||||
// Function
|
||||
export default {
|
||||
meta: {
|
||||
guildOnly: true,
|
||||
ephemeral: true,
|
||||
permissions: [Permissions.FLAGS.MANAGE_GUILD],
|
||||
},
|
||||
|
||||
data: (command: SlashCommandSubcommandBuilder) => {
|
||||
return command
|
||||
.setName("audits")
|
||||
|
@ -25,7 +31,7 @@ export default {
|
|||
option
|
||||
.setName("channel")
|
||||
.setDescription("Channel for audit messages.")
|
||||
.addChannelType(ChannelType.GuildText as number)
|
||||
.addChannelTypes(ChannelType.GuildText)
|
||||
);
|
||||
},
|
||||
execute: async (interaction: CommandInteraction) => {
|
|
@ -1,5 +1,5 @@
|
|||
// Dependencies
|
||||
import { CommandInteraction } from "discord.js";
|
||||
import { CommandInteraction, Permissions } from "discord.js";
|
||||
|
||||
// Configurations
|
||||
import { successColor, footerText, footerIcon } from "@config/embed";
|
||||
|
@ -13,6 +13,12 @@ import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
|
|||
|
||||
// Function
|
||||
export default {
|
||||
meta: {
|
||||
guildOnly: true,
|
||||
ephemeral: true,
|
||||
permissions: [Permissions.FLAGS.MANAGE_GUILD],
|
||||
},
|
||||
|
||||
data: (command: SlashCommandSubcommandBuilder) => {
|
||||
return command
|
||||
.setName("credits")
|
8
src/plugins/settings/groups/guild/modules/index.ts
Normal file
8
src/plugins/settings/groups/guild/modules/index.ts
Normal file
|
@ -0,0 +1,8 @@
|
|||
import audits from "@plugins/settings/groups/guild/modules/audits";
|
||||
import credits from "@plugins/settings/groups/guild/modules/credits";
|
||||
import points from "@plugins/settings/groups/guild/modules/points";
|
||||
import pterodactyl from "@plugins/settings/groups/guild/modules/pterodactyl";
|
||||
import shop from "@plugins/settings/groups/guild/modules/shop";
|
||||
import welcome from "@plugins/settings/groups/guild/modules/welcome";
|
||||
|
||||
export default { audits, credits, points, pterodactyl, shop, welcome };
|
|
@ -1,5 +1,5 @@
|
|||
// Dependencies
|
||||
import { CommandInteraction } from "discord.js";
|
||||
import { CommandInteraction, Permissions } from "discord.js";
|
||||
|
||||
// Configurations
|
||||
import { successColor, footerText, footerIcon } from "@config/embed";
|
||||
|
@ -13,6 +13,12 @@ import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
|
|||
|
||||
// Function
|
||||
export default {
|
||||
meta: {
|
||||
guildOnly: true,
|
||||
ephemeral: true,
|
||||
permissions: [Permissions.FLAGS.MANAGE_GUILD],
|
||||
},
|
||||
|
||||
data: (command: SlashCommandSubcommandBuilder) => {
|
||||
return command
|
||||
.setName("points")
|
|
@ -1,5 +1,5 @@
|
|||
// Dependencies
|
||||
import { CommandInteraction } from "discord.js";
|
||||
import { CommandInteraction, Permissions } from "discord.js";
|
||||
|
||||
// Configurations
|
||||
import { successColor, footerText, footerIcon } from "@config/embed";
|
||||
|
@ -14,6 +14,12 @@ import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
|
|||
|
||||
// Function
|
||||
export default {
|
||||
meta: {
|
||||
guildOnly: true,
|
||||
ephemeral: true,
|
||||
permissions: [Permissions.FLAGS.MANAGE_GUILD],
|
||||
},
|
||||
|
||||
data: (command: SlashCommandSubcommandBuilder) => {
|
||||
return command
|
||||
.setName("pterodactyl")
|
|
@ -1,5 +1,5 @@
|
|||
// Dependencies
|
||||
import { CommandInteraction } from "discord.js";
|
||||
import { CommandInteraction, Permissions } from "discord.js";
|
||||
|
||||
// Configurations
|
||||
import { successColor, footerText, footerIcon } from "@config/embed";
|
||||
|
@ -10,10 +10,15 @@ import logger from "@logger";
|
|||
// Models
|
||||
import guildSchema from "@schemas/guild";
|
||||
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
|
||||
import { ChannelType } from "discord-api-types/v10";
|
||||
|
||||
// Function
|
||||
export default {
|
||||
meta: {
|
||||
guildOnly: true,
|
||||
ephemeral: true,
|
||||
permissions: [Permissions.FLAGS.MANAGE_GUILD],
|
||||
},
|
||||
|
||||
data: (command: SlashCommandSubcommandBuilder) => {
|
||||
return command
|
||||
.setName("shop")
|
|
@ -1,5 +1,5 @@
|
|||
// Dependencies
|
||||
import { CommandInteraction } from "discord.js";
|
||||
import { CommandInteraction, Permissions } from "discord.js";
|
||||
|
||||
// Configurations
|
||||
import { successColor, footerText, footerIcon } from "@config/embed";
|
||||
|
@ -14,6 +14,12 @@ import { ChannelType } from "discord-api-types/v10";
|
|||
|
||||
// Function
|
||||
export default {
|
||||
meta: {
|
||||
guildOnly: true,
|
||||
ephemeral: true,
|
||||
permissions: [Permissions.FLAGS.MANAGE_GUILD],
|
||||
},
|
||||
|
||||
data: (command: SlashCommandSubcommandBuilder) => {
|
||||
return command
|
||||
.setName("welcome")
|
||||
|
@ -25,14 +31,16 @@ export default {
|
|||
option
|
||||
.setName("join-channel")
|
||||
.setDescription("Channel for join messages.")
|
||||
.addChannelType(ChannelType.GuildText as number)
|
||||
.addChannelTypes(ChannelType.GuildText)
|
||||
)
|
||||
|
||||
.addChannelOption((option) =>
|
||||
option
|
||||
.setName("leave-channel")
|
||||
.setDescription("Channel for leave messages.")
|
||||
.addChannelType(ChannelType.GuildText as number)
|
||||
.addChannelTypes(ChannelType.GuildText)
|
||||
)
|
||||
|
||||
.addStringOption((option) =>
|
||||
option
|
||||
.setName("leave-message")
|
3
src/plugins/settings/groups/index.ts
Normal file
3
src/plugins/settings/groups/index.ts
Normal file
|
@ -0,0 +1,3 @@
|
|||
import guild from "@plugins/settings/groups/guild";
|
||||
|
||||
export default { guild };
|
|
@ -1,94 +0,0 @@
|
|||
// Dependencies
|
||||
import { Permissions, CommandInteraction } from "discord.js";
|
||||
|
||||
// Configurations
|
||||
import { errorColor, footerText, footerIcon } from "@config/embed";
|
||||
|
||||
// Handlers
|
||||
import logger from "@logger";
|
||||
|
||||
// Modules
|
||||
import pterodactyl from "./modules/pterodactyl";
|
||||
import credits from "./modules/credits";
|
||||
import points from "./modules/points";
|
||||
import welcome from "./modules/welcome";
|
||||
import audits from "./modules/audits";
|
||||
import shop from "./modules/shop";
|
||||
import { SlashCommandSubcommandGroupBuilder } from "@discordjs/builders";
|
||||
|
||||
// Function
|
||||
export default {
|
||||
data: (group: SlashCommandSubcommandGroupBuilder) => {
|
||||
return group
|
||||
.setName("guild")
|
||||
.setDescription("Guild settings.")
|
||||
.addSubcommand(pterodactyl.data)
|
||||
.addSubcommand(credits.data)
|
||||
.addSubcommand(points.data)
|
||||
.addSubcommand(welcome.data)
|
||||
.addSubcommand(audits.data)
|
||||
.addSubcommand(shop.data);
|
||||
},
|
||||
execute: async (interaction: CommandInteraction) => {
|
||||
// Destructure member
|
||||
const { memberPermissions, options } = interaction;
|
||||
|
||||
// Check permission
|
||||
if (!memberPermissions?.has(Permissions?.FLAGS?.MANAGE_GUILD)) {
|
||||
logger?.verbose(`User does not have permission to execute command.`);
|
||||
|
||||
return interaction?.editReply({
|
||||
embeds: [
|
||||
{
|
||||
title: ":tools: Settings - Guild",
|
||||
color: errorColor,
|
||||
description: "You do not have permission to use this command.",
|
||||
timestamp: new Date(),
|
||||
footer: {
|
||||
iconURL: footerIcon as string,
|
||||
text: footerText as string,
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
if (options?.getSubcommand() === "pterodactyl") {
|
||||
logger?.verbose(`Executing pterodactyl subcommand`);
|
||||
|
||||
return pterodactyl.execute(interaction);
|
||||
}
|
||||
|
||||
if (options?.getSubcommand() === "credits") {
|
||||
logger?.verbose(`Executing credits subcommand`);
|
||||
|
||||
return credits.execute(interaction);
|
||||
}
|
||||
|
||||
if (options?.getSubcommand() === "points") {
|
||||
logger?.verbose(`Executing points subcommand`);
|
||||
|
||||
return points.execute(interaction);
|
||||
}
|
||||
|
||||
if (options?.getSubcommand() === "welcome") {
|
||||
logger?.verbose(`Executing welcome subcommand`);
|
||||
|
||||
return welcome.execute(interaction);
|
||||
}
|
||||
|
||||
if (options?.getSubcommand() === "audits") {
|
||||
logger?.verbose(`Executing audit subcommand`);
|
||||
|
||||
return audits.execute(interaction);
|
||||
}
|
||||
|
||||
if (options?.getSubcommand() === "shop") {
|
||||
logger?.verbose(`Executing shop subcommand`);
|
||||
|
||||
return shop.execute(interaction);
|
||||
}
|
||||
|
||||
logger?.verbose(`No subcommand found`);
|
||||
},
|
||||
};
|
|
@ -3,20 +3,20 @@ import { SlashCommandBuilder } from "@discordjs/builders";
|
|||
import { CommandInteraction } from "discord.js";
|
||||
|
||||
// Groups
|
||||
import guildGroup from "./guild";
|
||||
import userGroup from "./user";
|
||||
import groups from "./groups";
|
||||
|
||||
// Handlers
|
||||
import logger from "@logger";
|
||||
|
||||
// Function
|
||||
export default {
|
||||
metadata: { author: "Zyner" },
|
||||
groups,
|
||||
|
||||
data: new SlashCommandBuilder()
|
||||
.setName("settings")
|
||||
.setDescription("Manage settings.")
|
||||
.addSubcommandGroup(guildGroup.data)
|
||||
.addSubcommandGroup(userGroup.data),
|
||||
|
||||
.addSubcommandGroup(groups.guild.data),
|
||||
|
||||
async execute(interaction: CommandInteraction) {
|
||||
const { options } = interaction;
|
||||
|
@ -24,13 +24,7 @@ export default {
|
|||
if (options.getSubcommandGroup() === "guild") {
|
||||
logger.verbose(`Executing guild subcommand`);
|
||||
|
||||
return guildGroup.execute(interaction);
|
||||
}
|
||||
|
||||
if (options.getSubcommandGroup() === "user") {
|
||||
logger.verbose(`Executing user subcommand`);
|
||||
|
||||
return userGroup.execute(interaction);
|
||||
return groups.guild.execute(interaction);
|
||||
}
|
||||
|
||||
logger.verbose(`No subcommand group found`);
|
||||
|
|
|
@ -1,41 +0,0 @@
|
|||
// Dependencies
|
||||
import { SlashCommandSubcommandGroupBuilder } from "@discordjs/builders";
|
||||
import { CommandInteraction } from "discord.js";
|
||||
|
||||
// Handlers
|
||||
import logger from "@logger";
|
||||
|
||||
// Modules
|
||||
import appearance from "./modules/appearance";
|
||||
|
||||
// Function
|
||||
export default {
|
||||
data: (group: SlashCommandSubcommandGroupBuilder) => {
|
||||
return group
|
||||
.setName("user")
|
||||
.setDescription("User settings.")
|
||||
.addSubcommand((command) =>
|
||||
command
|
||||
.setName("appearance")
|
||||
.setDescription("User appearance settings.")
|
||||
.addStringOption((option) =>
|
||||
option
|
||||
.setName("language")
|
||||
.setDescription("Set the language.")
|
||||
.addChoice("English", "en")
|
||||
.addChoice("Swedish", "sv")
|
||||
)
|
||||
);
|
||||
},
|
||||
execute: async (interaction: CommandInteraction) => {
|
||||
const { options } = interaction;
|
||||
|
||||
if (options?.getSubcommand() === "appearance") {
|
||||
logger?.verbose(`Executing appearance subcommand`);
|
||||
|
||||
await appearance(interaction);
|
||||
}
|
||||
|
||||
logger?.verbose(`No subcommand found`);
|
||||
},
|
||||
};
|
|
@ -1,61 +0,0 @@
|
|||
// Dependencies
|
||||
import { CommandInteraction } from "discord.js";
|
||||
|
||||
// Configurations
|
||||
import { successColor, footerText, footerIcon } from "@config/embed";
|
||||
|
||||
// Handlers
|
||||
import logger from "@logger";
|
||||
|
||||
// Models
|
||||
import fetchUser from "@helpers/fetchUser";
|
||||
|
||||
// Function
|
||||
export default async (interaction: CommandInteraction) => {
|
||||
// Destructure member
|
||||
const { options, user, guild } = interaction;
|
||||
|
||||
// Get options
|
||||
const language = options?.getString("language");
|
||||
|
||||
if (guild === null) {
|
||||
return logger?.verbose(`Guild is null`);
|
||||
}
|
||||
|
||||
// Get user object
|
||||
const userDB = await fetchUser(user, guild);
|
||||
|
||||
if (userDB === null) {
|
||||
return logger?.verbose(`User is null`);
|
||||
}
|
||||
|
||||
// Modify values
|
||||
userDB.language = language !== null ? language : userDB?.language;
|
||||
|
||||
// Save guild
|
||||
await userDB?.save()?.then(async () => {
|
||||
logger?.verbose(`Updated user language.`);
|
||||
|
||||
return interaction?.editReply({
|
||||
embeds: [
|
||||
{
|
||||
title: ":hammer: Settings - User [Appearance]",
|
||||
description: "Successfully updated user settings.",
|
||||
color: successColor,
|
||||
fields: [
|
||||
{
|
||||
name: "🏳️🌈 Language",
|
||||
value: `${userDB?.language}`,
|
||||
inline: true,
|
||||
},
|
||||
],
|
||||
timestamp: new Date(),
|
||||
footer: {
|
||||
iconURL: footerIcon,
|
||||
text: footerText,
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
};
|
3
src/plugins/shop/groups/index.ts
Normal file
3
src/plugins/shop/groups/index.ts
Normal file
|
@ -0,0 +1,3 @@
|
|||
import roles from "./roles";
|
||||
|
||||
export default { roles };
|
|
@ -3,24 +3,25 @@ import { SlashCommandSubcommandGroupBuilder } from "@discordjs/builders";
|
|||
import { CommandInteraction } from "discord.js";
|
||||
|
||||
// Handlers
|
||||
import logger from "../../../logger";
|
||||
import logger from "@logger";
|
||||
|
||||
import { errorColor, footerText, footerIcon } from "@config/embed";
|
||||
|
||||
// Modules
|
||||
import buy from "./modules/buy";
|
||||
import cancel from "./modules/cancel";
|
||||
import modules from "./modules";
|
||||
|
||||
import guildSchema from "@schemas/guild";
|
||||
|
||||
// Function
|
||||
export default {
|
||||
modules,
|
||||
|
||||
data: (group: SlashCommandSubcommandGroupBuilder) => {
|
||||
return group
|
||||
.setName("roles")
|
||||
.setDescription("Shop for custom roles.")
|
||||
.addSubcommand(buy.data)
|
||||
.addSubcommand(cancel.data);
|
||||
.addSubcommand(modules.buy.data)
|
||||
.addSubcommand(modules.cancel.data);
|
||||
},
|
||||
execute: async (interaction: CommandInteraction) => {
|
||||
const { options, guild } = interaction;
|
||||
|
@ -53,13 +54,13 @@ export default {
|
|||
if (options?.getSubcommand() === "buy") {
|
||||
logger.verbose(`Executing buy subcommand`);
|
||||
|
||||
await buy.execute(interaction);
|
||||
await modules.buy.execute(interaction);
|
||||
}
|
||||
|
||||
if (options?.getSubcommand() === "cancel") {
|
||||
logger.verbose(`Executing cancel subcommand`);
|
||||
|
||||
await cancel.execute(interaction);
|
||||
await modules.cancel.execute(interaction);
|
||||
}
|
||||
},
|
||||
};
|
|
@ -25,6 +25,8 @@ import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
|
|||
|
||||
// Function
|
||||
export default {
|
||||
meta: { guildOnly: true, ephemeral: true },
|
||||
|
||||
data: (command: SlashCommandSubcommandBuilder) => {
|
||||
return command
|
||||
.setName("buy")
|
||||
|
@ -33,11 +35,13 @@ export default {
|
|||
option
|
||||
.setName("name")
|
||||
.setDescription("Name of the role you wish to buy.")
|
||||
.setRequired(true)
|
||||
)
|
||||
.addStringOption((option) =>
|
||||
option
|
||||
.setName("color")
|
||||
.setDescription("Color of the role you wish to buy.")
|
||||
.setRequired(true)
|
||||
);
|
||||
},
|
||||
execute: async (interaction: CommandInteraction) => {
|
|
@ -20,12 +20,17 @@ import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
|
|||
|
||||
// Function
|
||||
export default {
|
||||
meta: { guildOnly: true, ephemeral: true },
|
||||
|
||||
data: (command: SlashCommandSubcommandBuilder) => {
|
||||
return command
|
||||
.setName("cancel")
|
||||
.setDescription("Cancel a purchase.")
|
||||
.addRoleOption((option) =>
|
||||
option.setName("role").setDescription("Role you wish to cancel.")
|
||||
option
|
||||
.setName("role")
|
||||
.setDescription("Role you wish to cancel.")
|
||||
.setRequired(true)
|
||||
);
|
||||
},
|
||||
execute: async (interaction: CommandInteraction) => {
|
7
src/plugins/shop/groups/roles/modules/index.ts
Normal file
7
src/plugins/shop/groups/roles/modules/index.ts
Normal file
|
@ -0,0 +1,7 @@
|
|||
import buy from "./buy";
|
||||
import cancel from "./cancel";
|
||||
|
||||
export default {
|
||||
buy,
|
||||
cancel,
|
||||
};
|
|
@ -3,35 +3,37 @@ import { SlashCommandBuilder } from "@discordjs/builders";
|
|||
import { CommandInteraction } from "discord.js";
|
||||
|
||||
// Modules
|
||||
import pterodactyl from "./modules/pterodactyl";
|
||||
import modules from "./modules";
|
||||
|
||||
// Groups
|
||||
import roles from "./roles";
|
||||
import groups from "./groups";
|
||||
|
||||
// Handlers
|
||||
import logger from "../../logger";
|
||||
|
||||
// Function
|
||||
export default {
|
||||
metadata: { author: "Zyner" },
|
||||
modules,
|
||||
groups,
|
||||
|
||||
data: new SlashCommandBuilder()
|
||||
.setName("shop")
|
||||
.setDescription("Shop for credits and custom roles.")
|
||||
.addSubcommand(pterodactyl.data)
|
||||
.addSubcommandGroup(roles.data),
|
||||
.addSubcommand(modules.pterodactyl.data)
|
||||
.addSubcommandGroup(groups.roles.data),
|
||||
async execute(interaction: CommandInteraction) {
|
||||
const { options } = interaction;
|
||||
|
||||
if (options?.getSubcommand() === "pterodactyl") {
|
||||
logger.verbose(`Executing pterodactyl subcommand`);
|
||||
|
||||
return pterodactyl.execute(interaction);
|
||||
return modules.pterodactyl.execute(interaction);
|
||||
}
|
||||
|
||||
if (options?.getSubcommandGroup() === "roles") {
|
||||
logger?.verbose(`Subcommand group is roles`);
|
||||
|
||||
return roles.execute(interaction);
|
||||
return groups.roles.execute(interaction);
|
||||
}
|
||||
|
||||
logger?.verbose(`No subcommand found.`);
|
||||
|
|
3
src/plugins/shop/modules/index.ts
Normal file
3
src/plugins/shop/modules/index.ts
Normal file
|
@ -0,0 +1,3 @@
|
|||
import pterodactyl from "@plugins/shop/modules/pterodactyl";
|
||||
|
||||
export default { pterodactyl };
|
|
@ -1,9 +1,7 @@
|
|||
// Dependencies
|
||||
import { CommandInteraction } from "discord.js";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import axios from "axios";
|
||||
|
||||
// Configurations
|
||||
import {
|
||||
successColor,
|
||||
errorColor,
|
||||
|
@ -11,20 +9,18 @@ import {
|
|||
footerIcon,
|
||||
} from "@config/embed";
|
||||
|
||||
// Handlers
|
||||
import logger from "@logger";
|
||||
import encryption from "@handlers/encryption";
|
||||
|
||||
// Helpers
|
||||
import pluralize from "@helpers/pluralize";
|
||||
|
||||
// Models
|
||||
import apiSchema from "@schemas/api";
|
||||
import fetchUser from "@helpers/fetchUser";
|
||||
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
|
||||
|
||||
// Function
|
||||
export default {
|
||||
meta: { guildOnly: true, ephemeral: true },
|
||||
|
||||
data: (command: SlashCommandSubcommandBuilder) => {
|
||||
return command
|
||||
.setName("pterodactyl")
|
||||
|
@ -38,10 +34,8 @@ export default {
|
|||
execute: async (interaction: CommandInteraction) => {
|
||||
const { options, guild, user, client } = interaction;
|
||||
|
||||
// Get options
|
||||
const optionAmount = options?.getInteger("amount");
|
||||
|
||||
// If amount is null
|
||||
if (optionAmount === null) {
|
||||
logger?.verbose(`Amount is null.`);
|
||||
|
||||
|
@ -65,17 +59,14 @@ export default {
|
|||
return logger?.verbose(`Guild is null`);
|
||||
}
|
||||
|
||||
// Get user object
|
||||
const userDB = await fetchUser(user, guild);
|
||||
|
||||
if (userDB === null) {
|
||||
return logger?.verbose(`User is null`);
|
||||
}
|
||||
|
||||
// Get DM user object
|
||||
const dmUser = client?.users?.cache?.get(user?.id);
|
||||
|
||||
// Stop if amount or user credits is below 100
|
||||
if ((optionAmount || userDB?.credits) < 100) {
|
||||
logger?.verbose(`Amount or user credits is below 100.`);
|
||||
|
||||
|
@ -101,7 +92,6 @@ export default {
|
|||
});
|
||||
}
|
||||
|
||||
// Stop if amount or user credits is above 1.000.000
|
||||
if ((optionAmount || userDB?.credits) > 1000000) {
|
||||
logger?.verbose(`Amount or user credits is above 1.000.000.`);
|
||||
|
||||
|
@ -128,7 +118,6 @@ export default {
|
|||
});
|
||||
}
|
||||
|
||||
// Stop if user credits is below amount
|
||||
if (userDB?.credits < optionAmount) {
|
||||
logger?.verbose(`User credits is below amount.`);
|
||||
|
||||
|
@ -154,15 +143,12 @@ export default {
|
|||
});
|
||||
}
|
||||
|
||||
// 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: {
|
||||
|
@ -170,13 +156,10 @@ export default {
|
|||
},
|
||||
});
|
||||
|
||||
// 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,
|
||||
|
@ -184,17 +167,14 @@ export default {
|
|||
memo: `${interaction?.createdTimestamp} - ${interaction?.user?.id}`,
|
||||
})
|
||||
|
||||
// If successful
|
||||
?.then(async () => {
|
||||
logger?.verbose(`Successfully created voucher.`);
|
||||
|
||||
// Withdraw amount from user credits
|
||||
userDB.credits -= optionAmount || userDB?.credits;
|
||||
|
||||
// Save new credits
|
||||
await userDB
|
||||
?.save()
|
||||
// If successful
|
||||
|
||||
?.then(async () => {
|
||||
logger?.verbose(`Successfully saved new credits.`);
|
||||
|
||||
|
@ -237,7 +217,6 @@ export default {
|
|||
});
|
||||
})
|
||||
|
||||
// If error occurs
|
||||
.catch(async (error) => {
|
||||
logger?.verbose(`Error saving new credits. - ${error}`);
|
||||
|
||||
|
@ -258,7 +237,6 @@ export default {
|
|||
});
|
||||
})
|
||||
|
||||
// If error occurs
|
||||
.catch(async (error: any) => {
|
||||
logger?.verbose(`Error creating voucher. - ${error}`);
|
||||
|
||||
|
|
|
@ -1,45 +0,0 @@
|
|||
// Dependencies
|
||||
import { SlashCommandBuilder } from "@discordjs/builders";
|
||||
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 "../../logger";
|
||||
|
||||
// Function
|
||||
export default {
|
||||
metadata: { author: "Zyner" },
|
||||
data: new SlashCommandBuilder()
|
||||
.setName("utilities")
|
||||
.setDescription("Common utilities.")
|
||||
.addSubcommand(lookup.data)
|
||||
.addSubcommand(about.data)
|
||||
.addSubcommand(stats.data),
|
||||
async execute(interaction: CommandInteraction) {
|
||||
const { options } = interaction;
|
||||
|
||||
if (options?.getSubcommand() === "lookup") {
|
||||
logger.verbose(`Executing lookup subcommand`);
|
||||
|
||||
return lookup.execute(interaction);
|
||||
}
|
||||
|
||||
if (options?.getSubcommand() === "about") {
|
||||
logger.verbose(`Executing about subcommand`);
|
||||
|
||||
return about.execute(interaction);
|
||||
}
|
||||
|
||||
if (options?.getSubcommand() === "stats") {
|
||||
logger.verbose(`Executing stats subcommand`);
|
||||
|
||||
return stats.execute(interaction);
|
||||
}
|
||||
|
||||
logger.verbose(`No subcommand found.`);
|
||||
},
|
||||
};
|
|
@ -1,134 +0,0 @@
|
|||
// Dependencies
|
||||
import axios from "axios";
|
||||
import { CommandInteraction } from "discord.js";
|
||||
|
||||
// Configurations
|
||||
import {
|
||||
successColor,
|
||||
errorColor,
|
||||
footerText,
|
||||
footerIcon,
|
||||
} from "@config/embed";
|
||||
|
||||
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
|
||||
|
||||
// Handlers
|
||||
import logger from "@logger";
|
||||
|
||||
// Function
|
||||
export default {
|
||||
data: (command: SlashCommandSubcommandBuilder) => {
|
||||
return command
|
||||
.setName("lookup")
|
||||
.setDescription(
|
||||
"Lookup a domain or ip. (Request sent over HTTP, proceed with caution!)"
|
||||
)
|
||||
.addStringOption((option) =>
|
||||
option
|
||||
.setName("query")
|
||||
.setDescription("The query you want to look up.")
|
||||
.setRequired(true)
|
||||
);
|
||||
},
|
||||
execute: async (interaction: CommandInteraction) => {
|
||||
const { options } = interaction;
|
||||
// Get lookup query
|
||||
const query = options?.getString("query");
|
||||
|
||||
// Make API request
|
||||
await axios
|
||||
// Make a get request
|
||||
?.get(`http://ip-api.com/json/${query}`)
|
||||
|
||||
// If successful
|
||||
?.then(async (res) => {
|
||||
// If query failed
|
||||
if (res?.data?.status === "fail") {
|
||||
// Create embed object
|
||||
const embed = {
|
||||
title: ":hammer: Utilities - Lookup",
|
||||
description: `${res?.data?.message}: ${res?.data?.query}`,
|
||||
color: errorColor,
|
||||
timestamp: new Date(),
|
||||
footer: {
|
||||
iconURL: footerIcon,
|
||||
text: footerText,
|
||||
},
|
||||
};
|
||||
|
||||
// Send interaction reply
|
||||
await interaction?.editReply({ embeds: [embed] });
|
||||
}
|
||||
|
||||
// If query is successful
|
||||
else if (res?.data?.status === "success") {
|
||||
// Create embed object
|
||||
const embed = {
|
||||
title: ":hammer: Utilities - Lookup",
|
||||
fields: [
|
||||
{
|
||||
name: "AS",
|
||||
value: `${res?.data?.as || "Not available"}`,
|
||||
},
|
||||
{
|
||||
name: "Country",
|
||||
value: `${res?.data?.country || "Not available"}`,
|
||||
},
|
||||
{
|
||||
name: "Country Code",
|
||||
value: `${res?.data?.countryCode || "Not available"}`,
|
||||
},
|
||||
{
|
||||
name: "Region",
|
||||
value: `${res?.data?.region || "Not available"}`,
|
||||
},
|
||||
{
|
||||
name: "Region Name",
|
||||
value: `${res?.data?.regionName || "Not available"}`,
|
||||
},
|
||||
{
|
||||
name: "City",
|
||||
value: `${res?.data?.city || "Not available"}`,
|
||||
},
|
||||
{
|
||||
name: "ZIP Code",
|
||||
value: `${res?.data?.zip || "Not available"}`,
|
||||
},
|
||||
{
|
||||
name: "Latitude",
|
||||
value: `${res?.data?.lat || "Not available"}`,
|
||||
},
|
||||
{
|
||||
name: "Longitude",
|
||||
value: `${res?.data?.lon || "Not available"}`,
|
||||
},
|
||||
{
|
||||
name: "Timezone",
|
||||
value: `${res?.data?.timezone || "Not available"}`,
|
||||
},
|
||||
{
|
||||
name: "ISP",
|
||||
value: `${res?.data?.isp || "Not available"}`,
|
||||
},
|
||||
{
|
||||
name: "Organization",
|
||||
value: `${res?.data?.org || "Not available"}`,
|
||||
},
|
||||
],
|
||||
color: successColor,
|
||||
timestamp: new Date(),
|
||||
footer: {
|
||||
iconURL: footerIcon,
|
||||
text: footerText,
|
||||
},
|
||||
};
|
||||
|
||||
// Send interaction reply
|
||||
await interaction?.editReply({ embeds: [embed] });
|
||||
}
|
||||
})
|
||||
.catch(async (e) => {
|
||||
logger?.error(e);
|
||||
});
|
||||
},
|
||||
};
|
40
src/plugins/utility/index.ts
Normal file
40
src/plugins/utility/index.ts
Normal file
|
@ -0,0 +1,40 @@
|
|||
// Dependencies
|
||||
import { SlashCommandBuilder } from "@discordjs/builders";
|
||||
import { CommandInteraction } from "discord.js";
|
||||
|
||||
// Modules
|
||||
import modules from "@plugins/utility/modules";
|
||||
|
||||
// Handlers
|
||||
import logger from "../../logger";
|
||||
|
||||
// Function
|
||||
export default {
|
||||
modules,
|
||||
|
||||
data: new SlashCommandBuilder()
|
||||
.setName("utility")
|
||||
.setDescription("Common utility.")
|
||||
|
||||
.addSubcommand(modules.lookup.data)
|
||||
.addSubcommand(modules.about.data)
|
||||
.addSubcommand(modules.stats.data)
|
||||
.addSubcommand(modules.avatar.data),
|
||||
|
||||
async execute(interaction: CommandInteraction) {
|
||||
const { options } = interaction;
|
||||
|
||||
switch (options.getSubcommand()) {
|
||||
case "lookup":
|
||||
return modules.lookup.execute(interaction);
|
||||
case "about":
|
||||
return modules.about.execute(interaction);
|
||||
case "stats":
|
||||
return modules.stats.execute(interaction);
|
||||
case "avatar":
|
||||
return modules.avatar.execute(interaction);
|
||||
default:
|
||||
logger.error(`Unknown subcommand ${options.getSubcommand()}`);
|
||||
}
|
||||
},
|
||||
};
|
|
@ -9,6 +9,8 @@ import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
|
|||
|
||||
// Function
|
||||
export default {
|
||||
meta: { guildOnly: false, ephemeral: false },
|
||||
|
||||
data: (command: SlashCommandSubcommandBuilder) => {
|
||||
return command.setName("about").setDescription("About this bot!)");
|
||||
},
|
52
src/plugins/utility/modules/avatar.ts
Normal file
52
src/plugins/utility/modules/avatar.ts
Normal file
|
@ -0,0 +1,52 @@
|
|||
import { successColor, footerText, footerIcon } from "@config/embed";
|
||||
|
||||
import i18next from "i18next";
|
||||
import { CommandInteraction, MessageEmbed } from "discord.js";
|
||||
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
|
||||
|
||||
export default {
|
||||
meta: { guildOnly: false, ephemeral: false },
|
||||
|
||||
data: (command: SlashCommandSubcommandBuilder) => {
|
||||
return command
|
||||
.setName("avatar")
|
||||
.setDescription("Check someones avatar!)")
|
||||
.addUserOption((option) =>
|
||||
option
|
||||
.setName("user")
|
||||
.setDescription("The user whose avatar you want to check")
|
||||
);
|
||||
},
|
||||
execute: async (interaction: CommandInteraction) => {
|
||||
const { locale } = interaction;
|
||||
|
||||
const userOption = interaction.options.getUser("user");
|
||||
|
||||
const targetUser = userOption || interaction.user;
|
||||
|
||||
const embed = new MessageEmbed()
|
||||
.setTitle(
|
||||
i18next.t("utility:modules:avatar:general:title", {
|
||||
lng: locale,
|
||||
ns: "plugins",
|
||||
})
|
||||
)
|
||||
.setTimestamp(new Date())
|
||||
.setFooter({ text: footerText, iconURL: footerIcon });
|
||||
|
||||
return interaction.editReply({
|
||||
embeds: [
|
||||
embed
|
||||
.setDescription(
|
||||
i18next.t("utility:modules:avatar:success01:description", {
|
||||
lng: locale,
|
||||
ns: "plugins",
|
||||
user: targetUser,
|
||||
})
|
||||
)
|
||||
.setThumbnail(targetUser.displayAvatarURL())
|
||||
.setColor(successColor),
|
||||
],
|
||||
});
|
||||
},
|
||||
};
|
11
src/plugins/utility/modules/index.ts
Normal file
11
src/plugins/utility/modules/index.ts
Normal file
|
@ -0,0 +1,11 @@
|
|||
import avatar from "@plugins/utility/modules/avatar";
|
||||
import about from "@plugins/utility/modules/about";
|
||||
import lookup from "@plugins/utility/modules/lookup";
|
||||
import stats from "@plugins/utility/modules/stats";
|
||||
|
||||
export default {
|
||||
avatar,
|
||||
about,
|
||||
lookup,
|
||||
stats,
|
||||
};
|
124
src/plugins/utility/modules/lookup.ts
Normal file
124
src/plugins/utility/modules/lookup.ts
Normal file
|
@ -0,0 +1,124 @@
|
|||
import axios from "axios";
|
||||
import { CommandInteraction, MessageEmbed } from "discord.js";
|
||||
|
||||
import {
|
||||
successColor,
|
||||
errorColor,
|
||||
footerText,
|
||||
footerIcon,
|
||||
} from "@config/embed";
|
||||
|
||||
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
|
||||
|
||||
import logger from "@logger";
|
||||
import embedBuilder from "@root/helpers/embedBuilder";
|
||||
|
||||
export default {
|
||||
meta: { guildOnly: false, ephemeral: false },
|
||||
|
||||
data: (command: SlashCommandSubcommandBuilder) => {
|
||||
return command
|
||||
.setName("lookup")
|
||||
.setDescription(
|
||||
"Lookup a domain or ip. (Request sent over HTTP, proceed with caution!)"
|
||||
)
|
||||
.addStringOption((option) =>
|
||||
option
|
||||
.setName("query")
|
||||
.setDescription("The query you want to look up.")
|
||||
.setRequired(true)
|
||||
);
|
||||
},
|
||||
execute: async (interaction: CommandInteraction) => {
|
||||
const embedTitle = "[:hammer:] Utility (Lookup)";
|
||||
|
||||
embedBuilder.setTitle(embedTitle);
|
||||
|
||||
const { options } = interaction;
|
||||
const query = options.getString("query");
|
||||
|
||||
await axios
|
||||
.get(`http://ip-api.com/json/${query}`)
|
||||
.then(async (response) => {
|
||||
if (response.data.status !== "success") {
|
||||
await interaction.editReply({
|
||||
embeds: [
|
||||
embedBuilder
|
||||
.setColor(errorColor)
|
||||
.setDescription(
|
||||
`${response?.data?.message}: ${response?.data?.query}`
|
||||
),
|
||||
],
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
await interaction.editReply({
|
||||
embeds: [
|
||||
embedBuilder.setColor(successColor).setFields([
|
||||
{
|
||||
name: ":classical_building: AS",
|
||||
value: `${response.data.as || "Unknown"}`,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: ":classical_building: ISP",
|
||||
value: `${response.data.isp || "Unknown"}`,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: ":classical_building: Organization",
|
||||
value: `${response.data.org || "Unknown"}`,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: ":compass: Latitude",
|
||||
value: `${response.data.lat || "Unknown"}`,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: ":compass: Longitude",
|
||||
value: `${response.data.lon || "Unknown"}`,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: ":clock4: Timezone",
|
||||
value: `${response.data.timezone || "Unknown"}`,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: ":globe_with_meridians: Country",
|
||||
value: `${response.data.country || "Unknown"}`,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: ":globe_with_meridians: Region",
|
||||
value: `${response.data.regionName || "Unknown"}`,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: ":globe_with_meridians: City",
|
||||
value: `${response.data.city || "Unknown"}`,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: ":globe_with_meridians: Country Code",
|
||||
value: `${response.data.countryCode || "Unknown"}`,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: ":globe_with_meridians: Region Code",
|
||||
value: `${response.data.region || "Unknown"}`,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: ":globe_with_meridians: ZIP",
|
||||
value: `${response.data.zip || "Unknown"}`,
|
||||
inline: true,
|
||||
},
|
||||
]),
|
||||
],
|
||||
});
|
||||
});
|
||||
},
|
||||
};
|
|
@ -2,6 +2,8 @@ import { successColor, footerText, footerIcon } from "@config/embed";
|
|||
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
|
||||
import { CommandInteraction } from "discord.js";
|
||||
export default {
|
||||
meta: { guildOnly: false, ephemeral: false },
|
||||
|
||||
data: (command: SlashCommandSubcommandBuilder) => {
|
||||
return command.setName("stats").setDescription("Check bot statistics!)");
|
||||
},
|
|
@ -55,13 +55,25 @@ export default async (client: Client) => {
|
|||
|
||||
const rRole = rMember.roles.cache.get(roleId);
|
||||
|
||||
if (!rRole) {
|
||||
logger.error(`Role ${roleId} not found for shop role ${roleId}.`);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!rMember) {
|
||||
if (!rMember || !rRole) {
|
||||
logger.error(`Member ${userId} not found for shop role ${roleId}.`);
|
||||
await shopRoleSchema
|
||||
.deleteOne({
|
||||
userId,
|
||||
roleId,
|
||||
guildId,
|
||||
})
|
||||
.then(async () => {
|
||||
logger.verbose(
|
||||
`Shop role document ${roleId} has been deleted from user ${userId}.`
|
||||
);
|
||||
})
|
||||
.catch(async (error) => {
|
||||
logger.error(
|
||||
`Error deleting shop role document ${roleId} from user ${userId}.`,
|
||||
error
|
||||
);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -79,23 +91,6 @@ export default async (client: Client) => {
|
|||
|
||||
if (!rMember) {
|
||||
logger.error(`Member ${userId} not found for shop role ${roleId}.`);
|
||||
await shopRoleSchema
|
||||
.deleteOne({
|
||||
userId,
|
||||
roleId,
|
||||
guildId,
|
||||
})
|
||||
.then(async () => {
|
||||
logger.verbose(
|
||||
`Shop role document ${roleId} has been deleted from user ${userId}.`
|
||||
);
|
||||
})
|
||||
.catch(async (error) => {
|
||||
logger.error(
|
||||
`Error deleting shop role document ${roleId} from user ${userId}.`,
|
||||
error
|
||||
);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
"moduleResolution": "node",
|
||||
"isolatedModules": true,
|
||||
"outDir": "./build",
|
||||
"resolveJsonModule": true,
|
||||
"baseUrl": "./src",
|
||||
"typeRoots": ["/types/common", "./node_modules/@types"],
|
||||
"paths": {
|
||||
|
|
Loading…
Add table
Reference in a new issue