Using collector.on('end') to edit reply?

I'm trying to create a polling bot that edits their reply once the poll has concluded, but i can't figure out how to do that, and was wondering if anyone had any advice? I'm not sure if I should figure out a way to do it through collector.on('collect') or if there is a way to do it with collector.on('end'). If the right way to do it is through collector.on('collect'), i'm not sure if i can combine a switch statement with an await 60 _ 000 to update the message when the timer has ticked down
22 Replies
d.js toolkit
d.js toolkit3mo 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! - Marked as resolved by OP
Penitent
Penitent3mo ago
collector.on('collect', i => {
console.log('Hello from the collector');
if (voters.has(i.user.id)) {
i.reply({content: `You've already voted on this poll!`, ephemeral: true});
}
else {
voters.add(i.user.id);
switch(i.customId){
case 'firstChoiceButton':
votes.firstChoice = votes.firstChoice += 1;
votes.total = votes.total += 1;
console.log(votes);
i.update({embeds: [createPollEmbed(votes)], components: [row], fetchReply: true})
break;
case 'secondChoiceButton':
votes.secondChoice = votes.secondChoice += 1;
votes.total = votes.total += 1;
console.log(votes);
i.update({embeds: [createPollEmbed(votes)], components: [row], fetchReply: true})
break;
case 'thirdChoiceButton':
votes.thirdChoice = votes.thirdChoice += 1;
votes.total = votes.total += 1;
console.log(votes);
i.update({embeds: [createPollEmbed(votes)], components: [row], fetchReply: true})
}
}
});
collector.on('end', i => {
console.log(`${i} has ended`)
})
collector.on('collect', i => {
console.log('Hello from the collector');
if (voters.has(i.user.id)) {
i.reply({content: `You've already voted on this poll!`, ephemeral: true});
}
else {
voters.add(i.user.id);
switch(i.customId){
case 'firstChoiceButton':
votes.firstChoice = votes.firstChoice += 1;
votes.total = votes.total += 1;
console.log(votes);
i.update({embeds: [createPollEmbed(votes)], components: [row], fetchReply: true})
break;
case 'secondChoiceButton':
votes.secondChoice = votes.secondChoice += 1;
votes.total = votes.total += 1;
console.log(votes);
i.update({embeds: [createPollEmbed(votes)], components: [row], fetchReply: true})
break;
case 'thirdChoiceButton':
votes.thirdChoice = votes.thirdChoice += 1;
votes.total = votes.total += 1;
console.log(votes);
i.update({embeds: [createPollEmbed(votes)], components: [row], fetchReply: true})
}
}
});
collector.on('end', i => {
console.log(`${i} has ended`)
})
for reference this is my code
Spaxter
Spaxter3mo ago
You can just set the timeout to 60000 and use
collector.on('end', (i, reason) => {
if (reason === 'time') {
// Edit your reply here
}
});
collector.on('end', (i, reason) => {
if (reason === 'time') {
// Edit your reply here
}
});
Penitent
Penitent3mo ago
yuh but i tried doing i.update(0) and i.editReply() but both give me an error i shouldve mentioned that my bad
Spaxter
Spaxter3mo ago
"an error" is pretty vague. What error did you get?
Penitent
Penitent3mo ago
neither i.update() nor i.editReply() are actual functions, and im pretty sure its cause i is an object map
Spaxter
Spaxter3mo ago
You should edit the original interaction of the command instead, I don't believe the 'end' event callback has an interaction since the collector has ended
Penitent
Penitent3mo ago
fair point, i have this line which sends the original embed: const response = await modalSubmission.reply({ embeds: [createPollEmbed(votes)], components: [row], fetchReply: true }); and i tried updating it with response.editReply, but that is also apparently not a valid function (i got editReply from this: https://discordjs.guide/slash-commands/response-methods.html#ephemeral-responses)
discord.js Guide
Imagine a guide... that explores the many possibilities for your discord.js bot.
Penitent
Penitent3mo ago
also if i try interaction.editreply " throw new DiscordAPIError(data, "code" in data ? data.code : data.error, status, method, url, requestData); ^ DiscordAPIError[10008]: Unknown Message"
duck
duck3mo ago
1. just making sure you're aware that the native polls beta launched last week https://discord.com/channels/222078108977594368/992166350640386090/1220461677364117626 2. the end event does emit with a Collection of the collected items, so it does contain the previous interactions you'd need to pick one (<Collection>.first() just being the first one if it doesn't matter)
Penitent
Penitent3mo ago
i did not know about native polls 😅 i'll def take a look the collected items are interactions to buttons i really only wanna edit the message itself
Penitent
Penitent3mo ago
No description
Penitent
Penitent3mo ago
I wanna take this message and update it with saying "the poll has ended, B has the most votes with 100% of the votes" or something like that
duck
duck3mo ago
yes, but while i.editReply() doesn't exist because i is a Collection, <ButtonInteraction>.editReply() does exist
Penitent
Penitent3mo ago
ahhh okay, that makes sense, so then it would be i.first().editReply()?
duck
duck3mo ago
assuming it does collect an interaction, yes
Penitent
Penitent3mo ago
ahhh it works! however it doesnt remove the embed
Penitent
Penitent3mo ago
just leaves me like this for some reason:
No description
duck
duck3mo ago
are you passing an empty array for embeds? care to share your updated code?
Penitent
Penitent3mo ago
const response = await modalSubmission.reply({ embeds: [createPollEmbed(votes)], components: [row], fetchReply: true });

const collector = response.createMessageComponentCollector({ componentType: ComponentType.Button, time: 5_000 });

collector.on('collect', i => {
if (voters.has(i.user.id)) {
i.reply({content: `You've already voted on this poll!`, ephemeral: true});
}
else {
voters.add(i.user.id);
switch(i.customId){
case 'firstChoiceButton':
votes.firstChoice = votes.firstChoice += 1;
votes.total = votes.total += 1;
console.log(votes);
i.update({embeds: [createPollEmbed(votes)], components: [row], fetchReply: true})
break;
case 'secondChoiceButton':
votes.secondChoice = votes.secondChoice += 1;
votes.total = votes.total += 1;
console.log(votes);
i.update({embeds: [createPollEmbed(votes)], components: [row], fetchReply: true})
break;
case 'thirdChoiceButton':
votes.thirdChoice = votes.thirdChoice += 1;
votes.total = votes.total += 1;
console.log(votes);
i.update({embeds: [createPollEmbed(votes)], components: [row], fetchReply: true})
}
}

});
collector.on('end', i => {
i.first().editReply({content: 'hello'})
})
const response = await modalSubmission.reply({ embeds: [createPollEmbed(votes)], components: [row], fetchReply: true });

const collector = response.createMessageComponentCollector({ componentType: ComponentType.Button, time: 5_000 });

collector.on('collect', i => {
if (voters.has(i.user.id)) {
i.reply({content: `You've already voted on this poll!`, ephemeral: true});
}
else {
voters.add(i.user.id);
switch(i.customId){
case 'firstChoiceButton':
votes.firstChoice = votes.firstChoice += 1;
votes.total = votes.total += 1;
console.log(votes);
i.update({embeds: [createPollEmbed(votes)], components: [row], fetchReply: true})
break;
case 'secondChoiceButton':
votes.secondChoice = votes.secondChoice += 1;
votes.total = votes.total += 1;
console.log(votes);
i.update({embeds: [createPollEmbed(votes)], components: [row], fetchReply: true})
break;
case 'thirdChoiceButton':
votes.thirdChoice = votes.thirdChoice += 1;
votes.total = votes.total += 1;
console.log(votes);
i.update({embeds: [createPollEmbed(votes)], components: [row], fetchReply: true})
}
}

});
collector.on('end', i => {
i.first().editReply({content: 'hello'})
})
function createPollEmbed(){
console.log(votes)

const pollEmbed = new EmbedBuilder()
.setColor(0x0099FF)
.setTitle(pollTitle)
.setDescription('Choose one of the following options')
.addFields(
{ name: '\u200B', value: `${firstChoice} - ${calculatePercentage(votes.firstChoice, votes.total)}
${':blue_square:'.repeat(calculateNumSquares(votes.firstChoice, votes.total))}${':black_large_square:'.repeat((10 - calculateNumSquares(votes.firstChoice, votes.total)))}
${secondChoice} - ${calculatePercentage(votes.secondChoice, votes.total)}
${':blue_square:'.repeat(calculateNumSquares(votes.secondChoice, votes.total))}${':black_large_square:'.repeat((10 - calculateNumSquares(votes.secondChoice, votes.total)))}
${thirdChoice} - ${calculatePercentage(votes.thirdChoice, votes.total)}
${':blue_square:'.repeat(calculateNumSquares(votes.thirdChoice, votes.total))}${':black_large_square:'.repeat((10 - calculateNumSquares(votes.thirdChoice, votes.total)))}` },
);
return pollEmbed;
}
function createPollEmbed(){
console.log(votes)

const pollEmbed = new EmbedBuilder()
.setColor(0x0099FF)
.setTitle(pollTitle)
.setDescription('Choose one of the following options')
.addFields(
{ name: '\u200B', value: `${firstChoice} - ${calculatePercentage(votes.firstChoice, votes.total)}
${':blue_square:'.repeat(calculateNumSquares(votes.firstChoice, votes.total))}${':black_large_square:'.repeat((10 - calculateNumSquares(votes.firstChoice, votes.total)))}
${secondChoice} - ${calculatePercentage(votes.secondChoice, votes.total)}
${':blue_square:'.repeat(calculateNumSquares(votes.secondChoice, votes.total))}${':black_large_square:'.repeat((10 - calculateNumSquares(votes.secondChoice, votes.total)))}
${thirdChoice} - ${calculatePercentage(votes.thirdChoice, votes.total)}
${':blue_square:'.repeat(calculateNumSquares(votes.thirdChoice, votes.total))}${':black_large_square:'.repeat((10 - calculateNumSquares(votes.thirdChoice, votes.total)))}` },
);
return pollEmbed;
}
its an array of only 1 element
duck
duck3mo ago
not sure what you mean by it's an array of only 1 element to remove all embeds from a message when editing, you should pass an empty array for embeds it does not edit properties you don't specify
Penitent
Penitent3mo ago
ahh sorry i misunderstood i thought you were asking if in the initial interaction i was passing an empty array for embeds and then populating sorry got it, it works now! thanks @duck