问题描述
message.channel.send(bot.guilds.cache.map(g=> "*Name:* **"+g.name +'** *ID:* **'+g.id+"** *Owner:* **"+g.owner.user.tag+"**"))
我有这个代码来发送所有公会,名称 id 和所有者名称,但是我怎样才能使第 10 个显示在嵌入页面上,然后反应箭头将??您带到显示其他公会的下一页然后后面的反应带你回到一个页面
I have this code to send all guilds, the name id and owner name, however how can I make this so that the fisrt 10 are displayed on an embed page, then a reaction arrow takes you to the next page showing other guilds and then the back reaction takes you back a page
推荐答案
Discord.js v13
您可以使用 Discord 相对较新的 按钮:
import {MessageActionRow, MessageButton, MessageEmbed} from 'discord.js' // Constants const backId = 'back' const forwardId = 'forward' const backButton = new MessageButton({ style: 'SECONDARY', label: 'Back', emoji: '??', customId: backId }) const forwardButton = new MessageButton({ style: 'SECONDARY', label: 'Forward', emoji: '??', customId: forwardId }) // Put the following code wherever you want to send the embed pages: const {author, channel} = message const guilds = [...client.guilds.cache.values()] /** * Creates an embed with guilds starting from an index. * @param {number} start The index to start from. * @returns {Promise<MessageEmbed>} */ const generateEmbed = async start => { const current = guilds.slice(start, start + 10) // You can of course customise this embed however you want return new MessageEmbed({ title: `Showing guilds ${start + 1}-${start + current.length} out of ${ guilds.length }`, fields: await Promise.all( current.map(async guild => ({ name: guild.name, value: `**ID:** ${guild.id} **Owner:** ${(await guild.fetchOwner()).user.tag}` })) ) }) } // Send the embed with the first 10 guilds const canFitOnOnePage = guilds.length <= 10 const embedMessage = await channel.send({ embeds: [await generateEmbed(0)], components: canFitOnOnePage ? [] : [new MessageActionRow({components: [forwardButton]})] }) // Exit if there is only one page of guilds (no need for all of this) if (canFitOnOnePage) return // Collect button interactions (when a user clicks a button), // but only when the button as clicked by the original message author const collector = embedMessage.createMessageComponentCollector({ filter: ({user}) => user.id === author.id }) let currentIndex = 0 collector.on('collect', async interaction => { // Increase/decrease index interaction.customId === backId ? (currentIndex -= 10) : (currentIndex += 10) // Respond to interaction by updating message with new embed await interaction.update({ embeds: [await generateEmbed(currentIndex)], components: [ new MessageActionRow({ components: [ // back button if it isn't the start ...(currentIndex ? [backButton] : []), // forward button if it isn't the end ...(currentIndex + 10 < guilds.length ? [forwardButton] : []) ] }) ] }) })
这是一个预览(带有显示分页的垃圾字段):
Here's a preview (with rubbish fields to show the pagination):
这是我使用反应发布的原始版本.此代码仅适用于 Discord.js v12.
This is the original version I posted using reactions. This code only works for Discord.js v12.
const guilds = bot.guilds.cache.array() /** * Creates an embed with guilds starting from an index. * @param {number} start The index to start from. */ const generateEmbed = start => { const current = guilds.slice(start, start + 10) // you can of course customise this embed however you want return new MessageEmbed({ title: `Showing guilds ${start + 1}-${start + current.length} out of ${guilds.length}`, fields: current.map(guild => ({ name: guild.name, value: `**ID:** ${guild.id} **Owner:** ${guild.owner.user.tag}` })) }) } const {author, channel} = message.author // send the embed with the first 10 guilds channel.send(generateEmbed(0)).then(message => { // exit if there is only one page of guilds (no need for all of this) if (guilds.length <= 10) return // react with the right arrow (so that the user can click it) (left arrow isn't needed because it is the start) message.react('??') const collector = message.createReactionCollector( // only collect left and right arrow reactions from the message author (reaction, user) => ['??', '??'].includes(reaction.emoji.name) && user.id === author.id, // time out after a minute {time: 60000} ) let currentIndex = 0 collector.on('collect', async reaction => { // remove the existing reactions await message.reactions.removeAll() // increase/decrease index reaction.emoji.name === '??' ? currentIndex -= 10 : currentIndex += 10 // edit message with new embed await message.edit(generateEmbed(currentIndex)) // react with left arrow if it isn't the start if (currentIndex !== 0) await message.react('??') // react with right arrow if it isn't the end if (currentIndex + 10 < guilds.length) await message.react('??') }) })