How can I effectively use the `PaginatedMessage` function?

const queue = this.container.client.player.getQueue(interaction.guild!);

if (!queue) return interaction.reply({ content: `${this.container.client.dev.error} | I am not in a voice channel`, ephemeral: true });
if (!queue.tracks || !queue.current)
return interaction.reply({ content: `${this.container.client.dev.error} | There is no queue`, ephemeral: true });

await interaction.deferReply();

const { title, url } = queue.current;
let pagesNum = Math.ceil(queue.tracks.length / 5);
if (pagesNum === 0) pagesNum = 1;

const tracks: any = [];
for (let i = 0; i < queue.tracks.length; i++) {
const song = queue.tracks[i];
tracks.push(
`**${i + 1})** [${song.title}](${song.url})
`
);
}

const pages: any = [];
for (let i = 0; i < pagesNum; i++) {
const str = tracks.slice(i * 5, i * 5 + 5).join('');
const embed = new EmbedBuilder()
.setAuthor({
name: `Queue for ${interaction.guild!.name}`,
iconURL: interaction.guild?.iconURL()?.toString()
})
.setColor('Red')
.setDescription(`**Now Playing:** [${title}](${url})\n\n**Queue:** ${str === '' ? '*No more queued songs*' : `\n${str}`}`)
.setFooter({
text: `${queue.tracks.length} song(s) in queue`
});

pages.push(embed);
}

const paginatedMessage = new PaginatedMessage().addPageEmbed(pages[0]);
if (pagesNum > 1) paginatedMessage.addPageBuilder((builder) => builder.setEmbeds(pages));

return paginatedMessage.run(interaction, interaction.user);
const queue = this.container.client.player.getQueue(interaction.guild!);

if (!queue) return interaction.reply({ content: `${this.container.client.dev.error} | I am not in a voice channel`, ephemeral: true });
if (!queue.tracks || !queue.current)
return interaction.reply({ content: `${this.container.client.dev.error} | There is no queue`, ephemeral: true });

await interaction.deferReply();

const { title, url } = queue.current;
let pagesNum = Math.ceil(queue.tracks.length / 5);
if (pagesNum === 0) pagesNum = 1;

const tracks: any = [];
for (let i = 0; i < queue.tracks.length; i++) {
const song = queue.tracks[i];
tracks.push(
`**${i + 1})** [${song.title}](${song.url})
`
);
}

const pages: any = [];
for (let i = 0; i < pagesNum; i++) {
const str = tracks.slice(i * 5, i * 5 + 5).join('');
const embed = new EmbedBuilder()
.setAuthor({
name: `Queue for ${interaction.guild!.name}`,
iconURL: interaction.guild?.iconURL()?.toString()
})
.setColor('Red')
.setDescription(`**Now Playing:** [${title}](${url})\n\n**Queue:** ${str === '' ? '*No more queued songs*' : `\n${str}`}`)
.setFooter({
text: `${queue.tracks.length} song(s) in queue`
});

pages.push(embed);
}

const paginatedMessage = new PaginatedMessage().addPageEmbed(pages[0]);
if (pagesNum > 1) paginatedMessage.addPageBuilder((builder) => builder.setEmbeds(pages));

