2023-06-10 22:53:11 +02:00
import { GuildScheduledEvent , Message , TextChannel } from "discord.js" ;
import { ScheduledTask , schedule } from "node-cron" ;
2023-06-10 14:23:10 +02:00
import { v4 as uuid } from "uuid" ;
import { jellyfinHandler } from "../.." ;
2023-06-10 22:53:11 +02:00
import { closePoll } from "../commands/closepoll" ;
2023-06-10 14:23:10 +02:00
import { config } from "../configuration" ;
2023-06-10 22:53:11 +02:00
import { logger } from "../logger" ;
2023-06-12 19:43:33 +02:00
import toDate from "date-fns/fp/toDate" ;
import { addDays , isAfter , isBefore } from "date-fns" ;
2023-06-10 14:23:10 +02:00
export const name = 'guildScheduledEventCreate'
2023-06-10 22:53:11 +02:00
export enum Emotes { "1️ ⃣" , "2️ ⃣" , "3️ ⃣" , "4️ ⃣" , "5️ ⃣" , "6️ ⃣" , "7️ ⃣" , "8️ ⃣" , "9️ ⃣" , "🔟" }
export let task : ScheduledTask | undefined
2023-06-10 14:23:10 +02:00
export async function execute ( event : GuildScheduledEvent ) {
const requestId = uuid ( )
logger . debug ( ` New event created: ${ JSON . stringify ( event , null , 2 ) } ` , { guildId : event.guildId , requestId } )
if ( event . name . toLowerCase ( ) . includes ( "!nextwp" ) ) {
logger . info ( "Event was a placeholder event to start a new watchparty and voting. Creating vote!" , { guildId : event.guildId , requestId } )
logger . debug ( "Renaming event" , { guildId : event.guildId , requestId } )
event . edit ( { name : "Watchparty - Voting offen" } )
const movies = await jellyfinHandler . getRandomMovies ( 5 , event . guildId , requestId )
logger . info ( ` Got ${ movies . length } random movies. Creating voting ` , { guildId : event.guildId , requestId } )
logger . debug ( ` Movies: ${ JSON . stringify ( movies . map ( movie = > movie . name ) ) } ` , { guildId : event.guildId , requestId } )
const channel : TextChannel = < TextChannel > ( await event . guild ? . channels . fetch ( ) ) ? . filter ( channel = > channel ! . id === config . bot . announcement_channel_id ) . map ( ( value , _ ) = > value ) [ 0 ] //todo: needs to be done less sketchy
2023-06-10 22:58:00 +02:00
logger . debug ( ` Found channel ${ JSON . stringify ( channel , null , 2 ) } ` , { guildId : event.guildId , requestId } )
2023-06-10 14:23:10 +02:00
2023-06-10 17:27:32 +02:00
let message = "[Abstimmung]\nEs gibt eine neue Abstimmung für die nächste Watchparty! Stimme hierunter für den nächsten Film ab!\n"
2023-06-10 14:23:10 +02:00
for ( let i = 0 ; i < movies . length ; i ++ ) {
2023-06-10 17:27:32 +02:00
message = message . concat ( Emotes [ i ] ) . concat ( ": " ) . concat ( movies [ i ] . name ! ) . concat ( "\n" )
2023-06-10 14:23:10 +02:00
}
const sentMessage : Message < true > = await ( await channel . fetch ( ) ) . send ( message )
for ( let i = 0 ; i < movies . length ; i ++ ) {
2023-06-10 17:27:32 +02:00
sentMessage . react ( Emotes [ i ] )
2023-06-10 14:23:10 +02:00
}
2023-06-11 09:01:25 +02:00
if ( ! task ) {
2023-06-10 22:53:11 +02:00
task = schedule ( "0 * * * * *" , ( ) = > checkForPollsToClose ( event ) )
}
2023-06-10 17:27:32 +02:00
// sentMessage.pin() //todo: uncomment when bot has permission to pin messages. Also update closepoll.ts to only fetch pinned messages
2023-06-10 14:23:10 +02:00
}
2023-06-10 22:53:11 +02:00
}
async function checkForPollsToClose ( event : GuildScheduledEvent ) : Promise < void > {
const requestId = uuid ( )
logger . info ( ` Automatic check for poll closing. ` , { guildId : event.guildId , requestId } )
if ( ! event . guild ) {
logger . error ( "No guild in event. Cancelling." , { guildId : event.guildId , requestId } )
return
}
//refetch event in case the time changed or the poll is already closed
const events = ( await event . guild . scheduledEvents . fetch ( ) )
. filter ( event = > event . name . toLowerCase ( ) . includes ( "voting offen" ) )
. map ( ( value , _ ) = > value )
2023-06-11 09:01:25 +02:00
if ( ! events || events . length <= 0 ) {
2023-06-10 22:53:11 +02:00
logger . info ( "Did not find any events. Cancelling" , { guildId : event.guildId , requestId } )
return
2023-06-11 09:01:25 +02:00
} else if ( events . length > 1 ) {
2023-06-10 22:53:11 +02:00
logger . error ( ` More than one event found. Don't know which one is the right one :( Events: ${ JSON . stringify ( events , null , 2 ) } ` , { guildId : event.guildId , requestId } )
return
}
const updatedEvent = events [ 0 ] //add two hours because of different timezones in discord api and Date.now()
2023-06-11 09:01:25 +02:00
if ( ! updatedEvent . scheduledStartTimestamp ) {
2023-06-10 22:53:11 +02:00
logger . error ( "Event does not have a scheduled start time. Cancelling" , { guildId : event.guildId , requestId } )
return
}
2023-06-12 19:43:33 +02:00
const eventDate : Date = toDate ( updatedEvent . scheduledStartTimestamp )
const closePollDate : Date = addDays ( eventDate , - 2 )
if ( isAfter ( Date . now ( ) , closePollDate ) ) {
2023-06-10 22:53:11 +02:00
logger . info ( "Less than two days until event. Closing poll" , { guildId : event.guildId , requestId } )
closePoll ( event . guild , requestId )
} else {
2023-06-12 19:43:33 +02:00
logger . info ( ` ScheduledStart: ${ closePollDate } . Now: ${ toDate ( Date . now ( ) ) } ` , { guildId : event.guildId , requestId } )
2023-06-10 22:53:11 +02:00
}
2023-06-10 14:23:10 +02:00
}