import {Container} from "../../Container/Container"; import {PlaydateRepository} from "../../Database/Repositories/PlaydateRepository"; import {GroupConfigurationHandler} from "../../Configuration/Groups/GroupConfigurationHandler"; 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"; 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.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] } }) } }