Leaderboard
The `leaderboard` command displays rankings for various metrics within a Discord guild and globally, such as coin balance, spent coins, and streaks for specific activities. It can be triggered using the prefixes `P`, `p`, or the slash command `/`.
Command Details
- Name: leaderboard
- Aliases: rank, top, lb
- Category: Rank
- Description: Displays top coin, spent coin, and streak rankings in your Discord guild and globally.
- Usage:
P leaderboard [type]
,p leaderboard [type]
, or/leaderboard [type]
- Examples:
P leaderboard bal
p leaderboard peach
/leaderboard slots
- Cooldown: 3 seconds
- Arguments: Optional (defaults to "bal")
- Slash Command: Enabled
- Permissions:
- Bot: SendMessages, ViewChannel, EmbedLinks
- User: None
- Player Requirements: None (no voice, DJ, or active player required)
Functionality
- If no type is specified, the command defaults to showing the "balance" leaderboard.
- The command fetches user rankings based on the specified type (e.g., balance, peach, slots) using
client.utils.userRanking
. - It displays up to 100 users in a paginated embed, with each page showing 10 users. Each entry includes:
- Position with an emoji rank indicator (e.g., 🥇 for 1st).
- Username (or "Unknown" if not available).
- Total value for the selected metric (formatted number) with a relevant emoji.
- Pagination is handled via
client.utils.reactionPaginate
, allowing users to navigate through pages. - If no users are found for the leaderboard, an error message is displayed using
client.utils.oops
. - Supports both prefix-based (
P
orp
) and slash command (/
) inputs. - Uses language localization for titles, messages, and emojis.
Options
The command accepts a type
option to specify which leaderboard to display:
Name | Value | Description |
---|---|---|
Balance | balance | Displays coin balance ranking |
Peach | peach | Displays peach streak ranking |
Goma | goma | Displays goma streak ranking |
Slots | slots | Displays slots streak ranking |
Blackjack | blackjack | Displays blackjack ranking |
Coinflip | coinflip | Displays coinflip ranking |
Sponsor | sponsor | Displays sponsor ranking |
Code Overview
The command is built using a Command
class structure and handles both message-based and interaction-based (slash command) inputs. It uses:
client.utils.userRanking
to fetch ranking data.client.embed()
to create formatted embeds for each page.client.utils.chunk
to split the leaderboard into pages of 10 users.client.utils.reactionPaginate
for pagination navigation.client.utils.emojiRank
andclient.utils.typeRanking
for dynamic emoji display.- Language localization for messages, titles, and footers.
- Error handling for cases where no users are found.
const { Command } = require("../../structures");
module.exports = class Ranking extends Command {
constructor(client) {
super(client, {
name: "leaderboard",
description: {
content:
"Check top coin, spent coin, and streak of peachy in your Discord guild and globally.",
examples: ["leaderboard bal", "leaderboard peach", "leaderboard slots"],
usage: "leaderboard bal\nrank bal\ntop bal\nlb bal",
},
category: "rank",
aliases: ["rank", "top", "lb"],
cooldown: 3,
args: false,
permissions: {
dev: false,
client: ["SendMessages", "ViewChannel", "EmbedLinks"],
user: [],
},
slashCommand: true,
options: [
{
name: "type",
type: 3,
description: "Choose which leaderboard to display",
required: true,
choices: [
{ name: "Balance", value: "balance" },
{ name: "Peach", value: "peach" },
{ name: "Goma", value: "goma" },
{ name: "Slots", value: "slots" },
{ name: "Blackjack", value: "blackjack" },
{ name: "Coinflip", value: "coinflip" },
{ name: "Sponsor", value: "sponsor" },
],
},
],
});
}
async run(client, ctx, args, color, emoji, language) {
const generalMessages = language.locales.get(
language.defaultLocale
)?.generalMessages;
const rankingMessages = language.locales.get(language.defaultLocale)
?.economyMessages?.rankingMessages;
const type = ctx.isInteraction
? ctx.interaction.options.data[0]?.value
: args[0] || "bal";
const users = await client.utils.userRanking(client, ctx, color, type);
if (!users.length) {
return await client.utils.oops(
client,
ctx,
rankingMessages.notFound,
color
);
}
const leaderboardList = users.slice(0, 100).map((user, index) => {
const position = index + 1;
const emojiRank = client.utils.emojiRank(emoji, position);
return `**${emojiRank} ${position}. ${
user.username || "Unknown"
}**\n**${client.utils.formatNumber(
user.total ?? 0
)}** ${client.utils.typeRanking(type, emoji)}`;
});
const chunks = client.utils.chunk(leaderboardList, 10);
const pages = chunks.map((chunk, i) => {
return client
.embed()
.setColor(color.main)
.setDescription(
generalMessages.title
.replace("%{mainLeft}", emoji.rank.owner)
.replace(
"%{title}",
client.utils.titleRanking(type, rankingMessages)
)
.replace("%{mainRight}", emoji.rank.owner) + `${chunk.join("\n\n")}`
)
.setFooter({
text: `${generalMessages.requestedBy.replace(
"%{username}",
ctx.author.displayName
)} | Page ${i + 1} of ${chunks.length}`,
iconURL: ctx.author.displayAvatarURL(),
});
});
return await client.utils.reactionPaginate(ctx, pages);
}
};
Username
The `username` command allows users to update their displayed username in the bot's database. This is separate from their Discord username and appears in various bot features and profile displays.
Relationship
The relationship command allows users to manage social relationships (partner, bestie, brother, sister) with other users, with limits on the number of relationships per type. This command is available to all registered users.