Compare commits
18 commits
c187f87dd0
...
6f130b4dc4
Author | SHA1 | Date | |
---|---|---|---|
6f130b4dc4 | |||
cca34a476c | |||
ad2e4d8f9b | |||
c83a2329cc | |||
5f054b02a5 | |||
808f5e3b1c | |||
68f29c814a | |||
96bd4ef83e | |||
c201d10d07 | |||
0a251b2691 | |||
07237b82aa | |||
56f0d105be | |||
f0ab3b9080 | |||
7c2870d28e | |||
26e7c20389 | |||
4eabb2fbde | |||
24146e9772 | |||
9e01c1871d |
27 changed files with 1348 additions and 1173 deletions
4
.dev.env
4
.dev.env
|
@ -7,7 +7,7 @@
|
||||||
# any secret values.
|
# any secret values.
|
||||||
|
|
||||||
BOT_TOKEN=
|
BOT_TOKEN=
|
||||||
BOT_VER=3.2 DEV
|
BOT_VER=3.2.1
|
||||||
BOT_AUTHOR=Vylpes
|
BOT_AUTHOR=Vylpes
|
||||||
BOT_OWNERID=147392775707426816
|
BOT_OWNERID=147392775707426816
|
||||||
BOT_CLIENTID=682942374040961060
|
BOT_CLIENTID=682942374040961060
|
||||||
|
@ -15,6 +15,8 @@ BOT_CLIENTID=682942374040961060
|
||||||
ABOUT_FUNDING=https://ko-fi.com/vylpes
|
ABOUT_FUNDING=https://ko-fi.com/vylpes
|
||||||
ABOUT_REPO=https://gitea.vylpes.xyz/RabbitLabs/vylbot-app
|
ABOUT_REPO=https://gitea.vylpes.xyz/RabbitLabs/vylbot-app
|
||||||
|
|
||||||
|
CACHE_INTERVAL=1800000 # 30 minutes
|
||||||
|
|
||||||
DB_HOST=127.0.0.1
|
DB_HOST=127.0.0.1
|
||||||
DB_PORT=3101
|
DB_PORT=3101
|
||||||
DB_NAME=vylbot
|
DB_NAME=vylbot
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
# any secret values.
|
# any secret values.
|
||||||
|
|
||||||
BOT_TOKEN=
|
BOT_TOKEN=
|
||||||
BOT_VER=3.2
|
BOT_VER=3.2.1
|
||||||
BOT_AUTHOR=Vylpes
|
BOT_AUTHOR=Vylpes
|
||||||
BOT_OWNERID=147392775707426816
|
BOT_OWNERID=147392775707426816
|
||||||
BOT_CLIENTID=680083120896081954
|
BOT_CLIENTID=680083120896081954
|
||||||
|
@ -15,6 +15,8 @@ BOT_CLIENTID=680083120896081954
|
||||||
ABOUT_FUNDING=https://ko-fi.com/vylpes
|
ABOUT_FUNDING=https://ko-fi.com/vylpes
|
||||||
ABOUT_REPO=https://gitea.vylpes.xyz/RabbitLabs/vylbot-app
|
ABOUT_REPO=https://gitea.vylpes.xyz/RabbitLabs/vylbot-app
|
||||||
|
|
||||||
|
CACHE_INTERVAL=1800000 # 30 minutes
|
||||||
|
|
||||||
DB_HOST=127.0.0.1
|
DB_HOST=127.0.0.1
|
||||||
DB_PORT=3121
|
DB_PORT=3121
|
||||||
DB_NAME=vylbot
|
DB_NAME=vylbot
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
# any secret values.
|
# any secret values.
|
||||||
|
|
||||||
BOT_TOKEN=
|
BOT_TOKEN=
|
||||||
BOT_VER=3.2 BETA
|
BOT_VER=3.2.1
|
||||||
BOT_AUTHOR=Vylpes
|
BOT_AUTHOR=Vylpes
|
||||||
BOT_OWNERID=147392775707426816
|
BOT_OWNERID=147392775707426816
|
||||||
BOT_CLIENTID=1016767908740857949
|
BOT_CLIENTID=1016767908740857949
|
||||||
|
@ -15,6 +15,8 @@ BOT_CLIENTID=1016767908740857949
|
||||||
ABOUT_FUNDING=https://ko-fi.com/vylpes
|
ABOUT_FUNDING=https://ko-fi.com/vylpes
|
||||||
ABOUT_REPO=https://gitea.vylpes.xyz/RabbitLabs/vylbot-app
|
ABOUT_REPO=https://gitea.vylpes.xyz/RabbitLabs/vylbot-app
|
||||||
|
|
||||||
|
CACHE_INTERVAL=1800000 # 30 minutes
|
||||||
|
|
||||||
DB_HOST=127.0.0.1
|
DB_HOST=127.0.0.1
|
||||||
DB_PORT=3111
|
DB_PORT=3111
|
||||||
DB_NAME=vylbot
|
DB_NAME=vylbot
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
ALTER TABLE server
|
||||||
|
ADD LastCached datetime NOT NULL DEFAULT '2024-03-01 18:10:04';
|
10
package.json
10
package.json
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "vylbot-app",
|
"name": "vylbot-app",
|
||||||
"version": "3.1.3",
|
"version": "3.2.1",
|
||||||
"description": "A discord bot made for Vylpes' Den",
|
"description": "A discord bot made for Vylpes' Den",
|
||||||
"main": "./dist/vylbot",
|
"main": "./dist/vylbot",
|
||||||
"typings": "./dist",
|
"typings": "./dist",
|
||||||
|
@ -11,6 +11,7 @@
|
||||||
"test": "echo true",
|
"test": "echo true",
|
||||||
"db:up": "typeorm migration:run -d dist/database/dataSources/appDataSource.js",
|
"db:up": "typeorm migration:run -d dist/database/dataSources/appDataSource.js",
|
||||||
"db:down": "typeorm migration:revert -d dist/database/dataSources/appDataSource.js",
|
"db:down": "typeorm migration:revert -d dist/database/dataSources/appDataSource.js",
|
||||||
|
"db:create": "typeorm migration:create ./src/database/migrations",
|
||||||
"release": "np --no-publish"
|
"release": "np --no-publish"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
|
@ -38,14 +39,15 @@
|
||||||
"mysql": "^2.18.1",
|
"mysql": "^2.18.1",
|
||||||
"random-bunny": "^2.0.5",
|
"random-bunny": "^2.0.5",
|
||||||
"ts-jest": "^29.0.0",
|
"ts-jest": "^29.0.0",
|
||||||
"typeorm": "0.3.17"
|
"typeorm": "0.3.20"
|
||||||
},
|
},
|
||||||
"resolutions": {
|
"resolutions": {
|
||||||
"**/semver": "^7.5.2"
|
"**/semver": "^7.5.2",
|
||||||
|
"**/undici": "^5.28.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^20.0.0",
|
"@types/node": "^20.0.0",
|
||||||
"np": "^8.0.4",
|
"np": "^9.0.0",
|
||||||
"typescript": "^5.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,14 @@ import { Command } from "../type/command";
|
||||||
import { Events } from "./events";
|
import { Events } from "./events";
|
||||||
import { Util } from "./util";
|
import { Util } from "./util";
|
||||||
import AppDataSource from "../database/dataSources/appDataSource";
|
import AppDataSource from "../database/dataSources/appDataSource";
|
||||||
|
import ButtonEventItem from "../contracts/ButtonEventItem";
|
||||||
|
import { ButtonEvent } from "../type/buttonEvent";
|
||||||
|
import CacheHelper from "../helpers/CacheHelper";
|
||||||
|
|
||||||
export class CoreClient extends Client {
|
export class CoreClient extends Client {
|
||||||
private static _commandItems: ICommandItem[];
|
private static _commandItems: ICommandItem[];
|
||||||
private static _eventItems: IEventItem[];
|
private static _eventItems: IEventItem[];
|
||||||
|
private static _buttonEvents: ButtonEventItem[];
|
||||||
|
|
||||||
private _events: Events;
|
private _events: Events;
|
||||||
private _util: Util;
|
private _util: Util;
|
||||||
|
@ -25,12 +29,17 @@ export class CoreClient extends Client {
|
||||||
return this._eventItems;
|
return this._eventItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static get buttonEvents(): ButtonEventItem[] {
|
||||||
|
return this._buttonEvents;
|
||||||
|
}
|
||||||
|
|
||||||
constructor(intents: number[], partials: Partials[]) {
|
constructor(intents: number[], partials: Partials[]) {
|
||||||
super({ intents: intents, partials: partials });
|
super({ intents: intents, partials: partials });
|
||||||
dotenv.config();
|
dotenv.config();
|
||||||
|
|
||||||
CoreClient._commandItems = [];
|
CoreClient._commandItems = [];
|
||||||
CoreClient._eventItems = [];
|
CoreClient._eventItems = [];
|
||||||
|
CoreClient._buttonEvents = [];
|
||||||
|
|
||||||
this._events = new Events();
|
this._events = new Events();
|
||||||
this._util = new Util();
|
this._util = new Util();
|
||||||
|
@ -51,6 +60,10 @@ export class CoreClient extends Client {
|
||||||
|
|
||||||
await super.login(process.env.BOT_TOKEN);
|
await super.login(process.env.BOT_TOKEN);
|
||||||
|
|
||||||
|
this.guilds.cache.forEach(async (guild) => {
|
||||||
|
await CacheHelper.UpdateServerCache(guild);
|
||||||
|
});
|
||||||
|
|
||||||
this._util.loadEvents(this, CoreClient._eventItems);
|
this._util.loadEvents(this, CoreClient._eventItems);
|
||||||
this._util.loadSlashCommands(this);
|
this._util.loadSlashCommands(this);
|
||||||
}
|
}
|
||||||
|
@ -73,4 +86,13 @@ export class CoreClient extends Client {
|
||||||
|
|
||||||
CoreClient._eventItems.push(item);
|
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 { Interaction } from "discord.js";
|
||||||
import ICommandItem from "../contracts/ICommandItem";
|
import ChatInputCommand from "./interactionCreate/chatInputCommand";
|
||||||
import SettingsHelper from "../helpers/SettingsHelper";
|
import Button from "./interactionCreate/button";
|
||||||
import { CoreClient } from "./client";
|
|
||||||
|
|
||||||
export class Events {
|
export class Events {
|
||||||
public async onInteractionCreate(interaction: Interaction) {
|
public async onInteractionCreate(interaction: Interaction) {
|
||||||
if (!interaction.isChatInputCommand()) return;
|
|
||||||
if (!interaction.guildId) return;
|
if (!interaction.guildId) return;
|
||||||
|
|
||||||
const disabledCommandsString = await SettingsHelper.GetSetting("commands.disabled", interaction.guildId);
|
if (interaction.isChatInputCommand()) {
|
||||||
const disabledCommands = disabledCommandsString?.split(",");
|
ChatInputCommand.onChatInput(interaction);
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const item = CoreClient.commandItems.find(x => x.Name == interaction.commandName && !x.ServerId);
|
if (interaction.isButton()) {
|
||||||
const itemForServer = CoreClient.commandItems.find(x => x.Name == interaction.commandName && x.ServerId == interaction.guildId);
|
Button.onButtonClicked(interaction);
|
||||||
|
|
||||||
let itemToUse: ICommandItem;
|
|
||||||
|
|
||||||
if (!itemForServer) {
|
|
||||||
if (!item) {
|
|
||||||
await interaction.reply('Command not found');
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
itemToUse = item;
|
|
||||||
} else {
|
|
||||||
itemToUse = itemForServer;
|
|
||||||
}
|
|
||||||
|
|
||||||
itemToUse.Command.execute(interaction);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Emit when bot is logged in and ready to use
|
// 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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -121,9 +121,9 @@ export default class Config extends Command {
|
||||||
var defaultValue = DefaultValues.GetValue(key.value.toString());
|
var defaultValue = DefaultValues.GetValue(key.value.toString());
|
||||||
|
|
||||||
if (defaultValue) {
|
if (defaultValue) {
|
||||||
await interaction.reply(`\`${key}\`: \`${defaultValue}\` <DEFAULT>`);
|
await interaction.reply(`\`${key.value}\`: \`${defaultValue}\` <DEFAULT>`);
|
||||||
} else {
|
} else {
|
||||||
await interaction.reply(`\`${key}\`: <NONE>`);
|
await interaction.reply(`\`${key.value}\`: <NONE>`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 { existsSync, readFileSync } from "fs";
|
||||||
import EmbedColours from "../constants/EmbedColours";
|
import EmbedColours from "../constants/EmbedColours";
|
||||||
import { Command } from "../type/command";
|
import { Command } from "../type/command";
|
||||||
|
import SettingsHelper from "../helpers/SettingsHelper";
|
||||||
|
|
||||||
interface IRules {
|
interface IRules {
|
||||||
title?: string;
|
title?: string;
|
||||||
|
@ -14,13 +15,36 @@ export default class Rules extends Command {
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
super.CommandBuilder = new SlashCommandBuilder()
|
this.CommandBuilder = new SlashCommandBuilder()
|
||||||
.setName("rules")
|
.setName('rules')
|
||||||
.setDescription("Send the rules embeds for this server")
|
.setDescription("Rules-related commands")
|
||||||
.setDefaultMemberPermissions(PermissionsBitField.Flags.Administrator);
|
.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) {
|
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 (!interaction.guildId) return;
|
||||||
|
|
||||||
if (!existsSync(`${process.cwd()}/data/rules/${interaction.guildId}.json`)) {
|
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 });
|
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)
|
// Rules (Command)
|
||||||
this.values.push({ Key: "rules.file", Value: "data/rules/rules" });
|
this.values.push({ Key: "rules.file", Value: "data/rules/rules" });
|
||||||
|
this.values.push({ Key: "rules.access.label", Value: "Verify" });
|
||||||
|
|
||||||
// Channels
|
// Channels
|
||||||
this.values.push({ Key: "channels.logs.message", Value: "message-logs" });
|
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;
|
|
@ -1,4 +1,4 @@
|
||||||
import { Entity, OneToMany } from "typeorm";
|
import { Column, Entity, OneToMany } from "typeorm";
|
||||||
import BaseEntity from "../../contracts/BaseEntity";
|
import BaseEntity from "../../contracts/BaseEntity";
|
||||||
import Role from "./Role";
|
import Role from "./Role";
|
||||||
import Setting from "./Setting";
|
import Setting from "./Setting";
|
||||||
|
@ -9,14 +9,22 @@ export default class Server extends BaseEntity {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
this.Id = serverId;
|
this.Id = serverId;
|
||||||
|
this.LastCached = new Date();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Column({ default: "2024-03-01 18:10:04" })
|
||||||
|
LastCached: Date;
|
||||||
|
|
||||||
@OneToMany(() => Setting, x => x.Server)
|
@OneToMany(() => Setting, x => x.Server)
|
||||||
Settings: Setting[];
|
Settings: Setting[];
|
||||||
|
|
||||||
@OneToMany(() => Role, x => x.Server)
|
@OneToMany(() => Role, x => x.Server)
|
||||||
Roles: Role[];
|
Roles: Role[];
|
||||||
|
|
||||||
|
public UpdateLastCached(lastCached: Date) {
|
||||||
|
this.LastCached = lastCached;
|
||||||
|
}
|
||||||
|
|
||||||
public AddSettingToServer(setting: Setting) {
|
public AddSettingToServer(setting: Setting) {
|
||||||
this.Settings.push(setting);
|
this.Settings.push(setting);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
import { MigrationInterface, QueryRunner } from "typeorm"
|
||||||
|
import MigrationHelper from "../../../helpers/MigrationHelper"
|
||||||
|
|
||||||
|
export class AddServerCacheDate1709316734401 implements MigrationInterface {
|
||||||
|
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
MigrationHelper.Up('1709316734401-AddServerCacheDate', '3.2.1', [
|
||||||
|
"01-Server",
|
||||||
|
], queryRunner);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,10 +1,13 @@
|
||||||
import { EmbedBuilder, GuildMember, TextChannel } from "discord.js";
|
import { EmbedBuilder, GuildMember, TextChannel } from "discord.js";
|
||||||
import EmbedColours from "../../constants/EmbedColours";
|
import EmbedColours from "../../constants/EmbedColours";
|
||||||
import SettingsHelper from "../../helpers/SettingsHelper";
|
import SettingsHelper from "../../helpers/SettingsHelper";
|
||||||
|
import CacheHelper from "../../helpers/CacheHelper";
|
||||||
|
|
||||||
export default async function GuildMemberAdd(member: GuildMember) {
|
export default async function GuildMemberAdd(member: GuildMember) {
|
||||||
if (!member.guild) return;
|
if (!member.guild) return;
|
||||||
|
|
||||||
|
await CacheHelper.UpdateServerCache(member.guild);
|
||||||
|
|
||||||
const enabled = await SettingsHelper.GetSetting("event.member.add.enabled", member.guild.id);
|
const enabled = await SettingsHelper.GetSetting("event.member.add.enabled", member.guild.id);
|
||||||
if (!enabled || enabled.toLowerCase() != "true") return;
|
if (!enabled || enabled.toLowerCase() != "true") return;
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
import { EmbedBuilder, GuildMember, TextChannel } from "discord.js";
|
import { EmbedBuilder, GuildMember, TextChannel } from "discord.js";
|
||||||
import EmbedColours from "../../constants/EmbedColours";
|
import EmbedColours from "../../constants/EmbedColours";
|
||||||
import SettingsHelper from "../../helpers/SettingsHelper";
|
import SettingsHelper from "../../helpers/SettingsHelper";
|
||||||
|
import CacheHelper from "../../helpers/CacheHelper";
|
||||||
|
|
||||||
export default async function GuildMemberRemove(member: GuildMember) {
|
export default async function GuildMemberRemove(member: GuildMember) {
|
||||||
if (!member.guild) return;
|
if (!member.guild) return;
|
||||||
|
|
||||||
|
await CacheHelper.UpdateServerCache(member.guild);
|
||||||
|
|
||||||
const enabled = await SettingsHelper.GetSetting("event.member.remove.enabled", member.guild.id);
|
const enabled = await SettingsHelper.GetSetting("event.member.remove.enabled", member.guild.id);
|
||||||
if (!enabled || enabled.toLowerCase() != "true") return;
|
if (!enabled || enabled.toLowerCase() != "true") return;
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
import { GuildMember } from "discord.js";
|
import { GuildMember } from "discord.js";
|
||||||
import NicknameChanged from "./GuildMemberUpdate/NicknameChanged";
|
import NicknameChanged from "./GuildMemberUpdate/NicknameChanged";
|
||||||
|
import CacheHelper from "../../helpers/CacheHelper";
|
||||||
|
|
||||||
export default async function GuildMemberUpdate(oldMember: GuildMember, newMember: GuildMember) {
|
export default async function GuildMemberUpdate(oldMember: GuildMember, newMember: GuildMember) {
|
||||||
if (oldMember.nickname != newMember.nickname) { // Nickname change
|
await CacheHelper.UpdateServerCache(newMember.guild);
|
||||||
|
|
||||||
|
if (oldMember.nickname !== newMember.nickname) { // Nickname change
|
||||||
await NicknameChanged(oldMember, newMember);
|
await NicknameChanged(oldMember, newMember);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,11 +1,14 @@
|
||||||
import { Message } from "discord.js";
|
import { Message } from "discord.js";
|
||||||
import SettingsHelper from "../../helpers/SettingsHelper";
|
import SettingsHelper from "../../helpers/SettingsHelper";
|
||||||
import VerificationCheck from "./MessageCreate/VerificationCheck";
|
import VerificationCheck from "./MessageCreate/VerificationCheck";
|
||||||
|
import CacheHelper from "../../helpers/CacheHelper";
|
||||||
|
|
||||||
export default async function MessageCreate(message: Message) {
|
export default async function MessageCreate(message: Message) {
|
||||||
if (!message.guild) return;
|
if (!message.guild) return;
|
||||||
if (message.author.bot) return;
|
if (message.author.bot) return;
|
||||||
|
|
||||||
|
await CacheHelper.UpdateServerCache(message.guild);
|
||||||
|
|
||||||
const isVerificationEnabled = await SettingsHelper.GetSetting("verification.enabled", message.guild.id);
|
const isVerificationEnabled = await SettingsHelper.GetSetting("verification.enabled", message.guild.id);
|
||||||
|
|
||||||
if (isVerificationEnabled && isVerificationEnabled.toLocaleLowerCase() == "true") {
|
if (isVerificationEnabled && isVerificationEnabled.toLocaleLowerCase() == "true") {
|
||||||
|
|
|
@ -2,11 +2,14 @@ import { EmbedBuilder, Message, TextChannel } from "discord.js";
|
||||||
import EmbedColours from "../../constants/EmbedColours";
|
import EmbedColours from "../../constants/EmbedColours";
|
||||||
import IgnoredChannel from "../../database/entities/IgnoredChannel";
|
import IgnoredChannel from "../../database/entities/IgnoredChannel";
|
||||||
import SettingsHelper from "../../helpers/SettingsHelper";
|
import SettingsHelper from "../../helpers/SettingsHelper";
|
||||||
|
import CacheHelper from "../../helpers/CacheHelper";
|
||||||
|
|
||||||
export default async function MessageDelete(message: Message) {
|
export default async function MessageDelete(message: Message) {
|
||||||
if (!message.guild) return;
|
if (!message.guild) return;
|
||||||
if (message.author.bot) return;
|
if (message.author.bot) return;
|
||||||
|
|
||||||
|
await CacheHelper.UpdateServerCache(message.guild);
|
||||||
|
|
||||||
const enabled = await SettingsHelper.GetSetting("event.message.delete.enabled", message.guild.id);
|
const enabled = await SettingsHelper.GetSetting("event.message.delete.enabled", message.guild.id);
|
||||||
if (!enabled || enabled.toLowerCase() != "true") return;
|
if (!enabled || enabled.toLowerCase() != "true") return;
|
||||||
|
|
||||||
|
|
|
@ -2,10 +2,14 @@ import { EmbedBuilder, Message, TextChannel } from "discord.js";
|
||||||
import EmbedColours from "../../constants/EmbedColours";
|
import EmbedColours from "../../constants/EmbedColours";
|
||||||
import IgnoredChannel from "../../database/entities/IgnoredChannel";
|
import IgnoredChannel from "../../database/entities/IgnoredChannel";
|
||||||
import SettingsHelper from "../../helpers/SettingsHelper";
|
import SettingsHelper from "../../helpers/SettingsHelper";
|
||||||
|
import CacheHelper from "../../helpers/CacheHelper";
|
||||||
|
|
||||||
export default async function MessageUpdate(oldMessage: Message, newMessage: Message) {
|
export default async function MessageUpdate(oldMessage: Message, newMessage: Message) {
|
||||||
if (!newMessage.guild) return;
|
if (!newMessage.guild) return;
|
||||||
if (newMessage.author.bot) return;
|
if (newMessage.author.bot) return;
|
||||||
|
|
||||||
|
await CacheHelper.UpdateServerCache(newMessage.guild);
|
||||||
|
|
||||||
if (oldMessage.content == newMessage.content) return;
|
if (oldMessage.content == newMessage.content) return;
|
||||||
|
|
||||||
const enabled = await SettingsHelper.GetSetting("event.message.update.enabled", newMessage.guild.id);
|
const enabled = await SettingsHelper.GetSetting("event.message.update.enabled", newMessage.guild.id);
|
||||||
|
|
27
src/helpers/CacheHelper.ts
Normal file
27
src/helpers/CacheHelper.ts
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
import { Guild } from "discord.js";
|
||||||
|
import Server from "../database/entities/Server";
|
||||||
|
|
||||||
|
export default class CacheHelper {
|
||||||
|
public static async UpdateServerCache(guild: Guild) {
|
||||||
|
const cacheInterval = process.env.CACHE_INTERVAL;
|
||||||
|
|
||||||
|
if (!cacheInterval) return;
|
||||||
|
|
||||||
|
let server = await Server.FetchOneById(Server, guild.id);
|
||||||
|
|
||||||
|
if (!server) {
|
||||||
|
server = new Server(guild.id);
|
||||||
|
await server.Save(Server, server);
|
||||||
|
|
||||||
|
await CacheHelper.UpdateCache(guild);
|
||||||
|
} else if (server.LastCached.getTime() + Number(cacheInterval) < Date.now()) {
|
||||||
|
await CacheHelper.UpdateCache(guild);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async UpdateCache(guild: Guild) {
|
||||||
|
console.log(`Updating cache for ${guild.name} (${guild.id})`);
|
||||||
|
|
||||||
|
await guild.members.fetch();
|
||||||
|
}
|
||||||
|
}
|
|
@ -37,6 +37,9 @@ import MessageDelete from "./events/MessageEvents/MessageDelete";
|
||||||
import MessageUpdate from "./events/MessageEvents/MessageUpdate";
|
import MessageUpdate from "./events/MessageEvents/MessageUpdate";
|
||||||
import MessageCreate from "./events/MessageEvents/MessageCreate";
|
import MessageCreate from "./events/MessageEvents/MessageCreate";
|
||||||
|
|
||||||
|
// Button Event Imports
|
||||||
|
import Verify from "./buttonEvents/verify";
|
||||||
|
|
||||||
export default class Registry {
|
export default class Registry {
|
||||||
public static RegisterCommands() {
|
public static RegisterCommands() {
|
||||||
CoreClient.RegisterCommand("about", new About());
|
CoreClient.RegisterCommand("about", new About());
|
||||||
|
@ -84,4 +87,8 @@ export default class Registry {
|
||||||
CoreClient.RegisterEvent(EventType.MessageUpdate, MessageUpdate);
|
CoreClient.RegisterEvent(EventType.MessageUpdate, MessageUpdate);
|
||||||
CoreClient.RegisterEvent(EventType.MessageCreate, MessageCreate);
|
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.RegisterCommands();
|
||||||
registry.RegisterEvents();
|
registry.RegisterEvents();
|
||||||
|
registry.RegisterButtonEvents();
|
||||||
|
|
||||||
client.start();
|
client.start();
|
||||||
|
|
Loading…
Reference in a new issue