changing stuff around when a button is clicked

how would i make it so when a button is clicked on an embed, it does the following things; change the embed into something else (title, desc, etc.) make the buttons disable (gray out) make the bot reply with an epheral message saying whatever
32 Replies
d.js toolkit
d.js toolkit•5mo ago
- What's your exact discord.js npm list discord.js and node node -v version? - Not a discord.js issue? Check out #other-js-ts. - Consider reading #how-to-get-help to improve your question! - Explain what exactly your issue is. - Post the full error stack trace, not just the top part! - Show your code! - Issue solved? Press the button!
Harnes
Harnes•5mo ago
You need to create a message component collector or simply use interactionCreate event Make a new action row using static ActionRowBuilder#from and change button disabled property (Or make a normal action row with using button (ButtonBuilder#from) and use ButtonBuilder#setDisabled method) Then edit the original message with the other embed (you can also use static EmbedBuilder#from method) <Buttoninteraction>.update(...)
xx_lavaboy_xx123
xx_lavaboy_xx123•5mo ago
he would need to use <Interaction>.message.edit instead of update cus he wants to send a reply after editing
duck
duck•5mo ago
they could also just use <ButtonInteraction>.followUp() after using <ButtonInteraction>.update() this would be the means of achieving this through the interaction webhook
Harnes
Harnes•5mo ago
Does followUp support ephemeral?
duck
duck•5mo ago
yes
Harnes
Harnes•5mo ago
oh, good to know
astro
astro•5mo ago
im sorry im a bit lost here i'm new to DJS 😅 this is what i have thus far
const { SlashCommandBuilder, EmbedBuilder, ButtonBuilder, ButtonStyle, ActionRowBuilder } = require('discord.js');

module.exports = {
data: new SlashCommandBuilder()
.setName('award-request')
.setDescription('Requests an award for a user')
.addUserOption(option =>
option.setName('awardee')
.setDescription('The user you are awarding')
.setRequired(true))
.addStringOption(option =>
option.setName('award')
.setDescription("The award you are awarding.")
.setRequired(true))
.addStringOption(option =>
option.setName('reason')
.setDescription('Why should this user be given the award?')
.setRequired(true))
.addAttachmentOption(option =>
option.setName('evidence')
.setDescription('Supply supporting evidence to warrant this award.')),
async execute(interaction){

const approve = new ButtonBuilder()
.setCustomId('approve')
.setLabel('Approve')
.setStyle(ButtonStyle.Success);

const deny = new ButtonBuilder()
.setCustomId('deny')
.setLabel('Deny')
.setStyle(ButtonStyle.Danger);

const row = new ActionRowBuilder()
.addComponents(approve, deny);

const test = new EmbedBuilder()
.setColor('#b3a622')
.setTitle("New award request")
.setDescription("A new award request has been submitted.")
.addFields(
{ name: "Requested Award", value: interaction.options.getString("award") },
{ name: 'Awarder', value: `<@${interaction.member.id}>`, inline: true },
{ name: 'Awardee', value: `<@${interaction.options.getUser('awardee').id}>`, inline: true },
{ name: 'Reason', value: interaction.options.getString("reason"), inline: true }
)


if (interaction.options.getAttachment("evidence")) {
test.setImage(interaction.options.getAttachment("evidence").url)
}


await interaction.reply({
embeds: [test],
components: [row],
});
},
};
const { SlashCommandBuilder, EmbedBuilder, ButtonBuilder, ButtonStyle, ActionRowBuilder } = require('discord.js');

