xyter/src/plugins/shop/modules/pterodactyl.ts
2022-04-13 17:22:22 +02:00

242 lines
7 KiB
TypeScript

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