diff --git a/.dev.env b/.dev.env index a994934..003bbd6 100644 --- a/.dev.env +++ b/.dev.env @@ -15,6 +15,8 @@ BOT_CLIENTID=682942374040961060 ABOUT_FUNDING=https://ko-fi.com/vylpes ABOUT_REPO=https://gitea.vylpes.xyz/RabbitLabs/vylbot-app +CACHE_INTERVAL=1800000 # 30 minutes + DB_HOST=127.0.0.1 DB_PORT=3101 DB_NAME=vylbot diff --git a/.prod.env b/.prod.env index 7e1588f..fbdb633 100644 --- a/.prod.env +++ b/.prod.env @@ -15,6 +15,8 @@ BOT_CLIENTID=680083120896081954 ABOUT_FUNDING=https://ko-fi.com/vylpes ABOUT_REPO=https://gitea.vylpes.xyz/RabbitLabs/vylbot-app +CACHE_INTERVAL=1800000 # 30 minutes + DB_HOST=127.0.0.1 DB_PORT=3121 DB_NAME=vylbot diff --git a/.stage.env b/.stage.env index db2f0de..4704272 100644 --- a/.stage.env +++ b/.stage.env @@ -15,6 +15,8 @@ BOT_CLIENTID=1016767908740857949 ABOUT_FUNDING=https://ko-fi.com/vylpes ABOUT_REPO=https://gitea.vylpes.xyz/RabbitLabs/vylbot-app +CACHE_INTERVAL=1800000 # 30 minutes + DB_HOST=127.0.0.1 DB_PORT=3111 DB_NAME=vylbot diff --git a/database/3.2.1/1709316734401-AddServerCacheDate/Up/01-Server.sql b/database/3.2.1/1709316734401-AddServerCacheDate/Up/01-Server.sql new file mode 100644 index 0000000..a3b92b9 --- /dev/null +++ b/database/3.2.1/1709316734401-AddServerCacheDate/Up/01-Server.sql @@ -0,0 +1,2 @@ +ALTER TABLE server +ADD LastCached datetime NOT NULL DEFAULT '2024-03-01 18:10:04'; \ No newline at end of file diff --git a/package.json b/package.json index 79fb8a8..d858d85 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "vylbot-app", - "version": "3.2.0", + "version": "3.2.1", "description": "A discord bot made for Vylpes' Den", "main": "./dist/vylbot", "typings": "./dist", @@ -11,6 +11,7 @@ "test": "jest", "db:up": "typeorm migration:run -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" }, "repository": { @@ -41,7 +42,8 @@ "typeorm": "0.3.20" }, "resolutions": { - "**/semver": "^7.5.2" + "**/semver": "^7.5.2", + "**/undici": "^6.0.0" }, "devDependencies": { "@types/node": "^20.0.0", diff --git a/src/client/client.ts b/src/client/client.ts index 5cf9063..1e16e08 100644 --- a/src/client/client.ts +++ b/src/client/client.ts @@ -11,6 +11,7 @@ import { Util } from "./util"; 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 { public static commandItems: ICommandItem[]; @@ -47,6 +48,10 @@ export class CoreClient extends Client { 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.loadSlashCommands(this); } diff --git a/src/database/entities/Server.ts b/src/database/entities/Server.ts index 211ea9c..623f816 100644 --- a/src/database/entities/Server.ts +++ b/src/database/entities/Server.ts @@ -1,4 +1,4 @@ -import { Entity, OneToMany } from "typeorm"; +import { Column, Entity, OneToMany } from "typeorm"; import BaseEntity from "../../contracts/BaseEntity"; import Role from "./Role"; import Setting from "./Setting"; @@ -9,14 +9,22 @@ export default class Server extends BaseEntity { super(); this.Id = serverId; + this.LastCached = new Date(); } + @Column({ default: "2024-03-01 18:10:04" }) + LastCached: Date; + @OneToMany(() => Setting, x => x.Server) Settings: Setting[]; @OneToMany(() => Role, x => x.Server) Roles: Role[]; + public UpdateLastCached(lastCached: Date) { + this.LastCached = lastCached; + } + public AddSettingToServer(setting: Setting) { this.Settings.push(setting); } diff --git a/src/database/migrations/3.2.1/1709316734401-AddServerCacheDate.ts b/src/database/migrations/3.2.1/1709316734401-AddServerCacheDate.ts new file mode 100644 index 0000000..5104655 --- /dev/null +++ b/src/database/migrations/3.2.1/1709316734401-AddServerCacheDate.ts @@ -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 { + MigrationHelper.Up('1709316734401-AddServerCacheDate', '3.2.1', [ + "01-Server", + ], queryRunner); + } + + public async down(queryRunner: QueryRunner): Promise { + } + +} diff --git a/src/events/MemberEvents/GuildMemberAdd.ts b/src/events/MemberEvents/GuildMemberAdd.ts index 025be0b..55f91a1 100644 --- a/src/events/MemberEvents/GuildMemberAdd.ts +++ b/src/events/MemberEvents/GuildMemberAdd.ts @@ -1,10 +1,13 @@ import { EmbedBuilder, GuildMember, TextChannel } from "discord.js"; import EmbedColours from "../../constants/EmbedColours"; import SettingsHelper from "../../helpers/SettingsHelper"; +import CacheHelper from "../../helpers/CacheHelper"; export default async function GuildMemberAdd(member: GuildMember) { if (!member.guild) return; + await CacheHelper.UpdateServerCache(member.guild); + const enabled = await SettingsHelper.GetSetting("event.member.add.enabled", member.guild.id); if (!enabled || enabled.toLowerCase() != "true") return; diff --git a/src/events/MemberEvents/GuildMemberRemove.ts b/src/events/MemberEvents/GuildMemberRemove.ts index bf6ae96..0f24f47 100644 --- a/src/events/MemberEvents/GuildMemberRemove.ts +++ b/src/events/MemberEvents/GuildMemberRemove.ts @@ -1,10 +1,13 @@ import { EmbedBuilder, GuildMember, TextChannel } from "discord.js"; import EmbedColours from "../../constants/EmbedColours"; import SettingsHelper from "../../helpers/SettingsHelper"; +import CacheHelper from "../../helpers/CacheHelper"; export default async function GuildMemberRemove(member: GuildMember) { if (!member.guild) return; + await CacheHelper.UpdateServerCache(member.guild); + const enabled = await SettingsHelper.GetSetting("event.member.remove.enabled", member.guild.id); if (!enabled || enabled.toLowerCase() != "true") return; diff --git a/src/events/MemberEvents/GuildMemberUpdate.ts b/src/events/MemberEvents/GuildMemberUpdate.ts index 0a7bbb1..cd26953 100644 --- a/src/events/MemberEvents/GuildMemberUpdate.ts +++ b/src/events/MemberEvents/GuildMemberUpdate.ts @@ -1,8 +1,11 @@ import { GuildMember } from "discord.js"; import NicknameChanged from "./GuildMemberUpdate/NicknameChanged"; +import CacheHelper from "../../helpers/CacheHelper"; 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); } } \ No newline at end of file diff --git a/src/events/MessageEvents/MessageCreate.ts b/src/events/MessageEvents/MessageCreate.ts index a91250d..1dac122 100644 --- a/src/events/MessageEvents/MessageCreate.ts +++ b/src/events/MessageEvents/MessageCreate.ts @@ -1,11 +1,14 @@ import { Message } from "discord.js"; import SettingsHelper from "../../helpers/SettingsHelper"; import VerificationCheck from "./MessageCreate/VerificationCheck"; +import CacheHelper from "../../helpers/CacheHelper"; export default async function MessageCreate(message: Message) { if (!message.guild) return; if (message.author.bot) return; + await CacheHelper.UpdateServerCache(message.guild); + const isVerificationEnabled = await SettingsHelper.GetSetting("verification.enabled", message.guild.id); if (isVerificationEnabled && isVerificationEnabled.toLocaleLowerCase() == "true") { diff --git a/src/events/MessageEvents/MessageDelete.ts b/src/events/MessageEvents/MessageDelete.ts index 5f66300..f24ec5d 100644 --- a/src/events/MessageEvents/MessageDelete.ts +++ b/src/events/MessageEvents/MessageDelete.ts @@ -2,11 +2,14 @@ import { EmbedBuilder, Message, TextChannel } from "discord.js"; import EmbedColours from "../../constants/EmbedColours"; import IgnoredChannel from "../../database/entities/IgnoredChannel"; import SettingsHelper from "../../helpers/SettingsHelper"; +import CacheHelper from "../../helpers/CacheHelper"; export default async function MessageDelete(message: Message) { if (!message.guild) return; if (message.author.bot) return; + await CacheHelper.UpdateServerCache(message.guild); + const enabled = await SettingsHelper.GetSetting("event.message.delete.enabled", message.guild.id); if (!enabled || enabled.toLowerCase() != "true") return; diff --git a/src/events/MessageEvents/MessageUpdate.ts b/src/events/MessageEvents/MessageUpdate.ts index 7564a2f..27369a4 100644 --- a/src/events/MessageEvents/MessageUpdate.ts +++ b/src/events/MessageEvents/MessageUpdate.ts @@ -2,10 +2,14 @@ import { EmbedBuilder, Message, TextChannel } from "discord.js"; import EmbedColours from "../../constants/EmbedColours"; import IgnoredChannel from "../../database/entities/IgnoredChannel"; import SettingsHelper from "../../helpers/SettingsHelper"; +import CacheHelper from "../../helpers/CacheHelper"; export default async function MessageUpdate(oldMessage: Message, newMessage: Message) { if (!newMessage.guild) return; if (newMessage.author.bot) return; + + await CacheHelper.UpdateServerCache(newMessage.guild); + if (oldMessage.content == newMessage.content) return; const enabled = await SettingsHelper.GetSetting("event.message.update.enabled", newMessage.guild.id); diff --git a/src/helpers/CacheHelper.ts b/src/helpers/CacheHelper.ts new file mode 100644 index 0000000..22b6fd7 --- /dev/null +++ b/src/helpers/CacheHelper.ts @@ -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(); + } +} \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index af29c08..ee640cc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -850,9 +850,9 @@ "@types/istanbul-lib-report" "*" "@types/jest@^29.0.0": - version "29.5.11" - resolved "https://registry.yarnpkg.com/@types/jest/-/jest-29.5.11.tgz#0c13aa0da7d0929f078ab080ae5d4ced80fa2f2c" - integrity sha512-S2mHmYIVe13vrm6q4kN6fLYYAka15ALQki/vgDC3mIukEOx8WJlv0kQPM+d4w8Gp6u0uSdKND04IlTXBv0rwnQ== + version "29.5.12" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-29.5.12.tgz#7f7dc6eb4cf246d2474ed78744b05d06ce025544" + integrity sha512-eDC8bTvT/QhYdxJAulQikueigY5AsdBRH2yDKW3yveW7svY3+DzN84/2NUgkw10RTiJbWqZrTtoGVdYlvFJdLw== dependencies: expect "^29.0.0" pretty-format "^29.0.0" @@ -864,7 +864,14 @@ dependencies: "@types/node" "*" -"@types/node@*", "@types/node@^20.0.0": +"@types/node@*": + version "20.11.16" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.11.16.tgz#4411f79411514eb8e2926f036c86c9f0e4ec6708" + integrity sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ== + dependencies: + undici-types "~5.26.4" + +"@types/node@^20.0.0": version "20.11.10" resolved "https://registry.yarnpkg.com/@types/node/-/node-20.11.10.tgz#6c3de8974d65c362f82ee29db6b5adf4205462f9" integrity sha512-rZEfe/hJSGYmdfX9tvcPMYeYPW2sNl50nsw4jZmRcaG0HIAb0WYEpsB05GOb53vjqpyE9GUhlDQ4jLSoB5q9kg== @@ -1782,9 +1789,9 @@ dot-prop@^7.2.0: type-fest "^2.11.2" dotenv@^16.0.0, dotenv@^16.0.3: - version "16.4.1" - resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.4.1.tgz#1d9931f1d3e5d2959350d1250efab299561f7f11" - integrity sha512-CjA3y+Dr3FyFDOAMnxZEGtnW9KBR2M0JvvUtXNW+dYJL5ROWxP9DUHCwgFqpMk0OXCc0ljhaNTr2w/kutYIcHQ== + version "16.4.5" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.4.5.tgz#cdd3b3b604cb327e286b4762e13502f717cb099f" + integrity sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg== eastasianwidth@^0.2.0: version "0.2.0" @@ -4651,9 +4658,9 @@ ts-essentials@^7.0.3: integrity sha512-8+gr5+lqO3G84KdiTSMRLtuyJ+nTBVRKuCrK4lidMPdVeEp0uqC875uE5NMcaA7YYMN7XsNiFQuMvasF8HT/xQ== ts-jest@^29.0.0: - version "29.1.1" - resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-29.1.1.tgz#f58fe62c63caf7bfcc5cc6472082f79180f0815b" - integrity sha512-D6xjnnbP17cC85nliwGiL+tpoKN0StpgE0TeOjXQTU6MVCfsB4v7aW05CgQ/1OywGb0x/oy9hHFnN+sczTiRaA== + version "29.1.2" + resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-29.1.2.tgz#7613d8c81c43c8cb312c6904027257e814c40e09" + integrity sha512-br6GJoH/WUX4pu7FbZXuWGKGNDuU7b8Uj77g/Sp7puZV6EXzuByl6JrECvm0MzVzSTkSHWTihsXt+5XYER5b+g== dependencies: bs-logger "0.x" fast-json-stable-stringify "2.x" @@ -4777,10 +4784,10 @@ undici-types@~5.26.4: resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== -undici@5.27.2: - version "5.27.2" - resolved "https://registry.yarnpkg.com/undici/-/undici-5.27.2.tgz#a270c563aea5b46cc0df2550523638c95c5d4411" - integrity sha512-iS857PdOEy/y3wlM3yRp+6SNQQ6xU0mmZcwRSriqk+et/cwWAtwmIGf6WkoDN2EK/AMdCO/dfXzIwi+rFMrjjQ== +undici@5.27.2, undici@^6.0.0: + version "6.7.0" + resolved "https://registry.yarnpkg.com/undici/-/undici-6.7.0.tgz#ab7eccb292c8e831c93564ac59f8323c0e8aa842" + integrity sha512-IcWssIyDN1gk6Mcae44q04oRoWTKrW8OKz0effVK1xdWwAgMPnfpxhn9RXUSL5JlwSikO18R7Ibk7Nukz6kxWA== dependencies: "@fastify/busboy" "^2.0.0"