admin管理员组文章数量:1290938
This is how I create and send the button:
client.on('messageCreate', (message) => {
/* ... Checking Command ... */
const actionRow = new MessageActionRow().addComponents(
new MessageButton()
.setStyle("PRIMARY")
.setLabel("X")
.setCustomId("test"));
message.channel.send({ content: "Test", ponents: [actionRow] });
}
A blue Button appears in the chat, as expected.
This is my Button-Listener:
client.on("interactionCreate", (interaction) => {
if (interaction.isButton()) {
if (interaction.customId === "test") {
//Before: console.log(interactionponent);
interactionponent.setStyle("DANGER");
//After: console.log(interactionponent);
}
}
});
Logging the ponent-object before and after .setStyle("DANGER")
also reveals, that the style got changed from Primary to Danger successfully.
But in my Discord Client, the Style/Color didn't change, and ontop of that I am getting an error, saying that the interaction failed.
The style-property doesn't seem to be read-only:
So what am I doing wrong?
This is how I create and send the button:
client.on('messageCreate', (message) => {
/* ... Checking Command ... */
const actionRow = new MessageActionRow().addComponents(
new MessageButton()
.setStyle("PRIMARY")
.setLabel("X")
.setCustomId("test"));
message.channel.send({ content: "Test", ponents: [actionRow] });
}
A blue Button appears in the chat, as expected.
This is my Button-Listener:
client.on("interactionCreate", (interaction) => {
if (interaction.isButton()) {
if (interaction.customId === "test") {
//Before: console.log(interaction.ponent);
interaction.ponent.setStyle("DANGER");
//After: console.log(interaction.ponent);
}
}
});
Logging the ponent-object before and after .setStyle("DANGER")
also reveals, that the style got changed from Primary to Danger successfully.
But in my Discord Client, the Style/Color didn't change, and ontop of that I am getting an error, saying that the interaction failed.
The style-property doesn't seem to be read-only: https://discord.js/#/docs/main/stable/class/MessageButton?scrollTo=style
So what am I doing wrong?
Share Improve this question asked Aug 12, 2021 at 21:35 FireFuro99FireFuro99 3932 gold badges6 silver badges21 bronze badges3 Answers
Reset to default 3You updated the style only locally, you didn't send the changed ponent back to the Discord API.
To get rid of the error "This interaction failed", you need to respond to the interaction. One way to respond is to use MessageComponentInteraction.update()
, which updates the original message.
client.on("interactionCreate", (interaction) => {
if (interaction.isButton()) {
if (interaction.customId === "test") {
// Change the style of received button ponent
interaction.ponent.setStyle("DANGER");
// Respond to the interaction,
// and send updated ponent to the Discord API
interaction.update({
ponents: [
new MessageActionRow().addComponents(interaction.ponent)
]
});
}
}
});
To make this work with multiple buttons, use the example below.
client.on("interactionCreate", (interaction) => {
if (interaction.isButton()) {
// Make this work only for certain buttons,
// with IDs like switch_0, switch_1, etc.
if (interaction.customId.startsWith("switch_")) {
// Change the style of the button ponent,
// that triggered this interaction
interaction.ponent.setStyle("DANGER");
// Respond to the interaction,
// and send updated ponents to the Discord API
interaction.update({
ponents: interaction.message.ponents
});
}
}
});
For any future viewers who might be using Discordjs V14+ you can't edit the ponents directly anymore, so you need to recreate them in order to edit them. This is a solution I came up with that flips the color when clicked!
const collector = interaction.channel.createMessageComponentCollector({ time: 15000 });
collector.on('collect', async i => {
//loop through each action row on the embed and update it accordingly
let newActionRowEmbeds = i.message.ponents.map(oldActionRow => {
//create a new action row to add the new data
updatedActionRow = new ActionRowBuilder();
// Loop through old action row ponents (which are buttons in this case)
updatedActionRow.addComponents(oldActionRow.ponents.map(buttonComponent => {
//create a new button from the old button, to change it if necessary
newButton = ButtonBuilder.from(buttonComponent)
//if this was the button that was clicked, this is the one to change!
if(i.ponent.customId == buttonComponent.customId){
//If the button was a primary button then change to secondary, or vise versa
if(buttonComponent.style == ButtonStyle.Primary){
newButton.setStyle(ButtonStyle.Secondary)
}
else if (buttonComponent.style == ButtonStyle.Secondary){
newButton.setStyle(ButtonStyle.Primary)
}
}
return newButton
}));
return updatedActionRow
});
// and then finally update the message
await i.update({ponents: newActionRowEmbeds})
});
Just some minor improvements to the solution of @LachyLegend for easier use.
TypeScript:
function updateComponent<T extends MessageActionRowComponentBuilder>(interaction: MessageComponentInteraction, newButtonFunc: (ponent: T) => T, customId = interaction.customId): ActionRowBuilder<MessageActionRowComponentBuilder>[] {
const indices = findComponent(interaction, customId);
if (!indices) {
return [];
}
const actionRows = interaction.message.ponents.map<ActionRowBuilder<MessageActionRowComponentBuilder>>((row) => ActionRowBuilder.from(row));
newButtonFunc(actionRows[indices.actionRowIndex].ponents[indices.ponentIndex] as T);
return actionRows;
}
function findComponent(interaction: MessageComponentInteraction, customId: string): {actionRowIndex: number, ponentIndex: number} | undefined {
const actionRows = interaction.message.ponents;
for (let actionRowIndex = 0; actionRowIndex < actionRows.length; ++actionRowIndex) {
const actionRow = actionRows[actionRowIndex];
for (let ponentIndex = 0; ponentIndex < actionRow.ponents.length; ++ponentIndex) {
if (actionRow.ponents[ponentIndex].customId === customId) {
return {
actionRowIndex,
ponentIndex,
};
}
}
}
}
JavaScript
function updateComponent(interaction, newButtonFunc, customId = interaction.customId) {
const indices = findComponent(interaction, customId);
if (!indices) {
return [];
}
const actionRows = interaction.message.ponents.map((row) => ActionRowBuilder.from(row));
newButtonFunc(actionRows[indices.actionRowIndex].ponents[indices.ponentIndex]);
return actionRows;
}
function findComponent(interaction, customId) {
const actionRows = interaction.message.ponents;
for (let actionRowIndex = 0; actionRowIndex < actionRows.length; ++actionRowIndex) {
const actionRow = actionRows[actionRowIndex];
for (let ponentIndex = 0; ponentIndex < actionRow.ponents.length; ++ponentIndex) {
if (actionRow.ponents[ponentIndex].customId === customId) {
return {
actionRowIndex,
ponentIndex,
};
}
}
}
}
usage:
const reply = await interaction.reply(messageContent);
const collector = reply.createMessageComponentCollector({ ponentType: ComponentType.Button, time: 3_600_000 });
collector.on('collect', async (buttonInteraction) => {
const newActionRows = updateComponent(buttonInteraction, (button) => button.setStyle(button.data.style === ButtonStyle.Success ? ButtonStyle.Danger : ButtonStyle.Success));
// updateButton<ButtonBuilder>(...) or updateButton<TheBuilderYouOverride>(...) for TypeScript
await reply.edit({
content: buttonInteraction.message.content,
ponents: newActionRows,
});
buttonInteraction.update({});
});
本文标签: javascriptDiscordjsHow to change style of ButtonStack Overflow
版权声明:本文标题:javascript - Discord.js - How to change style of Button - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741510416a2382574.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论