buttondiscorddiscord.jsembedslash

Discord.js v14 | How do I make a Button that doesn't expire


I will send my index.js file and my command file and tell me what wrong with it the only button that works is my roles buttons Please help me as fast as possible Thanks.

Index.js

const { Client, GatewayIntentBits, PermissionsBitField, Permissions, MessageManager, Collection, ActivityType, EmbedBuilder } = require('discord.js');
const fs = require('fs');
const client = new Client({ intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages, GatewayIntentBits.MessageContent] }); 

client.commands = new Collection();

require('dotenv').config();

const functions = fs.readdirSync("./functions").filter(file => file.endsWith(".js"));
const eventFiles = fs.readdirSync("./events").filter(file => file.endsWith(".js"));
const commandFolders = fs.readdirSync("./commands");

client.on('ready', async() => {
    console.log('Bot is Online!');
    client.user.setPresence({
        activities: [{ name: '${client.guilds.cache.size} Servers! | /help', type: ActivityType.Watching}],
        status: 'idle',
    })
})

client.on('interactionCreate', async interaction => {
    if (interaction.customId !== 'roles') return;
    const lvlroles = new EmbedBuilder()
    .setTitle('<:IconPerson:1095955255973396613> Level Rewards')
    .setColor('#2f3136')
    .setDescription('As you talk in the server, you gain points known as XP. The more points you get, the higher level you unlock, and these levels unlock new perks you can use within the server.')
    .setURL('https://discord.com/channels/1085663118199373875/1111458583188607087')
    .addFields({
        name: 'Member',
        value: '<@&000>\n• Acquired when you send your first message\n• New Color + Role Icon',
        inline: true
    })
    .addFields({
        name: 'Level 5',
        value: '<@&00>\n• Post in <#1111475091721687132>\n• Add Reactions to messages',
        inline: true
    })
    .addFields({
        name: 'Level 10',
        value: '<@&0>\n• Post in <#1111475469938872430>\n• Access to <#1115048952002261032>',
        inline: true
    })
    .addFields({
        name: 'Level 20',
        value: '<@&00>\n• Eligible for Staff\n• Add Reactions\n• Post in <#1111459958513479681>\n• Access to <#1115049432862445659>',
        inline: true
    })
    .addFields({
        name: 'Level 50',
        value: '<@&00>\n• Send Image permission in the chat',
        inline: true
    })
    .addFields({
        name: 'Level 70',
        value: '<@&00>\nAcquired at Level 70',
        inline: true
    })
    .addFields({
        name: 'Level 100',
        value: '<@&00>\n• Post in <#1111481584806268939>',
        inline: true
    })

    const uniqueroles = new EmbedBuilder()
    .setTitle('<:IconPlanet:1095955265041469550> Special Roles')
    .setColor('#2f3136')
    .setDescription('These roles are usually harder to unlock and show some sign of authority/popularity within Discord or the Community.')
    .addFields({
        name: '** **',
        value: "<@&1122944246610137194>\n• For those who are popular on the internet or have a large following outside of Discord. Also given to partnered server owners, highly active users, and Jet's friends or colleagues.",
        inline: true
    })
    .addFields({
        name: '** **',
        value: '<@&1095423865984917595>\n• Over 100+ Subscribers\n• Over 200+ Views\n• Must meet Production Quality Criteria (No Shorts / Reposts)\n• Channel must be connected to the account.',
        inline: true
    })
    .addFields({
        name: '** **',
        value: '<@&1109912588042633307>\n• Temporary role is given for 12 hours when you vote for our server on our [top.gg listing](https://top.gg/servers/1085663118199373875/vote).',
        inline: true
    })

    const boostroles = new EmbedBuilder()
    .setTitle('<:IconBoost:1095955197567701093> Booster Perks')
    .setColor('#2f3136')
    .setDescription('Boosting the server helps us out massively, so we really appreciate your thought to boost. Boost us, and as a return gift from us, you will unlock special perks and access to hidden channels.')
    .addFields({
        name: '<:IconBoost:1095955197567701093> Boost Once, and Get',
        value: '• Hoisted role\n• Custom Role (Name, Color, + Icon)\n• Attach files in the chat\n• Change Nickname\n• Add Reactions\n• and More!',
        inline: true
    })
    .addFields({
        name: '<:IconBoost:1095955197567701093> Additional Boosting Perks',
        value: '• <@&1122930521534644394>\n• <@&1122930649632866365>\n\nA chance to get friended by AllenPlayz or ProFireJet, a priority reply to Support, and much more!',
        inline: true
    })
    .addFields({
        name: '** **',
        value: 'Open a [Support Ticket](https://discord.com/channels/1085663118199373875/1122931747726827540) to claim your perks.'
    })

    await interaction.reply({ embeds: [lvlroles, uniqueroles, boostroles], ephemeral: true });

    if (interaction.customId !== 'rules') return;
    const rules = new EmbedBuilder()
    .setColor('#ed8866')
    .setDescription('To ensure that everyone has a positive and enjoyable experience, we have established the following rules and guidelines:')
    .addFields({
        name: '<:IconHeart:1095955230887247974> Respect and Kindness',
        value: 'We expect everyone to treat each other with respect and kindness. We will not tolerate harassment, hate speech, or discrimination of any kind. We understand that everyone comes from different backgrounds and experiences, but we believe that everyone deserves to be treated with respect. Please keep the conversations positive and avoid being argumentative. If someone is causing issues, please report them to the moderators.',
        inline: true
    })
    .addFields({
        name: '<:IconBook:1095955185374859274> Appropriate Content',
        value: 'Our server is open to all ages, so we want to make sure that everyone feels safe and comfortable here. We ask that you keep the conversation and content appropriate for all ages. Please avoid using explicit language, sharing inappropriate images, or discussing sensitive topics that might make others uncomfortable. We want to make sure that everyone feels welcome and respected.',
        inline: true
    })
    .addFields({
        name: '** **',
        value: '** **'
    })
    .addFields({
        name: '<:IconBook:1095955185374859274> Stay on Topic',
        value: 'Our server is focused on graphic design, Discord, and other relevant categories. Please keep the conversation and content related to these topics. If you have something else you would like to talk about, please use the appropriate channels. This helps to keep the server organized and relevant for everyone.',
        inline: true
    })
    .addFields({
        name: "<:IconBook:1095955185374859274> Follow Discord's TOS:",
        value: "We want to remind everyone that all Discord terms of service apply to our server. Any violations will result in appropriate consequences, including warnings, mutes, kicks, or bans. We reserve the right to take appropriate action as needed. We encourage everyone to familiarize themselves with Discord's TOS.",
        inline: true
    })
    .addFields({
        name: '** **',
        value: '** **'
    })
    .addFields({
        name: '** **',
        value: '** **'
    })
    .setFooter({
        text: 'By joining and participating in this server, you agree to be bound by these rules. Please note that these rules and guidelines are subject to change at any time at the discretion of the server administrators. Additionally, we reserve the right to take appropriate action if any rule is found to be broken, including warnings, mutes, kicks, or bans.',
        iconURL: `${interaction.author.avatarURL}`
    })

    await interaction.reply({ embeds: [rules], ephemeral: true });

    if (interaction.customId !== 'support') return;
    const support = new EmbedBuilder()
    .setTitle('You can support us by:')
    .setColor('#ed8866')
    .setDescription('• Voting and reviewing the server on Top.GG! [JetArmy is on Top.GG](https://top.gg/servers/1085663118199373875/vote) and gain additional perks for voting!\n• Boosting the Server, view perks below\n• Following us on Twitter [@FireJetArmy](https://twitter.com)')

    const boost = new EmbedBuilder()
    .setTitle('<:IconBoost:1095955197567701093> Booster Perks')
    .setColor('#2f3136')
    .setDescription('Boosting the server helps us out massively, so we really appreciate your thought to boost. Boost us, and as a return gift from us, you will unlock special perks and access to hidden channels.')
    .addFields({
        name: '<:IconBoost:1095955197567701093> Boost Once, and Get',
        value: '• Hoisted role\n• Custom Role (Name, Color, + Icon)\n• Attach files in the chat\n• Change Nickname\n• Add Reactions\n• and More!',
        inline: true
    })
    .addFields({
        name: '<:IconBoost:1095955197567701093> Additional Boosting Perks',
        value: '• <@&1122930521534644394>\n• <@&1122930649632866365>\n\nA chance to get friended by Roonie, a priority reply to Support, and much more!',
        inline: true
    })
    .addFields({
        name: '** **',
        value: 'Open a [Support Ticket](https://discord.com/channels/1085663118199373875/1122931747726827540) to claim your perks.'
    })

    await interaction.reply({ embeds: [support, boost], ephemeral: true });
})

