250 lines
6.4 KiB
TypeScript
250 lines
6.4 KiB
TypeScript
// Dependencies
|
|
import { CommandInteraction, MessageEmbed } from "discord.js";
|
|
|
|
// Configurations
|
|
import getEmbedConfig from "../../../../../helpers/getEmbedConfig";
|
|
|
|
// Handlers
|
|
import logger from "../../../../../logger";
|
|
|
|
import mongoose from "mongoose";
|
|
|
|
// Models
|
|
import fetchUser from "../../../../../helpers/fetchUser";
|
|
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
|
|
|
|
// Function
|
|
export default {
|
|
metadata: { guildOnly: true, ephemeral: true },
|
|
|
|
builder: (command: SlashCommandSubcommandBuilder) => {
|
|
return command
|
|
.setName("gift")
|
|
.setDescription(`Gift a user credits`)
|
|
.addUserOption((option) =>
|
|
option
|
|
.setName("user")
|
|
.setDescription("The user you want to gift credits to.")
|
|
.setRequired(true)
|
|
)
|
|
.addIntegerOption((option) =>
|
|
option
|
|
.setName("amount")
|
|
.setDescription("The amount of credits you want to gift.")
|
|
.setRequired(true)
|
|
)
|
|
.addStringOption((option) =>
|
|
option.setName("reason").setDescription("Your reason.")
|
|
);
|
|
},
|
|
execute: async (interaction: CommandInteraction) => {
|
|
const { errorColor, successColor, footerText, footerIcon } =
|
|
await getEmbedConfig(interaction.guild);
|
|
const { options, user, guild, client } = interaction;
|
|
|
|
const optionUser = options.getUser("user");
|
|
const optionAmount = options.getInteger("amount");
|
|
const optionReason = options.getString("reason");
|
|
|
|
const embed = new MessageEmbed()
|
|
.setTitle("[:dollar:] Gift")
|
|
.setTimestamp(new Date())
|
|
.setFooter({ text: footerText, iconURL: footerIcon });
|
|
|
|
if (guild === null) {
|
|
logger.silly(`Guild is null`);
|
|
|
|
return interaction.editReply({
|
|
embeds: [
|
|
embed.setDescription("Guild is not found").setColor(errorColor),
|
|
],
|
|
});
|
|
}
|
|
|
|
if (optionUser === null) {
|
|
logger.silly(`User not found`);
|
|
|
|
return interaction.editReply({
|
|
embeds: [
|
|
embed
|
|
.setDescription(`User is not found in this guild`)
|
|
.setColor(errorColor),
|
|
],
|
|
});
|
|
}
|
|
|
|
// Get fromUserDB object
|
|
const fromUserDB = await fetchUser(user, guild);
|
|
|
|
// Get toUserDB object
|
|
const toUserDB = await fetchUser(optionUser, guild);
|
|
|
|
if (fromUserDB === null) {
|
|
logger.silly(`User not found`);
|
|
|
|
return interaction.editReply({
|
|
embeds: [
|
|
embed
|
|
.setDescription(
|
|
"You do not have any credits. Please write something in the chat to get some."
|
|
)
|
|
.setColor(errorColor),
|
|
],
|
|
});
|
|
}
|
|
|
|
if (toUserDB === null) {
|
|
logger.silly(`User not found`);
|
|
|
|
return interaction.editReply({
|
|
embeds: [
|
|
embed
|
|
.setDescription(
|
|
"The user you want to gift credits to does not have any credits. Please wait until that user has typed something in the chat to get some."
|
|
)
|
|
.setColor(errorColor),
|
|
],
|
|
});
|
|
}
|
|
|
|
// If receiver is same as sender
|
|
if (optionUser.id === user.id) {
|
|
logger.silly(`User is same as sender`);
|
|
|
|
return interaction.editReply({
|
|
embeds: [
|
|
embed
|
|
.setDescription(
|
|
"You can't gift credits to yourself. Please choose a different user."
|
|
)
|
|
.setColor(errorColor),
|
|
],
|
|
});
|
|
}
|
|
|
|
// If amount is null
|
|
if (optionAmount === null) {
|
|
logger.silly(`Amount is null`);
|
|
|
|
return interaction.editReply({
|
|
embeds: [
|
|
embed
|
|
.setDescription(
|
|
"Please specify the amount of credits you want to gift."
|
|
)
|
|
.setColor(errorColor),
|
|
],
|
|
});
|
|
}
|
|
|
|
// If amount is zero or below
|
|
if (optionAmount <= 0) {
|
|
logger.silly(`Amount is zero or below`);
|
|
|
|
return interaction.editReply({
|
|
embeds: [
|
|
embed
|
|
.setDescription(
|
|
"Please specify a valid amount of credits you want to gift."
|
|
)
|
|
.setColor(errorColor),
|
|
],
|
|
});
|
|
}
|
|
|
|
// If user has below gifting amount
|
|
if (fromUserDB.credits < optionAmount) {
|
|
logger.silly(`User has below gifting amount`);
|
|
|
|
return interaction.editReply({
|
|
embeds: [
|
|
embed
|
|
.setDescription(
|
|
"You don't have enough credits to gift that amount. Please try again with a lower amount."
|
|
)
|
|
.setColor(errorColor),
|
|
],
|
|
});
|
|
}
|
|
|
|
// If toUserDB has no credits
|
|
if (toUserDB === null) {
|
|
logger.silly(`User has no credits`);
|
|
|
|
return interaction.editReply({
|
|
embeds: [
|
|
embed
|
|
.setDescription(
|
|
"The user you want to gift credits to does not have any credits. Please wait until that user has typed something in the chat to get some."
|
|
)
|
|
.setColor(errorColor),
|
|
],
|
|
});
|
|
}
|
|
|
|
const session = await mongoose.startSession();
|
|
|
|
session.startTransaction();
|
|
|
|
try {
|
|
// Withdraw amount from fromUserDB
|
|
fromUserDB.credits -= optionAmount;
|
|
|
|
// Deposit amount to toUserDB
|
|
toUserDB.credits += optionAmount;
|
|
|
|
await fromUserDB.save();
|
|
|
|
await toUserDB.save();
|
|
|
|
await session.commitTransaction();
|
|
} catch (error) {
|
|
await session.abortTransaction();
|
|
session.endSession();
|
|
logger.error(`${error}`);
|
|
|
|
return interaction.editReply({
|
|
embeds: [
|
|
embed
|
|
.setDescription(
|
|
"An error occurred while trying to gift credits. Please try again."
|
|
)
|
|
.setColor(errorColor),
|
|
],
|
|
});
|
|
} finally {
|
|
// ending the session
|
|
session.endSession();
|
|
}
|
|
|
|
// Get DM user object
|
|
const dmUser = client.users.cache.get(optionUser.id);
|
|
|
|
if (!dmUser) throw new Error("User not found");
|
|
|
|
// Send DM to user
|
|
await dmUser.send({
|
|
embeds: [
|
|
embed
|
|
.setDescription(
|
|
`${user.tag} has gifted you ${optionAmount} credits with reason: ${
|
|
optionReason || "unspecified"
|
|
}`
|
|
)
|
|
.setColor(successColor),
|
|
],
|
|
});
|
|
|
|
return interaction.editReply({
|
|
embeds: [
|
|
embed
|
|
.setDescription(
|
|
`Successfully gifted ${optionAmount} credits to ${
|
|
optionUser.tag
|
|
} with reason: ${optionReason || "unspecified"}`
|
|
)
|
|
.setColor(successColor),
|
|
],
|
|
});
|
|
},
|
|
};
|