module.exports = {
data: new SlashCommandBuilder()
.setName('award-request')
.setDescription('Requests an award for a user')
.addUserOption(option =>
option.setName('awardee')
.setDescription('The user you are awarding')
.setRequired(true))
.addStringOption(option =>
option.setName('award')
.setDescription("The award you are awarding.")
.setRequired(true))
.addStringOption(option =>
option.setName('reason')
.setDescription('Why should this user be given the award?')
.setRequired(true))
.addAttachmentOption(option =>
option.setName('evidence')
.setDescription('Supply supporting evidence to warrant this award.')),
async execute(interaction){

const approve = new ButtonBuilder()
.setCustomId('approve')
.setLabel('Approve')
.setStyle(ButtonStyle.Success);

const deny = new ButtonBuilder()
.setCustomId('deny')
.setLabel('Deny')
.setStyle(ButtonStyle.Danger);

const row = new ActionRowBuilder()
.addComponents(approve, deny);

const test = new EmbedBuilder()
.setColor('#b3a622')
.setTitle("New award request")
.setDescription("A new award request has been submitted.")
.addFields(
{ name: "Requested Award", value: interaction.options.getString("award") },
{ name: 'Awarder', value: `<@${interaction.member.id}>`, inline: true },
{ name: 'Awardee', value: `<@${interaction.options.getUser('awardee').id}>`, inline: true },
{ name: 'Reason', value: interaction.options.getString("reason"), inline: true }
)


if (interaction.options.getAttachment("evidence")) {
test.setImage(interaction.options.getAttachment("evidence").url)
}


await interaction.reply({
embeds: [test],
components: [row],
});
},
};
Wdym?
d.js docs
d.js docs•5mo ago
guide Message Components: Component interactions read more
duck
duck•5mo ago
interactions can only be responded to once, so you can't use both <ButtonInteraction>.update() and <ButtonInteraction>.reply(), as these are both initial interaction responses I imagine lavaboy was suggesting using <ButtonInteraction>.reply() to send the subsequent ephemeral message and <ButtonInteraction>.message.edit() to update the button's message personally I would still suggest using <ButtonInteraction>.update() to update the button's message and <ButtonInteraction>.followUp() to send the subsequent ephemeral message since both of these methods go through the interaction rather than needing to edit the message as a bot user utilizing the interaction webhook bypasses the need to think about any sort of restrictions such as permissions, whereas <ButtonInteraction>.message.edit() at least requires your bot to be able to view the channel and its messages
astro
astro•5mo ago
Where would I use this though. And how would I make it so it checks for which button was clicked (because one button needs to edit the embed to one thing, while the other button needs to edit it to something else Also what's <ButtonInteraction>
d.js docs
d.js docs•5mo ago
Explaining <Class> and Class#method notation: learn more
Harnes
Harnes•5mo ago
Every button has a custom id
d.js docs
d.js docs•5mo ago
guide Message Components: Buttons read more
astro
astro•5mo ago
I see. But where would I put this into my code, I don't know where to add it into
Harnes
Harnes•5mo ago
Read guide that I sent
d.js docs
d.js docs•5mo ago
guide Message Components: Component interactions read more
Harnes
Harnes•5mo ago
and this
astro
astro•5mo ago
right so the problem im having now is when i'm trying to use update() it's telling me "Unresolved function or method update()" here's the piece of code where it's in
const response = await interaction.reply({
embeds: [test],
components: [row],
});
try {
if (interaction.customID === 'approve') {
await test.update({ embeds: [test2] })
}
} catch (error){
console.log(error);
}
const response = await interaction.reply({
embeds: [test],
components: [row],
});
try {
if (interaction.customID === 'approve') {
await test.update({ embeds: [test2] })
}
} catch (error){
console.log(error);
}
Harnes
Harnes•5mo ago
That does not how buttons and interaction work Please read guide There's everything you need to know about component interactions and buttons
astro
astro•5mo ago
Right, but I have multiple permanent buttons the The Client#interactionCreate event part of the guide only explains how to do it for one any button, which is not what I'm looking for I'm looking for how to make a specific button on an embed do what I tell it to
Harnes
Harnes•5mo ago
Every button have custom id You need to check in every button interaction it's custom id (ButtonInteraction#customId) If custom id matches Then execute code for that button
astro
astro•5mo ago
Yeah but my ID is in another file this is interactionCreate.js
const { Events } = require('discord.js');

module.exports = {
name: Events.InteractionCreate,
async execute(interaction) {
if (interaction.isChatInputCommand()) {

const command = interaction.client.commands.get(interaction.commandName);

if (!command) {
console.error(`No command matching ${interaction.commandName} was found.`);
return;
}

try {
await command.execute(interaction);
} catch (error) {
console.error(error);
if (interaction.replied || interaction.deferred) {
await interaction.followUp({
content: 'There was an error while executing this command!',
ephemeral: true
});
} else {
await interaction.reply({
content: 'There was an error while executing this command!',
ephemeral: true
});
}
}} else if (interaction.isButton()) {

} else if (interaction.isStringSelectMenu()) {
// respond to the select menu
}
}
}
const { Events } = require('discord.js');

module.exports = {
name: Events.InteractionCreate,
async execute(interaction) {
if (interaction.isChatInputCommand()) {

const command = interaction.client.commands.get(interaction.commandName);

if (!command) {
console.error(`No command matching ${interaction.commandName} was found.`);
return;
}

try {
await command.execute(interaction);
} catch (error) {
console.error(error);
if (interaction.replied || interaction.deferred) {
await interaction.followUp({
content: 'There was an error while executing this command!',
ephemeral: true
});
} else {
await interaction.reply({
content: 'There was an error while executing this command!',
ephemeral: true
});
}
}} else if (interaction.isButton()) {

} else if (interaction.isStringSelectMenu()) {
// respond to the select menu
}
}
}
Harnes
Harnes•5mo ago
You will receive custom id in interaction object
astro
astro•5mo ago
what do you mean
d.js docs
d.js docs•5mo ago
property ButtonInteraction#customId The custom id of the component which was interacted with
Harnes
Harnes•5mo ago
You have this property on interaction Use that
astro
astro•5mo ago
oh wait so can i make an if statement in the else if loop saying if the id is one of the button's, it executes code? so like alright so i've gotten to the point where when i click a button, the content updates what i need now is when the button is clicked, the embed updates, but all the embeds and data that's in the embed is stored in seperate file from the button handler is it possible that i can onlyupdate a piece of the embed wihout rebuilding the entire embed from the ground up and if so how
Harnes
Harnes•5mo ago
As I said higher you can use static EmbedBuilder#from method
d.js docs
d.js docs•5mo ago
method (static) EmbedBuilder.from() Creates a new embed builder from JSON data
astro
astro•5mo ago
yeah but how do i utilize JSON here? my embed builders look like this, i'm not sure how this static thingy works
No description
duck
duck•5mo ago
EmbedBuilder.from() would be used to create an EmbedBuilder from existing data when you don't already have an EmbedBuilder in the given context, so you probably wouldn't use it here where you presumably send the embed and the buttons in the first place the aforementioned <ButtonInteraction>.message is the message the button is on, so you're free to grab your Embed from <ButtonInteraction>.message.embeds wherever you're handling button interactions