Add auto kick functionality (#502)
All checks were successful
Test / build (push) Successful in 13s

- Add command to configure the auto kick function
- Added ability to run functions on a cron job
- Added a cron job every hour to check if a user has had a role for a configured amount of time and kick them if they have
    - The function also optionally sends a notice embed at a configured time before the kick

#485

Reviewed-on: #502
Reviewed-by: VylpesTester <tester@vylpes.com>
Co-authored-by: Ethan Lane <ethan@vylpes.com>
Co-committed-by: Ethan Lane <ethan@vylpes.com>
This commit is contained in:
Ethan Lane 2025-01-03 17:47:16 +00:00 committed by Vylpes
parent bfbf386eeb
commit cdf689f1c5
16 changed files with 467 additions and 4 deletions

View file

@ -0,0 +1,37 @@
import AutoKickConfig from "../database/entities/AutoKickConfig";
export default class AutoKickHelper {
public static async GetSetting(serverId: string): Promise<AutoKickConfig | null> {
const configs = await AutoKickConfig.FetchAllByServerId(serverId);
if (configs.length != 1) {
return null;
}
return configs[0];
}
public static async SetSetting(serverId: string, roleId: string, kickTime: number, noticeTime?: number, noticeChannelId?: string) {
const configs = await AutoKickConfig.FetchAllByServerId(serverId);
if (configs.length == 0) {
const config = new AutoKickConfig(serverId, roleId, kickTime, noticeTime, noticeChannelId);
await config.Save(AutoKickConfig, config);
return;
}
const config = configs[0];
config.UpdateBasicDetails(roleId, kickTime, noticeTime, noticeChannelId);
await config.Save(AutoKickConfig, config);
}
public static async UnsetSetting(serverId: string) {
const configs = await AutoKickConfig.FetchAllByServerId(serverId);
for (let config of configs) {
await AutoKickConfig.Remove(AutoKickConfig, config);
}
}
}

View file

@ -0,0 +1,81 @@
import {CronJob} from "cron";
import {primitive} from "../type/primitive";
import {v4} from "uuid";
interface Timer {
id: string;
job: CronJob;
context: Map<string, primitive>;
onTick: ((context: Map<string, primitive>) => void) | ((context: Map<string, primitive>) => Promise<void>);
runOnStart: boolean;
}
export default class TimerHelper {
private _timers: Timer[];
constructor() {
this._timers = [];
}
public AddTimer(
cronTime: string,
timeZone: string,
onTick: ((context: Map<string, primitive>) => void) | ((context: Map<string, primitive>) => Promise<void>),
runOnStart: boolean = false): string {
const context = new Map<string, primitive>();
const job = new CronJob(
cronTime,
() => {
onTick(context);
},
null,
false,
timeZone,
);
const id = v4();
this._timers.push({
id,
job,
context,
onTick,
runOnStart,
});
return id;
}
public StartAllTimers() {
this._timers.forEach(timer => this.StartJob(timer));
}
public StopAllTimers() {
this._timers.forEach(timer => timer.job.stop());
}
public StartTimer(id: string) {
const timer = this._timers.find(x => x.id == id);
if (!timer) return;
this.StartJob(timer);
}
public StopTimer(id: string) {
const timer = this._timers.find(x => x.id == id);
if (!timer) return;
timer.job.stop();
}
private StartJob(timer: Timer) {
timer.job.start();
if (timer.runOnStart) {
timer.onTick(timer.context);
}
}
}