const { ContainerBuilder, SectionBuilder, TextDisplayBuilder, ThumbnailBuilder, SeparatorBuilder, SeparatorSpacingSize, MessageFlags, } = require("discord.js"); const GuildPrefix = require("../../models/GuildPrefix"); const UserPrefix = require("../../models/UserPrefix"); const DisabledChannels = require("../../models/DisabledChannels"); const Blacklist = require("../../models/Blacklist"); const config = require("../../config/config.json"); const colors = require("colors"); module.exports = { name: "messageCreate", async execute(message, client) { if (message.author?.bot || !message.guild) return; const defaultPrefix = config.prefix ?? "d!"; const botAvatarURL = client.user?.displayAvatarURL({ extension: "png", size: 512 }) ?? ""; // Fetch all relevant data const [ guildData, userData, userBlacklist, guildBlacklist, disabledData, ] = await Promise.all([ GuildPrefix.findOne({ guildId: message.guild.id }), UserPrefix.findOne({ userId: message.author.id }), Blacklist.findOne({ type: "user", id: message.author.id }), Blacklist.findOne({ type: "guild", id: message.guild.id }), DisabledChannels.findOne({ guildId: message.guild.id }), ]); // Set defaults for all potentially undefined values const guildPrefix = guildData?.prefix ?? defaultPrefix; const userPrefixValue = userData?.prefix ?? "None"; const disabledChannelsCount = disabledData?.channels?.length ?? 0; const userBlacklistReason = userBlacklist?.reason ?? "None"; const guildBlacklistReason = guildBlacklist?.reason ?? "None"; const isUserBlacklisted = !!userBlacklist; const isGuildBlacklisted = !!guildBlacklist; const isChannelDisabled = disabledData?.channels?.includes(message.channel.id); const botName = client.user?.username ?? "None"; const botId = client.user?.id ?? "None"; const commandsLoaded = String(client.pcommands?.size ?? 0); // Accurate guild count with sharding let totalGuilds = client.guilds.cache.size; if (client.shard) { try { const results = await client.shard.fetchClientValues("guilds.cache.size"); totalGuilds = results.reduce((acc, count) => acc + count, 0); } catch { totalGuilds = client.guilds.cache.size; } } const totalGuildsStr = String(totalGuilds); // ───── Bot mention info panel ───── const mentionRegex = new RegExp(`^<@!?${client.user.id}>$`); if (message.content.match(mentionRegex)) { const mainContainer = new ContainerBuilder() .setAccentColor(0x00c9a7) .addSectionComponents(section => { section.addTextDisplayComponents( new TextDisplayBuilder().setContent("🐼 **Hello! I'm Dozzie**"), new TextDisplayBuilder().setContent("Your friendly panda bot ready to help!"), new SeparatorBuilder().setSpacing(SeparatorSpacingSize.Large) ); section.setThumbnailAccessory(thumbnail => thumbnail.setURL(botAvatarURL).setDescription("Dozzie Bot Avatar") ); return section; }) .addSectionComponents(section => { section.addTextDisplayComponents( new TextDisplayBuilder().setContent( `🤖 **Bot Info:**\n• Name: ${botName}\n• ID: ${botId}\n• Servers: ${totalGuildsStr}\n• Commands Loaded: ${commandsLoaded}` ), new SeparatorBuilder().setSpacing(SeparatorSpacingSize.Large) ); return section; }) .addSectionComponents(section => { section.addTextDisplayComponents( new TextDisplayBuilder().setContent( `🏡 **Server Prefix:**\n• Prefix: \`${guildPrefix}\`\n• Disabled Channels: ${disabledChannelsCount}` ), new SeparatorBuilder().setSpacing(SeparatorSpacingSize.Large) ); return section; }) .addSectionComponents(section => { section.addTextDisplayComponents( new TextDisplayBuilder().setContent( `👤 **Your Prefix:**\n• Prefix: \`${userPrefixValue}\`\n• Blacklist: ${ isUserBlacklisted ? `⛔ ${userBlacklistReason}` : "✅ Clear" }` ), new SeparatorBuilder().setSpacing(SeparatorSpacingSize.Large) ); return section; }) .addSectionComponents(section => { section.addTextDisplayComponents( new TextDisplayBuilder().setContent( "💡 **Tips:**\n• Use personal prefixes for shortcuts.\n• Use server prefixes for consistency." ), new TextDisplayBuilder().setContent( "• Mention me (@Dozzie) anytime to open this panel.\n• Keep commands organized for a smoother experience." ) ); return section; }); return message.reply({ components: [mainContainer], flags: MessageFlags.IsComponentsV2, }); } // ───── Prefix command logic ───── let usedPrefix = null; if (userPrefixValue !== "None" && message.content.startsWith(userPrefixValue)) usedPrefix = userPrefixValue; else if (message.content.startsWith(guildPrefix)) usedPrefix = guildPrefix; if (!usedPrefix) return; // Helper to create notice containers const createNoticeContainer = (title, content, color = 0xff0000) => { return new ContainerBuilder() .setAccentColor(color) .addSectionComponents(section => { section.addTextDisplayComponents( new TextDisplayBuilder().setContent(title), new TextDisplayBuilder().setContent(content) ); return section; }); }; // Channel disabled if (isChannelDisabled) { const container = createNoticeContainer("❌ **Channel Disabled**", "Commands are disabled in this channel."); return message.reply({ components: [container], flags: MessageFlags.IsComponentsV2, }); } // User blacklisted if (isUserBlacklisted) { const container = createNoticeContainer( "❌ **Blacklisted User**", `You are blacklisted from using this bot.\n**Reason:** ${userBlacklistReason}` ); return message.reply({ components: [container], flags: MessageFlags.IsComponentsV2, }); } // Guild blacklisted if (isGuildBlacklisted) { const container = createNoticeContainer( "❌ **Server Blacklisted**", `This server is blacklisted.\n**Reason:** ${guildBlacklistReason}` ); return message.reply({ components: [container], flags: MessageFlags.IsComponentsV2, }); } // Parse command const args = message.content.slice(usedPrefix.length).trim().split(/ +/); const commandName = args.shift()?.toLowerCase(); const command = client.pcommands.get(commandName) || client.pcommands.get(client.aliases.get(commandName)); if (!command) return; // Execute command try { console.log(colors.cyan(`[PREFIX CMD] ${message.author?.tag} used: ${usedPrefix}${commandName}`)); await command.execute(message, client, args); } catch (error) { console.error(colors.red(`[PREFIX CMD ERROR] ${commandName}:`), error); const errorContainer = createNoticeContainer( "❌ **Command Error**", `An error occurred while executing this command.\n\`\`\`${error?.message ?? "None"}\`\`\`` ); message.reply({ components: [errorContainer], flags: MessageFlags.IsComponentsV2, }).catch(() => {}); } }, };