import { format } from "date-fns" import add from "date-fns/add" import { DateResolvable, Guild, GuildScheduledEvent, GuildScheduledEventCreateOptions } from "discord.js" import { client } from "../../.." import { CustomError, errorCodes, Maybe } from "../../interfaces" import { RepetitonInfo, Schedule, supportedSchedule } from "../../types/scheduledEventTypes" export const repetitionMarkerIsFound = (desc: string): boolean => desc.includes('$rep') export function createEventInGuild(guild: Guild, eventInfo: GuildScheduledEventCreateOptions): Promise { return guild.scheduledEvents.create(eventInfo) } export function getRepetitonInfo(description: string): RepetitonInfo { const lines = description.split(`\n`) const repetitionString = lines.find(x => x.startsWith('$rep:')) if (!repetitionString) throw new CustomError('Cant find repetition string', errorCodes.no_string_present) const scheduleString = determineScheduleString(repetitionString) const schedule: Schedule = new Schedule(scheduleString) const { totalAmount, alreadyOccured } = determineRepetitionCount(repetitionString) const endDate = determineEndDate(repetitionString) return { totalAmount, alreadyOccured, schedule, endDate } } export function determineScheduleString(repetitionLine: string): supportedSchedule { const segments = repetitionLine.split(':') const scheduleSegment = segments[1] if (scheduleSegment) return scheduleSegment else throw new CustomError('No schedule segment found', errorCodes.no_schedule) } export function determineRepetitionCount(description: string): { totalAmount: number; alreadyOccured: number } { const segments = description.split(':') const amountSegment = segments[2] if (amountSegment) { const amounts = amountSegment.split('/') return { totalAmount: Number(amounts[1]) ?? 0, alreadyOccured: Number(amounts[0]) ?? 0 } } else { throw new CustomError('No amount was defined', errorCodes.no_repetition_amount) } } export function buildNewRepetitionString(repetitionInfo: RepetitonInfo) { if (repetitionInfo.endDate) return `$rep:${repetitionInfo.schedule}:${format(repetitionInfo.endDate, 'yyyy-MM-dd')}` return `$rep:${repetitionInfo.schedule}:${repetitionInfo.alreadyOccured + 1}/${repetitionInfo.totalAmount}` } export function addRepetitonStringToEventDescription(oldguildScheduledEvent: string, newRepetitonString: string): string | undefined { const lines = oldguildScheduledEvent.split(`\n`) const repLineIndex = lines.findIndex(x => x.startsWith('$rep:')) const newLines = lines.filter((_, index) => repLineIndex !== index) newLines.push(newRepetitonString) return newLines.join('\n') } function determineEndDate(description: string): Maybe { const segments = description.split(':') if (segments.length === 3) { // rep:sched:countOrDate const segmentValue = segments[2] if (segmentValue.includes('/')) { if (segmentValue.match(/\//g) || [].length !== 2) { return } } const dateValue = new Date(segmentValue) return dateValue } else if (segments.length === 4) { // rep:sched:count:date const segmentValue = segments[3] const dateValue = new Date(segmentValue) return dateValue } return } export function checkIfRepetitionStringIsValid(description: string): string { if (!description) return 'not_present' if (repetitionMarkerIsFound(description)) { let repetitionInfo try { repetitionInfo = getRepetitonInfo(description) if (!repetitionInfo.schedule) return 'no_schedule' if (!repetitionInfo.totalAmount && !repetitionInfo.alreadyOccured && !repetitionInfo.endDate) { if (!repetitionInfo.totalAmount || !repetitionInfo.alreadyOccured) return 'no_amount' if (!repetitionInfo.endDate) return 'no_end' } return 'valid' } catch (error) { if (error instanceof CustomError) { return error.getCode() } return 'invalid' } } return 'not_present' } export async function validateRepetitionStringAndSendMessageOnFail(event: GuildScheduledEvent): Promise { const validResponses = [ 'valid', 'not_present' ] const resultstring: string = checkIfRepetitionStringIsValid(event.description ?? "") if (validResponses.includes(resultstring)) { // do success things? } else { const creatorMessage = `The repetition string in your event could not be parsed. Reason: ${resultstring}` console.log(creatorMessage) if (!event.creatorId) throw new CustomError('No creator ID present', errorCodes.no_creator_id) const creator = await client.users.fetch(event.creatorId) console.log(`Creator ${JSON.stringify(creator)}`) if (creator) if (!creator.dmChannel) await creator.createDM() await creator.dmChannel?.send(creatorMessage) } }