async () => {
    for (file of functions) {
        require(`./functions/${file}`)(client);
    }
    client.handleEvents(eventFiles, "./events");
    client.handleCommands(commandFolders, "./commands");
    client.login(process.env.token)
};

embed.js

const { SlashCommandBuilder, EmbedBuilder, ButtonBuilder, ActionRowBuilder, ButtonStyle, AttachmentBuilder } = require('discord.js');

module.exports = {
    data: new SlashCommandBuilder()
    .setName('embeds')
    .setDescription('Sends embeds to a channel.'),
    async execute(interaction) {

        if(interaction.member.id !== '325873177697976322' && interaction.member.id !== '720442895735324674')return interaction.reply({ content: `Only Developers are allowed to use this command.` });

        const welcome1 = new EmbedBuilder()
        .setAuthor({ name: 'ProFireJet™#3151', iconURL: 'https://cdn.discordapp.com/avatars/720442895735324674/ae6dedf6d4dc47e98f33caf34456448b.png?size=4096' })
        .setDescription(`> Thank you for joining my Discord server. I'm 14 years old Minecraft Server. I run a YouTube channel with 200+ subscribers, where I make videos about Memes. I also run a Spotify Podcast with 2k+ followers, where I make podcasts about Games.\n\n**Check out my socials for more information about my work!**\nFeel free to contact <@720442895735324674> via DMs, it's open!`)
        .setColor('#2f3136')

        const welcome2 = new EmbedBuilder()
        .setAuthor({ name: 'Jet Army', iconURL: 'https://cdn.discordapp.com/attachments/1120138152275886100/1123413609482047659/jet-29166.png' })
        .setDescription('Thanks for joining. We hope the ride was stellar. JetArmy is based around the Content Creator, Graphic Designer, and Gamers, ProFireJet.\n\nDespite that, anyone is welcome to join the community and enjoy the company of creative like-minded individuals!\n\n**Feel free to <#1123414240854810675> yourself!**')
        .setColor('#ed8866')

        const file = new AttachmentBuilder('assets/Welcome.png');

        const youtube = new ButtonBuilder()
        .setLabel('YouTube')
        .setStyle(ButtonStyle.Link)
        .setURL('https://m.youtube.com/@TheJetarmy')
        .setEmoji('<:IconYouTube:1095955282644979754> ')

        const website = new ButtonBuilder()
        .setLabel('Website')
        .setCustomId('web')
        .setStyle(ButtonStyle.Secondary)
        .setEmoji('<:IconDribbble:1095955214755954748> ')

        const podcast = new ButtonBuilder()
        .setLabel('Podcast')
        .setStyle(ButtonStyle.Link)
        .setURL('https://open.spotify.com/show/6cZnwufE0p4fV4KZ7rYdpl')
        .setEmoji('<:IconPodcast:1122601872549761095> ')

        const twitch = new ButtonBuilder()
        .setLabel('Twitch')
        .setStyle(ButtonStyle.Link)
        .setURL('https://www.twitch.tv/thejetarmy')
        .setEmoji('<:Twitch:1111770769538699315> ')


        const roles = new ButtonBuilder()
        .setLabel('Roles Info')
        .setCustomId('roles')
        .setStyle(ButtonStyle.Secondary)
        .setEmoji('<:IconPerson:1095955255973396613> ')

        const rules = new ButtonBuilder()
        .setLabel('Server Rules')
        .setCustomId('rules')
        .setStyle(ButtonStyle.Secondary)
        .setEmoji('<:IconBook:1095955185374859274> ')

        const support = new ButtonBuilder()
        .setLabel('Support')
        .setCustomId('support')
        .setStyle(ButtonStyle.Secondary)
        .setEmoji('<:IconBoost:1095955197567701093>')

        const wrow1 = new ActionRowBuilder()
        .addComponents(roles)
        .addComponents(rules)
        .addComponents(support)

        const wrow2 = new ActionRowBuilder()
        .addComponents(roles)
        .addComponents(rules)
        .addComponents(support)

        interaction.deferReply()
        interaction.deleteReply()
        interaction.channel.send({ embeds: [welcome1, welcome2], files: [file], components: [wrow1, wrow2] });
    }
}

