122 lines
4 KiB
TypeScript
122 lines
4 KiB
TypeScript
import { CategoryChannel, EmbedOptions, RESTChannelInvite, TextChannel, VoiceChannel } from "eris";
|
|
import moment from "moment-timezone";
|
|
import { embedPadding, formatNumber, memoize, MINUTES, trimLines } from "../../../utils";
|
|
import { utilityCmd } from "../types";
|
|
import humanizeDuration from "humanize-duration";
|
|
|
|
export const ServerCmd = utilityCmd({
|
|
trigger: "server",
|
|
description: "Show information about the server",
|
|
usage: "!server",
|
|
permission: "can_server",
|
|
|
|
async run({ message, pluginData }) {
|
|
const { guild } = pluginData;
|
|
|
|
const embed: EmbedOptions = {
|
|
fields: [],
|
|
color: parseInt("6b80cf", 16),
|
|
};
|
|
|
|
embed.thumbnail = { url: guild.iconURL };
|
|
|
|
const createdAt = moment(guild.createdAt);
|
|
const serverAge = humanizeDuration(moment().valueOf() - guild.createdAt, {
|
|
largest: 2,
|
|
round: true,
|
|
});
|
|
|
|
const owner = pluginData.client.users.get(guild.ownerID);
|
|
const ownerName = owner ? `${owner.username}#${owner.discriminator}` : "Unknown#0000";
|
|
|
|
embed.fields.push({
|
|
name: `Server information - ${guild.name}`,
|
|
value:
|
|
trimLines(`
|
|
Created: **${serverAge} ago** (${createdAt.format("YYYY-MM-DD[T]HH:mm:ss")})
|
|
Owner: **${ownerName}** (${guild.ownerID})
|
|
Voice region: **${guild.region}**
|
|
${guild.features.length > 0 ? "Features: " + guild.features.join(", ") : ""}
|
|
`) + embedPadding,
|
|
});
|
|
|
|
const restGuild = await memoize(
|
|
() => pluginData.client.getRESTGuild(guild.id),
|
|
`getRESTGuild_${guild.id}`,
|
|
10 * MINUTES,
|
|
);
|
|
|
|
// For servers with a vanity URL, we can use the numbers from the invite for online count
|
|
// (which is nowadays usually more accurate for large servers)
|
|
const invite = guild.vanityURL
|
|
? ((await memoize(
|
|
() => pluginData.client.getInvite(guild.vanityURL, true),
|
|
`getInvite_${guild.vanityURL}`,
|
|
10 * MINUTES,
|
|
)) as RESTChannelInvite)
|
|
: null;
|
|
|
|
const totalMembers = invite?.memberCount || guild.memberCount;
|
|
|
|
const onlineMemberCount = invite ? invite.presenceCount : guild.members.filter(m => m.status !== "offline").length;
|
|
const offlineMemberCount = guild.memberCount - onlineMemberCount;
|
|
|
|
let memberCountTotalLines = `Total: **${formatNumber(totalMembers)}**`;
|
|
if (restGuild.maxMembers) {
|
|
memberCountTotalLines += `\nMax: **${formatNumber(restGuild.maxMembers)}**`;
|
|
}
|
|
|
|
let memberCountOnlineLines = `Online: **${formatNumber(onlineMemberCount)}**`;
|
|
if (restGuild.maxPresences) {
|
|
memberCountOnlineLines += `\nMax online: **${formatNumber(restGuild.maxPresences)}**`;
|
|
}
|
|
|
|
embed.fields.push({
|
|
name: "Members",
|
|
inline: true,
|
|
value: trimLines(`
|
|
${memberCountTotalLines}
|
|
${memberCountOnlineLines}
|
|
Offline: **${formatNumber(offlineMemberCount)}**
|
|
`),
|
|
});
|
|
|
|
const totalChannels = guild.channels.size;
|
|
const categories = guild.channels.filter(channel => channel instanceof CategoryChannel);
|
|
const textChannels = guild.channels.filter(channel => channel instanceof TextChannel);
|
|
const voiceChannels = guild.channels.filter(channel => channel instanceof VoiceChannel);
|
|
|
|
embed.fields.push({
|
|
name: "Channels",
|
|
inline: true,
|
|
value:
|
|
trimLines(`
|
|
Total: **${totalChannels}** / 500
|
|
Categories: **${categories.length}**
|
|
Text: **${textChannels.length}**
|
|
Voice: **${voiceChannels.length}**
|
|
`) + embedPadding,
|
|
});
|
|
|
|
const maxEmojis =
|
|
{
|
|
0: 50,
|
|
1: 100,
|
|
2: 150,
|
|
3: 250,
|
|
}[guild.premiumTier] || 50;
|
|
|
|
embed.fields.push({
|
|
name: "Other stats",
|
|
inline: true,
|
|
value:
|
|
trimLines(`
|
|
Roles: **${guild.roles.size}** / 250
|
|
Emojis: **${guild.emojis.length}** / ${maxEmojis}
|
|
Boosts: **${guild.premiumSubscriptionCount ?? 0}** (level ${guild.premiumTier})
|
|
`) + embedPadding,
|
|
});
|
|
|
|
message.channel.createMessage({ embed });
|
|
},
|
|
});
|