From 90d3731de9c97ee09532a1ba9d2e5f1e4c3323d3 Mon Sep 17 00:00:00 2001
From: Cody <36463298+ugcodrr@users.noreply.github.com>
Date: Sun, 1 Nov 2026 20:57:37 -0500
Subject: [PATCH 1/3] feat(discord-bot): keep quests, ratios, guild and cape
page buttons working after restarts
---
.../src/commands/guild/guild.command.tsx | 6 +++++-
.../src/commands/minecraft/cape.command.ts | 6 +++++-
.../src/commands/quests/quests.command.tsx | 14 ++++++++++++--
.../src/commands/ratios/ratios.command.tsx | 14 ++++++++++++--
4 files changed, 34 insertions(+), 6 deletions(-)
diff --git a/apps/discord-bot/src/commands/guild/guild.command.tsx b/apps/discord-bot/src/commands/guild/guild.command.tsx
index 26f42b701..fd38d14de 100644
--- a/apps/discord-bot/src/commands/guild/guild.command.tsx
+++ b/apps/discord-bot/src/commands/guild/guild.command.tsx
@@ -16,7 +16,9 @@ import {
paginate,
PlayerArgument,
SubCommand,
+ createCustomId,
} from "@statsify/discord";
+import { GUILD_ROUTE } from "./guild.route.js";
import { GuildListProfile, GuildListProfileProps } from "./guild-list.profile.js";
import { GuildMember } from "@statsify/schemas";
import { GuildMemberProfile } from "./guild-member.profile.js";
@@ -85,7 +87,9 @@ export class GuildCommand extends GuildTopSubCommand {
label: "Misc",
generator: () => render(, getTheme(user)),
},
- ]);
+ ], (page) =>
+ createCustomId(GUILD_ROUTE, context.getInteraction().getUserId(), context.getCommandName(), guild.id, page)
+ );
}
@SubCommand({ description: (t) => t("commands.guild-list"), args: GuildArgument })
diff --git a/apps/discord-bot/src/commands/minecraft/cape.command.ts b/apps/discord-bot/src/commands/minecraft/cape.command.ts
index 501e9ca71..46158c2da 100644
--- a/apps/discord-bot/src/commands/minecraft/cape.command.ts
+++ b/apps/discord-bot/src/commands/minecraft/cape.command.ts
@@ -12,9 +12,11 @@ import {
CommandContext,
ErrorMessage,
MojangPlayerArgument,
+ createCustomId,
paginate
} from "@statsify/discord";
import { Image, loadImage } from "skia-canvas";
+import { PROFILE_ROUTE } from "#commands/base.hypixel-command";
import { createCanvas } from "@statsify/rendering";
import type { Skin } from "@statsify/schemas";
@@ -48,7 +50,9 @@ export class CapeCommand {
(t) => t("errors.noCape.description", { username: player.username })
);
- return paginate(context, pages);
+ return paginate(context, pages, (page) =>
+ createCustomId(PROFILE_ROUTE, context.getInteraction().getUserId(), context.getCommandName(), player.uuid, page)
+ );
}
private async getOptifineCape(username: string) {
diff --git a/apps/discord-bot/src/commands/quests/quests.command.tsx b/apps/discord-bot/src/commands/quests/quests.command.tsx
index 3d640798d..40125bd8f 100644
--- a/apps/discord-bot/src/commands/quests/quests.command.tsx
+++ b/apps/discord-bot/src/commands/quests/quests.command.tsx
@@ -14,7 +14,9 @@ import {
paginate,
PlayerArgument,
SubCommand,
+ createCustomId,
} from "@statsify/discord";
+import { PROFILE_ROUTE } from "#commands/base.hypixel-command";
import { QUEST_MODES, QuestTime } from "@statsify/schemas";
import { QuestProfileProps, QuestsProfile } from "./quests.profile.js";
import { getAllGameIcons, getBackground, getLogo } from "@statsify/assets";
@@ -67,7 +69,7 @@ export class QuestsCommand {
private async run(context: CommandContext, time: QuestTime) {
const user = context.getUser();
- const player = await this.apiService.getPlayer(context.option("player"), user);
+ const player = await this.apiService.getPlayer(context.option("player"), user, context.getCacheLevel());
const [logo, skin, badge, gameIcons, verifiedLogo, crossLogo] = await Promise.all([
getLogo(user),
@@ -112,6 +114,14 @@ export class QuestsCommand {
},
}));
- return paginate(context, pages);
+ return paginate(context, pages, (page) =>
+ createCustomId(
+ PROFILE_ROUTE,
+ context.getInteraction().getUserId(),
+ `quests.${context.getCommandName()}`,
+ player.uuid,
+ page
+ )
+ );
}
}
diff --git a/apps/discord-bot/src/commands/ratios/ratios.command.tsx b/apps/discord-bot/src/commands/ratios/ratios.command.tsx
index c6ff87793..7cc5fbd7f 100644
--- a/apps/discord-bot/src/commands/ratios/ratios.command.tsx
+++ b/apps/discord-bot/src/commands/ratios/ratios.command.tsx
@@ -42,6 +42,7 @@ import {
paginate,
PlayerArgument,
SubCommand,
+ createCustomId,
} from "@statsify/discord";
import { Constructor, prettify } from "@statsify/util";
import {
@@ -50,6 +51,7 @@ import {
MODES_TO_FORMATTED,
mapBackground,
} from "#constants";
+import { PROFILE_ROUTE } from "#commands/base.hypixel-command";
import { RatiosProfile, RatiosProfileProps } from "./ratios.profile.js";
import { filterMegaWallsKits } from "../megawalls/megawalls.command.js";
import { getBackground, getLogo } from "@statsify/assets";
@@ -187,7 +189,7 @@ export class RatiosCommand {
filterModes?: (player: Player, modes: GameModeWithSubModes[]) => GameModeWithSubModes[]
) {
const user = context.getUser();
- const player = await this.apiService.getPlayer(context.option("player"), user);
+ const player = await this.apiService.getPlayer(context.option("player"), user, context.getCacheLevel());
const [logo, skin, badge] = await Promise.all([
getLogo(user),
@@ -242,7 +244,15 @@ export class RatiosCommand {
},
}));
- return paginate(context, pages);
+ return paginate(context, pages, (page) =>
+ createCustomId(
+ PROFILE_ROUTE,
+ context.getInteraction().getUserId(),
+ `ratios.${context.getCommandName()}`,
+ player.uuid,
+ page
+ )
+ );
}
private getModeStats(game: PlayerStats[keyof PlayerStats], mode: GameModeWithSubModes) {
From 593938768a86512baab1f6f51a23d37d9149b17b Mon Sep 17 00:00:00 2001
From: Cody <36463298+ugcodrr@users.noreply.github.com>
Date: Thu, 5 Nov 2026 12:12:06 -0500
Subject: [PATCH 2/3] refactor(discord-bot): build quests, ratios and cape
custom ids with getProfileCustomId
---
.../src/commands/minecraft/cape.command.ts | 7 ++-----
.../src/commands/quests/quests.command.tsx | 13 ++-----------
.../src/commands/ratios/ratios.command.tsx | 13 ++-----------
3 files changed, 6 insertions(+), 27 deletions(-)
diff --git a/apps/discord-bot/src/commands/minecraft/cape.command.ts b/apps/discord-bot/src/commands/minecraft/cape.command.ts
index 46158c2da..d5f97682a 100644
--- a/apps/discord-bot/src/commands/minecraft/cape.command.ts
+++ b/apps/discord-bot/src/commands/minecraft/cape.command.ts
@@ -12,11 +12,10 @@ import {
CommandContext,
ErrorMessage,
MojangPlayerArgument,
- createCustomId,
paginate
} from "@statsify/discord";
import { Image, loadImage } from "skia-canvas";
-import { PROFILE_ROUTE } from "#commands/base.hypixel-command";
+import { getProfileCustomId } from "#commands/base.hypixel-command";
import { createCanvas } from "@statsify/rendering";
import type { Skin } from "@statsify/schemas";
@@ -50,9 +49,7 @@ export class CapeCommand {
(t) => t("errors.noCape.description", { username: player.username })
);
- return paginate(context, pages, (page) =>
- createCustomId(PROFILE_ROUTE, context.getInteraction().getUserId(), context.getCommandName(), player.uuid, page)
- );
+ return paginate(context, pages, getProfileCustomId(context, player.uuid));
}
private async getOptifineCape(username: string) {
diff --git a/apps/discord-bot/src/commands/quests/quests.command.tsx b/apps/discord-bot/src/commands/quests/quests.command.tsx
index 40125bd8f..d8ac3c45e 100644
--- a/apps/discord-bot/src/commands/quests/quests.command.tsx
+++ b/apps/discord-bot/src/commands/quests/quests.command.tsx
@@ -14,9 +14,8 @@ import {
paginate,
PlayerArgument,
SubCommand,
- createCustomId,
} from "@statsify/discord";
-import { PROFILE_ROUTE } from "#commands/base.hypixel-command";
+import { getProfileCustomId } from "#commands/base.hypixel-command";
import { QUEST_MODES, QuestTime } from "@statsify/schemas";
import { QuestProfileProps, QuestsProfile } from "./quests.profile.js";
import { getAllGameIcons, getBackground, getLogo } from "@statsify/assets";
@@ -114,14 +113,6 @@ export class QuestsCommand {
},
}));
- return paginate(context, pages, (page) =>
- createCustomId(
- PROFILE_ROUTE,
- context.getInteraction().getUserId(),
- `quests.${context.getCommandName()}`,
- player.uuid,
- page
- )
- );
+ return paginate(context, pages, getProfileCustomId(context, player.uuid, `quests.${context.getCommandName()}`));
}
}
diff --git a/apps/discord-bot/src/commands/ratios/ratios.command.tsx b/apps/discord-bot/src/commands/ratios/ratios.command.tsx
index 7cc5fbd7f..7bc49e46b 100644
--- a/apps/discord-bot/src/commands/ratios/ratios.command.tsx
+++ b/apps/discord-bot/src/commands/ratios/ratios.command.tsx
@@ -42,7 +42,6 @@ import {
paginate,
PlayerArgument,
SubCommand,
- createCustomId,
} from "@statsify/discord";
import { Constructor, prettify } from "@statsify/util";
import {
@@ -51,7 +50,7 @@ import {
MODES_TO_FORMATTED,
mapBackground,
} from "#constants";
-import { PROFILE_ROUTE } from "#commands/base.hypixel-command";
+import { getProfileCustomId } from "#commands/base.hypixel-command";
import { RatiosProfile, RatiosProfileProps } from "./ratios.profile.js";
import { filterMegaWallsKits } from "../megawalls/megawalls.command.js";
import { getBackground, getLogo } from "@statsify/assets";
@@ -244,15 +243,7 @@ export class RatiosCommand {
},
}));
- return paginate(context, pages, (page) =>
- createCustomId(
- PROFILE_ROUTE,
- context.getInteraction().getUserId(),
- `ratios.${context.getCommandName()}`,
- player.uuid,
- page
- )
- );
+ return paginate(context, pages, getProfileCustomId(context, player.uuid, `ratios.${context.getCommandName()}`));
}
private getModeStats(game: PlayerStats[keyof PlayerStats], mode: GameModeWithSubModes) {
From c91d883225b8f6acbf9eea84c5687c6403d7966d Mon Sep 17 00:00:00 2001
From: Cody <36463298+ugcodrr@users.noreply.github.com>
Date: Thu, 5 Nov 2026 12:12:16 -0500
Subject: [PATCH 3/3] feat(discord-bot): keep /events page buttons working
after restarts
---
apps/discord-bot/src/commands/events/events.command.tsx | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/apps/discord-bot/src/commands/events/events.command.tsx b/apps/discord-bot/src/commands/events/events.command.tsx
index a8af305f0..3c13fb6a5 100644
--- a/apps/discord-bot/src/commands/events/events.command.tsx
+++ b/apps/discord-bot/src/commands/events/events.command.tsx
@@ -17,6 +17,7 @@ import { EVENT_TYPES, GENERAL_MODES } from "@statsify/schemas";
import { EventsProfile } from "./events.profile.js";
import { arrayGroup } from "@statsify/util";
import { getBackground, getLogo } from "@statsify/assets";
+import { getProfileCustomId } from "#commands/base.hypixel-command";
import { getTheme } from "#themes";
import { mapBackground } from "#constants";
import { render } from "@statsify/rendering";
@@ -29,7 +30,7 @@ export class EventsCommand {
const user = context.getUser();
const t = context.t();
- const player = await this.apiService.getPlayer(context.option("player"), user);
+ const player = await this.apiService.getPlayer(context.option("player"), user, context.getCacheLevel());
const [logo, skin, badge] = await Promise.all([
getLogo(user),
@@ -57,7 +58,11 @@ export class EventsCommand {
/>,
getTheme(user)
);
- })
+ }),
+ undefined,
+ undefined,
+ false,
+ getProfileCustomId(context, player.uuid)
);
}
}