Merge pull request #347 from VermiumSifell/dev
New Features and Breaking Changes
This commit is contained in:
commit
9793cc294c
128 changed files with 1160 additions and 1837 deletions
|
@ -1,5 +1,6 @@
|
|||
# Custom Dictionary Words
|
||||
Controlpanel
|
||||
cooldown
|
||||
cpgg
|
||||
dagen
|
||||
discordjs
|
||||
|
|
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -5,9 +5,7 @@ config.json
|
|||
package-lock.json
|
||||
|
||||
|
||||
**/config/*.ts
|
||||
!**/config/index.ts
|
||||
!**/config/example.*.ts
|
||||
config/
|
||||
|
||||
# Build
|
||||
build/
|
||||
|
|
|
@ -1,43 +0,0 @@
|
|||
// Dependencies
|
||||
import { SlashCommandBuilder } from "@discordjs/builders";
|
||||
import { CommandInteraction } from "discord.js";
|
||||
|
||||
// Modules
|
||||
import modules from "./modules";
|
||||
|
||||
// Handlers
|
||||
import logger from "../../logger";
|
||||
|
||||
export const builder = new SlashCommandBuilder()
|
||||
.setName("config")
|
||||
.setDescription("Manage guild configurations.")
|
||||
|
||||
.addSubcommand(modules.pterodactyl.builder)
|
||||
.addSubcommand(modules.credits.builder)
|
||||
.addSubcommand(modules.points.builder)
|
||||
.addSubcommand(modules.welcome.builder)
|
||||
.addSubcommand(modules.audits.builder)
|
||||
.addSubcommand(modules.shop.builder)
|
||||
.addSubcommand(modules.embeds.builder);
|
||||
|
||||
export const moduleData = modules;
|
||||
|
||||
// Function
|
||||
export const execute = async (interaction: CommandInteraction) => {
|
||||
switch (interaction.options?.getSubcommand()) {
|
||||
case "pterodactyl":
|
||||
return modules.pterodactyl.execute(interaction);
|
||||
case "credits":
|
||||
return modules.credits.execute(interaction);
|
||||
case "points":
|
||||
return modules.points.execute(interaction);
|
||||
case "welcome":
|
||||
return modules.welcome.execute(interaction);
|
||||
case "audits":
|
||||
return modules.audits.execute(interaction);
|
||||
case "shop":
|
||||
return modules.shop.execute(interaction);
|
||||
case "embeds":
|
||||
return modules.embeds.execute(interaction);
|
||||
}
|
||||
};
|
|
@ -1,95 +0,0 @@
|
|||
// Dependencies
|
||||
import { CommandInteraction, Permissions } from "discord.js";
|
||||
|
||||
// Configurations
|
||||
import getEmbedConfig from "../../../../helpers/getEmbedConfig";
|
||||
|
||||
// Handlers
|
||||
import logger from "../../../../logger";
|
||||
|
||||
// Models
|
||||
import guildSchema from "../../../../database/schemas/guild";
|
||||
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
|
||||
import { ChannelType } from "discord-api-types/v10";
|
||||
|
||||
// Function
|
||||
export default {
|
||||
metadata: {
|
||||
guildOnly: true,
|
||||
ephemeral: true,
|
||||
permissions: [Permissions.FLAGS.MANAGE_GUILD],
|
||||
},
|
||||
|
||||
builder: (command: SlashCommandSubcommandBuilder) => {
|
||||
return command
|
||||
.setName("audits")
|
||||
.setDescription("Audits")
|
||||
.addBooleanOption((option) =>
|
||||
option.setName("status").setDescription("Should audits be enabled?")
|
||||
)
|
||||
.addChannelOption((option) =>
|
||||
option
|
||||
.setName("channel")
|
||||
.setDescription("Channel for audit messages.")
|
||||
.addChannelTypes(ChannelType.GuildText)
|
||||
);
|
||||
},
|
||||
execute: async (interaction: CommandInteraction) => {
|
||||
if (interaction.guild == null) return;
|
||||
const { successColor, footerText, footerIcon } = await getEmbedConfig(
|
||||
interaction.guild
|
||||
);
|
||||
|
||||
const { guild, options } = interaction;
|
||||
|
||||
// Get options
|
||||
const status = options?.getBoolean("status");
|
||||
const channel = options?.getChannel("channel");
|
||||
|
||||
// Get guild object
|
||||
const guildDB = await guildSchema?.findOne({
|
||||
guildId: guild?.id,
|
||||
});
|
||||
|
||||
if (guildDB === null) {
|
||||
return logger?.silly(`Guild not found in database.`);
|
||||
}
|
||||
|
||||
// Modify values
|
||||
guildDB.audits.status = status !== null ? status : guildDB?.audits?.status;
|
||||
guildDB.audits.channelId =
|
||||
channel !== null ? channel.id : guildDB?.audits?.channelId;
|
||||
|
||||
// Save guild
|
||||
await guildDB?.save()?.then(async () => {
|
||||
logger?.silly(`Guild audits updated.`);
|
||||
|
||||
return interaction?.editReply({
|
||||
embeds: [
|
||||
{
|
||||
title: ":hammer: Settings - Guild [Audits]",
|
||||
description: `Audits settings updated.`,
|
||||
color: successColor,
|
||||
fields: [
|
||||
{
|
||||
name: "🤖 Status",
|
||||
value: `${guildDB?.audits?.status}`,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: "🌊 Channel",
|
||||
value: `${guildDB?.audits?.channelId}`,
|
||||
inline: true,
|
||||
},
|
||||
],
|
||||
timestamp: new Date(),
|
||||
footer: {
|
||||
iconURL: footerIcon,
|
||||
text: footerText,
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
},
|
||||
};
|
|
@ -1,144 +0,0 @@
|
|||
// Dependencies
|
||||
import { CommandInteraction, Permissions } from "discord.js";
|
||||
|
||||
// Configurations
|
||||
import getEmbedConfig from "../../../../helpers/getEmbedConfig";
|
||||
|
||||
//Handlers
|
||||
import logger from "../../../../logger";
|
||||
|
||||
// Models
|
||||
import guildSchema from "../../../../database/schemas/guild";
|
||||
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
|
||||
|
||||
// Function
|
||||
export default {
|
||||
metadata: {
|
||||
guildOnly: true,
|
||||
ephemeral: true,
|
||||
permissions: [Permissions.FLAGS.MANAGE_GUILD],
|
||||
},
|
||||
|
||||
builder: (command: SlashCommandSubcommandBuilder) => {
|
||||
return command
|
||||
.setName("credits")
|
||||
.setDescription(`Credits`)
|
||||
.addBooleanOption((option) =>
|
||||
option.setName("status").setDescription("Should credits be enabled?")
|
||||
)
|
||||
.addNumberOption((option) =>
|
||||
option.setName("rate").setDescription("Amount of credits per message.")
|
||||
)
|
||||
.addNumberOption((option) =>
|
||||
option
|
||||
.setName("minimum-length")
|
||||
.setDescription("Minimum length of message to earn credits.")
|
||||
)
|
||||
.addNumberOption((option) =>
|
||||
option
|
||||
.setName("work-rate")
|
||||
.setDescription("Maximum amount of credits on work.")
|
||||
)
|
||||
.addNumberOption((option) =>
|
||||
option
|
||||
.setName("work-timeout")
|
||||
.setDescription("Timeout between work schedules (seconds).")
|
||||
)
|
||||
.addNumberOption((option) =>
|
||||
option
|
||||
.setName("timeout")
|
||||
.setDescription("Timeout between earning credits (seconds).")
|
||||
);
|
||||
},
|
||||
execute: async (interaction: CommandInteraction) => {
|
||||
if (interaction.guild == null) return;
|
||||
const { successColor, footerText, footerIcon } = await getEmbedConfig(
|
||||
interaction.guild
|
||||
); // Destructure member
|
||||
const { guild, options } = interaction;
|
||||
|
||||
if (guild == null) return;
|
||||
|
||||
// Get options
|
||||
const status = options?.getBoolean("status");
|
||||
const rate = options?.getNumber("rate");
|
||||
const timeout = options?.getNumber("timeout");
|
||||
const minimumLength = options?.getNumber("minimum-length");
|
||||
const workRate = options?.getNumber("work-rate");
|
||||
const workTimeout = options?.getNumber("work-timeout");
|
||||
|
||||
// Get guild object
|
||||
const guildDB = await guildSchema?.findOne({
|
||||
guildId: guild?.id,
|
||||
});
|
||||
|
||||
if (guildDB === null) {
|
||||
return logger?.silly(`Guild is null`);
|
||||
}
|
||||
|
||||
// Modify values
|
||||
guildDB.credits.status =
|
||||
status !== null ? status : guildDB?.credits?.status;
|
||||
guildDB.credits.rate = rate !== null ? rate : guildDB?.credits?.rate;
|
||||
guildDB.credits.timeout =
|
||||
timeout !== null ? timeout : guildDB?.credits?.timeout;
|
||||
guildDB.credits.workRate =
|
||||
workRate !== null ? workRate : guildDB?.credits?.workRate;
|
||||
guildDB.credits.workTimeout =
|
||||
workTimeout !== null ? workTimeout : guildDB?.credits?.workTimeout;
|
||||
guildDB.credits.minimumLength =
|
||||
minimumLength !== null ? minimumLength : guildDB?.credits?.minimumLength;
|
||||
|
||||
// Save guild
|
||||
await guildDB?.save()?.then(async () => {
|
||||
logger?.silly(`Guild saved`);
|
||||
|
||||
return interaction?.editReply({
|
||||
embeds: [
|
||||
{
|
||||
title: ":tools: Settings - Guild [Credits]",
|
||||
description: `Credits settings updated.`,
|
||||
color: successColor,
|
||||
fields: [
|
||||
{
|
||||
name: "🤖 Status",
|
||||
value: `${guildDB?.credits?.status}`,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: "📈 Rate",
|
||||
value: `${guildDB?.credits?.rate}`,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: "📈 Work Rate",
|
||||
value: `${guildDB?.credits?.workRate}`,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: "🔨 Minimum Length",
|
||||
value: `${guildDB?.credits?.minimumLength}`,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: "⏰ Timeout",
|
||||
value: `${guildDB?.credits?.timeout}`,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: "⏰ Work Timeout",
|
||||
value: `${guildDB?.credits?.workTimeout}`,
|
||||
inline: true,
|
||||
},
|
||||
],
|
||||
timestamp: new Date(),
|
||||
footer: {
|
||||
iconURL: footerIcon,
|
||||
text: footerText,
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
},
|
||||
};
|
|
@ -1,38 +0,0 @@
|
|||
import { ColorResolvable, CommandInteraction } from "discord.js";
|
||||
import guildSchema from "../../../../../../database/schemas/guild";
|
||||
import getEmbedConfig from "../../../../../../helpers/getEmbedConfig";
|
||||
|
||||
export default async (interaction: CommandInteraction) => {
|
||||
const { options, guild } = interaction;
|
||||
|
||||
if (!guild) throw new Error("Guild not found");
|
||||
|
||||
const embedConfig = await getEmbedConfig(guild);
|
||||
if (!embedConfig) throw new Error("Embed config not found");
|
||||
|
||||
// Get new values
|
||||
const newSuccessColor = options.getString("success-color") as ColorResolvable;
|
||||
const newWaitColor = options.getString("wait-color") as ColorResolvable;
|
||||
const newErrorColor = options.getString("error-color") as ColorResolvable;
|
||||
const newFooterIcon = options.getString("footer-icon");
|
||||
const newFooterText = options.getString("footer-text");
|
||||
|
||||
// Get guild values
|
||||
const guildData = await guildSchema.findOne({
|
||||
guildId: guild.id,
|
||||
});
|
||||
if (!guildData) throw new Error("Guild data not found");
|
||||
if (!guildData?.embeds)
|
||||
throw new Error("Guild embed configuration not found");
|
||||
let { successColor, waitColor, errorColor, footerText, footerIcon } =
|
||||
guildData.embeds;
|
||||
|
||||
// Set new values
|
||||
successColor = newSuccessColor || successColor;
|
||||
waitColor = newWaitColor || waitColor;
|
||||
errorColor = newErrorColor || errorColor;
|
||||
footerIcon = newFooterIcon || footerIcon;
|
||||
footerText = newFooterText || footerText;
|
||||
|
||||
return { successColor, waitColor, errorColor, footerText, footerIcon };
|
||||
};
|
|
@ -1,104 +0,0 @@
|
|||
// Dependencies
|
||||
import {
|
||||
ColorResolvable,
|
||||
CommandInteraction,
|
||||
MessageEmbed,
|
||||
Permissions,
|
||||
} from "discord.js";
|
||||
|
||||
//Handlers
|
||||
import logger from "../../../../logger";
|
||||
|
||||
// Models
|
||||
import guildSchema from "../../../../database/schemas/guild";
|
||||
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
|
||||
import getEmbedConfig from "../../../../helpers/getEmbedConfig";
|
||||
import getValues from "./components/getValues";
|
||||
|
||||
// Function
|
||||
export default {
|
||||
metadata: {
|
||||
guildOnly: true,
|
||||
ephemeral: true,
|
||||
permissions: [Permissions.FLAGS.MANAGE_GUILD],
|
||||
},
|
||||
|
||||
builder: (command: SlashCommandSubcommandBuilder) => {
|
||||
return command
|
||||
.setName("embeds")
|
||||
.setDescription(`Embeds`)
|
||||
.addStringOption((option) =>
|
||||
option
|
||||
.setName("success-color")
|
||||
.setDescription("No provided description")
|
||||
)
|
||||
.addStringOption((option) =>
|
||||
option.setName("wait-color").setDescription("No provided description")
|
||||
)
|
||||
.addStringOption((option) =>
|
||||
option.setName("error-color").setDescription("No provided description")
|
||||
)
|
||||
.addStringOption((option) =>
|
||||
option.setName("footer-icon").setDescription("No provided description")
|
||||
)
|
||||
.addStringOption((option) =>
|
||||
option.setName("footer-text").setDescription("No provided description")
|
||||
);
|
||||
},
|
||||
execute: async (interaction: CommandInteraction) => {
|
||||
const { guild } = interaction;
|
||||
if (!guild) throw new Error("Guild not found");
|
||||
|
||||
const { successColor, waitColor, errorColor, footerText, footerIcon } =
|
||||
await getValues(interaction);
|
||||
|
||||
// Initialize embed object
|
||||
const embed = new MessageEmbed()
|
||||
.setTitle("[:tools:] Embeds")
|
||||
.setFooter({ text: footerText, iconURL: footerIcon })
|
||||
.setTimestamp(new Date());
|
||||
|
||||
// Get guild values
|
||||
const guildData = await guildSchema.findOne({
|
||||
guildId: guild.id,
|
||||
});
|
||||
if (!guildData) throw new Error("Guild data not found");
|
||||
|
||||
await guildData.save().then(async () => {
|
||||
embed
|
||||
.setDescription("Following embed configuration will be used.")
|
||||
.setColor(successColor)
|
||||
.addFields([
|
||||
{
|
||||
name: "🟢 Success Color",
|
||||
value: `${successColor}`,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: "🟡 Wait Color",
|
||||
value: `${waitColor}`,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: "🔴 Error Color",
|
||||
value: `${errorColor}`,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: "🖼️ Footer Icon",
|
||||
value: `${footerIcon}`,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: "📄 Footer Text",
|
||||
value: `${footerText}`,
|
||||
inline: true,
|
||||
},
|
||||
]);
|
||||
|
||||
return interaction.editReply({
|
||||
embeds: [embed],
|
||||
});
|
||||
});
|
||||
},
|
||||
};
|
|
@ -1,9 +0,0 @@
|
|||
import audits from "./audits";
|
||||
import credits from "./credits";
|
||||
import points from "./points";
|
||||
import pterodactyl from "./pterodactyl";
|
||||
import shop from "./shop";
|
||||
import welcome from "./welcome";
|
||||
import embeds from "./embeds";
|
||||
|
||||
export default { audits, credits, points, pterodactyl, shop, welcome, embeds };
|
|
@ -1,117 +0,0 @@
|
|||
// Dependencies
|
||||
import { CommandInteraction, Permissions } from "discord.js";
|
||||
|
||||
// Configurations
|
||||
import getEmbedConfig from "../../../../helpers/getEmbedConfig";
|
||||
|
||||
// Handlers
|
||||
import logger from "../../../../logger";
|
||||
|
||||
// Models
|
||||
import guildSchema from "../../../../database/schemas/guild";
|
||||
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
|
||||
|
||||
// Function
|
||||
export default {
|
||||
metadata: {
|
||||
guildOnly: true,
|
||||
ephemeral: true,
|
||||
permissions: [Permissions.FLAGS.MANAGE_GUILD],
|
||||
},
|
||||
|
||||
builder: (command: SlashCommandSubcommandBuilder) => {
|
||||
return command
|
||||
.setName("points")
|
||||
.setDescription("Points")
|
||||
.addBooleanOption((option) =>
|
||||
option.setName("status").setDescription("Should credits be enabled?")
|
||||
)
|
||||
.addNumberOption((option) =>
|
||||
option.setName("rate").setDescription("Amount of credits per message.")
|
||||
)
|
||||
.addNumberOption((option) =>
|
||||
option
|
||||
.setName("minimum-length")
|
||||
.setDescription("Minimum length of message to earn credits.")
|
||||
)
|
||||
.addNumberOption((option) =>
|
||||
option
|
||||
.setName("timeout")
|
||||
.setDescription("Timeout between earning credits (milliseconds).")
|
||||
);
|
||||
},
|
||||
execute: async (interaction: CommandInteraction) => {
|
||||
if (interaction.guild == null) return;
|
||||
const { successColor, footerText, footerIcon } = await getEmbedConfig(
|
||||
interaction.guild
|
||||
);
|
||||
|
||||
// Destructure member
|
||||
const { options, guild } = interaction;
|
||||
|
||||
// Get options
|
||||
const status = options?.getBoolean("status");
|
||||
const rate = options?.getNumber("rate");
|
||||
const timeout = options?.getNumber("timeout");
|
||||
const minimumLength = options?.getNumber("minimum-length");
|
||||
|
||||
// Get guild object
|
||||
const guildDB = await guildSchema?.findOne({
|
||||
guildId: guild?.id,
|
||||
});
|
||||
|
||||
if (guildDB === null) {
|
||||
return logger?.silly(`Guild not found in database.`);
|
||||
}
|
||||
|
||||
// Modify values
|
||||
guildDB.points.status = status !== null ? status : guildDB?.points?.status;
|
||||
guildDB.points.rate = rate !== null ? rate : guildDB?.points?.rate;
|
||||
guildDB.points.timeout =
|
||||
timeout !== null ? timeout : guildDB?.points?.timeout;
|
||||
guildDB.points.minimumLength =
|
||||
minimumLength !== null ? minimumLength : guildDB?.points?.minimumLength;
|
||||
|
||||
// Save guild
|
||||
await guildDB?.save()?.then(async () => {
|
||||
logger?.silly(`Guild points updated.`);
|
||||
|
||||
return interaction?.editReply({
|
||||
embeds: [
|
||||
{
|
||||
title: ":hammer: Settings - Guild [Points]",
|
||||
description: `Points settings updated.`,
|
||||
color: successColor,
|
||||
fields: [
|
||||
{
|
||||
name: "🤖 Status",
|
||||
value: `${guildDB?.points?.status}`,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: "📈 Rate",
|
||||
value: `${guildDB?.points?.rate}`,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: "🔨 Minimum Length",
|
||||
value: `${guildDB?.points?.minimumLength}`,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: "⏰ Timeout",
|
||||
value: `${guildDB?.points?.timeout}`,
|
||||
inline: true,
|
||||
},
|
||||
],
|
||||
timestamp: new Date(),
|
||||
footer: {
|
||||
iconURL: footerIcon,
|
||||
text: footerText,
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
},
|
||||
};
|
|
@ -1,78 +0,0 @@
|
|||
// Dependencies
|
||||
import { CommandInteraction, Permissions } from "discord.js";
|
||||
|
||||
// Configurations
|
||||
import getEmbedConfig from "../../../../helpers/getEmbedConfig";
|
||||
|
||||
// Handlers
|
||||
import logger from "../../../../logger";
|
||||
|
||||
// Models
|
||||
import apiSchema from "../../../../database/schemas/api";
|
||||
import encryption from "../../../../handlers/encryption";
|
||||
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
|
||||
|
||||
// Function
|
||||
export default {
|
||||
metadata: {
|
||||
guildOnly: true,
|
||||
ephemeral: true,
|
||||
permissions: [Permissions.FLAGS.MANAGE_GUILD],
|
||||
},
|
||||
|
||||
builder: (command: SlashCommandSubcommandBuilder) => {
|
||||
return command
|
||||
.setName("pterodactyl")
|
||||
.setDescription("Controlpanel.gg")
|
||||
.addStringOption((option) =>
|
||||
option
|
||||
.setName("url")
|
||||
.setDescription(`Controlpanel.gg URL`)
|
||||
.setRequired(true)
|
||||
)
|
||||
.addStringOption((option) =>
|
||||
option
|
||||
.setName("token")
|
||||
.setDescription(`Controlpanel.gg Token`)
|
||||
.setRequired(true)
|
||||
);
|
||||
},
|
||||
execute: async (interaction: CommandInteraction) => {
|
||||
if (interaction.guild == null) return;
|
||||
const { successColor, footerText, footerIcon } = await getEmbedConfig(
|
||||
interaction.guild
|
||||
); // Destructure member
|
||||
const { options, guild } = interaction;
|
||||
|
||||
// Get options
|
||||
const tokenData = options.getString("token");
|
||||
const url = options.getString("url");
|
||||
const token = tokenData && encryption.encrypt(tokenData);
|
||||
|
||||
// Update API credentials
|
||||
await apiSchema
|
||||
?.findOneAndUpdate(
|
||||
{ guildId: guild?.id },
|
||||
{ url, token },
|
||||
{ new: true, upsert: true }
|
||||
)
|
||||
.then(async () => {
|
||||
logger?.silly(`Updated API credentials.`);
|
||||
|
||||
return interaction?.editReply({
|
||||
embeds: [
|
||||
{
|
||||
title: ":hammer: Settings - Guild [Pterodactyl]",
|
||||
color: successColor,
|
||||
description: `Successfully updated API credentials.`,
|
||||
timestamp: new Date(),
|
||||
footer: {
|
||||
iconURL: footerIcon,
|
||||
text: footerText,
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
},
|
||||
};
|
|
@ -1,97 +0,0 @@
|
|||
// Dependencies
|
||||
import { CommandInteraction, Permissions } from "discord.js";
|
||||
|
||||
// Configurations
|
||||
import getEmbedConfig from "../../../../helpers/getEmbedConfig";
|
||||
|
||||
// Handlers
|
||||
import logger from "../../../../logger";
|
||||
|
||||
// Models
|
||||
import guildSchema from "../../../../database/schemas/guild";
|
||||
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
|
||||
|
||||
// Function
|
||||
export default {
|
||||
metadata: {
|
||||
guildOnly: true,
|
||||
ephemeral: true,
|
||||
permissions: [Permissions.FLAGS.MANAGE_GUILD],
|
||||
},
|
||||
|
||||
builder: (command: SlashCommandSubcommandBuilder) => {
|
||||
return command
|
||||
.setName("shop")
|
||||
.setDescription("Shop")
|
||||
.addBooleanOption((option) =>
|
||||
option
|
||||
.setName("roles-status")
|
||||
.setDescription("Should roles be enabled?")
|
||||
)
|
||||
.addNumberOption((option) =>
|
||||
option
|
||||
.setName("roles-price-per-hour")
|
||||
.setDescription("Price per hour for roles.")
|
||||
);
|
||||
},
|
||||
execute: async (interaction: CommandInteraction) => {
|
||||
if (interaction.guild == null) return;
|
||||
const { successColor, footerText, footerIcon } = await getEmbedConfig(
|
||||
interaction.guild
|
||||
); // Destructure member
|
||||
const { options, guild } = interaction;
|
||||
|
||||
// Get options
|
||||
const rolesStatus = options?.getBoolean("roles-status");
|
||||
const rolesPricePerHour = options?.getNumber("roles-price-per-hour");
|
||||
|
||||
// Get guild object
|
||||
const guildDB = await guildSchema?.findOne({
|
||||
guildId: guild?.id,
|
||||
});
|
||||
|
||||
if (guildDB === null) {
|
||||
return logger?.silly(`Guild not found in database.`);
|
||||
}
|
||||
|
||||
// Modify values
|
||||
guildDB.shop.roles.status =
|
||||
rolesStatus !== null ? rolesStatus : guildDB?.shop?.roles?.status;
|
||||
guildDB.shop.roles.pricePerHour =
|
||||
rolesPricePerHour !== null
|
||||
? rolesPricePerHour
|
||||
: guildDB?.shop?.roles?.pricePerHour;
|
||||
|
||||
// Save guild
|
||||
await guildDB?.save()?.then(async () => {
|
||||
logger?.silly(`Guild shop updated.`);
|
||||
|
||||
return interaction?.editReply({
|
||||
embeds: [
|
||||
{
|
||||
title: ":hammer: Settings - Guild [Shop]",
|
||||
description: `Shop settings updated.`,
|
||||
color: successColor,
|
||||
fields: [
|
||||
{
|
||||
name: "🤖 Roles Status",
|
||||
value: `${guildDB?.shop?.roles.status}`,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: "🌊 Roles Price Per Hour",
|
||||
value: `${guildDB?.shop?.roles.pricePerHour}`,
|
||||
inline: true,
|
||||
},
|
||||
],
|
||||
timestamp: new Date(),
|
||||
footer: {
|
||||
iconURL: footerIcon,
|
||||
text: footerText,
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
},
|
||||
};
|
|
@ -1,142 +0,0 @@
|
|||
// Dependencies
|
||||
import { CommandInteraction, Permissions } from "discord.js";
|
||||
|
||||
// Configurations
|
||||
import getEmbedConfig from "../../../../helpers/getEmbedConfig";
|
||||
|
||||
// Handlers
|
||||
import logger from "../../../../logger";
|
||||
|
||||
// Models
|
||||
import guildSchema from "../../../../database/schemas/guild";
|
||||
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
|
||||
import { ChannelType } from "discord-api-types/v10";
|
||||
|
||||
// Function
|
||||
export default {
|
||||
metadata: {
|
||||
guildOnly: true,
|
||||
ephemeral: true,
|
||||
permissions: [Permissions.FLAGS.MANAGE_GUILD],
|
||||
},
|
||||
|
||||
builder: (command: SlashCommandSubcommandBuilder) => {
|
||||
return command
|
||||
.setName("welcome")
|
||||
.setDescription("Welcome")
|
||||
.addBooleanOption((option) =>
|
||||
option.setName("status").setDescription("Should welcome be enabled?")
|
||||
)
|
||||
.addChannelOption((option) =>
|
||||
option
|
||||
.setName("join-channel")
|
||||
.setDescription("Channel for join messages.")
|
||||
.addChannelTypes(ChannelType.GuildText)
|
||||
)
|
||||
|
||||
.addChannelOption((option) =>
|
||||
option
|
||||
.setName("leave-channel")
|
||||
.setDescription("Channel for leave messages.")
|
||||
.addChannelTypes(ChannelType.GuildText)
|
||||
)
|
||||
|
||||
.addStringOption((option) =>
|
||||
option
|
||||
.setName("leave-message")
|
||||
.setDescription("Message for leave messages.")
|
||||
)
|
||||
.addStringOption((option) =>
|
||||
option
|
||||
.setName("join-message")
|
||||
.setDescription("Message for join messages.")
|
||||
);
|
||||
},
|
||||
execute: async (interaction: CommandInteraction) => {
|
||||
if (interaction.guild == null) return;
|
||||
const { successColor, footerText, footerIcon } = await getEmbedConfig(
|
||||
interaction.guild
|
||||
); // Destructure member
|
||||
const { options, guild } = interaction;
|
||||
|
||||
// Get options
|
||||
const status = options?.getBoolean("status");
|
||||
const joinChannel = options?.getChannel("join-channel");
|
||||
const leaveChannel = options?.getChannel("leave-channel");
|
||||
const joinChannelMessage = options?.getString("join-message");
|
||||
const leaveChannelMessage = options?.getString("leave-message");
|
||||
|
||||
// Get guild object
|
||||
const guildDB = await guildSchema?.findOne({
|
||||
guildId: guild?.id,
|
||||
});
|
||||
|
||||
if (guildDB === null) {
|
||||
return logger?.silly(`Guild not found in database.`);
|
||||
}
|
||||
|
||||
// Modify values
|
||||
guildDB.welcome.status =
|
||||
status !== null ? status : guildDB?.welcome?.status;
|
||||
guildDB.welcome.joinChannel =
|
||||
joinChannel !== null ? joinChannel.id : guildDB?.welcome?.joinChannel;
|
||||
guildDB.welcome.leaveChannel =
|
||||
leaveChannel !== null ? leaveChannel.id : guildDB?.welcome?.leaveChannel;
|
||||
|
||||
guildDB.welcome.joinChannelMessage =
|
||||
joinChannelMessage !== null
|
||||
? joinChannelMessage
|
||||
: guildDB?.welcome?.joinChannelMessage;
|
||||
guildDB.welcome.leaveChannelMessage =
|
||||
leaveChannelMessage !== null
|
||||
? leaveChannelMessage
|
||||
: guildDB?.welcome?.leaveChannelMessage;
|
||||
|
||||
// Save guild
|
||||
await guildDB?.save()?.then(async () => {
|
||||
logger?.silly(`Guild welcome updated.`);
|
||||
|
||||
if (!guildDB?.welcome?.status) {
|
||||
return interaction?.editReply({
|
||||
embeds: [
|
||||
{
|
||||
title: "[:tools:] Welcome",
|
||||
description: `This module is currently disabled, please enable it to continue.`,
|
||||
color: successColor,
|
||||
timestamp: new Date(),
|
||||
footer: {
|
||||
iconURL: footerIcon,
|
||||
text: footerText,
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
return interaction?.editReply({
|
||||
embeds: [
|
||||
{
|
||||
title: "[:tools:] Welcome",
|
||||
description: `The following configuration will be used.
|
||||
|
||||
[👋] **Welcome**
|
||||
|
||||
ㅤ**Channel**: <#${guildDB?.welcome?.joinChannel}>
|
||||
ㅤ**Message**: ${guildDB?.welcome?.joinChannelMessage}
|
||||
|
||||
[🚪] **Leave**
|
||||
|
||||
ㅤ**Channel**: <#${guildDB?.welcome?.leaveChannel}>
|
||||
ㅤ**Message**: ${guildDB?.welcome?.leaveChannelMessage}`,
|
||||
color: successColor,
|
||||
timestamp: new Date(),
|
||||
footer: {
|
||||
iconURL: footerIcon,
|
||||
text: footerText,
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
},
|
||||
};
|
|
@ -1,165 +0,0 @@
|
|||
// Dependencies
|
||||
import { CommandInteraction } from "discord.js";
|
||||
|
||||
// Configurations
|
||||
import getEmbedConfig from "../../../helpers/getEmbedConfig";
|
||||
|
||||
import { timeout } from "../../../config/reputation";
|
||||
|
||||
// Handlers
|
||||
import logger from "../../../logger";
|
||||
|
||||
// Models
|
||||
import timeoutSchema from "../../../database/schemas/timeout";
|
||||
import fetchUser from "../../../helpers/fetchUser";
|
||||
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
|
||||
|
||||
// Function
|
||||
export default {
|
||||
metadata: { guildOnly: true, ephemeral: true },
|
||||
|
||||
builder: (command: SlashCommandSubcommandBuilder) => {
|
||||
return command
|
||||
.setName("give")
|
||||
.setDescription("Give reputation to a user")
|
||||
.addUserOption((option) =>
|
||||
option
|
||||
.setName("target")
|
||||
.setDescription("The user you want to repute.")
|
||||
.setRequired(true)
|
||||
)
|
||||
.addStringOption((option) =>
|
||||
option
|
||||
.setName("type")
|
||||
.setDescription("What type of reputation you want to repute")
|
||||
.setRequired(true)
|
||||
.addChoices(
|
||||
{ name: "Positive", value: "positive" },
|
||||
{
|
||||
name: "Negative",
|
||||
value: "negative",
|
||||
}
|
||||
)
|
||||
);
|
||||
},
|
||||
execute: async (interaction: CommandInteraction) => {
|
||||
if (interaction.guild == null) return;
|
||||
const { errorColor, successColor, footerText, footerIcon } =
|
||||
await getEmbedConfig(interaction.guild); // Destructure
|
||||
const { options, user, guild } = interaction;
|
||||
|
||||
// Target option
|
||||
const optionTarget = options?.getUser("target");
|
||||
|
||||
// Type information
|
||||
const optionType = options?.getString("type");
|
||||
|
||||
if (guild === null) {
|
||||
return logger?.silly(`Guild is null`);
|
||||
}
|
||||
|
||||
// User information
|
||||
const userObj = await fetchUser(user, guild);
|
||||
|
||||
if (userObj === null) {
|
||||
return logger?.silly(`User is null`);
|
||||
}
|
||||
|
||||
// Check if user has a timeout
|
||||
const isTimeout = await timeoutSchema?.findOne({
|
||||
guildId: guild?.id,
|
||||
userId: user?.id,
|
||||
timeoutId: "2022-04-10-16-42",
|
||||
});
|
||||
|
||||
// If user is not on timeout
|
||||
if (isTimeout) {
|
||||
logger?.silly(`User is on timeout`);
|
||||
|
||||
return interaction?.editReply({
|
||||
embeds: [
|
||||
{
|
||||
title: ":loudspeaker: Reputation [Give]",
|
||||
description: `You cannot give reputation while on timeout, please wait ${timeout} seconds.`,
|
||||
timestamp: new Date(),
|
||||
color: errorColor,
|
||||
footer: {
|
||||
iconURL: footerIcon,
|
||||
text: footerText,
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
// Do not allow self reputation
|
||||
if (optionTarget?.id === user?.id) {
|
||||
logger?.silly(`User is trying to give reputation to self`);
|
||||
|
||||
return interaction?.editReply({
|
||||
embeds: [
|
||||
{
|
||||
title: ":loudspeaker: Reputation [Give]",
|
||||
description: `You cannot give reputation to yourself.`,
|
||||
timestamp: new Date(),
|
||||
color: errorColor,
|
||||
footer: {
|
||||
iconURL: footerIcon,
|
||||
text: footerText,
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
// If type is positive
|
||||
if (optionType === "positive") {
|
||||
logger?.silly(`User is giving positive reputation`);
|
||||
|
||||
userObj.reputation += 1;
|
||||
}
|
||||
|
||||
// If type is negative
|
||||
else if (optionType === "negative") {
|
||||
logger?.silly(`User is giving negative reputation`);
|
||||
|
||||
userObj.reputation -= 1;
|
||||
}
|
||||
|
||||
// Save user
|
||||
await userObj?.save()?.then(async () => {
|
||||
logger?.silly(`User reputation has been updated`);
|
||||
|
||||
await timeoutSchema?.create({
|
||||
guildId: guild?.id,
|
||||
userId: user?.id,
|
||||
timeoutId: "2022-04-10-16-42",
|
||||
});
|
||||
|
||||
return interaction?.editReply({
|
||||
embeds: [
|
||||
{
|
||||
title: ":loudspeaker: Reputation [Give]",
|
||||
description: `You have given reputation to ${optionTarget}`,
|
||||
timestamp: new Date(),
|
||||
color: successColor,
|
||||
footer: {
|
||||
iconURL: footerIcon,
|
||||
text: footerText,
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
setTimeout(async () => {
|
||||
logger?.silly(`Removing timeout`);
|
||||
|
||||
await timeoutSchema?.deleteOne({
|
||||
guildId: guild?.id,
|
||||
userId: user?.id,
|
||||
timeoutId: "2022-04-10-16-42",
|
||||
});
|
||||
}, timeout);
|
||||
},
|
||||
};
|
|
@ -1,4 +0,0 @@
|
|||
import pterodactyl from "./pterodactyl";
|
||||
import * as roles from "./roles";
|
||||
|
||||
export default { pterodactyl, roles };
|
|
@ -1,38 +0,0 @@
|
|||
// Dependencies
|
||||
import { CommandInteraction } from "discord.js";
|
||||
|
||||
// Configurations
|
||||
import getEmbedConfig from "../../../helpers/getEmbedConfig";
|
||||
|
||||
import { hosterName, hosterUrl } from "../../../config/other";
|
||||
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
|
||||
|
||||
// Function
|
||||
export default {
|
||||
metadata: { guildOnly: false, ephemeral: false },
|
||||
|
||||
builder: (command: SlashCommandSubcommandBuilder) => {
|
||||
return command.setName("about").setDescription("About this bot!)");
|
||||
},
|
||||
execute: async (interaction: CommandInteraction) => {
|
||||
if (interaction.guild == null) return;
|
||||
const { successColor, footerText, footerIcon } = await getEmbedConfig(
|
||||
interaction.guild
|
||||
);
|
||||
const interactionEmbed = {
|
||||
title: ":hammer: Utilities [About]",
|
||||
description: `This bot is hosted by ${
|
||||
hosterUrl ? `[${hosterName}](${hosterUrl})` : `${hosterName}`
|
||||
}, the bot is developed by [Zyner](https://github.com/ZynerOrg)!
|
||||
|
||||
If you are interested in contributing, then just [fork it](https://github.com/ZynerOrg/xyter) yourself, we :heart: Open Source.`,
|
||||
color: successColor,
|
||||
timestamp: new Date(),
|
||||
footer: {
|
||||
iconURL: footerIcon,
|
||||
text: footerText,
|
||||
},
|
||||
};
|
||||
interaction?.editReply({ embeds: [interactionEmbed] });
|
||||
},
|
||||
};
|
|
@ -8,7 +8,7 @@ export const guildId = "";
|
|||
export const hosterName = "someone";
|
||||
|
||||
// Hoster Url
|
||||
export const hosterUrl = "scheme://domain.tld";
|
||||
export const hosterUrl = "https://xyter.zyner.org/customization/change-hoster";
|
||||
|
||||
// Winston log level
|
||||
export const logLevel = "info";
|
|
@ -1,22 +0,0 @@
|
|||
// 3rd party dependencies
|
||||
import mongoose from "mongoose";
|
||||
|
||||
// Dependencies
|
||||
import logger from "../logger";
|
||||
|
||||
// Configuration
|
||||
import { url } from "../config/database";
|
||||
|
||||
export default async () => {
|
||||
await mongoose.connect(url).then(async (connection) => {
|
||||
logger.info(`Connected to database: ${connection.connection.name}`);
|
||||
});
|
||||
|
||||
mongoose.connection.on("error", async (error) => {
|
||||
logger.error(`${error}`);
|
||||
});
|
||||
|
||||
mongoose.connection.on("warn", async (warning) => {
|
||||
logger.warn(warning);
|
||||
});
|
||||
};
|
|
@ -1,58 +0,0 @@
|
|||
import logger from "../../logger";
|
||||
import { GuildMember, MessageEmbed, TextChannel } from "discord.js";
|
||||
|
||||
import guildSchema from "../../database/schemas/guild";
|
||||
|
||||
import getEmbedConfig from "../../helpers/getEmbedConfig";
|
||||
|
||||
export default {
|
||||
execute: async (member: GuildMember) => {
|
||||
const { footerText, footerIcon, successColor } = await getEmbedConfig(
|
||||
member.guild
|
||||
);
|
||||
|
||||
const guildData = await guildSchema.findOne({ guildId: member.guild.id });
|
||||
|
||||
const { client } = member;
|
||||
|
||||
if (guildData === null) return;
|
||||
|
||||
if (guildData.audits.status !== true) return;
|
||||
if (!guildData.audits.channelId) return;
|
||||
|
||||
const channel = client.channels.cache.get(`${guildData.audits.channelId}`);
|
||||
|
||||
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,
|
||||
}),
|
||||
],
|
||||
})
|
||||
.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})`
|
||||
);
|
||||
});
|
||||
},
|
||||
};
|
|
@ -1,55 +0,0 @@
|
|||
import logger from "../../logger";
|
||||
import { GuildMember, MessageEmbed, TextChannel } from "discord.js";
|
||||
|
||||
import guildSchema from "../../database/schemas/guild";
|
||||
|
||||
import getEmbedConfig from "../../helpers/getEmbedConfig";
|
||||
|
||||
export default {
|
||||
execute: async (member: GuildMember) => {
|
||||
const { footerText, footerIcon, errorColor } = await getEmbedConfig(
|
||||
member.guild
|
||||
);
|
||||
|
||||
const guildData = await guildSchema.findOne({ guildId: member.guild.id });
|
||||
|
||||
const { client } = member;
|
||||
|
||||
if (guildData === null) return;
|
||||
|
||||
if (guildData.audits.status !== true) return;
|
||||
if (!guildData.audits.channelId) return;
|
||||
|
||||
const channel = client.channels.cache.get(`${guildData.audits.channelId}`);
|
||||
|
||||
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,
|
||||
}),
|
||||
],
|
||||
})
|
||||
.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})`
|
||||
);
|
||||
});
|
||||
},
|
||||
};
|
|
@ -1,23 +0,0 @@
|
|||
// 3rd party dependencies
|
||||
import { CommandInteraction } from "discord.js";
|
||||
|
||||
// Dependencies
|
||||
import isCommand from "../../events/interactionCreate/components/isCommand";
|
||||
import logger from "../../logger";
|
||||
import audits from "./audits";
|
||||
import { IEventOptions } from "../../interfaces/EventOptions";
|
||||
|
||||
export const options: IEventOptions = {
|
||||
type: "on",
|
||||
};
|
||||
|
||||
export const execute = async (interaction: CommandInteraction) => {
|
||||
const { guild, id } = interaction;
|
||||
|
||||
logger?.silly(
|
||||
`New interaction: ${id} in guild: ${guild?.name} (${guild?.id})`
|
||||
);
|
||||
|
||||
await audits.execute(interaction);
|
||||
await isCommand(interaction);
|
||||
};
|
|
@ -1,85 +0,0 @@
|
|||
import logger from "../../../../logger";
|
||||
import timeouts from "../../../../database/schemas/timeout";
|
||||
import { Message } from "discord.js";
|
||||
|
||||
import fetchUser from "../../../../helpers/fetchUser";
|
||||
import fetchGuild from "../../../../helpers/fetchGuild";
|
||||
|
||||
export default {
|
||||
execute: async (message: Message) => {
|
||||
const { guild, author, content, channel } = message;
|
||||
|
||||
if (guild == null) return;
|
||||
if (author.bot) return;
|
||||
if (channel?.type !== "GUILD_TEXT") return;
|
||||
|
||||
const { id: guildId } = guild;
|
||||
const { id: userId } = author;
|
||||
|
||||
const guildData = await fetchGuild(guild);
|
||||
const userData = await fetchUser(author, guild);
|
||||
|
||||
if (content.length < guildData.credits.minimumLength) return;
|
||||
|
||||
const timeoutData = {
|
||||
guildId,
|
||||
userId,
|
||||
timeoutId: "2022-04-14-13-51-00",
|
||||
};
|
||||
|
||||
const timeout = await timeouts.findOne(timeoutData);
|
||||
|
||||
if (timeout) {
|
||||
logger.silly(
|
||||
`User ${userId} in guild ${guildId} is on timeout 2022-04-14-13-51-00`
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
userData.credits += guildData.credits.rate;
|
||||
|
||||
await userData
|
||||
.save()
|
||||
.then(async () => {
|
||||
logger.silly(
|
||||
`User ${userId} in guild ${guildId} has ${userData.credits} credits`
|
||||
);
|
||||
})
|
||||
.catch(async (err) => {
|
||||
logger.error(
|
||||
`Error saving credits for user ${userId} in guild ${guildId}`,
|
||||
err
|
||||
);
|
||||
});
|
||||
|
||||
await timeouts
|
||||
.create(timeoutData)
|
||||
.then(async () => {
|
||||
logger.silly(
|
||||
`Timeout 2022-04-14-13-51-00 for user ${userId} in guild ${guildId} has been created`
|
||||
);
|
||||
})
|
||||
.catch(async (err) => {
|
||||
logger.error(
|
||||
`Error creating timeout 2022-04-14-13-51-00 for user ${userId} in guild ${guildId}`,
|
||||
err
|
||||
);
|
||||
});
|
||||
|
||||
setTimeout(async () => {
|
||||
await timeouts
|
||||
.deleteOne(timeoutData)
|
||||
.then(async () => {
|
||||
logger.silly(
|
||||
`Timeout 2022-04-14-13-51-00 for user ${userId} in guild ${guildId} has been deleted`
|
||||
);
|
||||
})
|
||||
.catch(async (err) => {
|
||||
logger.error(
|
||||
`Error deleting timeout 2022-04-14-13-51-00 for user ${userId} in guild ${guildId}`,
|
||||
err
|
||||
);
|
||||
});
|
||||
}, guildData.credits.timeout);
|
||||
},
|
||||
};
|
|
@ -1,89 +0,0 @@
|
|||
import logger from "../../../../logger";
|
||||
import timeouts from "../../../../database/schemas/timeout";
|
||||
|
||||
import fetchUser from "../../../../helpers/fetchUser";
|
||||
import fetchGuild from "../../../../helpers/fetchGuild";
|
||||
|
||||
import { Message } from "discord.js";
|
||||
export default {
|
||||
execute: async (message: Message) => {
|
||||
const { guild, author, content, channel } = message;
|
||||
|
||||
if (guild == null) return;
|
||||
if (author.bot) return;
|
||||
if (channel?.type !== "GUILD_TEXT") return;
|
||||
|
||||
const { id: guildId } = guild;
|
||||
const { id: userId } = author;
|
||||
|
||||
const guildData = await fetchGuild(guild);
|
||||
const userData = await fetchUser(author, guild);
|
||||
|
||||
if (content.length < guildData.credits.minimumLength) return;
|
||||
|
||||
const timeoutData = {
|
||||
guildId,
|
||||
userId,
|
||||
timeoutId: "2022-04-14-14-15-00",
|
||||
};
|
||||
|
||||
const timeout = await timeouts.findOne(timeoutData);
|
||||
|
||||
if (timeout) {
|
||||
logger.silly(
|
||||
`User ${author.tag} (${author.id}) in guild: ${guild?.name} (${guild?.id} is on timeout 2022-04-14-14-15-00`
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
userData.points += guildData.points.rate;
|
||||
|
||||
await userData
|
||||
.save()
|
||||
.then(async () => {
|
||||
logger.silly(
|
||||
`Successfully saved user ${author.tag} (${author.id}) in guild: ${guild?.name} (${guild?.id})`
|
||||
);
|
||||
})
|
||||
.catch(async (err) => {
|
||||
logger.error(
|
||||
`Error saving points for user ${author.tag} (${author.id}) in guild: ${guild?.name} (${guild?.id})`,
|
||||
err
|
||||
);
|
||||
});
|
||||
|
||||
logger.silly(
|
||||
`User ${author.tag} (${author.id}) in guild: ${guild?.name} (${guild?.id}) has ${userData.points} points`
|
||||
);
|
||||
|
||||
await timeouts
|
||||
.create(timeoutData)
|
||||
.then(async () => {
|
||||
logger.silly(
|
||||
`Successfully created timeout for user ${author.tag} (${author.id}) in guild: ${guild?.name} (${guild?.id})`
|
||||
);
|
||||
})
|
||||
.catch(async (err) => {
|
||||
logger.error(
|
||||
`Error creating timeout 2022-04-14-14-15-00 for user ${author.tag} (${author.id}) in guild: ${guild?.name} (${guild?.id})`,
|
||||
err
|
||||
);
|
||||
});
|
||||
|
||||
setTimeout(async () => {
|
||||
await timeouts
|
||||
.deleteOne(timeoutData)
|
||||
.then(async () => {
|
||||
logger.silly(
|
||||
`Successfully deleted timeout 2022-04-14-14-15-00 for user ${author.tag} (${author.id}) in guild: ${guild?.name} (${guild?.id})`
|
||||
);
|
||||
})
|
||||
.catch(async (err) => {
|
||||
logger.error(
|
||||
`Error deleting timeout 2022-04-14-14-15-00 for user ${author.tag} (${author.id}) in guild: ${guild?.name} (${guild?.id})`,
|
||||
err
|
||||
);
|
||||
});
|
||||
}, guildData.points.timeout);
|
||||
},
|
||||
};
|
|
@ -12,6 +12,10 @@ import { ICommand } from "../interfaces/Command";
|
|||
export default async (client: Client) => {
|
||||
const commandList: Array<RESTPostAPIApplicationCommandsJSONBody> = [];
|
||||
|
||||
if (!client.commands) {
|
||||
throw new Error("client.commands is not defined");
|
||||
}
|
||||
|
||||
logger.info("Gathering command list");
|
||||
|
||||
await Promise.all(
|
||||
|
@ -25,7 +29,7 @@ export default async (client: Client) => {
|
|||
logger.info(`Finished gathering command list.`);
|
||||
})
|
||||
.catch(async (error) => {
|
||||
logger.error(`${error}`);
|
||||
throw new Error(`Could not gather command list: ${error}`);
|
||||
});
|
||||
|
||||
const rest = new REST({ version: "9" }).setToken(token);
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
// Dependencies
|
||||
import { Client } from "discord.js";
|
||||
import schedule from "node-schedule";
|
||||
|
||||
import logger from "../../logger";
|
||||
|
||||
// Jobs
|
||||
import shopRoles from "../../jobs/shopRoles";
|
||||
|
||||
export default async (client: Client) => {
|
||||
const expression = "*/5 * * * *";
|
||||
|
||||
schedule.scheduleJob(expression, async () => {
|
||||
logger.info("Running jobs.");
|
||||
|
||||
await shopRoles(client)
|
||||
.then(() => {
|
||||
logger.info("Shop roles job finished.");
|
||||
})
|
||||
.catch((err) => {
|
||||
logger.error(`Shop roles job failed: ${err}`);
|
||||
});
|
||||
});
|
||||
};
|
7
src/helpers/addSeconds/index.ts
Normal file
7
src/helpers/addSeconds/index.ts
Normal file
|
@ -0,0 +1,7 @@
|
|||
export default async (numOfSeconds: number, date: Date) => {
|
||||
if (!numOfSeconds) throw new Error("numOfSeconds is required");
|
||||
|
||||
date.setSeconds(date.getSeconds() + numOfSeconds);
|
||||
|
||||
return date;
|
||||
};
|
112
src/helpers/cooldown/index.ts
Normal file
112
src/helpers/cooldown/index.ts
Normal file
|
@ -0,0 +1,112 @@
|
|||
// Dependencies
|
||||
import { CommandInteraction, Message } from "discord.js";
|
||||
|
||||
import logger from "../../logger";
|
||||
|
||||
import getEmbedConfig from "../../helpers/getEmbedConfig";
|
||||
import timeoutSchema from "../../models/timeout";
|
||||
import addSeconds from "../../helpers/addSeconds";
|
||||
|
||||
export const interaction = async (i: CommandInteraction, cooldown: number) => {
|
||||
const { guild, user, commandId } = i;
|
||||
|
||||
// Check if user has a timeout
|
||||
const hasTimeout = await timeoutSchema.findOne({
|
||||
guildId: guild?.id || "0",
|
||||
userId: user.id,
|
||||
cooldown: cooldown,
|
||||
timeoutId: commandId,
|
||||
});
|
||||
|
||||
// If user is not on timeout
|
||||
if (hasTimeout) {
|
||||
const { guildId, userId, timeoutId, createdAt } = hasTimeout;
|
||||
const overDue = (await addSeconds(cooldown, createdAt)) < new Date();
|
||||
|
||||
if (!overDue) {
|
||||
const diff = Math.round(
|
||||
(new Date(hasTimeout.createdAt).getTime() - new Date().getTime()) / 1000
|
||||
);
|
||||
|
||||
throw new Error(
|
||||
`You must wait ${diff} seconds before using this command.`
|
||||
);
|
||||
}
|
||||
|
||||
// Delete timeout
|
||||
await timeoutSchema
|
||||
.deleteOne({
|
||||
guildId,
|
||||
userId,
|
||||
timeoutId,
|
||||
cooldown,
|
||||
})
|
||||
.then(async () => {
|
||||
logger.debug(
|
||||
`Timeout document ${timeoutId} has been deleted from user ${userId}.`
|
||||
);
|
||||
});
|
||||
}
|
||||
// Create timeout
|
||||
await timeoutSchema.create({
|
||||
guildId: guild?.id || "0",
|
||||
userId: user.id,
|
||||
cooldown: cooldown,
|
||||
timeoutId: commandId,
|
||||
});
|
||||
};
|
||||
|
||||
export const message = async (
|
||||
message: Message,
|
||||
cooldown: number,
|
||||
id: string
|
||||
) => {
|
||||
const { guild, member } = message;
|
||||
if (!guild) throw new Error("Guild is undefined");
|
||||
if (!member) throw new Error("Member is undefined");
|
||||
|
||||
// Check if user has a timeout
|
||||
const hasTimeout = await timeoutSchema.findOne({
|
||||
guildId: guild?.id || "0",
|
||||
userId: member.id,
|
||||
cooldown: cooldown,
|
||||
timeoutId: id,
|
||||
});
|
||||
|
||||
// If user is not on timeout
|
||||
if (hasTimeout) {
|
||||
const { guildId, userId, timeoutId, createdAt } = hasTimeout;
|
||||
const overDue = (await addSeconds(cooldown, createdAt)) < new Date();
|
||||
|
||||
if (!overDue) {
|
||||
const diff = Math.round(
|
||||
(new Date(hasTimeout.createdAt).getTime() - new Date().getTime()) / 1000
|
||||
);
|
||||
|
||||
throw new Error(
|
||||
`User: ${userId} on timeout-id: ${id} with cooldown: ${cooldown} secs with remaining: ${diff} secs.`
|
||||
);
|
||||
}
|
||||
|
||||
// Delete timeout
|
||||
await timeoutSchema
|
||||
.deleteOne({
|
||||
guildId,
|
||||
userId: member.id,
|
||||
timeoutId: id,
|
||||
cooldown,
|
||||
})
|
||||
.then(async () => {
|
||||
logger.debug(
|
||||
`Timeout document ${timeoutId} has been deleted from user ${userId}.`
|
||||
);
|
||||
});
|
||||
}
|
||||
// Create timeout
|
||||
await timeoutSchema.create({
|
||||
guildId: guild?.id || "0",
|
||||
userId: member.id,
|
||||
cooldown: cooldown,
|
||||
timeoutId: id,
|
||||
});
|
||||
};
|
|
@ -2,8 +2,6 @@ import { CommandInteraction, MessageEmbed } from "discord.js";
|
|||
import getEmbedConfig from "../../helpers/getEmbedConfig";
|
||||
|
||||
export default async (interaction: CommandInteraction, ephemeral: boolean) => {
|
||||
if (interaction.guild == null) return;
|
||||
|
||||
await interaction.deferReply({
|
||||
ephemeral,
|
||||
});
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import guildSchema from "../../database/schemas/guild";
|
||||
import userSchema from "../../database/schemas/user";
|
||||
import apiSchema from "../../database/schemas/api";
|
||||
import counterSchema from "../../database/schemas/counter";
|
||||
import shopRoleSchema from "../../database/schemas/shopRole";
|
||||
import timeoutSchema from "../../database/schemas/timeout";
|
||||
import guildSchema from "../../models/guild";
|
||||
import userSchema from "../../models/user";
|
||||
import apiSchema from "../../models/api";
|
||||
import counterSchema from "../../models/counter";
|
||||
import shopRoleSchema from "../../models/shopRole";
|
||||
import timeoutSchema from "../../models/timeout";
|
||||
|
||||
import logger from "../../logger";
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import userSchema from "../../database/schemas/user";
|
||||
import userSchema from "../../models/user";
|
||||
|
||||
import logger from "../../logger";
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
import { Guild } from "discord.js";
|
||||
|
||||
// Models
|
||||
import guildSchema from "../../database/schemas/guild";
|
||||
import guildSchema from "../../models/guild";
|
||||
|
||||
// Handlers
|
||||
import logger from "../../logger";
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
import { Guild, User } from "discord.js";
|
||||
|
||||
// Models
|
||||
import userSchema from "../../database/schemas/user";
|
||||
import userSchema from "../../models/user";
|
||||
|
||||
// Handlers
|
||||
import logger from "../../logger";
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import guildSchema from "../../database/schemas/guild";
|
||||
import guildSchema from "../../models/guild";
|
||||
import * as embedConfig from "../../config/embed";
|
||||
|
||||
import { Guild } from "discord.js";
|
||||
|
|
|
@ -2,9 +2,7 @@ import fs from "fs";
|
|||
const fsPromises = fs.promises;
|
||||
|
||||
export default async (path: string) => {
|
||||
try {
|
||||
return await fsPromises.readdir(path);
|
||||
} catch (err) {
|
||||
console.error("Error occurred while reading directory!", err);
|
||||
}
|
||||
return fsPromises.readdir(path).catch(async (e) => {
|
||||
throw new Error(`Could not list directory: ${path}`, e);
|
||||
});
|
||||
};
|
||||
|
|
17
src/index.ts
17
src/index.ts
|
@ -4,10 +4,7 @@ import { token, intents } from "./config/discord";
|
|||
|
||||
import { Client } from "discord.js"; // discord.js
|
||||
|
||||
import database from "./database";
|
||||
import schedules from "./handlers/schedules";
|
||||
import * as eventManager from "./managers/event";
|
||||
import * as commandManager from "./managers/command";
|
||||
import * as managers from "./managers";
|
||||
|
||||
// Main process that starts all other sub processes
|
||||
const main = async () => {
|
||||
|
@ -16,17 +13,7 @@ const main = async () => {
|
|||
intents,
|
||||
});
|
||||
|
||||
// Start database manager
|
||||
await database();
|
||||
|
||||
// Start schedule manager
|
||||
await schedules(client);
|
||||
|
||||
// Start command handler
|
||||
await commandManager.register(client);
|
||||
|
||||
// Start event handler
|
||||
await eventManager.register(client);
|
||||
await managers.start(client);
|
||||
|
||||
// Authorize with Discord's API
|
||||
await client.login(token);
|
||||
|
|
6
src/interfaces/Event.ts
Normal file
6
src/interfaces/Event.ts
Normal file
|
@ -0,0 +1,6 @@
|
|||
import { IEventOptions } from "./EventOptions";
|
||||
|
||||
export interface IEvent {
|
||||
options: IEventOptions;
|
||||
execute: (...args: Promise<void>[]) => Promise<void>;
|
||||
}
|
8
src/interfaces/Job.ts
Normal file
8
src/interfaces/Job.ts
Normal file
|
@ -0,0 +1,8 @@
|
|||
import { Client } from "discord.js";
|
||||
|
||||
export interface IJob {
|
||||
options: {
|
||||
schedule: string;
|
||||
};
|
||||
execute: (client: Client) => Promise<void>;
|
||||
}
|
|
@ -4,57 +4,47 @@ import { Client } from "discord.js";
|
|||
import logger from "../logger";
|
||||
|
||||
// Schemas
|
||||
import userSchema from "../database/schemas/user";
|
||||
import shopRoleSchema from "../database/schemas/shopRole";
|
||||
import guildSchema from "../database/schemas/guild";
|
||||
import userSchema from "../models/user";
|
||||
import shopRoleSchema from "../models/shopRole";
|
||||
import guildSchema from "../models/guild";
|
||||
|
||||
export default async (client: Client) => {
|
||||
export const options = {
|
||||
schedule: "*/5 * * * *", // https://crontab.guru/
|
||||
};
|
||||
|
||||
export const execute = async (client: Client) => {
|
||||
const roles = await shopRoleSchema.find();
|
||||
|
||||
await Promise.all(
|
||||
roles.map(async (role) => {
|
||||
const { guildId, userId, roleId } = role;
|
||||
|
||||
const lastPayment = new Date(role.lastPayed);
|
||||
|
||||
const nextPayment = new Date(
|
||||
lastPayment.setHours(lastPayment.getHours() + 1)
|
||||
);
|
||||
|
||||
if (new Date() < nextPayment) {
|
||||
logger.silly(`Shop role ${roleId} is not due for payment.`);
|
||||
}
|
||||
|
||||
const guildData = await guildSchema.findOne({ guildId });
|
||||
|
||||
if (!guildData) {
|
||||
logger.error(`Guild ${guildId} not found.`);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!userId) {
|
||||
logger.error(`User ID not found for shop role ${roleId}.`);
|
||||
return;
|
||||
}
|
||||
|
||||
const userData = await userSchema.findOne({ guildId, userId });
|
||||
|
||||
if (!userData) {
|
||||
logger.error(`User ${userId} not found for shop role ${roleId}.`);
|
||||
return;
|
||||
}
|
||||
|
||||
const rGuild = client?.guilds?.cache?.get(guildId);
|
||||
|
||||
const rMember = await rGuild?.members?.fetch(userId);
|
||||
|
||||
if (!rMember) {
|
||||
logger.error(`Member ${userId} not found for shop role ${roleId}.`);
|
||||
return;
|
||||
}
|
||||
|
||||
const rRole = rMember.roles.cache.get(roleId);
|
||||
|
||||
if (!rMember || !rRole) {
|
||||
logger.error(`Member ${userId} not found for shop role ${roleId}.`);
|
||||
await shopRoleSchema
|
||||
|
@ -76,36 +66,27 @@ export default async (client: Client) => {
|
|||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (new Date() > nextPayment) {
|
||||
logger.silly(
|
||||
`Shop role ${roleId} is due for payment. Withdrawing credits from user ${userId}.`
|
||||
);
|
||||
|
||||
const { pricePerHour } = guildData.shop.roles;
|
||||
|
||||
if (userData.credits < pricePerHour) {
|
||||
logger.error(
|
||||
`User ${userId} does not have enough credits to pay for shop role ${roleId}.`
|
||||
);
|
||||
|
||||
if (!rMember) {
|
||||
logger.error(`Member ${userId} not found for shop role ${roleId}.`);
|
||||
return;
|
||||
}
|
||||
|
||||
rMember.roles.remove(roleId);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
userData.credits -= pricePerHour;
|
||||
|
||||
await userData
|
||||
.save()
|
||||
.then(async () => {
|
||||
role.lastPayed = new Date();
|
||||
|
||||
await role
|
||||
.save()
|
||||
.then(async () => {
|
||||
|
@ -117,7 +98,6 @@ export default async (client: Client) => {
|
|||
err
|
||||
);
|
||||
});
|
||||
|
||||
logger.silly(
|
||||
`Shop role ${roleId} has been paid for. Keeping role ${roleId} for user ${userId}.`
|
||||
);
|
||||
|
|
35
src/jobs/timeouts.ts
Normal file
35
src/jobs/timeouts.ts
Normal file
|
@ -0,0 +1,35 @@
|
|||
import logger from "../logger";
|
||||
|
||||
import timeoutSchema from "../models/timeout";
|
||||
|
||||
import addSeconds from "../helpers/addSeconds";
|
||||
|
||||
export const options = {
|
||||
schedule: "*/30 * * * *", // https://crontab.guru/
|
||||
};
|
||||
|
||||
export const execute = async () => {
|
||||
const timeouts = await timeoutSchema.find();
|
||||
await Promise.all(
|
||||
timeouts.map(async (timeout) => {
|
||||
const { guildId, userId, timeoutId, cooldown, createdAt } = timeout;
|
||||
|
||||
const overDue = (await addSeconds(cooldown, createdAt)) < new Date();
|
||||
|
||||
if (overDue) {
|
||||
timeoutSchema
|
||||
.deleteOne({
|
||||
guildId,
|
||||
userId,
|
||||
timeoutId,
|
||||
cooldown,
|
||||
})
|
||||
.then(async () => {
|
||||
logger.debug(
|
||||
`Timeout document ${timeoutId} has been deleted from user ${userId}.`
|
||||
);
|
||||
});
|
||||
}
|
||||
})
|
||||
);
|
||||
};
|
|
@ -3,7 +3,8 @@ import "winston-daily-rotate-file";
|
|||
|
||||
import { logLevel } from "../config/other";
|
||||
|
||||
const { combine, timestamp, printf, colorize, align, json } = winston.format;
|
||||
const { combine, timestamp, printf, errors, colorize, align, json } =
|
||||
winston.format;
|
||||
|
||||
export default winston.createLogger({
|
||||
level: logLevel || "info",
|
||||
|
@ -16,6 +17,7 @@ export default winston.createLogger({
|
|||
}),
|
||||
new winston.transports.Console({
|
||||
format: combine(
|
||||
errors({ stack: true, trace: true }), // <-- use errors format
|
||||
colorize({ all: true }),
|
||||
timestamp({
|
||||
format: "YYYY-MM-DD HH:MM:ss",
|
||||
|
|
|
@ -1,20 +1,25 @@
|
|||
import fs from "fs"; // fs
|
||||
import { Collection, Client } from "discord.js"; // discord.js
|
||||
import logger from "../../logger";
|
||||
import { ICommand } from "../../interfaces/Command";
|
||||
import { Collection, Client } from "discord.js";
|
||||
import listDir from "../../helpers/listDir";
|
||||
import logger from "../../logger";
|
||||
|
||||
import { ICommand } from "../../interfaces/Command";
|
||||
|
||||
export const register = async (client: Client) => {
|
||||
client.commands = new Collection();
|
||||
|
||||
const commandNames = await listDir("commands");
|
||||
if (!commandNames) return;
|
||||
const commandNames = await listDir("plugins/commands");
|
||||
|
||||
if (!commandNames) throw new Error("Could not list commands");
|
||||
|
||||
logger.info(`Loading ${commandNames.length} commands`);
|
||||
|
||||
await Promise.all(
|
||||
commandNames.map(async (commandName, index) => {
|
||||
const command: ICommand = await import(`../../commands/${commandName}`);
|
||||
commandNames.map(async (commandName) => {
|
||||
const command: ICommand = await import(
|
||||
`../../plugins/commands/${commandName}`
|
||||
).catch(async (e) => {
|
||||
throw new Error(`Could not load command: ${commandName}`, e);
|
||||
});
|
||||
|
||||
client.commands.set(command.builder.name, command);
|
||||
|
||||
|
@ -25,6 +30,6 @@ export const register = async (client: Client) => {
|
|||
logger.info(`Finished loading commands.`);
|
||||
})
|
||||
.catch(async (err) => {
|
||||
logger.error(`${err}`);
|
||||
throw new Error(`Could not load commands: ${err}`);
|
||||
});
|
||||
};
|
||||
|
|
27
src/managers/database/index.ts
Normal file
27
src/managers/database/index.ts
Normal file
|
@ -0,0 +1,27 @@
|
|||
// 3rd party dependencies
|
||||
import mongoose from "mongoose";
|
||||
|
||||
// Dependencies
|
||||
import logger from "../../logger";
|
||||
|
||||
// Configuration
|
||||
import { url } from "../../config/database";
|
||||
|
||||
export const start = async () => {
|
||||
await mongoose
|
||||
.connect(url)
|
||||
.then(async (connection) => {
|
||||
logger.info(`Connected to database: ${connection.connection.name}`);
|
||||
})
|
||||
.catch(async (e) => {
|
||||
logger.error("Could not connect to database", e);
|
||||
});
|
||||
|
||||
mongoose.connection.on("error", async (error) => {
|
||||
logger.error(`${error}`);
|
||||
});
|
||||
|
||||
mongoose.connection.on("warn", async (warning) => {
|
||||
logger.warn(warning);
|
||||
});
|
||||
};
|
|
@ -1,14 +1,19 @@
|
|||
/* eslint-disable no-loops/no-loops */
|
||||
import { Client } from "discord.js";
|
||||
import listDir from "../../helpers/listDir";
|
||||
import { IEvent } from "../../interfaces/Event";
|
||||
import logger from "../../logger";
|
||||
|
||||
export const register = async (client: Client) => {
|
||||
const eventNames = await listDir("events");
|
||||
const eventNames = await listDir("plugins/events");
|
||||
if (!eventNames) return;
|
||||
|
||||
for await (const eventName of eventNames) {
|
||||
const event = await import(`../../events/${eventName}`);
|
||||
const eventExecutor = async (...args: any[]) => event.execute(...args);
|
||||
const event: IEvent = await import(`../../plugins/events/${eventName}`);
|
||||
const eventExecutor = async (...args: Promise<void>[]) =>
|
||||
event.execute(...args).catch(async (err) => {
|
||||
logger.error(`${err}`);
|
||||
});
|
||||
if (!event.options?.type) return;
|
||||
|
||||
switch (event.options.type) {
|
||||
|
|
13
src/managers/index.ts
Normal file
13
src/managers/index.ts
Normal file
|
@ -0,0 +1,13 @@
|
|||
import { Client } from "discord.js";
|
||||
|
||||
import * as database from "./database";
|
||||
import * as schedule from "./schedule";
|
||||
import * as event from "./event";
|
||||
import * as command from "./command";
|
||||
|
||||
export const start = async (client: Client) => {
|
||||
await database.start();
|
||||
await schedule.start(client);
|
||||
await command.register(client);
|
||||
await event.register(client);
|
||||
};
|
29
src/managers/schedule/index.ts
Normal file
29
src/managers/schedule/index.ts
Normal file
|
@ -0,0 +1,29 @@
|
|||
import logger from "../../logger";
|
||||
import { Client } from "discord.js";
|
||||
|
||||
import { IJob } from "../../interfaces/Job";
|
||||
|
||||
import listDir from "../../helpers/listDir";
|
||||
|
||||
import schedule from "node-schedule";
|
||||
|
||||
export const start = async (client: Client) => {
|
||||
logger.info("Starting schedule manager...");
|
||||
|
||||
const jobNames = await listDir("jobs");
|
||||
if (!jobNames) return logger.info("No jobs found");
|
||||
|
||||
await Promise.all(
|
||||
jobNames.map(async (jobName) => {
|
||||
const job: IJob = await import(`../../jobs/${jobName}`);
|
||||
|
||||
schedule.scheduleJob(job.options.schedule, async () => {
|
||||
logger.info(`Executed job ${jobName}!`);
|
||||
await job.execute(client);
|
||||
});
|
||||
})
|
||||
).then(async () => {
|
||||
const list = schedule.scheduledJobs;
|
||||
logger.silly(list);
|
||||
});
|
||||
};
|
|
@ -1,6 +1,6 @@
|
|||
import { Snowflake } from "discord.js";
|
||||
import { model, Schema } from "mongoose";
|
||||
import { IEncryptionData } from "../../interfaces/EncryptionData";
|
||||
import { IEncryptionData } from "../interfaces/EncryptionData";
|
||||
|
||||
export interface IApi {
|
||||
guildId: Snowflake;
|
|
@ -4,7 +4,10 @@ import { Schema, model } from "mongoose";
|
|||
export interface ITimeout {
|
||||
userId: Snowflake;
|
||||
guildId: Snowflake;
|
||||
cooldown: number;
|
||||
timeoutId: string;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
}
|
||||
|
||||
const timeoutSchema = new Schema<ITimeout>(
|
||||
|
@ -21,6 +24,12 @@ const timeoutSchema = new Schema<ITimeout>(
|
|||
unique: false,
|
||||
index: true,
|
||||
},
|
||||
cooldown: {
|
||||
type: Number,
|
||||
required: true,
|
||||
unique: false,
|
||||
index: true,
|
||||
},
|
||||
timeoutId: { type: String },
|
||||
},
|
||||
{ timestamps: true }
|
8
src/plugins/buttons/primary/index.ts
Normal file
8
src/plugins/buttons/primary/index.ts
Normal file
|
@ -0,0 +1,8 @@
|
|||
import { CommandInteraction } from "discord.js";
|
||||
import logger from "../../../logger";
|
||||
|
||||
export const metadata = { guildOnly: false, ephemeral: false };
|
||||
|
||||
export const execute = async (interaction: CommandInteraction) => {
|
||||
logger.debug("primary button clicked!");
|
||||
};
|
|
@ -1,6 +1,6 @@
|
|||
import { CommandInteraction } from "discord.js";
|
||||
import { SlashCommandBuilder } from "@discordjs/builders";
|
||||
import logger from "../../logger";
|
||||
import logger from "../../../logger";
|
||||
|
||||
import modules from "../../commands/counters/modules";
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
import getEmbedConfig from "../../../../helpers/getEmbedConfig";
|
||||
import getEmbedConfig from "../../../../../helpers/getEmbedConfig";
|
||||
|
||||
import { CommandInteraction, MessageEmbed } from "discord.js";
|
||||
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
|
||||
import { ChannelType } from "discord-api-types/v10";
|
||||
|
||||
import counterSchema from "../../../../database/schemas/counter";
|
||||
import counterSchema from "../../../../../models/counter";
|
||||
|
||||
export default {
|
||||
metadata: { guildOnly: true, ephemeral: false },
|
||||
|
@ -25,7 +25,6 @@ export default {
|
|||
},
|
||||
|
||||
execute: async (interaction: CommandInteraction) => {
|
||||
if (interaction.guild == null) return;
|
||||
const { errorColor, successColor, footerText, footerIcon } =
|
||||
await getEmbedConfig(interaction.guild);
|
||||
const { options, guild } = interaction;
|
|
@ -1,6 +1,6 @@
|
|||
import { SlashCommandBuilder } from "@discordjs/builders";
|
||||
import { CommandInteraction } from "discord.js";
|
||||
import logger from "../../logger";
|
||||
import logger from "../../../logger";
|
||||
|
||||
import modules from "./modules";
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
import getEmbedConfig from "../../../../helpers/getEmbedConfig";
|
||||
import getEmbedConfig from "../../../../../helpers/getEmbedConfig";
|
||||
|
||||
import { CommandInteraction, MessageEmbed } from "discord.js";
|
||||
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
|
||||
import logger from "../../../../logger";
|
||||
import logger from "../../../../../logger";
|
||||
|
||||
import fetchUser from "../../../../helpers/fetchUser";
|
||||
import fetchUser from "../../../../../helpers/fetchUser";
|
||||
|
||||
export default {
|
||||
metadata: { guildOnly: true, ephemeral: true },
|
||||
|
@ -19,7 +19,6 @@ export default {
|
|||
);
|
||||
},
|
||||
execute: async (interaction: CommandInteraction) => {
|
||||
if (interaction.guild == null) return;
|
||||
const { errorColor, successColor, footerText, footerIcon } =
|
||||
await getEmbedConfig(interaction.guild);
|
||||
const { options, user, guild } = interaction;
|
|
@ -2,15 +2,15 @@
|
|||
import { CommandInteraction, MessageEmbed } from "discord.js";
|
||||
|
||||
// Configurations
|
||||
import getEmbedConfig from "../../../../helpers/getEmbedConfig";
|
||||
import getEmbedConfig from "../../../../../helpers/getEmbedConfig";
|
||||
|
||||
// Handlers
|
||||
import logger from "../../../../logger";
|
||||
import logger from "../../../../../logger";
|
||||
|
||||
import mongoose from "mongoose";
|
||||
|
||||
// Models
|
||||
import fetchUser from "../../../../helpers/fetchUser";
|
||||
import fetchUser from "../../../../../helpers/fetchUser";
|
||||
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
|
||||
|
||||
// Function
|
||||
|
@ -38,7 +38,6 @@ export default {
|
|||
);
|
||||
},
|
||||
execute: async (interaction: CommandInteraction) => {
|
||||
if (interaction.guild == null) return;
|
||||
const { errorColor, successColor, footerText, footerIcon } =
|
||||
await getEmbedConfig(interaction.guild);
|
||||
const { options, user, guild, client } = interaction;
|
|
@ -1,10 +1,10 @@
|
|||
import getEmbedConfig from "../../../../helpers/getEmbedConfig";
|
||||
import getEmbedConfig from "../../../../../helpers/getEmbedConfig";
|
||||
|
||||
import { CommandInteraction, MessageEmbed } from "discord.js";
|
||||
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
|
||||
import logger from "../../../../logger";
|
||||
import logger from "../../../../../logger";
|
||||
|
||||
import userSchema, { IUser } from "../../../../database/schemas/user";
|
||||
import userSchema, { IUser } from "../../../../../models/user";
|
||||
|
||||
export default {
|
||||
metadata: { guildOnly: true, ephemeral: false },
|
||||
|
@ -13,7 +13,6 @@ export default {
|
|||
return command.setName("top").setDescription(`View the top users`);
|
||||
},
|
||||
execute: async (interaction: CommandInteraction) => {
|
||||
if (interaction.guild == null) return;
|
||||
const { errorColor, successColor, footerText, footerIcon } =
|
||||
await getEmbedConfig(interaction.guild);
|
||||
const { guild } = interaction;
|
|
@ -4,17 +4,17 @@ import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
|
|||
import Chance from "chance";
|
||||
|
||||
// Configurations
|
||||
import getEmbedConfig from "../../../../helpers/getEmbedConfig";
|
||||
import getEmbedConfig from "../../../../../helpers/getEmbedConfig";
|
||||
|
||||
// Handlers
|
||||
import logger from "../../../../logger";
|
||||
import logger from "../../../../../logger";
|
||||
|
||||
// Models
|
||||
import timeoutSchema from "../../../../database/schemas/timeout";
|
||||
import * as cooldown from "../../../../../helpers/cooldown";
|
||||
|
||||
// Helpers
|
||||
import fetchUser from "../../../../helpers/fetchUser";
|
||||
import fetchGuild from "../../../../helpers/fetchGuild";
|
||||
import fetchUser from "../../../../../helpers/fetchUser";
|
||||
import fetchGuild from "../../../../../helpers/fetchGuild";
|
||||
|
||||
export default {
|
||||
metadata: { guildOnly: true, ephemeral: true },
|
||||
|
@ -23,9 +23,9 @@ export default {
|
|||
return command.setName("work").setDescription(`Work to earn credits`);
|
||||
},
|
||||
execute: async (interaction: CommandInteraction) => {
|
||||
if (interaction.guild == null) return;
|
||||
const { errorColor, successColor, footerText, footerIcon } =
|
||||
await getEmbedConfig(interaction.guild); // Destructure member
|
||||
const { successColor, footerText, footerIcon } = await getEmbedConfig(
|
||||
interaction.guild
|
||||
); // Destructure member
|
||||
const { guild, user } = interaction;
|
||||
|
||||
const embed = new MessageEmbed()
|
||||
|
@ -39,33 +39,13 @@ export default {
|
|||
// Chance module
|
||||
const chance = new Chance();
|
||||
|
||||
// Check if user has a timeout
|
||||
const isTimeout = await timeoutSchema?.findOne({
|
||||
guildId: guild?.id,
|
||||
userId: user?.id,
|
||||
timeoutId: "2022-03-15-19-16",
|
||||
});
|
||||
|
||||
if (guild === null) {
|
||||
return logger?.silly(`Guild is null`);
|
||||
}
|
||||
|
||||
const guildDB = await fetchGuild(guild);
|
||||
|
||||
// If user is not on timeout
|
||||
if (isTimeout) {
|
||||
logger?.silly(`User ${user?.id} is on timeout`);
|
||||
|
||||
return interaction.editReply({
|
||||
embeds: [
|
||||
embed
|
||||
.setDescription(
|
||||
`You are on timeout, please wait ${guildDB?.credits.workTimeout} seconds.`
|
||||
)
|
||||
.setColor(errorColor),
|
||||
],
|
||||
});
|
||||
}
|
||||
await cooldown.interaction(interaction, guildDB?.credits?.workTimeout);
|
||||
|
||||
const creditsEarned = chance.integer({
|
||||
min: 0,
|
||||
|
@ -93,23 +73,5 @@ export default {
|
|||
],
|
||||
});
|
||||
});
|
||||
|
||||
// Create a timeout for the user
|
||||
await timeoutSchema?.create({
|
||||
guildId: guild?.id,
|
||||
userId: user?.id,
|
||||
timeoutId: "2022-03-15-19-16",
|
||||
});
|
||||
|
||||
setTimeout(async () => {
|
||||
logger?.silly(`Removing timeout for user ${user?.id}`);
|
||||
|
||||
// When timeout is out, remove it from the database
|
||||
await timeoutSchema?.deleteOne({
|
||||
guildId: guild?.id,
|
||||
userId: user?.id,
|
||||
timeoutId: "2022-03-15-19-16",
|
||||
});
|
||||
}, guildDB?.credits?.workTimeout);
|
||||
},
|
||||
};
|
|
@ -1,6 +1,6 @@
|
|||
import { SlashCommandBuilder } from "@discordjs/builders";
|
||||
import { CommandInteraction } from "discord.js";
|
||||
import logger from "../../logger";
|
||||
import logger from "../../../logger";
|
||||
|
||||
import modules from "../../commands/fun/modules";
|
||||
|
|
@ -1,11 +1,11 @@
|
|||
import getEmbedConfig from "../../../../helpers/getEmbedConfig";
|
||||
import getEmbedConfig from "../../../../../helpers/getEmbedConfig";
|
||||
|
||||
import axios from "axios";
|
||||
import { CommandInteraction, MessageEmbed } from "discord.js";
|
||||
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
|
||||
|
||||
export default {
|
||||
metadata: { guildOnly: false, ephemeral: false },
|
||||
metadata: { guildOnly: false, ephemeral: false, cooldown: 15 },
|
||||
|
||||
builder: (command: SlashCommandSubcommandBuilder) => {
|
||||
return command.setName("meme").setDescription("Get a meme from r/memes)");
|
|
@ -4,7 +4,7 @@ import { CommandInteraction } from "discord.js";
|
|||
|
||||
// Groups
|
||||
import modules from "../../commands/manage/modules";
|
||||
import logger from "../../logger";
|
||||
import logger from "../../../logger";
|
||||
|
||||
export const moduleData = modules;
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
import { SlashCommandSubcommandGroupBuilder } from "@discordjs/builders";
|
||||
import { CommandInteraction } from "discord.js";
|
||||
|
||||
import logger from "../../../../logger";
|
||||
import logger from "../../../../../logger";
|
||||
|
||||
// Modules
|
||||
import modules from "./modules";
|
|
@ -4,12 +4,12 @@ import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
|
|||
import { ChannelType } from "discord-api-types/v10";
|
||||
|
||||
// Configurations
|
||||
import getEmbedConfig from "../../../../../../helpers/getEmbedConfig";
|
||||
import getEmbedConfig from "../../../../../../../helpers/getEmbedConfig";
|
||||
|
||||
import logger from "../../../../../../logger";
|
||||
import logger from "../../../../../../../logger";
|
||||
|
||||
// Models
|
||||
import counterSchema from "../../../../../../database/schemas/counter";
|
||||
import counterSchema from "../../../../../../../models/counter";
|
||||
|
||||
// Function
|
||||
export default {
|
||||
|
@ -43,7 +43,6 @@ export default {
|
|||
);
|
||||
},
|
||||
execute: async (interaction: CommandInteraction) => {
|
||||
if (interaction.guild == null) return;
|
||||
const { errorColor, successColor, footerText, footerIcon } =
|
||||
await getEmbedConfig(interaction.guild);
|
||||
const { options, guild } = interaction;
|
|
@ -2,13 +2,13 @@
|
|||
import { CommandInteraction, MessageEmbed, Permissions } from "discord.js";
|
||||
|
||||
// Configurations
|
||||
import getEmbedConfig from "../../../../../../helpers/getEmbedConfig";
|
||||
import getEmbedConfig from "../../../../../../../helpers/getEmbedConfig";
|
||||
|
||||
// Handlers
|
||||
import logger from "../../../../../../logger";
|
||||
import logger from "../../../../../../../logger";
|
||||
|
||||
// Models
|
||||
import counterSchema from "../../../../../../database/schemas/counter";
|
||||
import counterSchema from "../../../../../../../models/counter";
|
||||
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
|
||||
import { ChannelType } from "discord-api-types/v10";
|
||||
|
||||
|
@ -33,7 +33,6 @@ export default {
|
|||
);
|
||||
},
|
||||
execute: async (interaction: CommandInteraction) => {
|
||||
if (interaction.guild == null) return;
|
||||
const { errorColor, successColor, footerText, footerIcon } =
|
||||
await getEmbedConfig(interaction.guild);
|
||||
const { options, guild } = interaction;
|
|
@ -1,6 +1,6 @@
|
|||
import { CommandInteraction } from "discord.js";
|
||||
import { SlashCommandSubcommandGroupBuilder } from "@discordjs/builders";
|
||||
import logger from "../../../../logger";
|
||||
import logger from "../../../../../logger";
|
||||
|
||||
import modules from "./modules";
|
||||
|
||||
|
@ -14,7 +14,7 @@ export const builder = (group: SlashCommandSubcommandGroupBuilder) => {
|
|||
.addSubcommand(modules.set.builder)
|
||||
.addSubcommand(modules.take.builder)
|
||||
.addSubcommand(modules.transfer.builder)
|
||||
.addSubcommand(modules.drop.builder);
|
||||
.addSubcommand(modules.giveaway.builder);
|
||||
};
|
||||
|
||||
export const execute = async (interaction: CommandInteraction) => {
|
||||
|
@ -27,7 +27,7 @@ export const execute = async (interaction: CommandInteraction) => {
|
|||
return modules.take.execute(interaction);
|
||||
case "transfer":
|
||||
return modules.transfer.execute(interaction);
|
||||
case "drop":
|
||||
return modules.drop.execute(interaction);
|
||||
case "giveaway":
|
||||
return modules.giveaway.execute(interaction);
|
||||
}
|
||||
};
|
|
@ -3,16 +3,16 @@ import { CommandInteraction, MessageEmbed, Permissions } from "discord.js";
|
|||
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
|
||||
|
||||
// Configurations
|
||||
import getEmbedConfig from "../../../../../../helpers/getEmbedConfig";
|
||||
import getEmbedConfig from "../../../../../../../helpers/getEmbedConfig";
|
||||
|
||||
// Handlers
|
||||
import logger from "../../../../../../logger";
|
||||
import logger from "../../../../../../../logger";
|
||||
|
||||
// Helpers
|
||||
import pluralize from "../../../../../../helpers/pluralize";
|
||||
import pluralize from "../../../../../../../helpers/pluralize";
|
||||
|
||||
// Models
|
||||
import fetchUser from "../../../../../../helpers/fetchUser";
|
||||
import fetchUser from "../../../../../../../helpers/fetchUser";
|
||||
|
||||
// Function
|
||||
export default {
|
||||
|
@ -40,7 +40,6 @@ export default {
|
|||
);
|
||||
},
|
||||
execute: async (interaction: CommandInteraction) => {
|
||||
if (interaction.guild == null) return;
|
||||
const { errorColor, successColor, footerText, footerIcon } =
|
||||
await getEmbedConfig(interaction.guild); // Destructure
|
||||
const { guild, options } = interaction;
|
|
@ -1,22 +1,21 @@
|
|||
// Dependencies
|
||||
import { CommandInteraction, MessageEmbed, Permissions } from "discord.js";
|
||||
import {
|
||||
CommandInteraction,
|
||||
MessageActionRow,
|
||||
MessageButton,
|
||||
MessageEmbed,
|
||||
Permissions,
|
||||
} from "discord.js";
|
||||
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import axios from "axios";
|
||||
import apiSchema from "../../../../../../database/schemas/api";
|
||||
import encryption from "../../../../../../handlers/encryption";
|
||||
import apiSchema from "../../../../../../../models/api";
|
||||
import encryption from "../../../../../../../handlers/encryption";
|
||||
|
||||
// Configurations
|
||||
import getEmbedConfig from "../../../../../../helpers/getEmbedConfig";
|
||||
import getEmbedConfig from "../../../../../../../helpers/getEmbedConfig";
|
||||
|
||||
// Handlers
|
||||
import logger from "../../../../../../logger";
|
||||
|
||||
// Helpers
|
||||
import pluralize from "../../../../../../helpers/pluralize";
|
||||
|
||||
// Models
|
||||
import fetchUser from "../../../../../../helpers/fetchUser";
|
||||
import { ChannelType } from "discord-api-types/v10";
|
||||
|
||||
// Function
|
||||
export default {
|
||||
|
@ -28,8 +27,8 @@ export default {
|
|||
|
||||
builder: (command: SlashCommandSubcommandBuilder) => {
|
||||
return command
|
||||
.setName("drop")
|
||||
.setDescription("Drop some credits for specified amount of users.")
|
||||
.setName("giveaway")
|
||||
.setDescription("Giveaway some credits for specified amount of users.")
|
||||
.addIntegerOption((option) =>
|
||||
option
|
||||
.setName("uses")
|
||||
|
@ -47,12 +46,13 @@ export default {
|
|||
.setName("channel")
|
||||
.setDescription("The channel to send the message to.")
|
||||
.setRequired(true)
|
||||
.addChannelTypes(ChannelType.GuildText)
|
||||
);
|
||||
},
|
||||
execute: async (interaction: CommandInteraction) => {
|
||||
if (interaction.guild == null) return;
|
||||
const { errorColor, successColor, footerText, footerIcon } =
|
||||
await getEmbedConfig(interaction.guild); // Destructure
|
||||
const { successColor, footerText, footerIcon } = await getEmbedConfig(
|
||||
interaction.guild
|
||||
); // Destructure
|
||||
const { guild, options } = interaction;
|
||||
|
||||
const uses = options?.getInteger("uses");
|
||||
|
@ -76,31 +76,39 @@ export default {
|
|||
if (!apiCredentials) return;
|
||||
|
||||
const api = axios?.create({
|
||||
baseURL: apiCredentials.url,
|
||||
baseURL: `${apiCredentials?.url}/api/`,
|
||||
headers: {
|
||||
Authorization: `Bearer ${encryption.decrypt(apiCredentials.token)}`,
|
||||
},
|
||||
});
|
||||
|
||||
const shopUrl = apiCredentials?.url?.replace("/api", "/store");
|
||||
const shopUrl = `${apiCredentials?.url}/store`;
|
||||
|
||||
await api
|
||||
.post("vouchers", {
|
||||
uses,
|
||||
code,
|
||||
credits: creditAmount,
|
||||
memo: `${interaction?.createdTimestamp} - ${interaction?.user?.id}`,
|
||||
memo: `[GIVEAWAY] ${interaction?.createdTimestamp} - ${interaction?.user?.id}`,
|
||||
})
|
||||
.then(async () => {
|
||||
await interaction.editReply({
|
||||
embeds: [
|
||||
embed
|
||||
.setColor(successColor)
|
||||
.setDescription(`Successfully crated code: ${code}`),
|
||||
.setDescription(`Successfully created code: ${code}`),
|
||||
],
|
||||
});
|
||||
|
||||
const discordChannel = guild.channels.cache.get(channel.id);
|
||||
const buttons = new MessageActionRow().addComponents(
|
||||
new MessageButton()
|
||||
.setLabel("Redeem it here")
|
||||
.setStyle("LINK")
|
||||
.setEmoji("🏦")
|
||||
.setURL(`${shopUrl}?voucher=${code}`)
|
||||
);
|
||||
|
||||
const discordChannel = guild?.channels.cache.get(channel.id);
|
||||
|
||||
if (!discordChannel) return;
|
||||
|
||||
|
@ -109,17 +117,20 @@ export default {
|
|||
discordChannel.send({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:parachute:] Code Drop!")
|
||||
.setTitle("[:parachute:] Credits!")
|
||||
.addFields([
|
||||
{ name: "Code", value: `${code}`, inline: true },
|
||||
{ name: "Amount", value: `${creditAmount}`, inline: true },
|
||||
{ name: "Uses", value: `${uses}`, inline: true },
|
||||
{
|
||||
name: "💶 Credits",
|
||||
value: `${creditAmount}`,
|
||||
inline: true,
|
||||
},
|
||||
])
|
||||
.setDescription(
|
||||
`${interaction.user} dropped a voucher! You can use the code [here](${shopUrl})!`
|
||||
`${interaction.user} dropped a voucher for a maximum **${uses}** members!`
|
||||
)
|
||||
.setColor(successColor),
|
||||
],
|
||||
components: [buttons],
|
||||
});
|
||||
});
|
||||
},
|
|
@ -2,6 +2,6 @@ import give from "./give";
|
|||
import set from "./set";
|
||||
import take from "./take";
|
||||
import transfer from "./transfer";
|
||||
import drop from "./drop";
|
||||
import giveaway from "./giveaway";
|
||||
|
||||
export default { give, set, take, transfer, drop };
|
||||
export default { give, set, take, transfer, giveaway };
|
|
@ -2,15 +2,15 @@
|
|||
import { CommandInteraction, MessageEmbed, Permissions } from "discord.js";
|
||||
|
||||
// Configurations
|
||||
import getEmbedConfig from "../../../../../../helpers/getEmbedConfig";
|
||||
import getEmbedConfig from "../../../../../../../helpers/getEmbedConfig";
|
||||
|
||||
// Handlers
|
||||
import logger from "../../../../../../logger";
|
||||
import logger from "../../../../../../../logger";
|
||||
|
||||
// Helpers
|
||||
|
||||
// Models
|
||||
import fetchUser from "../../../../../../helpers/fetchUser";
|
||||
import fetchUser from "../../../../../../../helpers/fetchUser";
|
||||
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
|
||||
|
||||
// Function
|
||||
|
@ -39,7 +39,6 @@ export default {
|
|||
);
|
||||
},
|
||||
execute: async (interaction: CommandInteraction) => {
|
||||
if (interaction.guild == null) return;
|
||||
const { errorColor, successColor, footerText, footerIcon } =
|
||||
await getEmbedConfig(interaction.guild);
|
||||
const { options, guild } = interaction;
|
|
@ -2,16 +2,16 @@
|
|||
import { CommandInteraction, MessageEmbed, Permissions } from "discord.js";
|
||||
|
||||
// Configurations
|
||||
import getEmbedConfig from "../../../../../../helpers/getEmbedConfig";
|
||||
import getEmbedConfig from "../../../../../../../helpers/getEmbedConfig";
|
||||
|
||||
// Handlers
|
||||
import logger from "../../../../../../logger";
|
||||
import logger from "../../../../../../../logger";
|
||||
|
||||
// Helpers
|
||||
import pluralize from "../../../../../../helpers/pluralize";
|
||||
import pluralize from "../../../../../../../helpers/pluralize";
|
||||
|
||||
// Models
|
||||
import fetchUser from "../../../../../../helpers/fetchUser";
|
||||
import fetchUser from "../../../../../../../helpers/fetchUser";
|
||||
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
|
||||
|
||||
// Function
|
||||
|
@ -40,7 +40,6 @@ export default {
|
|||
);
|
||||
},
|
||||
execute: async (interaction: CommandInteraction) => {
|
||||
if (interaction.guild == null) return;
|
||||
const { errorColor, successColor, footerText, footerIcon } =
|
||||
await getEmbedConfig(interaction.guild); // Destructure
|
||||
const { guild, options } = interaction;
|
|
@ -4,13 +4,13 @@ import { CommandInteraction, MessageEmbed, Permissions } from "discord.js";
|
|||
import mongoose from "mongoose";
|
||||
|
||||
// Configurations
|
||||
import getEmbedConfig from "../../../../../../helpers/getEmbedConfig";
|
||||
import getEmbedConfig from "../../../../../../../helpers/getEmbedConfig";
|
||||
|
||||
// Handlers
|
||||
import logger from "../../../../../../logger";
|
||||
import logger from "../../../../../../../logger";
|
||||
|
||||
// Models
|
||||
import fetchUser from "../../../../../../helpers/fetchUser";
|
||||
import fetchUser from "../../../../../../../helpers/fetchUser";
|
||||
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
|
||||
|
||||
// Function
|
||||
|
@ -45,7 +45,6 @@ export default {
|
|||
);
|
||||
},
|
||||
execute: async (interaction: CommandInteraction) => {
|
||||
if (interaction.guild == null) return;
|
||||
const { errorColor, successColor, footerText, footerIcon } =
|
||||
await getEmbedConfig(interaction.guild); // Destructure member
|
||||
const { guild, options } = interaction;
|
|
@ -6,7 +6,7 @@ import { CommandInteraction } from "discord.js";
|
|||
import modules from "../../commands/profile/modules";
|
||||
|
||||
// Handlers
|
||||
import logger from "../../logger";
|
||||
import logger from "../../../logger";
|
||||
|
||||
export const moduleData = modules;
|
||||
|
|
@ -2,12 +2,12 @@
|
|||
import { CommandInteraction } from "discord.js";
|
||||
|
||||
// Configurations
|
||||
import getEmbedConfig from "../../../helpers/getEmbedConfig";
|
||||
import getEmbedConfig from "../../../../../helpers/getEmbedConfig";
|
||||
|
||||
// Models
|
||||
import fetchUser from "../../../helpers/fetchUser";
|
||||
import fetchUser from "../../../../../helpers/fetchUser";
|
||||
|
||||
import logger from "../../../logger";
|
||||
import logger from "../../../../../logger";
|
||||
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
|
||||
|
||||
// Function
|
||||
|
@ -24,7 +24,6 @@ export default {
|
|||
},
|
||||
|
||||
execute: async (interaction: CommandInteraction) => {
|
||||
if (interaction.guild == null) return;
|
||||
const { successColor, footerText, footerIcon } = await getEmbedConfig(
|
||||
interaction.guild
|
||||
); // Destructure
|
|
@ -6,7 +6,7 @@ import { CommandInteraction } from "discord.js";
|
|||
import modules from "./modules";
|
||||
|
||||
// Handlers
|
||||
import logger from "../../logger";
|
||||
import logger from "../../../logger";
|
||||
|
||||
export const moduleData = modules;
|
||||
|
||||
|
@ -17,13 +17,7 @@ export const builder = new SlashCommandBuilder()
|
|||
.addSubcommand(modules.give.builder);
|
||||
|
||||
export const execute = async (interaction: CommandInteraction) => {
|
||||
const { options } = interaction;
|
||||
|
||||
if (options?.getSubcommand() === "give") {
|
||||
logger?.silly(`Executing give subcommand`);
|
||||
|
||||
if (interaction.options.getSubcommand() === "give") {
|
||||
await modules.give.execute(interaction);
|
||||
}
|
||||
|
||||
logger?.silly(`No subcommand found`);
|
||||
};
|
|
@ -0,0 +1,6 @@
|
|||
import { User } from "discord.js";
|
||||
export default async (to: User | null, from: User | null) => {
|
||||
if (from?.id === to?.id) {
|
||||
throw new Error("You cannot give reputation to yourself.");
|
||||
}
|
||||
};
|
87
src/plugins/commands/reputation/modules/give/index.ts
Normal file
87
src/plugins/commands/reputation/modules/give/index.ts
Normal file
|
@ -0,0 +1,87 @@
|
|||
import { CommandInteraction } from "discord.js";
|
||||
import getEmbedConfig from "../../../../../helpers/getEmbedConfig";
|
||||
import { timeout } from "../../../../../config/reputation";
|
||||
import logger from "../../../../../logger";
|
||||
import fetchUser from "../../../../../helpers/fetchUser";
|
||||
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
|
||||
import * as cooldown from "../../../../../helpers/cooldown";
|
||||
import noSelfReputation from "./components/noSelfReputation";
|
||||
|
||||
export default {
|
||||
metadata: { guildOnly: true, ephemeral: true },
|
||||
|
||||
builder: (command: SlashCommandSubcommandBuilder) => {
|
||||
return command
|
||||
.setName("give")
|
||||
.setDescription("Give reputation to a user")
|
||||
.addUserOption((option) =>
|
||||
option
|
||||
.setName("target")
|
||||
.setDescription("The user you want to repute.")
|
||||
.setRequired(true)
|
||||
)
|
||||
.addStringOption((option) =>
|
||||
option
|
||||
.setName("type")
|
||||
.setDescription("What type of reputation you want to repute")
|
||||
.setRequired(true)
|
||||
.addChoices(
|
||||
{ name: "Positive", value: "positive" },
|
||||
{
|
||||
name: "Negative",
|
||||
value: "negative",
|
||||
}
|
||||
)
|
||||
);
|
||||
},
|
||||
execute: async (interaction: CommandInteraction) => {
|
||||
const { options, user, guild } = interaction;
|
||||
|
||||
const { errorColor, successColor, footerText, footerIcon } =
|
||||
await getEmbedConfig(guild); // Destructure
|
||||
|
||||
const optionTarget = options?.getUser("target");
|
||||
const optionType = options?.getString("type");
|
||||
|
||||
if (!guild) throw new Error("Guild is undefined");
|
||||
|
||||
const userObj = await fetchUser(user, guild);
|
||||
if (!userObj) throw new Error("User is undefined");
|
||||
|
||||
// Pre-checks
|
||||
await noSelfReputation(optionTarget, user);
|
||||
|
||||
// Check if user is on cooldown otherwise create one
|
||||
await cooldown.interaction(interaction, timeout);
|
||||
|
||||
switch (optionType) {
|
||||
case "positive":
|
||||
userObj.reputation += 1;
|
||||
break;
|
||||
case "negative":
|
||||
userObj.reputation += 1;
|
||||
break;
|
||||
default:
|
||||
throw new Error("Invalid reputation type");
|
||||
}
|
||||
|
||||
await userObj.save().then(async () => {
|
||||
logger.silly(`User reputation has been updated`);
|
||||
|
||||
await interaction.editReply({
|
||||
embeds: [
|
||||
{
|
||||
title: "[:loudspeaker:] Give",
|
||||
description: `You have given a ${optionType} repute to ${optionTarget}`,
|
||||
timestamp: new Date(),
|
||||
color: successColor,
|
||||
footer: {
|
||||
iconURL: footerIcon,
|
||||
text: footerText,
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
},
|
||||
};
|
|
@ -6,7 +6,7 @@ import { CommandInteraction } from "discord.js";
|
|||
import modules from "./modules";
|
||||
|
||||
// Handlers
|
||||
import logger from "../../logger";
|
||||
import logger from "../../../logger";
|
||||
|
||||
export const moduleData = modules;
|
||||
|
||||
|
@ -14,16 +14,16 @@ export const moduleData = modules;
|
|||
export const builder = new SlashCommandBuilder()
|
||||
.setName("shop")
|
||||
.setDescription("Shop for credits and custom roles.")
|
||||
.addSubcommand(modules.pterodactyl.builder)
|
||||
.addSubcommand(modules.cpgg.builder)
|
||||
.addSubcommandGroup(modules.roles.builder);
|
||||
|
||||
export const execute = async (interaction: CommandInteraction) => {
|
||||
const { options } = interaction;
|
||||
|
||||
if (options?.getSubcommand() === "pterodactyl") {
|
||||
logger.silly(`Executing pterodactyl subcommand`);
|
||||
if (options?.getSubcommand() === "cpgg") {
|
||||
logger.silly(`Executing cpgg subcommand`);
|
||||
|
||||
return modules.pterodactyl.execute(interaction);
|
||||
return modules.cpgg.execute(interaction);
|
||||
}
|
||||
|
||||
if (options?.getSubcommandGroup() === "roles") {
|
|
@ -1,25 +1,30 @@
|
|||
import { CommandInteraction } from "discord.js";
|
||||
import {
|
||||
CommandInteraction,
|
||||
MessageActionRow,
|
||||
MessageButton,
|
||||
} from "discord.js";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import axios from "axios";
|
||||
|
||||
import getEmbedConfig from "../../../helpers/getEmbedConfig";
|
||||
import getEmbedConfig from "../../../../../helpers/getEmbedConfig";
|
||||
|
||||
import logger from "../../../logger";
|
||||
import encryption from "../../../handlers/encryption";
|
||||
import logger from "../../../../../logger";
|
||||
import encryption from "../../../../../handlers/encryption";
|
||||
|
||||
import pluralize from "../../../helpers/pluralize";
|
||||
import pluralize from "../../../../../helpers/pluralize";
|
||||
|
||||
import apiSchema from "../../../database/schemas/api";
|
||||
import fetchUser from "../../../helpers/fetchUser";
|
||||
import apiSchema from "../../../../../models/api";
|
||||
import fetchUser from "../../../../../helpers/fetchUser";
|
||||
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
|
||||
import { message } from "../../../../../helpers/cooldown/index";
|
||||
|
||||
export default {
|
||||
metadata: { guildOnly: true, ephemeral: true },
|
||||
|
||||
builder: (command: SlashCommandSubcommandBuilder) => {
|
||||
return command
|
||||
.setName("pterodactyl")
|
||||
.setDescription("Buy pterodactyl power.")
|
||||
.setName("cpgg")
|
||||
.setDescription("Buy cpgg power.")
|
||||
.addIntegerOption((option) =>
|
||||
option
|
||||
.setName("amount")
|
||||
|
@ -27,7 +32,6 @@ export default {
|
|||
);
|
||||
},
|
||||
execute: async (interaction: CommandInteraction) => {
|
||||
if (interaction.guild == null) return;
|
||||
const { errorColor, successColor, footerText, footerIcon } =
|
||||
await getEmbedConfig(interaction.guild);
|
||||
const { options, guild, user, client } = interaction;
|
||||
|
@ -71,8 +75,8 @@ export default {
|
|||
return interaction?.editReply({
|
||||
embeds: [
|
||||
{
|
||||
title: ":shopping_cart: Shop [Pterodactyl]",
|
||||
description: `You **can't** withdraw for __Pterodactyl__ below **100**.`,
|
||||
title: "[:shopping_cart:] CPGG",
|
||||
description: `You **can't** withdraw for __CPGG__ below **100**.`,
|
||||
color: errorColor,
|
||||
fields: [
|
||||
{
|
||||
|
@ -96,9 +100,9 @@ export default {
|
|||
return interaction?.editReply({
|
||||
embeds: [
|
||||
{
|
||||
title: ":shopping_cart: Shop [Pterodactyl]",
|
||||
title: "[:shopping_cart:] CPGG",
|
||||
description:
|
||||
"You **can't** withdraw for __Pterodactyl__ above **1.000.000**.",
|
||||
"You **can't** withdraw for __CPGG__ above **1.000.000**.",
|
||||
color: errorColor,
|
||||
fields: [
|
||||
{
|
||||
|
@ -122,7 +126,7 @@ export default {
|
|||
return interaction?.editReply({
|
||||
embeds: [
|
||||
{
|
||||
title: ":shopping_cart: Shop [Pterodactyl]",
|
||||
title: "[:shopping_cart:] CPGG",
|
||||
description: `You have **insufficient** credits.`,
|
||||
color: errorColor,
|
||||
fields: [
|
||||
|
@ -150,13 +154,21 @@ export default {
|
|||
if (!apiCredentials) return;
|
||||
|
||||
const api = axios?.create({
|
||||
baseURL: apiCredentials.url,
|
||||
baseURL: `${apiCredentials.url}/api/`,
|
||||
headers: {
|
||||
Authorization: `Bearer ${encryption.decrypt(apiCredentials.token)}`,
|
||||
},
|
||||
});
|
||||
|
||||
const shopUrl = apiCredentials?.url?.replace("/api", "/store");
|
||||
const shopUrl = `${apiCredentials?.url}/store`;
|
||||
|
||||
const buttons = new MessageActionRow().addComponents(
|
||||
new MessageButton()
|
||||
.setLabel("Redeem it here")
|
||||
.setStyle("LINK")
|
||||
.setEmoji("🏦")
|
||||
.setURL(`${shopUrl}?voucher=${code}`)
|
||||
);
|
||||
|
||||
await api
|
||||
|
||||
|
@ -178,15 +190,17 @@ export default {
|
|||
?.then(async () => {
|
||||
logger?.silly(`Successfully saved new credits.`);
|
||||
|
||||
await dmUser?.send({
|
||||
if (!interaction.guild) throw new Error("Guild is undefined");
|
||||
|
||||
await dmUser
|
||||
?.send({
|
||||
embeds: [
|
||||
{
|
||||
title: ":shopping_cart: Shop [Pterodactyl]",
|
||||
description: `Redeem this voucher [here](${shopUrl})!`,
|
||||
title: "[:shopping_cart:] CPGG",
|
||||
description: `This voucher comes from **${interaction.guild.name}**.`,
|
||||
fields: [
|
||||
{ name: "Code", value: `${code}`, inline: true },
|
||||
{
|
||||
name: "Credits",
|
||||
name: "💶 Credits",
|
||||
value: `${optionAmount || userDB?.credits}`,
|
||||
inline: true,
|
||||
},
|
||||
|
@ -199,13 +213,14 @@ export default {
|
|||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
components: [buttons],
|
||||
})
|
||||
.then(async (msg) => {
|
||||
return interaction?.editReply({
|
||||
embeds: [
|
||||
{
|
||||
title: ":shopping_cart: Shop [Pterodactyl]",
|
||||
description: "I have sent you the code in DM!",
|
||||
title: "[:shopping_cart:] CPGG",
|
||||
description: `I have sent you the code in [DM](${msg.url})!`,
|
||||
color: successColor,
|
||||
timestamp: new Date(),
|
||||
footer: {
|
||||
|
@ -215,6 +230,7 @@ export default {
|
|||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
})
|
||||
|
||||
.catch(async (error) => {
|
||||
|
@ -223,7 +239,7 @@ export default {
|
|||
return interaction?.editReply({
|
||||
embeds: [
|
||||
{
|
||||
title: ":shopping_cart: Shop [Pterodactyl]",
|
||||
title: "[:shopping_cart:] CPGG",
|
||||
description: "Something went wrong.",
|
||||
color: errorColor,
|
||||
timestamp: new Date(),
|
||||
|
@ -243,7 +259,7 @@ export default {
|
|||
return interaction?.editReply({
|
||||
embeds: [
|
||||
{
|
||||
title: ":shopping_cart: Shop [Pterodactyl]",
|
||||
title: "[:shopping_cart:] CPGG",
|
||||
description: "Something went wrong.",
|
||||
color: errorColor,
|
||||
timestamp: new Date(),
|
4
src/plugins/commands/shop/modules/index.ts
Normal file
4
src/plugins/commands/shop/modules/index.ts
Normal file
|
@ -0,0 +1,4 @@
|
|||
import cpgg from "./cpgg";
|
||||
import * as roles from "./roles";
|
||||
|
||||
export default { cpgg, roles };
|
|
@ -3,14 +3,14 @@ import { SlashCommandSubcommandGroupBuilder } from "@discordjs/builders";
|
|||
import { CommandInteraction } from "discord.js";
|
||||
|
||||
// Handlers
|
||||
import logger from "../../../../logger";
|
||||
import logger from "../../../../../logger";
|
||||
|
||||
import getEmbedConfig from "../../../../helpers/getEmbedConfig";
|
||||
import getEmbedConfig from "../../../../../helpers/getEmbedConfig";
|
||||
|
||||
// Modules
|
||||
import modules from "./modules";
|
||||
|
||||
import guildSchema from "../../../../database/schemas/guild";
|
||||
import guildSchema from "../../../../../models/guild";
|
||||
|
||||
export const moduleData = modules;
|
||||
|
|
@ -6,17 +6,17 @@ import {
|
|||
} from "discord.js";
|
||||
|
||||
// Configurations
|
||||
import getEmbedConfig from "../../../../../helpers/getEmbedConfig";
|
||||
import getEmbedConfig from "../../../../../../../helpers/getEmbedConfig";
|
||||
|
||||
// Models
|
||||
import shopRolesSchema from "../../../../../database/schemas/shopRole";
|
||||
import guildSchema from "../../../../../database/schemas/guild";
|
||||
import shopRolesSchema from "../../../../../../../models/shopRole";
|
||||
import guildSchema from "../../../../../../../models/guild";
|
||||
|
||||
import logger from "../../../../../logger";
|
||||
import logger from "../../../../../../../logger";
|
||||
|
||||
// Helpers
|
||||
import pluralize from "../../../../../helpers/pluralize";
|
||||
import fetchUser from "../../../../../helpers/fetchUser";
|
||||
import pluralize from "../../../../../../../helpers/pluralize";
|
||||
import fetchUser from "../../../../../../../helpers/fetchUser";
|
||||
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
|
||||
|
||||
// Function
|
||||
|
@ -41,7 +41,6 @@ export default {
|
|||
);
|
||||
},
|
||||
execute: async (interaction: CommandInteraction) => {
|
||||
if (interaction.guild == null) return;
|
||||
const { errorColor, successColor, footerText, footerIcon } =
|
||||
await getEmbedConfig(interaction.guild);
|
||||
const { options, guild, user, member } = interaction;
|
|
@ -2,16 +2,16 @@
|
|||
import { CommandInteraction, GuildMemberRoleManager } from "discord.js";
|
||||
|
||||
// Configurations
|
||||
import getEmbedConfig from "../../../../../helpers/getEmbedConfig";
|
||||
import getEmbedConfig from "../../../../../../../helpers/getEmbedConfig";
|
||||
|
||||
// Models
|
||||
import shopRolesSchema from "../../../../../database/schemas/shopRole";
|
||||
import shopRolesSchema from "../../../../../../../models/shopRole";
|
||||
|
||||
import logger from "../../../../../logger";
|
||||
import logger from "../../../../../../../logger";
|
||||
|
||||
// Helpers
|
||||
import pluralize from "../../../../../helpers/pluralize";
|
||||
import fetchUser from "../../../../../helpers/fetchUser";
|
||||
import pluralize from "../../../../../../../helpers/pluralize";
|
||||
import fetchUser from "../../../../../../../helpers/fetchUser";
|
||||
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
|
||||
|
||||
// Function
|
||||
|
@ -30,7 +30,6 @@ export default {
|
|||
);
|
||||
},
|
||||
execute: async (interaction: CommandInteraction) => {
|
||||
if (interaction.guild == null) return;
|
||||
const { errorColor, successColor, footerText, footerIcon } =
|
||||
await getEmbedConfig(interaction.guild);
|
||||
const { options, guild, user, member } = interaction;
|
|
@ -1,16 +1,9 @@
|
|||
// Dependencies
|
||||
import { SlashCommandBuilder } from "@discordjs/builders";
|
||||
import { CommandInteraction } from "discord.js";
|
||||
|
||||
// Modules
|
||||
import modules from "../../commands/utility/modules";
|
||||
|
||||
// Handlers
|
||||
import logger from "../../logger";
|
||||
|
||||
import modules from "./modules";
|
||||
export const moduleData = modules;
|
||||
|
||||
// Function
|
||||
export const builder = new SlashCommandBuilder()
|
||||
.setName("utility")
|
||||
.setDescription("Common utility.")
|
||||
|
@ -21,9 +14,7 @@ export const builder = new SlashCommandBuilder()
|
|||
.addSubcommand(modules.avatar.builder);
|
||||
|
||||
export const execute = async (interaction: CommandInteraction) => {
|
||||
const { options } = interaction;
|
||||
|
||||
switch (options.getSubcommand()) {
|
||||
switch (interaction.options.getSubcommand()) {
|
||||
case "lookup":
|
||||
return modules.lookup.execute(interaction);
|
||||
case "about":
|
||||
|
@ -33,6 +24,8 @@ export const execute = async (interaction: CommandInteraction) => {
|
|||
case "avatar":
|
||||
return modules.avatar.execute(interaction);
|
||||
default:
|
||||
logger.error(`Unknown subcommand ${options.getSubcommand()}`);
|
||||
throw new Error(
|
||||
`Unknown subcommand: ${interaction.options.getSubcommand()}`
|
||||
);
|
||||
}
|
||||
};
|
71
src/plugins/commands/utility/modules/about/index.ts
Normal file
71
src/plugins/commands/utility/modules/about/index.ts
Normal file
|
@ -0,0 +1,71 @@
|
|||
// Dependencies
|
||||
import {
|
||||
CommandInteraction,
|
||||
MessageActionRow,
|
||||
MessageButton,
|
||||
} from "discord.js";
|
||||
|
||||
// Configurations
|
||||
import getEmbedConfig from "../../../../../helpers/getEmbedConfig";
|
||||
|
||||
import { hosterName, hosterUrl } from "../../../../../config/other";
|
||||
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
|
||||
|
||||
// Function
|
||||
export default {
|
||||
metadata: { guildOnly: false, ephemeral: false },
|
||||
|
||||
builder: (command: SlashCommandSubcommandBuilder) => {
|
||||
return command.setName("about").setDescription("About this bot!)");
|
||||
},
|
||||
execute: async (interaction: CommandInteraction) => {
|
||||
const { successColor, footerText, footerIcon } = await getEmbedConfig(
|
||||
interaction.guild
|
||||
);
|
||||
|
||||
const buttons = new MessageActionRow().addComponents(
|
||||
new MessageButton()
|
||||
.setLabel("Source Code")
|
||||
.setStyle("LINK")
|
||||
.setEmoji("📄")
|
||||
.setURL("https://github.com/ZynerOrg/xyter"),
|
||||
new MessageButton()
|
||||
.setLabel("Website")
|
||||
.setStyle("LINK")
|
||||
.setEmoji("🌐")
|
||||
.setURL("https://zyner.org"),
|
||||
new MessageButton()
|
||||
.setLabel("Get Help")
|
||||
.setStyle("LINK")
|
||||
.setEmoji("💬")
|
||||
.setURL("https://discord.zyner.org"),
|
||||
new MessageButton()
|
||||
.setLabel(`Hosted by ${hosterName}`)
|
||||
.setStyle("LINK")
|
||||
.setEmoji("⚒️")
|
||||
.setURL(`${hosterUrl}`)
|
||||
);
|
||||
|
||||
const interactionEmbed = {
|
||||
title: "[:tools:] About",
|
||||
description: `
|
||||
**Xyter**'s goal is to provide a __privacy-friendly__ discord bot.
|
||||
We created **Xyter** to **replace the mess** of having a dozen or so bots in __your__ community.
|
||||
On top of this, you can also see our **source code** for **security** and **privacy** issues.
|
||||
As well as making your own **fork** of the bot, you can also get **help** from our community.
|
||||
|
||||
Developed with ❤️ by **Zyner**, a non-profit project by teens.
|
||||
`,
|
||||
color: successColor,
|
||||
timestamp: new Date(),
|
||||
footer: {
|
||||
iconURL: footerIcon,
|
||||
text: footerText,
|
||||
},
|
||||
};
|
||||
await interaction.editReply({
|
||||
embeds: [interactionEmbed],
|
||||
components: [buttons],
|
||||
});
|
||||
},
|
||||
};
|
|
@ -1,4 +1,4 @@
|
|||
import getEmbedConfig from "../../../helpers/getEmbedConfig";
|
||||
import getEmbedConfig from "../../../../../helpers/getEmbedConfig";
|
||||
|
||||
import { CommandInteraction, MessageEmbed } from "discord.js";
|
||||
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
|
||||
|
@ -17,7 +17,6 @@ export default {
|
|||
);
|
||||
},
|
||||
execute: async (interaction: CommandInteraction) => {
|
||||
if (interaction.guild == null) return;
|
||||
const { successColor, footerText, footerIcon } = await getEmbedConfig(
|
||||
interaction.guild
|
||||
);
|
|
@ -1,11 +1,11 @@
|
|||
import axios from "axios";
|
||||
import { CommandInteraction } from "discord.js";
|
||||
|
||||
import getEmbedConfig from "../../../helpers/getEmbedConfig";
|
||||
import getEmbedConfig from "../../../../../helpers/getEmbedConfig";
|
||||
|
||||
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
|
||||
|
||||
import embedBuilder from "../../../helpers/embedBuilder";
|
||||
import embedBuilder from "../../../../../helpers/embedBuilder";
|
||||
|
||||
export default {
|
||||
metadata: { guildOnly: false, ephemeral: false },
|
||||
|
@ -24,7 +24,6 @@ export default {
|
|||
);
|
||||
},
|
||||
execute: async (interaction: CommandInteraction) => {
|
||||
if (interaction.guild == null) return;
|
||||
const { errorColor, successColor, footerText, footerIcon } =
|
||||
await getEmbedConfig(interaction.guild);
|
||||
const embedTitle = "[:hammer:] Utility (Lookup)";
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue