✨ button cooldowns
This commit is contained in:
parent
e1ae56e360
commit
24e44f7235
16 changed files with 173 additions and 263 deletions
|
@ -1,5 +1,5 @@
|
|||
// Dependencies
|
||||
import { CommandInteraction, Message } from "discord.js";
|
||||
import { CommandInteraction, ButtonInteraction, Message } from "discord.js";
|
||||
|
||||
import logger from "../../logger";
|
||||
|
||||
|
@ -7,7 +7,7 @@ import getEmbedConfig from "../../helpers/getEmbedConfig";
|
|||
import timeoutSchema from "../../models/timeout";
|
||||
import addSeconds from "../../helpers/addSeconds";
|
||||
|
||||
export const interaction = async (i: CommandInteraction, cooldown: number) => {
|
||||
export const command = async (i: CommandInteraction, cooldown: number) => {
|
||||
const { guild, user, commandId } = i;
|
||||
|
||||
// Check if user has a timeout
|
||||
|
@ -56,12 +56,57 @@ export const interaction = async (i: CommandInteraction, cooldown: number) => {
|
|||
});
|
||||
};
|
||||
|
||||
export const message = async (
|
||||
message: Message,
|
||||
cooldown: number,
|
||||
id: string
|
||||
) => {
|
||||
const { guild, member } = message;
|
||||
export const button = async (i: ButtonInteraction, cooldown: number) => {
|
||||
const { guild, user, customId } = i;
|
||||
|
||||
// Check if user has a timeout
|
||||
const hasTimeout = await timeoutSchema.findOne({
|
||||
guildId: guild?.id || "0",
|
||||
userId: user.id,
|
||||
cooldown: cooldown,
|
||||
timeoutId: customId,
|
||||
});
|
||||
|
||||
// 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: customId,
|
||||
});
|
||||
};
|
||||
|
||||
export const message = async (msg: Message, cooldown: number, id: string) => {
|
||||
const { guild, member } = msg;
|
||||
if (!guild) throw new Error("Guild is undefined");
|
||||
if (!member) throw new Error("Member is undefined");
|
||||
|
||||
|
|
|
@ -1,25 +1,26 @@
|
|||
import { CommandInteraction, MessageEmbed } from "discord.js";
|
||||
import { Interaction, MessageEmbed } from "discord.js";
|
||||
import getEmbedConfig from "../../helpers/getEmbedConfig";
|
||||
|
||||
export default async (interaction: CommandInteraction, ephemeral: boolean) => {
|
||||
export default async (interaction: Interaction, ephemeral: boolean) => {
|
||||
if (!interaction.isRepliable())
|
||||
throw new Error(`Cannot reply to an interaction that is not repliable`);
|
||||
|
||||
await interaction.deferReply({
|
||||
ephemeral,
|
||||
});
|
||||
|
||||
const { waitColor, footerText, footerIcon } = await getEmbedConfig(
|
||||
interaction.guild
|
||||
);
|
||||
const embedConfig = await getEmbedConfig(interaction.guild);
|
||||
|
||||
await interaction.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setFooter({
|
||||
text: footerText,
|
||||
iconURL: footerIcon,
|
||||
text: embedConfig.footerText,
|
||||
iconURL: embedConfig.footerIcon,
|
||||
})
|
||||
.setTimestamp(new Date())
|
||||
.setTitle("Processing your request")
|
||||
.setColor(waitColor)
|
||||
.setColor(embedConfig.waitColor)
|
||||
.setDescription("Please wait..."),
|
||||
],
|
||||
});
|
||||
|
|
|
@ -4,7 +4,7 @@ import { Client } from "discord.js";
|
|||
import * as roles from "./modules/roles";
|
||||
|
||||
export const options = {
|
||||
schedule: "*/5 * * * * *", // https://crontab.guru/
|
||||
schedule: "*/5 * * * *", // https://crontab.guru/
|
||||
};
|
||||
|
||||
export const execute = async (client: Client) => {
|
||||
|
|
|
@ -4,7 +4,7 @@ import { IEncryptionData } from "../interfaces/EncryptionData";
|
|||
|
||||
export interface IApi {
|
||||
guildId: Snowflake;
|
||||
url: string;
|
||||
url: IEncryptionData;
|
||||
token: IEncryptionData;
|
||||
}
|
||||
|
||||
|
@ -17,11 +17,18 @@ const apiSchema = new Schema<IApi>(
|
|||
index: true,
|
||||
},
|
||||
url: {
|
||||
type: String,
|
||||
required: true,
|
||||
unique: false,
|
||||
index: true,
|
||||
default: "https://localhost/api/",
|
||||
iv: {
|
||||
type: String,
|
||||
required: true,
|
||||
unique: false,
|
||||
index: true,
|
||||
},
|
||||
content: {
|
||||
type: String,
|
||||
required: true,
|
||||
unique: false,
|
||||
index: true,
|
||||
},
|
||||
},
|
||||
token: {
|
||||
iv: {
|
||||
|
@ -29,14 +36,12 @@ const apiSchema = new Schema<IApi>(
|
|||
required: true,
|
||||
unique: false,
|
||||
index: true,
|
||||
default: "token",
|
||||
},
|
||||
content: {
|
||||
type: String,
|
||||
required: true,
|
||||
unique: false,
|
||||
index: true,
|
||||
default: "token",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
@ -54,7 +54,7 @@ export default {
|
|||
embeds: [
|
||||
embed
|
||||
.setDescription(
|
||||
`Below are the top 10 users in this guild.
|
||||
`Below are the top ten members in this guild.
|
||||
|
||||
${topTen.map(entry).join("\n")}
|
||||
`
|
||||
|
|
|
@ -45,7 +45,7 @@ export default {
|
|||
|
||||
const guildDB = await fetchGuild(guild);
|
||||
|
||||
await cooldown.interaction(interaction, guildDB?.credits?.workTimeout);
|
||||
await cooldown.command(interaction, guildDB?.credits?.workTimeout);
|
||||
|
||||
const creditsEarned = chance.integer({
|
||||
min: 0,
|
||||
|
|
|
@ -75,14 +75,16 @@ export default {
|
|||
|
||||
if (!apiCredentials) return;
|
||||
|
||||
const url = encryption.decrypt(apiCredentials?.url);
|
||||
|
||||
const api = axios?.create({
|
||||
baseURL: `${apiCredentials?.url}/api/`,
|
||||
baseURL: `${url}/api/`,
|
||||
headers: {
|
||||
Authorization: `Bearer ${encryption.decrypt(apiCredentials.token)}`,
|
||||
},
|
||||
});
|
||||
|
||||
const shopUrl = `${apiCredentials?.url}/store`;
|
||||
const shopUrl = `${url}/store`;
|
||||
|
||||
await api
|
||||
.post("vouchers", {
|
||||
|
|
|
@ -52,7 +52,7 @@ export default {
|
|||
await noSelfReputation(optionTarget, user);
|
||||
|
||||
// Check if user is on cooldown otherwise create one
|
||||
await cooldown.interaction(interaction, timeout);
|
||||
await cooldown.command(interaction, timeout);
|
||||
|
||||
switch (optionType) {
|
||||
case "positive":
|
||||
|
|
|
@ -153,15 +153,16 @@ export default {
|
|||
});
|
||||
|
||||
if (!apiCredentials) return;
|
||||
const url = encryption.decrypt(apiCredentials?.url);
|
||||
|
||||
const api = axios?.create({
|
||||
baseURL: `${apiCredentials.url}/api/`,
|
||||
baseURL: `${url}/api/`,
|
||||
headers: {
|
||||
Authorization: `Bearer ${encryption.decrypt(apiCredentials.token)}`,
|
||||
},
|
||||
});
|
||||
|
||||
const shopUrl = `${apiCredentials?.url}/store`;
|
||||
const shopUrl = `${url}/store`;
|
||||
|
||||
const buttons = new MessageActionRow().addComponents(
|
||||
new MessageButton()
|
||||
|
|
|
@ -1,51 +0,0 @@
|
|||
import { CommandInteraction, MessageEmbed } from "discord.js";
|
||||
import * as cooldown from "../../../../helpers/cooldown";
|
||||
import logger from "../../../../logger";
|
||||
|
||||
export default async (
|
||||
interaction: CommandInteraction,
|
||||
metadata: any,
|
||||
embedConfig: any
|
||||
) => {
|
||||
if (
|
||||
metadata.permissions &&
|
||||
metadata.guildOnly &&
|
||||
!interaction.memberPermissions?.has(metadata.permissions)
|
||||
) {
|
||||
return interaction?.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:x:] Permission")
|
||||
.setDescription(`You do not have the permission to manage the bot.`)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(embedConfig.errorColor)
|
||||
.setFooter({
|
||||
text: embedConfig.footerText,
|
||||
iconURL: embedConfig.footerIcon,
|
||||
}),
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
logger.info(metadata);
|
||||
|
||||
if (metadata.cooldown) {
|
||||
await cooldown
|
||||
.interaction(interaction, metadata.cooldown)
|
||||
.catch(async (error) => {
|
||||
throw new Error("Cooldown error: " + error);
|
||||
});
|
||||
}
|
||||
|
||||
if (metadata.guildOnly) {
|
||||
if (!interaction.guild) {
|
||||
throw new Error("This command is guild only.");
|
||||
}
|
||||
}
|
||||
|
||||
if (metadata.dmOnly) {
|
||||
if (interaction.guild) {
|
||||
throw new Error("This command is DM only.");
|
||||
}
|
||||
}
|
||||
};
|
|
@ -1,123 +0,0 @@
|
|||
// Dependencies
|
||||
import { CommandInteraction, MessageEmbed } from "discord.js";
|
||||
|
||||
import logger from "../../../../logger";
|
||||
|
||||
import deferReply from "../../../../helpers/deferReply";
|
||||
import getEmbedConfig from "../../../../helpers/getEmbedConfig";
|
||||
import capitalizeFirstLetter from "../../../../helpers/capitalizeFirstLetter";
|
||||
import * as cooldown from "../../../../helpers/cooldown";
|
||||
|
||||
export default async (interaction: CommandInteraction) => {
|
||||
if (!interaction.isButton()) return;
|
||||
|
||||
const { errorColor, footerText, footerIcon } = await getEmbedConfig(
|
||||
interaction.guild
|
||||
);
|
||||
|
||||
const { guild, customId, user, memberPermissions } = interaction;
|
||||
|
||||
const currentButton = await import(`../../../buttons/${customId}`);
|
||||
|
||||
if (currentButton == null) {
|
||||
logger.silly(`Button ${customId} not found`);
|
||||
}
|
||||
|
||||
const metadata = currentButton.metadata;
|
||||
|
||||
await deferReply(interaction, metadata.ephemeral || false);
|
||||
|
||||
if (metadata.guildOnly) {
|
||||
if (!guild) {
|
||||
logger.debug(`Guild is null`);
|
||||
|
||||
return interaction.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:x:] Permission")
|
||||
.setDescription("This command is only available for guild")
|
||||
.setColor(errorColor)
|
||||
.setTimestamp(new Date())
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
],
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
metadata.permissions &&
|
||||
metadata.guildOnly &&
|
||||
!memberPermissions?.has(metadata.permissions)
|
||||
) {
|
||||
return interaction?.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:x:] Permission")
|
||||
.setDescription(`You do not have the permission to manage the bot.`)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(errorColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
if (metadata.dmOnly) {
|
||||
if (guild) {
|
||||
logger.silly(`Guild exist`);
|
||||
|
||||
return interaction.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:x:] Permission")
|
||||
.setDescription("This command is only available in DM.")
|
||||
.setColor(errorColor)
|
||||
.setTimestamp(new Date())
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
],
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (metadata.cooldown) {
|
||||
await cooldown
|
||||
.interaction(interaction, metadata.cooldown)
|
||||
.catch(async (error) => {
|
||||
return interaction?.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle("[:x:] Permission")
|
||||
.setDescription(`${error}`)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(errorColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
],
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
await currentButton
|
||||
.execute(interaction)
|
||||
.then(async () => {
|
||||
return logger?.silly(
|
||||
`Button: ${customId} executed in guild: ${guild?.name} (${guild?.id}) by user: ${user?.tag} (${user?.id})`
|
||||
);
|
||||
})
|
||||
.catch(async (error: string) => {
|
||||
logger?.debug(`INTERACTION BUTTON CATCH: ${error}`);
|
||||
|
||||
return interaction.editReply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setTitle(
|
||||
`[:x:] ${capitalizeFirstLetter(
|
||||
interaction.options.getSubcommand()
|
||||
)}`
|
||||
)
|
||||
.setDescription(`${"``"}${error}${"``"}`)
|
||||
.setColor(errorColor)
|
||||
.setTimestamp(new Date())
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
],
|
||||
});
|
||||
});
|
||||
};
|
|
@ -1,48 +0,0 @@
|
|||
// Dependencies
|
||||
import { CommandInteraction, MessageEmbed } from "discord.js";
|
||||
|
||||
import logger from "../../../../logger";
|
||||
|
||||
import deferReply from "../../../../helpers/deferReply";
|
||||
import getEmbedConfig from "../../../../helpers/getEmbedConfig";
|
||||
import getCommandMetadata from "../../../../helpers/getCommandMetadata";
|
||||
import capitalizeFirstLetter from "../../../../helpers/capitalizeFirstLetter";
|
||||
import * as cooldown from "../../../../helpers/cooldown";
|
||||
|
||||
export default async (interaction: CommandInteraction) => {
|
||||
if (!interaction.isCommand()) return;
|
||||
|
||||
const { errorColor, footerText, footerIcon } = await getEmbedConfig(
|
||||
interaction.guild
|
||||
);
|
||||
|
||||
const { client, guild, commandName, user, memberPermissions } = interaction;
|
||||
|
||||
const currentCommand = client.commands.get(commandName);
|
||||
|
||||
if (currentCommand == null) {
|
||||
logger.silly(`Command ${commandName} not found`);
|
||||
}
|
||||
|
||||
const metadata = await getCommandMetadata(interaction, currentCommand);
|
||||
|
||||
await deferReply(interaction, metadata.ephemeral || false);
|
||||
|
||||
if (metadata.guildOnly && !guild)
|
||||
throw new Error("This command is guild only.");
|
||||
|
||||
if (
|
||||
metadata.permissions &&
|
||||
metadata.guildOnly &&
|
||||
!memberPermissions?.has(metadata.permissions)
|
||||
)
|
||||
throw new Error("You don't have the required permissions");
|
||||
|
||||
if (metadata.dmOnly && guild)
|
||||
throw new Error("This command is only available in DM");
|
||||
|
||||
if (metadata.cooldown)
|
||||
await cooldown.interaction(interaction, metadata.cooldown);
|
||||
|
||||
await currentCommand.execute(interaction);
|
||||
};
|
|
@ -0,0 +1,36 @@
|
|||
// Dependencies
|
||||
import { Interaction } from "discord.js";
|
||||
|
||||
import deferReply from "../../../../../helpers/deferReply";
|
||||
import * as cooldown from "../../../../../helpers/cooldown";
|
||||
|
||||
export default async (interaction: Interaction) => {
|
||||
if (!interaction.isButton()) return;
|
||||
|
||||
const { guild, customId, memberPermissions } = interaction;
|
||||
|
||||
const currentButton = await import(`../../../buttons/${customId}`);
|
||||
|
||||
if (!currentButton) throw new Error(`Unknown button ${customId}`);
|
||||
|
||||
const metadata = currentButton.metadata;
|
||||
|
||||
await deferReply(interaction, metadata.ephemeral || false);
|
||||
|
||||
if (metadata.guildOnly && !guild)
|
||||
throw new Error("This command is guild only.");
|
||||
|
||||
if (
|
||||
metadata.permissions &&
|
||||
metadata.guildOnly &&
|
||||
!memberPermissions?.has(metadata.permissions)
|
||||
)
|
||||
throw new Error("You don't have the required permissions");
|
||||
|
||||
if (metadata.dmOnly && guild)
|
||||
throw new Error("This command is only available in DM");
|
||||
|
||||
if (metadata.cooldown) await cooldown.button(interaction, metadata.cooldown);
|
||||
|
||||
await currentButton.execute(interaction);
|
||||
};
|
|
@ -0,0 +1,34 @@
|
|||
// Dependencies
|
||||
import { Interaction } from "discord.js";
|
||||
|
||||
import deferReply from "../../../../../helpers/deferReply";
|
||||
import getCommandMetadata from "../../../../../helpers/getCommandMetadata";
|
||||
import * as cooldown from "../../../../../helpers/cooldown";
|
||||
|
||||
export default async (interaction: Interaction) => {
|
||||
if (!interaction.isCommand()) return;
|
||||
const { client, commandName } = interaction;
|
||||
|
||||
const currentCommand = client.commands.get(commandName);
|
||||
if (!currentCommand) throw new Error(`Unknown command ${commandName}`);
|
||||
|
||||
const metadata = await getCommandMetadata(interaction, currentCommand);
|
||||
await deferReply(interaction, metadata.ephemeral || false);
|
||||
|
||||
if (metadata.guildOnly && !interaction.guild)
|
||||
throw new Error("This command is guild only.");
|
||||
|
||||
if (
|
||||
metadata.permissions &&
|
||||
metadata.guildOnly &&
|
||||
!interaction.memberPermissions?.has(metadata.permissions)
|
||||
)
|
||||
throw new Error("You don't have the required permissions");
|
||||
|
||||
if (metadata.dmOnly && interaction.guild)
|
||||
throw new Error("This command is only available in DM");
|
||||
|
||||
if (metadata.cooldown) await cooldown.command(interaction, metadata.cooldown);
|
||||
|
||||
await currentCommand.execute(interaction);
|
||||
};
|
11
src/plugins/events/interactionCreate/handlers/index.ts
Normal file
11
src/plugins/events/interactionCreate/handlers/index.ts
Normal file
|
@ -0,0 +1,11 @@
|
|||
import { Interaction } from "discord.js";
|
||||
|
||||
import button from "./button";
|
||||
import command from "./command";
|
||||
|
||||
import logger from "../../../../logger";
|
||||
|
||||
export const execute = async (interaction: Interaction) => {
|
||||
await button(interaction);
|
||||
await command(interaction);
|
||||
};
|
|
@ -2,8 +2,8 @@
|
|||
import { CommandInteraction, MessageEmbed } from "discord.js";
|
||||
|
||||
// Dependencies
|
||||
import isCommand from "../../events/interactionCreate/components/isCommand";
|
||||
import isButton from "../../events/interactionCreate/components/isButton";
|
||||
import * as handlers from "./handlers";
|
||||
|
||||
import logger from "../../../logger";
|
||||
import audits from "./audits";
|
||||
import { IEventOptions } from "../../../interfaces/EventOptions";
|
||||
|
@ -27,11 +27,8 @@ export const execute = async (interaction: CommandInteraction) => {
|
|||
|
||||
await audits.execute(interaction);
|
||||
|
||||
try {
|
||||
await isCommand(interaction);
|
||||
await isButton(interaction);
|
||||
} catch (error) {
|
||||
logger.debug(`${error}`);
|
||||
await handlers.execute(interaction).catch(async (err) => {
|
||||
logger.debug(`${err}`);
|
||||
|
||||
return interaction.editReply({
|
||||
embeds: [
|
||||
|
@ -41,11 +38,11 @@ export const execute = async (interaction: CommandInteraction) => {
|
|||
interaction.options.getSubcommand()
|
||||
)}`
|
||||
)
|
||||
.setDescription(`${"``"}${error}${"``"}`)
|
||||
.setDescription(`${"``"}${err}${"``"}`)
|
||||
.setColor(errorColor)
|
||||
.setTimestamp(new Date())
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
],
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue