Put role handling in background task scheduled at startup
This commit is contained in:
		@@ -39,7 +39,11 @@ async function sendAnnouncement(guildId: string, requestId: string): Promise<voi
 | 
				
			|||||||
    logger.info("Sending announcement")
 | 
					    logger.info("Sending announcement")
 | 
				
			||||||
    const announcementChannel: TextChannel = client.getAnnouncementChannelForGuild(guildId)
 | 
					    const announcementChannel: TextChannel = client.getAnnouncementChannelForGuild(guildId)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const body = `Hey! @everyone! Hier ist der Watchparty Bot vom Hartzarett. 
 | 
					    const currentPinnedAnnouncementMessages = (await announcementChannel.messages.fetchPinned()).filter(message => message.cleanContent.includes("[announcement]"))
 | 
				
			||||||
 | 
					    currentPinnedAnnouncementMessages.forEach(async (message) => await message.unpin())
 | 
				
			||||||
 | 
					    currentPinnedAnnouncementMessages.forEach(message => message.delete())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const body = `[announcement] Hey! @everyone! Hier ist der Watchparty Bot vom Hartzarett. 
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
Wir machen in Zukunft regelmäßig Watchparties! Falls du mitmachen möchtest, reagiere einfach auf diesen Post mit 🎫, dann bekommst du automatisch eine Rolle zugewiesen und wirst benachrichtigt sobald es in der Zukunft weitere Watchparties und Filme zum abstimmen gibt.
 | 
					Wir machen in Zukunft regelmäßig Watchparties! Falls du mitmachen möchtest, reagiere einfach auf diesen Post mit 🎫, dann bekommst du automatisch eine Rolle zugewiesen und wirst benachrichtigt sobald es in der Zukunft weitere Watchparties und Filme zum abstimmen gibt.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -51,20 +55,11 @@ Für eine Erklärung wie das alles funktioniert mach einfach /mitgucken für ein
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    const message: Message<true> = await announcementChannel.send(options)
 | 
					    const message: Message<true> = await announcementChannel.send(options)
 | 
				
			||||||
    await message.react("🎫")
 | 
					    await message.react("🎫")
 | 
				
			||||||
    // await message.pin()
 | 
					    await message.pin()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    task = schedule("* * * * * *", async () => {
 | 
					 | 
				
			||||||
        const reactions = await message.reactions.resolve("🎫")
 | 
					 | 
				
			||||||
        if (reactions) {
 | 
					 | 
				
			||||||
            manageAnnouncementRoles(message.guild, reactions)
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            logger.error("Did not get reactions! Aborting!", { guildId, requestId })
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    })
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
async function manageAnnouncementRoles(guild: Guild, reaction: MessageReaction) {
 | 
					export async function manageAnnouncementRoles(guild: Guild, reaction: MessageReaction, requestId: string) {
 | 
				
			||||||
    const requestId = uuid()
 | 
					 | 
				
			||||||
    const guildId = guild.id
 | 
					    const guildId = guild.id
 | 
				
			||||||
    logger.info("Managing roles", { guildId, requestId })
 | 
					    logger.info("Managing roles", { guildId, requestId })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,6 +4,10 @@ import fs from 'fs'
 | 
				
			|||||||
import { config } from "../configuration";
 | 
					import { config } from "../configuration";
 | 
				
			||||||
import { logger } from "../logger";
 | 
					import { logger } from "../logger";
 | 
				
			||||||
import { JellyfinHandler } from "../jellyfin/handler";
 | 
					import { JellyfinHandler } from "../jellyfin/handler";
 | 
				
			||||||
 | 
					import { ScheduledTask, schedule } from "node-cron";
 | 
				
			||||||
 | 
					import { manageAnnouncementRoles } from "../commands/announce";
 | 
				
			||||||
 | 
					import { v4 as uuid } from 'uuid'
 | 
				
			||||||
 | 
					import { task } from "../events/guildScheduledEventCreate";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -13,6 +17,7 @@ export class ExtendedClient extends Client {
 | 
				
			|||||||
  private jellyfin: JellyfinHandler
 | 
					  private jellyfin: JellyfinHandler
 | 
				
			||||||
  public commands: Collection<string, CommandType> = new Collection()
 | 
					  public commands: Collection<string, CommandType> = new Collection()
 | 
				
			||||||
  private announcementChannels: Collection<string, TextChannel> = new Collection //guildId to TextChannel
 | 
					  private announcementChannels: Collection<string, TextChannel> = new Collection //guildId to TextChannel
 | 
				
			||||||
 | 
					  private announcementRoleHandlerTask: Collection<string, ScheduledTask> = new Collection //one task per guild
 | 
				
			||||||
  public constructor(jf: JellyfinHandler) {
 | 
					  public constructor(jf: JellyfinHandler) {
 | 
				
			||||||
    const intents: IntentsBitField = new IntentsBitField()
 | 
					    const intents: IntentsBitField = new IntentsBitField()
 | 
				
			||||||
    intents.add(IntentsBitField.Flags.GuildMembers, IntentsBitField.Flags.MessageContent, IntentsBitField.Flags.Guilds, IntentsBitField.Flags.DirectMessages, IntentsBitField.Flags.GuildScheduledEvents, IntentsBitField.Flags.GuildVoiceStates)
 | 
					    intents.add(IntentsBitField.Flags.GuildMembers, IntentsBitField.Flags.MessageContent, IntentsBitField.Flags.Guilds, IntentsBitField.Flags.DirectMessages, IntentsBitField.Flags.GuildScheduledEvents, IntentsBitField.Flags.GuildVoiceStates)
 | 
				
			||||||
@@ -60,14 +65,15 @@ export class ExtendedClient extends Client {
 | 
				
			|||||||
        this.commands.set(command.name, command)
 | 
					        this.commands.set(command.name, command)
 | 
				
			||||||
        slashCommands.push(command)
 | 
					        slashCommands.push(command)
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      this.on("ready", (client: Client) => {
 | 
					      this.on("ready", async (client: Client) => {
 | 
				
			||||||
        //logger.info(`Ready processing ${JSON.stringify(client)}`)
 | 
					        //logger.info(`Ready processing ${JSON.stringify(client)}`)
 | 
				
			||||||
        logger.info(`SlashCommands: ${JSON.stringify(slashCommands)}`)
 | 
					        logger.info(`SlashCommands: ${JSON.stringify(slashCommands)}`)
 | 
				
			||||||
        const guilds = client.guilds.cache
 | 
					        const guilds = client.guilds.cache
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        this.registerCommands(slashCommands, guilds)
 | 
					        this.registerCommands(slashCommands, guilds)
 | 
				
			||||||
        this.cacheUsers(guilds)
 | 
					        this.cacheUsers(guilds)
 | 
				
			||||||
        this.cacheAnnouncementServer(guilds)
 | 
					        await this.cacheAnnouncementServer(guilds)
 | 
				
			||||||
 | 
					        this.startAnnouncementRoleBackgroundTask(guilds)
 | 
				
			||||||
      })
 | 
					      })
 | 
				
			||||||
    } catch (error) {
 | 
					    } catch (error) {
 | 
				
			||||||
      logger.info(`Error refreshing slash commands: ${error}`)
 | 
					      logger.info(`Error refreshing slash commands: ${error}`)
 | 
				
			||||||
@@ -117,4 +123,39 @@ export class ExtendedClient extends Client {
 | 
				
			|||||||
      logger.error(error)
 | 
					      logger.error(error)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public async startAnnouncementRoleBackgroundTask(guilds: Collection<string, Guild>) {
 | 
				
			||||||
 | 
					    for (const guild of guilds.values()) {
 | 
				
			||||||
 | 
					      logger.info("Starting background task for announcement role", { guildId: guild.id })
 | 
				
			||||||
 | 
					      const textChannel: TextChannel = this.getAnnouncementChannelForGuild(guild.id)
 | 
				
			||||||
 | 
					      this.announcementRoleHandlerTask.set(guild.id, schedule("*/10 * * * * *", async () => {
 | 
				
			||||||
 | 
					        const requestId = uuid()
 | 
				
			||||||
 | 
					        const messages = (await textChannel.messages.fetchPinned()).filter(message => message.cleanContent.includes("[announcement]"))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (messages.size > 1) {
 | 
				
			||||||
 | 
					          logger.error("More than one pinned announcement Messages found. Unable to know which one people react to. Please fix!", { guildId: guild.id, requestId })
 | 
				
			||||||
 | 
					        } else if (messages.size == 0) {
 | 
				
			||||||
 | 
					          logger.error("Could not find any pinned announcement messages. Unable to manage roles!", { guildId: guild.id, requestId })
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const message = messages.at(0)!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const reactions = await message.reactions.resolve("🎫")
 | 
				
			||||||
 | 
					        if (reactions) {
 | 
				
			||||||
 | 
					          manageAnnouncementRoles(message.guild, reactions, requestId)
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					          logger.error("Did not get reactions! Aborting!", { guildId: guild.id, requestId })
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }))
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  public stopAnnouncementRoleBackgroundTask(guild: string | Guild, requestId: string) {
 | 
				
			||||||
 | 
					    const guildId: string = guild instanceof Guild ? guild.id : guild
 | 
				
			||||||
 | 
					    const task: ScheduledTask | undefined = guild instanceof Guild ? this.announcementRoleHandlerTask.get(guild.id) : this.announcementRoleHandlerTask.get(guild)
 | 
				
			||||||
 | 
					    if (!task) {
 | 
				
			||||||
 | 
					      logger.error(`No task found for guildID ${guildId}.`, { guildId, requestId })
 | 
				
			||||||
 | 
					      return
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    task.stop()
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user