return paginatedMessage.run(interaction, interaction.user);
This code creates a paginated message, however when I add more embeds using builder.setEmbeds(pages), I want it to edit the current message to display the next pages, rather than send all embeds at once in the chat. Is there any way I can solve this?
Solution:
```ts import { PaginatedMessage } from '@sapphire/discord.js-utilities'; import type { Command } from '@sapphire/framework'; async function aa(this: Command, interaction: Command.ChatInputCommandInteraction) {...
Jump to solution
13 Replies
Auric
Auric17mo ago
to add on the addPages function kinda gets what I need, however it adds the pages but the pagination itself doesn't work this code worked as intended before @sapphire/discord.js-utilities was previously updated
Favna
Favna17mo ago
The package hasn't been updated in a very long time not counting the discordjs v14 update so "worked before" is nonsense. Anyway for starters you should remove that any, that's asking for problems Also interaction.user is the default so the second param is pretty useless there Lastly, @Dragonite is open source so check that ig. Or even check @Skyra whom while not updated, is still using the same principles because like I said, the core structure hasn't been updated in ages.
Spinel
Spinel17mo ago
Discord bots that use @sapphire/framework v4 - Official Bot Examples ᴱ ᴰ ᴶˢ - Dragonite ᴱ ᴰ Discord bots that use @sapphire/framework v3 - Archangel ᴱ ᴰ - Arima ᴱ - Nino ᴱ ᴰ - Operator ᴱ ᴬ ᴰ - Radon ᴱ ᴬ - Sapphire Application Commands Examples ᴱ - Spectera ᴬ Discord bots that use @sapphire/framework v2 - Materia ᴱ - RTByte ᴱ ᴬ - Skyra ᴬ ᴰ - YliasDiscordBot ᴬ : Uses ESM (if not specified then uses CJS) : Advanced bot (if not specified it is a simple bot, or not graded) : Uses Docker in production ᴶˢ: Written in JavaScript. If not specified then the bot is written in TypeScript.
Auric
Auric17mo ago
ah I see, then it must be any other package that was updated such as discord.js I will check those and try see how I can fix this
Favna
Favna17mo ago
Whenever you update your dependencies, always update everything pepeHmm
Auric
Auric17mo ago
ofc im up to date
Favna
Favna17mo ago
Use Version Lens vscode extension for example to make that easier
Auric
Auric17mo ago
yep already use it probs one of the best extensions to be made
Favna
Favna17mo ago
Anyway yeah paginatedmessage the only change for the new major was adjusting the types and functions for djs v14 I.e. how select menus are handled and buttons are build and such
Auric
Auric17mo ago
oh ok so it must be how i approach the function with my embeds i have done some logging and they all return as EmbedBuilder embeds which is what I want just the pages now
Solution
Favna
Favna17mo ago
import { PaginatedMessage } from '@sapphire/discord.js-utilities';
import type { Command } from '@sapphire/framework';

async function aa(this: Command, interaction: Command.ChatInputCommandInteraction) {
const queue = this.container.client.player.getQueue(interaction.guild!);

if (!queue) return interaction.reply({ content: `${this.container.client.dev.error} | I am not in a voice channel`, ephemeral: true });
if (!queue.tracks || !queue.current)
return interaction.reply({ content: `${this.container.client.dev.error} | There is no queue`, ephemeral: true });

await interaction.deferReply();

const { title, url } = queue.current;
let pagesNum = Math.ceil(queue.tracks.length / 5);

if (pagesNum === 0) {
pagesNum = 1;
}

const tracks: any = [];
for (let i = 0; i < queue.tracks.length; i++) {
const song = queue.tracks[i];
tracks.push(
`**${i + 1})** [${song.title}](${song.url})
`
);
}

const paginatedMessage = new PaginatedMessage();

for (let i = 0; i < pagesNum; i++) {
const str = tracks.slice(i * 5, i * 5 + 5).join('');

paginatedMessage.addPageEmbed((embed) =>
embed
.setAuthor({
name: `Queue for ${interaction.guild!.name}`,
iconURL: interaction.guild?.iconURL()?.toString()
})
.setColor('Red')
.setDescription(`**Now Playing:** [${title}](${url})\n\n**Queue:** ${str === '' ? '*No more queued songs*' : `\n${str}`}`)
.setFooter({
text: `${queue.tracks.length} song(s) in queue`
})
);
}

return paginatedMessage.run(interaction, interaction.user);
}
import { PaginatedMessage } from '@sapphire/discord.js-utilities';
import type { Command } from '@sapphire/framework';

async function aa(this: Command, interaction: Command.ChatInputCommandInteraction) {
const queue = this.container.client.player.getQueue(interaction.guild!);

if (!queue) return interaction.reply({ content: `${this.container.client.dev.error} | I am not in a voice channel`, ephemeral: true });
if (!queue.tracks || !queue.current)
return interaction.reply({ content: `${this.container.client.dev.error} | There is no queue`, ephemeral: true });

await interaction.deferReply();

const { title, url } = queue.current;
let pagesNum = Math.ceil(queue.tracks.length / 5);

if (pagesNum === 0) {
pagesNum = 1;
}

const tracks: any = [];
for (let i = 0; i < queue.tracks.length; i++) {
const song = queue.tracks[i];
tracks.push(
`**${i + 1})** [${song.title}](${song.url})
`
);
}

const paginatedMessage = new PaginatedMessage();

for (let i = 0; i < pagesNum; i++) {
const str = tracks.slice(i * 5, i * 5 + 5).join('');

paginatedMessage.addPageEmbed((embed) =>
embed
.setAuthor({
name: `Queue for ${interaction.guild!.name}`,
iconURL: interaction.guild?.iconURL()?.toString()
})
.setColor('Red')
.setDescription(`**Now Playing:** [${title}](${url})\n\n**Queue:** ${str === '' ? '*No more queued songs*' : `\n${str}`}`)
.setFooter({
text: `${queue.tracks.length} song(s) in queue`
})
);
}

return paginatedMessage.run(interaction, interaction.user);
}
(ignore the random function, wanted my own type checking to not crap itself) Just personal opinion but I'd go for something like this. I also don't get that last if (pagesNum > 1) statement, I can't see what purpose it serves at all.
Favna
Favna17mo ago
Other than that I removed the const pages = [] in favour of directly pushing pages into the PaginatedMessage
Auric
Auric17mo ago
honestly that pagesNum was literally code I took from an old bot of mine and I made a paginate function with it with hardly any error proofing so I did it outside the function and just hadn't changed it since ah i see what you've done with the loop, thanks for the help i'll keep that in mind for the next time I create a paginated message again i assume i should remove interaction.user as it already takes interaction and will resolve to using interaction.user automatically