UNPKG

discord-starboard-plus

Version:

Discord Starboard Plus: A clean, maintainable starboard system for Discord.js bots. Features per-guild configuration, TypeScript support. Highlight your community's favorite messages with customizable starboards.

142 lines 4.99 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ValidationService = void 0; const discord_js_1 = require("discord.js"); /** * Service for validating reactions, messages, and permissions. * Centralizes all validation logic following SRP. */ class ValidationService { logger; constructor(logger) { this.logger = logger; } /** * Check if a reaction should be processed for starboard. * * FIX: Corrected the logic bug from the original code. * Original buggy code: `!user.bot || !this.options.ignoreBots` always returned true * Fixed: Properly checks if bots should be ignored */ shouldProcessReaction(reaction, user, options) { // Null checks if (!reaction || !user) { return false; } // Check if reaction matches configured emoji const emojiMatch = reaction.emoji.name === options.starEmoji || reaction.emoji.toString() === options.starEmoji; if (!emojiMatch) { return false; } // FIX: Correct logic for ignoring bot reactions // If ignoreBots is true AND user is a bot, reject the reaction if (options.ignoreBots && user.bot) { this.logger.info('Ignoring bot reaction', { userId: user.id }); return false; } // Check for self-reaction (author starring their own message) if (options.ignoreSelf) { const messageAuthorId = reaction.message.author?.id; if (messageAuthorId === user.id) { this.logger.info('Ignoring self-reaction', { userId: user.id }); return false; } } return true; } /** * Check if a message is valid for starboard processing. */ isMessageValid(message, options) { // Must be in a guild if (!message.guild) { return false; } // Check ignored guilds if (options.ignoreGuilds.includes(message.guild.id)) { this.logger.info('Ignoring message from configured guild', { guildId: message.guild.id }); return false; } // Check ignored channels if (options.ignoredChannels.includes(message.channel.id)) { this.logger.info('Ignoring message from configured channel', { channelId: message.channel.id }); return false; } // Check NSFW setting using modern discord.js pattern if (!options.allowNSFW && this.isNSFWChannel(message)) { this.logger.info('Ignoring NSFW channel message', { channelId: message.channel.id }); return false; } return true; } /** * Get the count of valid reactions (excluding bots if configured). * * FIX: Corrected the filter logic from the original code. * This always returned true because of incorrect boolean logic. */ async getValidReactionCount(reaction, options) { const users = await reaction.users.fetch(); const validUsers = users.filter(user => { if (options.ignoreBots) { return !user.bot; } return true; }); return validUsers.size; } /** * Get the starboard channel for a guild. * Validates that the channel exists and is a text-based channel. */ getStarboardChannel(guildId, options, client) { const guild = client.guilds.cache.get(guildId); if (!guild) { this.logger.error('Guild not found', null, { guildId }); return null; } const channel = guild.channels.cache.get(options.starboardChannelID); if (!channel) { this.logger.error('Starboard channel not found', null, { channelId: options.starboardChannelID, guildId }); return null; } if (!this.isTextChannel(channel)) { this.logger.error('Starboard channel is not a text channel', null, { channelId: options.starboardChannelID, channelType: channel.type }); return null; } return channel; } /** * Check if a channel is a text-based channel that can receive messages. */ isTextChannel(channel) { return channel.type === discord_js_1.ChannelType.GuildText || channel.type === discord_js_1.ChannelType.GuildAnnouncement; } /** * Check if a message is in an NSFW channel. */ isNSFWChannel(message) { const channel = message.channel; // Check if channel has nsfw property (text-based channels) if ('nsfw' in channel) { return channel.nsfw === true; } return false; } } exports.ValidationService = ValidationService; //# sourceMappingURL=ValidationService.js.map