I'm Expecting TO have this does as soon as possible and have working buttons that don't expire that even work if the bot is offline/not running.


Solution

  • First You Should Create every Button Like You Did In Embed.js

    const { SlashCommandBuilder, EmbedBuilder, ButtonBuilder, ActionRowBuilder, ButtonStyle, AttachmentBuilder } = require('discord.js');
    
    module.exports = {
        data: new SlashCommandBuilder()
        .setName('embeds')
        .setDescription('Sends embeds to a channel.'),
        async execute(interaction) {
    
            if(interaction.member.id !== '325873177697976322' && interaction.member.id !== '720442895735324674')return interaction.reply({ content: `Only Developers are allowed to use this command.` });
    
            const welcome1 = new EmbedBuilder()
            .setAuthor({ name: 'ProFireJet™#3151', iconURL: 'https://cdn.discordapp.com/avatars/720442895735324674/ae6dedf6d4dc47e98f33caf34456448b.png?size=4096' })
            .setDescription(`> Thank you for joining my Discord server. I'm 14 years old Minecraft Server. I run a YouTube channel with 200+ subscribers, where I make videos about Memes. I also run a Spotify Podcast with 2k+ followers, where I make podcasts about Games.\n\n**Check out my socials for more information about my work!**\nFeel free to contact <@720442895735324674> via DMs, it's open!`)
            .setColor('#2f3136')
    
            const welcome2 = new EmbedBuilder()
            .setAuthor({ name: 'Jet Army', iconURL: 'https://cdn.discordapp.com/attachments/1120138152275886100/1123413609482047659/jet-29166.png' })
            .setDescription('Thanks for joining. We hope the ride was stellar. JetArmy is based around the Content Creator, Graphic Designer, and Gamers, ProFireJet.\n\nDespite that, anyone is welcome to join the community and enjoy the company of creative like-minded individuals!\n\n**Feel free to <#1123414240854810675> yourself!**')
            .setColor('#ed8866')
    
            const file = new AttachmentBuilder('assets/Welcome.png');
    
            const youtube = new ButtonBuilder()
            .setLabel('YouTube')
            .setStyle(ButtonStyle.Link)
            .setURL('https://m.youtube.com/@TheJetarmy')
            .setEmoji('<:IconYouTube:1095955282644979754> ')
    
            const website = new ButtonBuilder()
            .setLabel('Website')
            .setCustomId('web')
            .setStyle(ButtonStyle.Secondary)
            .setEmoji('<:IconDribbble:1095955214755954748> ')
    
            const podcast = new ButtonBuilder()
            .setLabel('Podcast')
            .setStyle(ButtonStyle.Link)
            .setURL('https://open.spotify.com/show/6cZnwufE0p4fV4KZ7rYdpl')
            .setEmoji('<:IconPodcast:1122601872549761095> ')
    
            const twitch = new ButtonBuilder()
            .setLabel('Twitch')
            .setStyle(ButtonStyle.Link)
            .setURL('https://www.twitch.tv/thejetarmy')
            .setEmoji('<:Twitch:1111770769538699315> ')
    
    
            const roles = new ButtonBuilder()
            .setLabel('Roles Info')
            .setCustomId('roles')
            .setStyle(ButtonStyle.Secondary)
            .setEmoji('<:IconPerson:1095955255973396613> ')
    
            const rules = new ButtonBuilder()
            .setLabel('Server Rules')
            .setCustomId('rules')
            .setStyle(ButtonStyle.Secondary)
            .setEmoji('<:IconBook:1095955185374859274> ')
    
            const support = new ButtonBuilder()
            .setLabel('Support')
            .setCustomId('support')
            .setStyle(ButtonStyle.Secondary)
            .setEmoji('<:IconBoost:1095955197567701093>')
    
            const wrow1 = new ActionRowBuilder()
            .addComponents(roles)
            .addComponents(rules)
            .addComponents(support)
    
            const wrow2 = new ActionRowBuilder()
            .addComponents(roles)
            .addComponents(rules)
            .addComponents(support)
    
            interaction.deferReply()
            interaction.deleteReply()
            interaction.channel.send({ embeds: [welcome1, welcome2], files: [file], components: [wrow1, wrow2] });
        }
    }
    

    Then Go To index.js And Handle The Buttons Using Their customId

    client.on('interactionCreate', async (interaction) => {
      if (!interaction.isButton()) return;
    
      if (interaction.customId === 'ButtonCustomId') {
        // Your Code Goes Here
        await interaction.reply({ content: 'UwU Button', ephemeral: true });
    
      } else if (interaction.customId === 'ButtonCustomId2') {
         await interaction.reply({ content: 'UwU Button 2', ephemeral: true });
    
      };
    });
    

    These Buttons Will Not Expire Even If The Bot Shut Down And Re-rune