Skip to content

Commit

Permalink
Merge pull request #104 from BingusBoingus-Developer-Team/refactor-cr…
Browse files Browse the repository at this point in the history
…onScheduler

Refactor Cron scheduler
  • Loading branch information
lulu12329 authored May 9, 2024
2 parents 70b3f39 + adc1cb1 commit a441116
Show file tree
Hide file tree
Showing 9 changed files with 104 additions and 6,579 deletions.
6,505 changes: 7 additions & 6,498 deletions package-lock.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
"devDependencies": {
"@eslint/js": "^9.2.0",
"@types/express": "^4.17.17",
"@types/node-cron": "^3.0.11",
"eslint": "^8.57.0",
"globals": "^15.1.0",
"prettier": "3.0.3",
Expand Down
63 changes: 0 additions & 63 deletions src/modules/cron-tasks/cron-scheduler.ts

This file was deleted.

72 changes: 72 additions & 0 deletions src/modules/cron-tasks/cron.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { Client, TextChannel } from 'discord.js';
import BirthdayShoutoutTask from './tasks/birthday-shoutout.task';
import { Inject, Injectable } from '@nestjs/common';
import WakeUpTask from './tasks/wake-up.task';
import * as cron from 'node-cron';
import { BirthdayEntryService } from '../models/birthday/service/birthday-entry.service';
import { TaskEntry } from './interfaces/task-entry.interface';
import { DiscordService } from '../discord/discord.service';

@Injectable()
export class CronService {
private static instance: CronService;
private tasks: TaskEntry[];

constructor(
@Inject(BirthdayEntryService)
private readonly birthdayService: BirthdayEntryService,
@Inject(DiscordService)
private readonly discordService: DiscordService,
) {
if (CronService.instance) {
throw new Error(`ERROR: An instance has already been created.`);
}

CronService.instance = this;
}

static getInstance(): CronService {
return CronService.instance;
}

public init() {
this.tasks = [
{
name: 'birthday-shoutout',
schedule: '0 10 * * *',
task: new BirthdayShoutoutTask(
this.discordService.client.channels.cache.find(
(channel) => channel.id === '447554141724737548',
) as TextChannel,
this.birthdayService,
),
},
{
name: 'first-of-the-month',
schedule: '0 12 1 * *',
task: new WakeUpTask(
this.discordService.client.channels.cache.find(
(channel) => channel.id === '447554141724737548',
) as TextChannel,
),
},
];
this.registerTasks();
}

registerTasks(): void {
this.tasks.forEach((task) => {
if (!cron.validate(task.schedule)) {
throw new Error(
`ERROR: Invalid cron schedule expression for task '${task.name}'`,
);
}

cron
.schedule(task.schedule, async () => {
await task.task.execute();
})
.start();
});
}
}
7 changes: 7 additions & 0 deletions src/modules/cron-tasks/interfaces/task-entry.interface.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { ITask } from '../tasks/interfaces/task.interface';

export interface TaskEntry {
name: string;
schedule: string;
task: ITask;
}
15 changes: 7 additions & 8 deletions src/modules/cron-tasks/task.module.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import { Module } from "@nestjs/common";
import { BirthdayEntryModule } from "../models/birthday/module/birthday-entry.module";

import { Module } from '@nestjs/common';
import { BirthdayEntryModule } from '../models/birthday/module/birthday-entry.module';
import { CronService } from './cron.service';
import { DiscordModule } from '../discord/discord.module';

@Module({
imports: [
BirthdayEntryModule,
],
providers: [],
exports: [],
imports: [DiscordModule, BirthdayEntryModule],
providers: [CronService],
exports: [CronService],
})
export class TaskModule {}
10 changes: 1 addition & 9 deletions src/modules/discord/discord.service.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,19 @@
import { Injectable } from '@nestjs/common';
import { Client, GatewayIntentBits } from 'discord.js';
import { AppConfigService } from '../../config/config.service';
import { CronScheduler } from '../cron-tasks/cron-scheduler';
import { BirthdayEntryService } from '../models/birthday/service/birthday-entry.service';

@Injectable()
export class DiscordService {
public readonly client: Client<boolean>;
public cronScheduler: CronScheduler;

constructor(configService: AppConfigService, private readonly birthdayService: BirthdayEntryService) {
constructor(configService: AppConfigService) {
this.client = new Client({
intents: [
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildMessages,
GatewayIntentBits.MessageContent,
],
});

this.client.login(configService.botToken);
this.client.on('ready', () => {
this.cronScheduler = new CronScheduler(this.client, birthdayService);
this.cronScheduler.registerTasks();
});
}
}
3 changes: 2 additions & 1 deletion src/modules/event/event.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ import { MessageEvent } from './services/messageEvent';
import { DiscordModule } from '../discord/discord.module';
import { CommandModule } from '../command/command.module';
import { PollModule } from '../models/poll/module/poll.module';
import { TaskModule } from '../cron-tasks/task.module';

@Module({
imports: [DiscordModule, CommandModule, PollModule],
imports: [DiscordModule, TaskModule, CommandModule, PollModule],
providers: [EventService, ClientReady, Interaction, MessageEvent],
exports: [EventService],
})
Expand Down
7 changes: 7 additions & 0 deletions src/modules/event/services/clientReady.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
import { Injectable } from '@nestjs/common';
import { ClientEvents, Events } from 'discord.js';
import { AEvent } from '../event.abstract';
import { CronService } from '../../cron-tasks/cron.service';

@Injectable()
export class ClientReady extends AEvent {
constructor(private readonly cronService: CronService) {
super();
}

event: keyof ClientEvents = Events.ClientReady;
once: boolean = true;

async execute(args: ClientEvents[Events.ClientReady]) {
console.log('Successfully connected to Discord');
console.log(`logged in as ${args[0].user.username}`);

this.cronService.init();
}
}

0 comments on commit a441116

Please sign in to comment.