pnp-scheduler/source/Events/Handlers/ReminderEvent.ts

128 lines
No EOL
4 KiB
TypeScript

import {Container} from "../../Container/Container";
import {PlaydateRepository} from "../../Database/Repositories/PlaydateRepository";
import {GroupConfigurationRepository} from "../../Database/Repositories/GroupConfigurationRepository";
import {PlaydateModel} from "../../Database/Models/PlaydateModel";
import {ChannelId} from "../../types/DiscordTypes";
import {DiscordClient} from "../../Discord/DiscordClient";
import {EmbedBuilder, roleMention, time} from "discord.js";
import {ArrayUtils} from "../../Utilities/ArrayUtils";
import {EventConfiguration, EventType, TimedEvent} from "../EventHandler.types";
import {ConfigurationHandler} from "../../Configuration/ConfigurationHandler";
import {
GroupConfigurationProvider,
RuntimeGroupConfiguration
} from "../../Configuration/Groups/GroupConfigurationProvider";
import {GroupConfigurationModel} from "../../Database/Models/GroupConfigurationModel";
export class ReminderEvent implements TimedEvent {
private static REMINDER_INTERVALS = [
1,
7
];
private static REMINDER_NOTIFICATIONS = [
'The darkness approaches. Get ready!',
'Your aid is requested once again.',
'Grab your dice and show them evil-doers how its done!',
]
type: EventType.TimeBased = EventType.TimeBased;
configuration: EventConfiguration = {
name: "Reminders",
}
cronExpression: string = "0 9 * * *"
private readonly groupConfigurationRepository: GroupConfigurationRepository
private playdateRepository: PlaydateRepository
private discordClient: DiscordClient
constructor() {
this.playdateRepository = Container.get<PlaydateRepository>(PlaydateRepository.name);
this.groupConfigurationRepository = Container.get<GroupConfigurationRepository>(GroupConfigurationRepository.name);
this.discordClient = Container.get<DiscordClient>(DiscordClient.name);
}
async execute() {
const today = new Date();
today.setHours(0, 0, 0, 0);
const playdates = ReminderEvent.REMINDER_INTERVALS.flatMap((interval) => {
const fromDate = new Date(today.valueOf())
fromDate.setDate(fromDate.getDate() + interval);
const toDate = new Date(today.valueOf())
toDate.setDate(toDate.getDate() + interval);
toDate.setHours(23, 59, 59, 999);
return this.playdateRepository.findPlaydatesInRange(fromDate, toDate);
}, this)
const promises = playdates
.map((playdate) => {
if (!playdate.group) {
return Promise.resolve();
}
const groupConfig = new ConfigurationHandler<GroupConfigurationModel, RuntimeGroupConfiguration>(
new GroupConfigurationProvider(
Container.get<GroupConfigurationRepository>(GroupConfigurationRepository.name),
playdate.group
)
);
const targetChannel = groupConfig.getConfigurationByPath("channels.playdateReminders").value;
if (!targetChannel) {
return Promise.resolve();
}
return this.sendReminder(playdate, <ChannelId>targetChannel);
}, this)
await Promise.all(promises);
}
private async sendReminder(playdate: PlaydateModel, targetChannel: ChannelId) {
if (!playdate.group) {
return;
}
const channel = await this.discordClient.Client.channels.fetch(targetChannel)
if (!channel) {
return;
}
if (!channel.isTextBased()) {
return;
}
if (!channel.isSendable()) {
return;
}
const embed = new EmbedBuilder()
.setTitle("Playdate reminder")
.setDescription(
ArrayUtils.chooseRandom(ReminderEvent.REMINDER_NOTIFICATIONS)
)
.addFields({
name: "Next Playdate:",
value: `${time(playdate.from_time, "F")} - ${time(playdate.from_time, 'R')}`,
})
.setFooter({
text: `Group: ${playdate.group.name}`
});
channel.send({
content: roleMention(playdate.group.role.roleid),
embeds: [
embed
],
allowedMentions: {
roles: [playdate.group.role.roleid]
}
})
}
}