Compare commits
3 commits
88154018d8
...
7db565b652
Author | SHA1 | Date | |
---|---|---|---|
7db565b652 | |||
56f0d105be | |||
f0ab3b9080 |
13 changed files with 484 additions and 331 deletions
|
@ -45,7 +45,7 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.0.0",
|
||||
"np": "^8.0.4",
|
||||
"np": "^9.0.0",
|
||||
"typescript": "^5.0.0"
|
||||
}
|
||||
}
|
||||
|
|
42
src/buttonEvents/verify.ts
Normal file
42
src/buttonEvents/verify.ts
Normal file
|
@ -0,0 +1,42 @@
|
|||
import { ButtonInteraction, CacheType } from "discord.js";
|
||||
import { ButtonEvent } from "../type/buttonEvent";
|
||||
import SettingsHelper from "../helpers/SettingsHelper";
|
||||
|
||||
export default class Verify extends ButtonEvent {
|
||||
public override async execute(interaction: ButtonInteraction<CacheType>) {
|
||||
if (!interaction.guildId || !interaction.guild) return;
|
||||
|
||||
const roleName = await SettingsHelper.GetSetting("verification.role", interaction.guildId);
|
||||
|
||||
if (!roleName) return;
|
||||
|
||||
const role = interaction.guild.roles.cache.find(x => x.name == roleName);
|
||||
|
||||
if (!role) {
|
||||
await interaction.reply({
|
||||
content: `Unable to find the role, ${roleName}`,
|
||||
ephemeral: true,
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const member = interaction.guild.members.cache.find(x => x.id == interaction.user.id);
|
||||
|
||||
if (!member || !member.manageable) {
|
||||
await interaction.reply({
|
||||
content: "Unable to give role to user",
|
||||
ephemeral: true,
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
await member.roles.add(role);
|
||||
|
||||
await interaction.reply({
|
||||
content: "Given role",
|
||||
ephemeral: true,
|
||||
});
|
||||
}
|
||||
}
|
|
@ -9,10 +9,13 @@ import { Command } from "../type/command";
|
|||
import { Events } from "./events";
|
||||
import { Util } from "./util";
|
||||
import AppDataSource from "../database/dataSources/appDataSource";
|
||||
import ButtonEventItem from "../contracts/ButtonEventItem";
|
||||
import { ButtonEvent } from "../type/buttonEvent";
|
||||
|
||||
export class CoreClient extends Client {
|
||||
private static _commandItems: ICommandItem[];
|
||||
private static _eventItems: IEventItem[];
|
||||
private static _buttonEvents: ButtonEventItem[];
|
||||
|
||||
private _events: Events;
|
||||
private _util: Util;
|
||||
|
@ -25,12 +28,17 @@ export class CoreClient extends Client {
|
|||
return this._eventItems;
|
||||
}
|
||||
|
||||
public static get buttonEvents(): ButtonEventItem[] {
|
||||
return this._buttonEvents;
|
||||
}
|
||||
|
||||
constructor(intents: number[], partials: Partials[]) {
|
||||
super({ intents: intents, partials: partials });
|
||||
dotenv.config();
|
||||
|
||||
CoreClient._commandItems = [];
|
||||
CoreClient._eventItems = [];
|
||||
CoreClient._buttonEvents = [];
|
||||
|
||||
this._events = new Events();
|
||||
this._util = new Util();
|
||||
|
@ -73,4 +81,13 @@ export class CoreClient extends Client {
|
|||
|
||||
CoreClient._eventItems.push(item);
|
||||
}
|
||||
|
||||
public static RegisterButtonEvent(buttonId: string, event: ButtonEvent) {
|
||||
const item: ButtonEventItem = {
|
||||
ButtonId: buttonId,
|
||||
Event: event,
|
||||
};
|
||||
|
||||
CoreClient._buttonEvents.push(item);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,40 +1,18 @@
|
|||
import { Interaction } from "discord.js";
|
||||
import ICommandItem from "../contracts/ICommandItem";
|
||||
import SettingsHelper from "../helpers/SettingsHelper";
|
||||
import { CoreClient } from "./client";
|
||||
import ChatInputCommand from "./interactionCreate/chatInputCommand";
|
||||
import Button from "./interactionCreate/button";
|
||||
|
||||
export class Events {
|
||||
public async onInteractionCreate(interaction: Interaction) {
|
||||
if (!interaction.isChatInputCommand()) return;
|
||||
if (!interaction.guildId) return;
|
||||
|
||||
const disabledCommandsString = await SettingsHelper.GetSetting("commands.disabled", interaction.guildId);
|
||||
const disabledCommands = disabledCommandsString?.split(",");
|
||||
|
||||
const disabledCommandsMessage = await SettingsHelper.GetSetting("commands.disabled.message", interaction.guildId);
|
||||
|
||||
if (disabledCommands?.find(x => x == interaction.commandName)) {
|
||||
await interaction.reply(disabledCommandsMessage || "This command is disabled.");
|
||||
return;
|
||||
if (interaction.isChatInputCommand()) {
|
||||
ChatInputCommand.onChatInput(interaction);
|
||||
}
|
||||
|
||||
const item = CoreClient.commandItems.find(x => x.Name == interaction.commandName && !x.ServerId);
|
||||
const itemForServer = CoreClient.commandItems.find(x => x.Name == interaction.commandName && x.ServerId == interaction.guildId);
|
||||
|
||||
let itemToUse: ICommandItem;
|
||||
|
||||
if (!itemForServer) {
|
||||
if (!item) {
|
||||
await interaction.reply('Command not found');
|
||||
return;
|
||||
}
|
||||
|
||||
itemToUse = item;
|
||||
} else {
|
||||
itemToUse = itemForServer;
|
||||
if (interaction.isButton()) {
|
||||
Button.onButtonClicked(interaction);
|
||||
}
|
||||
|
||||
itemToUse.Command.execute(interaction);
|
||||
}
|
||||
|
||||
// Emit when bot is logged in and ready to use
|
||||
|
|
17
src/client/interactionCreate/button.ts
Normal file
17
src/client/interactionCreate/button.ts
Normal file
|
@ -0,0 +1,17 @@
|
|||
import { ButtonInteraction } from "discord.js";
|
||||
import { CoreClient } from "../client";
|
||||
|
||||
export default class Button {
|
||||
public static async onButtonClicked(interaction: ButtonInteraction) {
|
||||
if (!interaction.isButton) return;
|
||||
|
||||
const item = CoreClient.buttonEvents.find(x => x.ButtonId == interaction.customId.split(" ")[0]);
|
||||
|
||||
if (!item) {
|
||||
await interaction.reply("Event not found.");
|
||||
return;
|
||||
}
|
||||
|
||||
item.Event.execute(interaction);
|
||||
}
|
||||
}
|
27
src/client/interactionCreate/chatInputCommand.ts
Normal file
27
src/client/interactionCreate/chatInputCommand.ts
Normal file
|
@ -0,0 +1,27 @@
|
|||
import { Interaction } from "discord.js";
|
||||
import { CoreClient } from "../client";
|
||||
import ICommandItem from "../../contracts/ICommandItem";
|
||||
|
||||
export default class ChatInputCommand {
|
||||
public static async onChatInput(interaction: Interaction) {
|
||||
if (!interaction.isChatInputCommand()) return;
|
||||
|
||||
const item = CoreClient.commandItems.find(x => x.Name == interaction.commandName && !x.ServerId);
|
||||
const itemForServer = CoreClient.commandItems.find(x => x.Name == interaction.commandName && x.ServerId == interaction.guildId);
|
||||
|
||||
let itemToUse: ICommandItem;
|
||||
|
||||
if (!itemForServer) {
|
||||
if (!item) {
|
||||
await interaction.reply("Command not found.");
|
||||
return;
|
||||
}
|
||||
|
||||
itemToUse = item;
|
||||
} else {
|
||||
itemToUse = itemForServer;
|
||||
}
|
||||
|
||||
itemToUse.Command.execute(interaction);
|
||||
}
|
||||
}
|
|
@ -1,7 +1,8 @@
|
|||
import { CommandInteraction, EmbedBuilder, PermissionsBitField, SlashCommandBuilder } from "discord.js";
|
||||
import { ActionRowBuilder, ButtonBuilder, ButtonStyle, CommandInteraction, EmbedBuilder, PermissionsBitField, SlashCommandBuilder } from "discord.js";
|
||||
import { existsSync, readFileSync } from "fs";
|
||||
import EmbedColours from "../constants/EmbedColours";
|
||||
import { Command } from "../type/command";
|
||||
import SettingsHelper from "../helpers/SettingsHelper";
|
||||
|
||||
interface IRules {
|
||||
title?: string;
|
||||
|
@ -14,13 +15,36 @@ export default class Rules extends Command {
|
|||
constructor() {
|
||||
super();
|
||||
|
||||
super.CommandBuilder = new SlashCommandBuilder()
|
||||
.setName("rules")
|
||||
.setDescription("Send the rules embeds for this server")
|
||||
.setDefaultMemberPermissions(PermissionsBitField.Flags.Administrator);
|
||||
this.CommandBuilder = new SlashCommandBuilder()
|
||||
.setName('rules')
|
||||
.setDescription("Rules-related commands")
|
||||
.setDefaultMemberPermissions(PermissionsBitField.Flags.Administrator)
|
||||
.addSubcommand(x =>
|
||||
x
|
||||
.setName('embeds')
|
||||
.setDescription('Send the rules embeds for this server'))
|
||||
.addSubcommand(x =>
|
||||
x
|
||||
.setName('access')
|
||||
.setDescription('Send the server verification embed button'));
|
||||
}
|
||||
|
||||
public override async execute(interaction: CommandInteraction) {
|
||||
if (!interaction.isChatInputCommand()) return;
|
||||
|
||||
switch (interaction.options.getSubcommand()) {
|
||||
case "embeds":
|
||||
await this.SendEmbeds(interaction);
|
||||
break;
|
||||
case "access":
|
||||
await this.SendAccessButton(interaction);
|
||||
break;
|
||||
default:
|
||||
await interaction.reply("Subcommand doesn't exist.");
|
||||
}
|
||||
}
|
||||
|
||||
private async SendEmbeds(interaction: CommandInteraction) {
|
||||
if (!interaction.guildId) return;
|
||||
|
||||
if (!existsSync(`${process.cwd()}/data/rules/${interaction.guildId}.json`)) {
|
||||
|
@ -71,4 +95,27 @@ export default class Rules extends Command {
|
|||
|
||||
await interaction.reply({ embeds: [ successEmbed ], ephemeral: true });
|
||||
}
|
||||
|
||||
private async SendAccessButton(interaction: CommandInteraction) {
|
||||
if (!interaction.guildId) return;
|
||||
|
||||
const buttonLabel = await SettingsHelper.GetSetting("rules.access.label", interaction.guildId);
|
||||
|
||||
const row = new ActionRowBuilder<ButtonBuilder>()
|
||||
.addComponents([
|
||||
new ButtonBuilder()
|
||||
.setCustomId('verify')
|
||||
.setStyle(ButtonStyle.Primary)
|
||||
.setLabel(buttonLabel || "Verify")
|
||||
]);
|
||||
|
||||
await interaction.channel?.send({
|
||||
components: [ row ]
|
||||
});
|
||||
|
||||
await interaction.reply({
|
||||
content: "Success",
|
||||
ephemeral: true,
|
||||
});
|
||||
}
|
||||
}
|
|
@ -31,6 +31,7 @@ export default class DefaultValues {
|
|||
|
||||
// Rules (Command)
|
||||
this.values.push({ Key: "rules.file", Value: "data/rules/rules" });
|
||||
this.values.push({ Key: "rules.access.label", Value: "Verify" });
|
||||
|
||||
// Channels
|
||||
this.values.push({ Key: "channels.logs.message", Value: "message-logs" });
|
||||
|
|
8
src/contracts/ButtonEventItem.ts
Normal file
8
src/contracts/ButtonEventItem.ts
Normal file
|
@ -0,0 +1,8 @@
|
|||
import { ButtonEvent } from "../type/buttonEvent";
|
||||
|
||||
interface ButtonEventItem {
|
||||
ButtonId: string,
|
||||
Event: ButtonEvent,
|
||||
}
|
||||
|
||||
export default ButtonEventItem;
|
|
@ -37,6 +37,9 @@ import MessageDelete from "./events/MessageEvents/MessageDelete";
|
|||
import MessageUpdate from "./events/MessageEvents/MessageUpdate";
|
||||
import MessageCreate from "./events/MessageEvents/MessageCreate";
|
||||
|
||||
// Button Event Imports
|
||||
import Verify from "./buttonEvents/verify";
|
||||
|
||||
export default class Registry {
|
||||
public static RegisterCommands() {
|
||||
CoreClient.RegisterCommand("about", new About());
|
||||
|
@ -84,4 +87,8 @@ export default class Registry {
|
|||
CoreClient.RegisterEvent(EventType.MessageUpdate, MessageUpdate);
|
||||
CoreClient.RegisterEvent(EventType.MessageCreate, MessageCreate);
|
||||
}
|
||||
|
||||
public static RegisterButtonEvents() {
|
||||
CoreClient.RegisterButtonEvent("verify", new Verify());
|
||||
}
|
||||
}
|
5
src/type/buttonEvent.ts
Normal file
5
src/type/buttonEvent.ts
Normal file
|
@ -0,0 +1,5 @@
|
|||
import { ButtonInteraction } from "discord.js";
|
||||
|
||||
export abstract class ButtonEvent {
|
||||
abstract execute(interaction: ButtonInteraction): Promise<void>;
|
||||
}
|
|
@ -37,5 +37,6 @@ const client = new CoreClient([
|
|||
|
||||
registry.RegisterCommands();
|
||||
registry.RegisterEvents();
|
||||
registry.RegisterButtonEvents();
|
||||
|
||||
client.start();
|
||||
|
|
Loading…
Reference in a new issue