import {
ActionRowBuilder,
ButtonBuilder,
ButtonStyle,
StringSelectMenuBuilder,
EmbedBuilder,
ChannelType,
version
} from 'discord.js';
export const name = 'serverinfo';
export const description = 'Command server info';
function formatBytes(bytes) {
if (bytes === 0) return '0 Bytes';
const k = 1024;
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
}
function getMemberStatuses(guild) {
const members = guild.members.cache;
return {
total: members.size,
online: members.filter(m => m.presence?.status === 'online').size,
idle: members.filter(m => m.presence?.status === 'idle').size,
dnd: members.filter(m => m.presence?.status === 'dnd').size,
offline: members.filter(m => !m.presence || m.presence.status === 'offline').size,
bots: members.filter(m => m.user.bot).size,
humans: members.filter(m => !m.user.bot).size
};
}
function getVerificationLevel(level) {
const levels = {
0: 'NONE',
1: 'LOW',
2: 'MEDIUM',
3: 'HIGH',
4: 'VERY_HIGH'
};
return levels[level] || 'UNKNOWN';
}
function getExplicitContentFilter(filter) {
const filters = {
0: 'DISABLED',
1: 'MEMBERS_WITHOUT_ROLES',
2: 'ALL_MEMBERS'
};
return filters[filter] || 'UNKNOWN';
}
export async function execute(message, client) {
const guild = message.guild;
if (!guild) return;
await guild.fetch();
await guild.members.fetch({ withPresences: true }).catch(() => {});
await guild.roles.fetch().catch(() => {});
await guild.channels.fetch().catch(() => {});
await guild.emojis.fetch().catch(() => {});
await guild.stickers.fetch().catch(() => {});
await guild.invites.fetch().catch(() => {});
const owner = await guild.fetchOwner().catch(() => null);
const createdAt = Math.floor(guild.createdAt.getTime() / 1000);
const bannerURL = guild.bannerURL({ size: 1024 }) || null;
const iconURL = guild.iconURL({ size: 512 }) || null;
const splashURL = guild.splashURL({ size: 1024 }) || null;
const discoverySplashURL = guild.discoverySplashURL({ size: 1024 }) || null;
const channels = guild.channels.cache;
const counts = {
categories: channels.filter(c => c.type === ChannelType.GuildCategory).size,
text: channels.filter(c => c.type === ChannelType.GuildText).size,
voice: channels.filter(c => c.type === ChannelType.GuildVoice).size,
stage: channels.filter(c => c.type === ChannelType.GuildStageVoice).size,
forum: channels.filter(c => c.type === ChannelType.GuildForum).size,
announcements: channels.filter(c => c.type === ChannelType.GuildAnnouncement).size,
threads: channels.filter(c => c.isThread()).size,
};
const memberStatuses = getMemberStatuses(guild);
const roles = guild.roles.cache;
const rolesSorted = roles
.filter(r => r.name !== '@everyone')
.sort((a, b) => b.position - a.position);
const emojis = guild.emojis.cache;
const emojiStats = {
total: emojis.size,
animated: emojis.filter(e => e.animated).size,
static: emojis.filter(e => !e.animated).size,
availableSlots: guild.emojiLimit - emojis.size
};
const baseEmbed = new EmbedBuilder()
.setTitle(`Server Information: ${guild.name}`)
.setThumbnail(iconURL)
.setColor(0x5865F2)
.addFields(
{ name: "Server ID", value: `\`${guild.id}\``, inline: true },
{ name: "Owner", value: owner ? `${owner.user.tag} (\`${owner.id}\`)` : 'N/A', inline: true },
{ name: "Created", value: `<t:${createdAt}:F>\n(<t:${createdAt}:R>)`, inline: true },
{ name: "Verification Level", value: `\`${getVerificationLevel(guild.verificationLevel)}\``, inline: true },
{ name: "Content Filter", value: `\`${getExplicitContentFilter(guild.explicitContentFilter)}\``, inline: true },
{ name: "Server Features", value: guild.features.length > 0 ? `\`${guild.features.join('`, `')}\`` : "None", inline: false },
)
.setTimestamp();
if (bannerURL) baseEmbed.setImage(bannerURL);
const membersEmbed = new EmbedBuilder()
.setTitle("Members")
.setColor(0x00A86B)
.setDescription([
`👥 **Total Members:** ${memberStatuses.total}`,
`🤖 **Bots:** ${memberStatuses.bots}`,
`👤 **Humans:** ${memberStatuses.humans}`,
``,
`🟢 **Online:** ${memberStatuses.online}`,
`🟡 **Idle:** ${memberStatuses.idle}`,
`🔴 **Do Not Disturb:** ${memberStatuses.dnd}`,
`⚫ **Offline:** ${memberStatuses.offline}`,
].join('\n'))
.addFields(
{ name: "Boosters", value: `${guild.premiumSubscriptionCount || 0}`, inline: true },
{ name: "Boost Tier", value: `Tier ${guild.premiumTier || 0}`, inline: true },
);
const channelsEmbed = new EmbedBuilder()
.setTitle("Channels")
.setColor(0x0099FF)
.setDescription([
`📊 **Total Channels:** ${channels.size}`,
``,
`📁 **Categories:** ${counts.categories}`,
`💬 **Text Channels:** ${counts.text}`,
`🔊 **Voice Channels:** ${counts.voice}`,
`🎤 **Stage Channels:** ${counts.stage}`,
`📝 **Forum Channels:** ${counts.forum}`,
`📢 **Announcement Channels:** ${counts.announcements}`,
`🧵 **Threads:** ${counts.threads}`,
].join('\n'));
const rolePages = [];
const rolePageSize = 10;
const roleList = rolesSorted.map(r => `${r.toString()} • ${r.members.size} members`);
for (let i = 0; i < roleList.length; i += rolePageSize) {
rolePages.push(roleList.slice(i, i + rolePageSize));
}
let currentRolePage = 0;
const rolesEmbed = () => new EmbedBuilder()
.setTitle("Roles")
.setColor(0xFFA500)
.setDescription(rolePages.length ? rolePages[currentRolePage].join('\n') : "No roles found")
.setFooter({
text: `Page ${rolePages.length ? currentRolePage + 1 : 0} of ${rolePages.length} • ${rolesSorted.length} roles total`
});
const emojisEmbed = new EmbedBuilder()
.setTitle("Emojis & Stickers")
.setColor(0x9B59B6)
.setDescription([
`😀 **Total Emojis:** ${emojiStats.total}`,
`🎬 **Animated:** ${emojiStats.animated}`,
`🖼️ **Static:** ${emojiStats.static}`,
`📦 **Available Slots:** ${emojiStats.availableSlots}`,
``,
`🏷️ **Stickers:** ${guild.stickers.cache.size}`,
].join('\n'));
const securityEmbed = new EmbedBuilder()
.setTitle("Security & Moderation")
.setColor(0xE74C3C)
.setDescription([
`🛡️ **Verification Level:** \`${getVerificationLevel(guild.verificationLevel)}\``,
`🔞 **Explicit Content Filter:** \`${getExplicitContentFilter(guild.explicitContentFilter)}\``,
`🔒 **MFA Required:** ${guild.mfaLevel === 1 ? '✅' : '❌'}`,
``,
`📊 **Active Invites:** ${guild.invites.cache.size}`,
`👑 **Server Owner:** ${owner ? owner.user.tag : 'N/A'}`,
].join('\n'));
const mainSelect = new StringSelectMenuBuilder()
.setCustomId('serverinfo_main')
.setPlaceholder('Select information category...')
.addOptions(
{ label: "General Information", value: 'general', description: "Basic server information" },
{ label: "Members", value: 'members', description: "Member statistics and statuses" },
{ label: "Channels", value: 'channels', description: "Channel breakdown and counts" },
{ label: "Roles", value: 'roles', description: "Server roles list" },
{ label: "Emojis & Stickers", value: 'emojis', description: "Emoji and sticker statistics" },
{ label: "Security & Moderation", value: 'security', description: "Security and moderation settings" },
);
const rowSelect = new ActionRowBuilder().addComponents(mainSelect);
const rowButtons = new ActionRowBuilder().addComponents(
new ButtonBuilder().setCustomId('serverinfo_prev').setLabel('⯇ Previous').setStyle(ButtonStyle.Secondary),
new ButtonBuilder().setCustomId('serverinfo_next').setLabel('Next ⯈').setStyle(ButtonStyle.Secondary),
new ButtonBuilder().setLabel('Server Icon').setStyle(ButtonStyle.Link).setURL(iconURL || 'https://discord.com'),
...(bannerURL ? [new ButtonBuilder().setLabel('Server Banner').setStyle(ButtonStyle.Link).setURL(bannerURL)] : []),
...(splashURL ? [new ButtonBuilder().setLabel('Server Splash').setStyle(ButtonStyle.Link).setURL(splashURL)] : [])
);
const sent = await message.channel.send({
embeds: [baseEmbed],
components: [rowSelect, rowButtons],
});
const collector = sent.createMessageComponentCollector({ time: 10 * 60 * 1000 });
let currentSection = 'general';
collector.on('collect', async (interaction) => {
if (interaction.user.id !== message.author.id) {
return interaction.reply({ content: "Only the command author can use these buttons", ephemeral: true });
}
if (interaction.isStringSelectMenu() && interaction.customId === 'serverinfo_main') {
const value = interaction.values[0];
currentSection = value;
const embeds = {
general: [baseEmbed],
members: [membersEmbed],
channels: [channelsEmbed],
roles: [rolesEmbed()],
emojis: [emojisEmbed],
security: [securityEmbed]
};
await interaction.update({ embeds: embeds[value] || [baseEmbed] });
return;
}
if (interaction.isButton() && currentSection === 'roles') {
if (interaction.customId === 'serverinfo_prev') {
if (currentRolePage > 0) currentRolePage--;
return interaction.update({ embeds: [rolesEmbed()] });
}
if (interaction.customId === 'serverinfo_next') {
if (currentRolePage < Math.max(0, rolePages.length - 1)) currentRolePage++;
return interaction.update({ embeds: [rolesEmbed()] });
}
return interaction.deferUpdate();
}
});
collector.on('end', async () => {
try {
await sent.edit({ components: [] });
} catch {}
});
}
Comentarios (0)
Inicia sesión para comentar
¡Aún no hay comentarios. Sé el primero en comentar!