import {EventConfiguration, TimedEvent} from "./EventHandler"; import {Container} from "../Container/Container"; import {PlaydateRepository} from "../Repositories/PlaydateRepository"; import {GroupConfigurationHandler} from "../Groups/GroupConfigurationHandler"; import {GroupConfigurationRepository} from "../Repositories/GroupConfigurationRepository"; import {PlaydateModel} from "../Models/PlaydateModel"; import {ChannelId} from "../types/DiscordTypes"; import {DiscordClient} from "../Discord/DiscordClient"; import {EmbedBuilder, roleMention, time} from "discord.js"; import {ArrayUtils} from "../Utilities/ArrayUtils"; 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!', ] configuration: EventConfiguration = { name: "Reminders", } cronExpression: string = "0 9 * * *" private readonly groupConfigurationRepository: GroupConfigurationRepository private playdateRepository: PlaydateRepository private discordClient: DiscordClient constructor() { this.playdateRepository = Container.get(PlaydateRepository.name); this.groupConfigurationRepository = Container.get(GroupConfigurationRepository.name); this.discordClient = Container.get(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 configurationHandler = new GroupConfigurationHandler( this.groupConfigurationRepository, playdate.group ); const config = configurationHandler.getConfiguration(); const targetChannel = config.channels?.playdateReminders; if (!targetChannel) { return Promise.resolve(); } return this.sendReminder(playdate, 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 ] } }) } }