/wouldyourather (slash command, issue with buttons)

Can anyone look at my code to see why buttons are not working I am trying to make code for /wouldyourrather slash command which prompts the user to enter input1 and input2 by pressing the option buttons then pressing enter to simulate voting and then ends the poll but the buttons are not working for some reason. I would appreciate it if you can look at my code and let me know if you can pinpoint the issue, here is the current code: https://sourceb.in/u0vgGQU2ZK
13 Replies
d.js toolkit
d.js toolkit4mo 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!
infinitygl
infinitygl4mo ago
mines is most likely discord.js version 14 here is the raw code
const { SlashCommandBuilder, Interaction, EmbedBuilder, ActionRowBuilder, ButtonBuilder } = require('discord.js');
const voteMap = new Map(); // Stores vote counts and user IDs for each option

module.exports = {
data: new SlashCommandBuilder()
.setName('wouldyourather')
.setDescription('Start a "Would you rather...?" poll anonymously')
.addStringOption(option => option.setName('option1').setDescription('Enter the first option'))
.addStringOption(option => option.setName('option2').setDescription('Enter the second option')), // Added input options
async execute(interaction) {
const option1 = interaction.options.getString('option1');
const option2 = interaction.options.getString('option2');

// Input Validation (Optional)
if (!option1 || !option2) {
return await interaction.reply({ content: 'Please provide both options for "Would you rather...?"', ephemeral: true });
}

const scenario = `**Would you rather...**\n1. ${option1}\n2. ${option2}`;

// Check for existing scenario (to avoid duplicate polls)
if (voteMap.has(scenario)) {
return await interaction.reply({ content: 'This "Would you rather...?" scenario is already active!', ephemeral: true });
}

voteMap.set(scenario, { option1: [], option2: [] }); // Initialize vote counts and user IDs

const embed = new EmbedBuilder()
.setColor(0x00ffff)
.setTitle('Would You Rather?')
.setDescription(scenario);

const buttonRow = new ActionRowBuilder()
.addComponents(
new ButtonBuilder().setCustomId('option1').setLabel(option1).setStyle('Primary'),
new ButtonBuilder().setCustomId('option2').setLabel(option2).setStyle('Primary'),
);
await interaction.reply({ embeds: [embed], components: [buttonRow] });

const message = await interaction.fetchReply(); // Get the message containing the embed and buttons

const collector = message.createMessageComponentCollector({ time: 60000 }); // 1 minute timeout

collector.on('collect', async (buttonInteraction) => {
if (!buttonInteraction.isButton()) return;
if (!buttonInteraction.data) { // Check for missing 'data' property
console.log('Invalid button interaction: missing data');
return;
}

if (!buttonInteraction.data.customId) { // Add this check
return console.log('Invalid button interaction: customId missing');
}
const { customId } = buttonInteraction.data;

const votes = voteMap.get(scenario);
if (!votes) return; // Handle potential race condition (less likely)

if (votes.option1.includes(buttonInteraction.user.id) || votes.option2.includes(buttonInteraction.user.id)) {
return await buttonInteraction.reply({ content: 'You already voted!', ephemeral: true });
}

if (customId === 'option1') {
votes.option1.push(buttonInteraction.user.id);
} else if (customId === 'option2') {
votes.option2.push(buttonInteraction.user.id);
}

voteMap.set(scenario, votes); // Update vote counts

await buttonInteraction.deferUpdate(); // Acknowledge button interaction
});
const { SlashCommandBuilder, Interaction, EmbedBuilder, ActionRowBuilder, ButtonBuilder } = require('discord.js');
const voteMap = new Map(); // Stores vote counts and user IDs for each option

module.exports = {
data: new SlashCommandBuilder()
.setName('wouldyourather')
.setDescription('Start a "Would you rather...?" poll anonymously')
.addStringOption(option => option.setName('option1').setDescription('Enter the first option'))
.addStringOption(option => option.setName('option2').setDescription('Enter the second option')), // Added input options
async execute(interaction) {
const option1 = interaction.options.getString('option1');
const option2 = interaction.options.getString('option2');

// Input Validation (Optional)
if (!option1 || !option2) {
return await interaction.reply({ content: 'Please provide both options for "Would you rather...?"', ephemeral: true });
}

const scenario = `**Would you rather...**\n1. ${option1}\n2. ${option2}`;

// Check for existing scenario (to avoid duplicate polls)
if (voteMap.has(scenario)) {
return await interaction.reply({ content: 'This "Would you rather...?" scenario is already active!', ephemeral: true });
}

voteMap.set(scenario, { option1: [], option2: [] }); // Initialize vote counts and user IDs

const embed = new EmbedBuilder()
.setColor(0x00ffff)
.setTitle('Would You Rather?')
.setDescription(scenario);

const buttonRow = new ActionRowBuilder()
.addComponents(
new ButtonBuilder().setCustomId('option1').setLabel(option1).setStyle('Primary'),
new ButtonBuilder().setCustomId('option2').setLabel(option2).setStyle('Primary'),
);
await interaction.reply({ embeds: [embed], components: [buttonRow] });

const message = await interaction.fetchReply(); // Get the message containing the embed and buttons

const collector = message.createMessageComponentCollector({ time: 60000 }); // 1 minute timeout

collector.on('collect', async (buttonInteraction) => {
if (!buttonInteraction.isButton()) return;
if (!buttonInteraction.data) { // Check for missing 'data' property
console.log('Invalid button interaction: missing data');
return;
}

if (!buttonInteraction.data.customId) { // Add this check
return console.log('Invalid button interaction: customId missing');
}
const { customId } = buttonInteraction.data;

const votes = voteMap.get(scenario);
if (!votes) return; // Handle potential race condition (less likely)

if (votes.option1.includes(buttonInteraction.user.id) || votes.option2.includes(buttonInteraction.user.id)) {
return await buttonInteraction.reply({ content: 'You already voted!', ephemeral: true });
}

if (customId === 'option1') {
votes.option1.push(buttonInteraction.user.id);
} else if (customId === 'option2') {
votes.option2.push(buttonInteraction.user.id);
}

voteMap.set(scenario, votes); // Update vote counts

await buttonInteraction.deferUpdate(); // Acknowledge button interaction
});
collector.on('end', async () => {
const votes = voteMap.get(scenario);
const totalVotes = votes.option1.length + votes.option2.length;

if (totalVotes === 0) {
return await message.edit({ content: 'Nobody participated in the "Would you rather...?" poll.', embeds: [], components: [] });
}

const winner = votes.option1.length > votes.option2.length ? 'Option 1' : 'Option 2';
const winPercentage = Math.round((votes[winner === 'Option 1' ? 'option1' : 'option2'].length / totalVotes) * 100);
const results = `**Results:**\n${option1} - ${votes.option1.length} votes (${winPercentage}%)\n${option2} - ${votes.option2.length} votes ${(100 - winPercentage)}%`;

const newEmbed = new EmbedBuilder().setColor(0x00ffff).setTitle('Would You Rather? Results').setDescription(results);

await message.edit({ embeds: [newEmbed], components: [] });
voteMap.delete(scenario); // Cleanup after the poll ends
});
},
};
collector.on('end', async () => {
const votes = voteMap.get(scenario);
const totalVotes = votes.option1.length + votes.option2.length;

if (totalVotes === 0) {
return await message.edit({ content: 'Nobody participated in the "Would you rather...?" poll.', embeds: [], components: [] });
}

const winner = votes.option1.length > votes.option2.length ? 'Option 1' : 'Option 2';
const winPercentage = Math.round((votes[winner === 'Option 1' ? 'option1' : 'option2'].length / totalVotes) * 100);
const results = `**Results:**\n${option1} - ${votes.option1.length} votes (${winPercentage}%)\n${option2} - ${votes.option2.length} votes ${(100 - winPercentage)}%`;

const newEmbed = new EmbedBuilder().setColor(0x00ffff).setTitle('Would You Rather? Results').setDescription(results);

await message.edit({ embeds: [newEmbed], components: [] });
voteMap.delete(scenario); // Cleanup after the poll ends
});
},
};
version here raw code is here explanation of what I need help with is here
d.js docs
d.js docs4mo ago
If you aren't getting any errors, try to place console.log checkpoints throughout your code to find out where execution stops. - Once you do, log relevant values and if-conditions - More sophisticated debugging methods are breakpoints and runtime inspections: learn more
infinitygl
infinitygl4mo ago
@Squid where should I put console.log checkpoints and how to should I implement this
Squid
Squid4mo ago
you saying that your buttons are "not working" is way too vague are the buttons getting sent? is the collector collecting the button interactions? does your vote map contain the scenario? are the new options being pushed to the vote map? is the collector's end event properly emitting, and if so, how far in it does your code run? Find out exactly where your code stops working by seeing when a basic console log doesnt appear
infinitygl
infinitygl4mo ago
to be honest with you i don't know js at all i used ai to code this lol it Says interaction failed on the discord server and then "Invalid button interaction: missing data" in the terminal im hosting it but I want it to work
Squid
Squid4mo ago
ok ill go tell the ai how to fix things
infinitygl
infinitygl4mo ago
you will?
Squid
Squid4mo ago
if you don't know how to code, i wont be able to explain things in a way youd understand you're expected to come into djs with a basic JS proficiency re #rules
infinitygl
infinitygl4mo ago
okay i was using gemini google ai btw and its somewhat understandable i have basic coding knowledge just not js i can understand the code thoughh if i look through it kind of
Squid
Squid4mo ago
the AI is making up properties that dont actually exist you should use the official documentation and guide to see what does exist, and base your logic around that
infinitygl
infinitygl4mo ago
Send the official documentation I’ll take a look
Squid
Squid4mo ago
Its at the top of #resources