From 46ed11f6b249165237b3d54e5b491f316aab178b Mon Sep 17 00:00:00 2001 From: tippfehlr Date: Sat, 21 Sep 2024 23:44:45 +0200 Subject: [PATCH] =?UTF-8?q?refactor:=20move=20=E2=80=9Ccron=20jobs?= =?UTF-8?q?=E2=80=9D=20to=20their=20own=20files?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/modules/bot.ready.ts | 123 +---------------------- src/modules/cron.ts | 23 +++++ src/modules/cron/checkRoles.ts | 20 ++++ src/modules/cron/scheduledRoleActions.ts | 57 +++++++++++ src/modules/cron/updateMemberCount.ts | 30 ++++++ 5 files changed, 134 insertions(+), 119 deletions(-) create mode 100644 src/modules/cron.ts create mode 100644 src/modules/cron/checkRoles.ts create mode 100644 src/modules/cron/scheduledRoleActions.ts create mode 100644 src/modules/cron/updateMemberCount.ts diff --git a/src/modules/bot.ready.ts b/src/modules/bot.ready.ts index f23bead..77e7d5b 100644 --- a/src/modules/bot.ready.ts +++ b/src/modules/bot.ready.ts @@ -6,12 +6,13 @@ import { client } from './bot'; import CommandHandler from './commandHandler'; import config from './config'; import { configureInfluxDB } from './metrics'; -import { getUserCount, getRolesCount, db } from './db'; +import { getUserCount, getRolesCount } from './db'; import { i18n, log } from './messages'; +import { cron } from './cron'; import activityStats from './commands/activityStats'; import addActivityRole from './commands/addActivityRole'; -import checkRoles, { checkRolesStandalone } from './commands/checkRoles'; +import checkRoles from './commands/checkRoles'; import deleteActivityRole from './commands/deleteActivityRole'; import deleteStatusRole from './commands/deleteStatusRole'; import _export from './commands/export'; @@ -102,122 +103,6 @@ export function initClientReady() { log.info( `The bot is currently in ${client.guilds.cache.size} guilds with ${await getUserCount()} users and manages ${await getRolesCount()} roles`, ); - - // checkroles: - // execute every 30 minutes - // check if the last check was more than 20 hours ago - checkGuilds(); - setInterval(checkGuilds, 30 * 60 * 1000); - - // membercount: - // execute every 24 hours - // check if the last update was more than 7 days ago - updateMemberCount(); - setInterval(updateMemberCount, 24 * 60 * 60 * 1000); - - // scheduled role actions: - // execute every 6 hours - // check for roles to add or remove in scheduledRoleActions - executeScheduledRoleActions(); - setInterval(executeScheduledRoleActions, 6 * 60 * 60 * 1000); + cron(); }); } - -const delay = (ms: number) => new Promise(resolve => setTimeout(resolve, ms)); - -async function checkGuilds() { - const guildsToCheck = await db - .selectFrom('guilds') - .select('guildID') - .where('lastCheckRoles', '<', new Date(Date.now() - 20 * 60 * 60 * 1000)) - .orderBy('lastCheckRoles asc') - .execute(); - await client.guilds.fetch(); - for (const { guildID } of guildsToCheck) { - await delay(30 * 1000); - const guild = client.guilds.cache.get(guildID); - if (guild) await checkRolesStandalone({ guild }); - } -} - -async function updateMemberCount() { - const guildsToUpdate = await db - .selectFrom('guilds') - .select(['guildID']) - .where(eb => - eb.or([ - eb('approxMemberCountLastUpdate', '<', new Date(Date.now() - 7 * 24 * 60 * 60 * 1000)), - eb('approxMemberCountLastUpdate', 'is', null), - eb('approxMemberCount', 'is', null), - ]), - ) - .execute(); - await client.guilds.fetch(); - for (const dbGuild of guildsToUpdate) { - const guild = client.guilds.cache.get(dbGuild.guildID); - if (!guild) continue; - await guild.members.fetch(); - await db - .updateTable('guilds') - .set({ - approxMemberCount: guild.memberCount, - approxMemberCountLastUpdate: new Date(), - }) - .where('guildID', '=', dbGuild.guildID) - .execute(); - } -} - -async function executeScheduledRoleActions() { - // ensure that only executed schedules get deleted. - // otherwise, this could start at 23:59 and end after midnight, - // deleting the schedules for the new day accidently. - const date = new Date(); - const actionsDue = await db - .deleteFrom('scheduledRoleActions') - .where('scheduledDate', '<=', date) - .returning(['action', 'roleID', 'guildID', 'userID']) - .execute(); - let stats = { added: 0, removed: 0 }; - - for (const action of actionsDue) { - if (action.action === 'add') { - const guild = await client.guilds.fetch(action.guildID); - if (!guild) continue; - const user = await guild.members.fetch(action.userID); - if (!user) continue; - - try { - user.roles.add(action.roleID); - stats.added += 1; - } catch (error) { - log.error( - `scheduledRoleActions: should assign role ${action.roleID} to user ` + - `${user.nickname} (${user.id}) on guild ${guild.name} (${guild.id}) ` + - 'but it (probably) doesn’t exist.', - error, - ); - } - } else if (action.action === 'remove') { - const guild = await client.guilds.fetch(action.guildID); - if (1 || 2) { - } - if (!guild) continue; - const user = await guild.members.fetch(action.userID); - if (!user) continue; - - try { - user.roles.remove(action.roleID); - stats.removed += 1; - } catch (error) { - log.error( - `scheduledRoleActions: should remove role ${action.roleID} to user ` + - `${user.nickname} (${user.id}) on guild ${guild.name} (${guild.id}) ` + - 'but it (probably) doesn’t exist.', - error, - ); - } - } - } - log.info(`scheduledRoleActions: added ${stats.added} and removed ${stats.removed} roles.`); -} diff --git a/src/modules/cron.ts b/src/modules/cron.ts new file mode 100644 index 0000000..cbcf7e3 --- /dev/null +++ b/src/modules/cron.ts @@ -0,0 +1,23 @@ +import { checkGuilds } from './cron/checkRoles'; +import { executeScheduledRoleActions } from './cron/scheduledRoleActions'; +import { updateMemberCount } from './cron/updateMemberCount'; + +export function cron() { + // checkroles: + // execute every 30 minutes + // check if the last check was more than 20 hours ago + checkGuilds(); + setInterval(checkGuilds, 30 * 60 * 1000); + + // membercount: + // execute every 24 hours + // check if the last update was more than 7 days ago + updateMemberCount(); + setInterval(updateMemberCount, 24 * 60 * 60 * 1000); + + // scheduled role actions: + // execute every 6 hours + // check for roles to add or remove in scheduledRoleActions + executeScheduledRoleActions(); + setInterval(executeScheduledRoleActions, 6 * 60 * 60 * 1000); +} diff --git a/src/modules/cron/checkRoles.ts b/src/modules/cron/checkRoles.ts new file mode 100644 index 0000000..b6008fe --- /dev/null +++ b/src/modules/cron/checkRoles.ts @@ -0,0 +1,20 @@ +import { client } from '../bot'; +import { checkRolesStandalone } from '../commands/checkRoles'; +import { db } from '../db'; + +const delay = (ms: number) => new Promise(resolve => setTimeout(resolve, ms)); + +export async function checkGuilds() { + const guildsToCheck = await db + .selectFrom('guilds') + .select('guildID') + .where('lastCheckRoles', '<', new Date(Date.now() - 20 * 60 * 60 * 1000)) + .orderBy('lastCheckRoles asc') + .execute(); + await client.guilds.fetch(); + for (const { guildID } of guildsToCheck) { + await delay(30 * 1000); + const guild = client.guilds.cache.get(guildID); + if (guild) await checkRolesStandalone({ guild }); + } +} diff --git a/src/modules/cron/scheduledRoleActions.ts b/src/modules/cron/scheduledRoleActions.ts new file mode 100644 index 0000000..2c0db61 --- /dev/null +++ b/src/modules/cron/scheduledRoleActions.ts @@ -0,0 +1,57 @@ +import { client } from '../bot'; +import { db } from '../db'; +import { log } from '../messages'; + +export async function executeScheduledRoleActions() { + // ensure that only executed schedules get deleted. + // otherwise, this could start at 23:59 and end after midnight, + // deleting the schedules for the new day accidently. + const date = new Date(); + const actionsDue = await db + .deleteFrom('scheduledRoleActions') + .where('scheduledDate', '<=', date) + .returning(['action', 'roleID', 'guildID', 'userID']) + .execute(); + let stats = { added: 0, removed: 0 }; + + for (const action of actionsDue) { + if (action.action === 'add') { + const guild = await client.guilds.fetch(action.guildID); + if (!guild) continue; + const user = await guild.members.fetch(action.userID); + if (!user) continue; + + try { + user.roles.add(action.roleID); + stats.added += 1; + } catch (error) { + log.error( + `scheduledRoleActions: should assign role ${action.roleID} to user ` + + `${user.nickname} (${user.id}) on guild ${guild.name} (${guild.id}) ` + + 'but it (probably) doesn’t exist.', + error, + ); + } + } else if (action.action === 'remove') { + const guild = await client.guilds.fetch(action.guildID); + if (1 || 2) { + } + if (!guild) continue; + const user = await guild.members.fetch(action.userID); + if (!user) continue; + + try { + user.roles.remove(action.roleID); + stats.removed += 1; + } catch (error) { + log.error( + `scheduledRoleActions: should remove role ${action.roleID} to user ` + + `${user.nickname} (${user.id}) on guild ${guild.name} (${guild.id}) ` + + 'but it (probably) doesn’t exist.', + error, + ); + } + } + } + log.info(`scheduledRoleActions: added ${stats.added} and removed ${stats.removed} roles.`); +} diff --git a/src/modules/cron/updateMemberCount.ts b/src/modules/cron/updateMemberCount.ts new file mode 100644 index 0000000..c546aca --- /dev/null +++ b/src/modules/cron/updateMemberCount.ts @@ -0,0 +1,30 @@ +import { client } from '../bot'; +import { db } from '../db'; + +export async function updateMemberCount() { + const guildsToUpdate = await db + .selectFrom('guilds') + .select(['guildID']) + .where(eb => + eb.or([ + eb('approxMemberCountLastUpdate', '<', new Date(Date.now() - 7 * 24 * 60 * 60 * 1000)), + eb('approxMemberCountLastUpdate', 'is', null), + eb('approxMemberCount', 'is', null), + ]), + ) + .execute(); + await client.guilds.fetch(); + for (const dbGuild of guildsToUpdate) { + const guild = client.guilds.cache.get(dbGuild.guildID); + if (!guild) continue; + await guild.members.fetch(); + await db + .updateTable('guilds') + .set({ + approxMemberCount: guild.memberCount, + approxMemberCountLastUpdate: new Date(), + }) + .where('guildID', '=', dbGuild.guildID) + .execute(); + } +}