announcements #18

Merged
kenobi merged 13 commits from feat/announce into master 2023-06-15 22:05:20 +02:00
2 changed files with 50 additions and 14 deletions
Showing only changes of commit e774474a55 - Show all commits

View File

@ -39,7 +39,11 @@ async function sendAnnouncement(guildId: string, requestId: string): Promise<voi
logger.info("Sending announcement")
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.
@ -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)
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) {
const requestId = uuid()
export async function manageAnnouncementRoles(guild: Guild, reaction: MessageReaction, requestId: string) {
const guildId = guild.id
logger.info("Managing roles", { guildId, requestId })

View File

@ -4,6 +4,10 @@ import fs from 'fs'
import { config } from "../configuration";
import { logger } from "../logger";
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
public commands: Collection<string, CommandType> = new Collection()
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) {
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)
@ -60,14 +65,15 @@ export class ExtendedClient extends Client {
this.commands.set(command.name, command)
slashCommands.push(command)
}
this.on("ready", (client: Client) => {
this.on("ready", async (client: Client) => {
//logger.info(`Ready processing ${JSON.stringify(client)}`)
logger.info(`SlashCommands: ${JSON.stringify(slashCommands)}`)
const guilds = client.guilds.cache
this.registerCommands(slashCommands, guilds)
this.cacheUsers(guilds)
this.cacheAnnouncementServer(guilds)
await this.cacheAnnouncementServer(guilds)
this.startAnnouncementRoleBackgroundTask(guilds)
})
} catch (error) {
logger.info(`Error refreshing slash commands: ${error}`)
@ -117,4 +123,39 @@ export class ExtendedClient extends Client {
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 })
kenobi marked this conversation as resolved
Review

Unable to continue, should result in a return.

Unable to continue, should result in a return.
}
const message = messages.at(0)!
kenobi marked this conversation as resolved Outdated
const message = await messages.at(0)?.fetch()
if (!message) {
  logger.error(`No pinned message found`,{requestId,guildId})
  return
}
``` const message = await messages.at(0)?.fetch() if (!message) { logger.error(`No pinned message found`,{requestId,guildId}) return } ```
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) {
kenobi marked this conversation as resolved Outdated

Would it be possible to just use string as type for guild so we don't have to check multiple times if we have a guild object?

Would it be possible to just use string as type for `guild` so we don't have to check multiple times if we have a guild object?
logger.error(`No task found for guildID ${guildId}.`, { guildId, requestId })
return
}
task.stop()
}
}