diff --git a/server/commands/closepoll.ts b/server/commands/closepoll.ts index fb8e74c..22c1a5f 100644 --- a/server/commands/closepoll.ts +++ b/server/commands/closepoll.ts @@ -5,6 +5,7 @@ import { Emotes } from '../events/guildScheduledEventCreate' import { logger } from '../logger' import { Command } from '../structures/command' import { RunOptions } from '../types/commandTypes' +import { client } from '../..' export default new Command({ name: 'closepoll', @@ -29,16 +30,8 @@ export default new Command({ export async function closePoll(guild: Guild, requestId: string) { const guildId = guild.id logger.info("stopping poll", { guildId: guildId, requestId }) - const channels: TextChannel[] = (await guild.channels.fetch()) - ?.filter(channel => channel!.id === config.bot.announcement_channel_id) - .map((value, _) => value) - - if(!channels || channels.length != 1) { - logger.error(`Could not find announcement channel. Found ${channels}`) - return - } - const announcementChannel = channels[0] + const announcementChannel: TextChannel = client.getAnnouncementChannelForGuild(guildId) const messages: Message[] = (await announcementChannel.messages.fetch()) //todo: fetch only pinned messages .map((value, _) => value) diff --git a/server/events/guildScheduledEventCreate.ts b/server/events/guildScheduledEventCreate.ts index f0b66b6..bdee85b 100644 --- a/server/events/guildScheduledEventCreate.ts +++ b/server/events/guildScheduledEventCreate.ts @@ -1,7 +1,7 @@ import { GuildScheduledEvent, Message, TextChannel } from "discord.js"; import { ScheduledTask, schedule } from "node-cron"; import { v4 as uuid } from "uuid"; -import { jellyfinHandler } from "../.."; +import { client, jellyfinHandler } from "../.."; import { closePoll } from "../commands/closepoll"; import { config } from "../configuration"; import { logger } from "../logger"; @@ -28,8 +28,8 @@ export async function execute(event: GuildScheduledEvent) { 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 = (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 - logger.debug(`Found channel ${JSON.stringify(channel, null, 2)}`, { guildId: event.guildId, requestId }) + const announcementChannel: TextChannel = client.getAnnouncementChannelForGuild(event.guildId) + logger.debug(`Found channel ${JSON.stringify(announcementChannel, null, 2)}`, { guildId: event.guildId, requestId }) let message = "[Abstimmung]\nEs gibt eine neue Abstimmung für die nächste Watchparty! Stimme hierunter für den nächsten Film ab!\n" @@ -37,7 +37,7 @@ export async function execute(event: GuildScheduledEvent) { message = message.concat(Emotes[i]).concat(": ").concat(movies[i].name!).concat("\n") } - const sentMessage: Message = await (await channel.fetch()).send(message) + const sentMessage: Message = await (await announcementChannel.fetch()).send(message) for (let i = 0; i < movies.length; i++) { sentMessage.react(Emotes[i]) diff --git a/server/structures/client.ts b/server/structures/client.ts index 06e1f50..d0b58cb 100644 --- a/server/structures/client.ts +++ b/server/structures/client.ts @@ -1,18 +1,21 @@ -import { ApplicationCommandDataResolvable, Client, ClientOptions, Collection, GatewayIntentBits, Guild, IntentsBitField, Snowflake } from "discord.js"; +import { ApplicationCommandDataResolvable, Client, ClientOptions, Collection, GatewayIntentBits, Guild, IntentsBitField, Snowflake, TextChannel } from "discord.js"; import { CommandType } from "../types/commandTypes"; import fs from 'fs' import { config } from "../configuration"; import { logger } from "../logger"; import { JellyfinHandler } from "../jellyfin/handler"; + + export class ExtendedClient extends Client { private eventFilePath = `${__dirname}/../events` private commandFilePath = `${__dirname}/../commands` private jellyfin: JellyfinHandler public commands: Collection = new Collection() + private announcementChannels: Collection = new Collection //guildId to TextChannel 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) + intents.add(IntentsBitField.Flags.GuildMembers, IntentsBitField.Flags.MessageContent, IntentsBitField.Flags.Guilds, IntentsBitField.Flags.DirectMessages, IntentsBitField.Flags.GuildScheduledEvents, IntentsBitField.Flags.GuildVoiceStates) const options: ClientOptions = { intents } super(options) this.jellyfin = jf @@ -61,20 +64,38 @@ export class ExtendedClient extends 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) }) } catch (error) { logger.info(`Error refreshing slash commands: ${error}`) } } + private async cacheAnnouncementServer(guilds: Collection) { + for (const guild of guilds.values()) { + const channels: TextChannel[] = (await guild.channels.fetch()) + ?.filter(channel => channel!.id === config.bot.announcement_channel_id) + .map((value, _) => value) + + if (!channels || channels.length != 1) { + logger.error(`Could not find announcement channel for guild ${guild.name} with guildId ${guild.id}. Found ${channels}`) + continue + } + logger.info(`Fetched announcement channel: ${JSON.stringify(channels[0])}`) + this.announcementChannels.set(guild.id, channels[0]) + } + } + public getAnnouncementChannelForGuild(guildId: string): TextChannel { + return this.announcementChannels.get(guildId)! //we set the channel by ourselves only if we find one, I think this is sage (mark my words) + } public async cacheUsers(guilds: Collection) { guilds.forEach((guild: Guild, id: Snowflake) => { logger.info(`Fetching members for ${guild.name}|${id}`) guild.members.fetch() logger.info(`Fetched: ${guild.memberCount} members`) }) - } public async registerEventCallback() { try {