Interactions overlapping? (I don't know what even happening anymore)

I have command that sends a ephemeral message with buttons, and then using message collector to get response from buttons.
const componentCollector = message.channel.createMessageComponentCollector({
filter: (int) => (int.user.id === interaction.user.id),
componentType: ComponentType.Button,
time: 60_000,
message,
max: 1,
})
const componentCollector = message.channel.createMessageComponentCollector({
filter: (int) => (int.user.id === interaction.user.id),
componentType: ComponentType.Button,
time: 60_000,
message,
max: 1,
})
I have a function that handles response:
componentCollector.on("collect", (buttonInteraction) => {
handleSelectedConvertType(buttonInteraction, interaction) // interaction - is initial interaction that comes when user executed /command
componentCollector.stop("collected")
})
componentCollector.on("collect", (buttonInteraction) => {
handleSelectedConvertType(buttonInteraction, interaction) // interaction - is initial interaction that comes when user executed /command
componentCollector.stop("collected")
})
In this function i'm getting options that user provide when executed /command, and creating some embeds with description Problem is here:
randomSelectedEmbed.description = randomSelectedEmbed.description.replace(
"%link%",
initialInteraction.user.toString()
)
randomSelectedEmbed.description = randomSelectedEmbed.description.replace(
"%link%",
initialInteraction.user.toString()
)
And somehow if two users manage to click button on the same time initialInteraction.user.toString() will be not what we expect. For example: I clicked button and should see in response my mention, but I see mention of my friend that manage to click it on the same time If I use buttonInteraction instead - all works fine. But i'm curious why initialInetraction picking up different user
33 Replies
d.js toolkit
d.js toolkit11mo 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
secre
secreOP11mo ago
In this example bot place mention of me instead of my friend. But I was doing literally NOTHING. I guess here problem with cache or maybe intents? Because I have no idea how bot picking up random people :DEAD:
d.js docs
d.js docs11mo ago
Tag suggestion for @secre: If you are waiting for button or select menu input from a specific message, don't create the collector on the channel. - Channel collectors return component interactions for any component within that channel.
- <Channel>.createMessageComponentCollector(…)
+ <Message>.createMessageComponentCollector(…)
- <Channel>.createMessageComponentCollector(…)
+ <Message>.createMessageComponentCollector(…)
secre
secreOP11mo ago
For more context callback for interactionCreate event
function handleCommand(interaction: ChatInputCommandInteraction) {
const commandName = interaction.commandName
const foundCommand = commands.find(({ name }) => name === commandName)

if (!foundCommand) return

foundCommand.exec(interaction)
}
function handleCommand(interaction: ChatInputCommandInteraction) {
const commandName = interaction.commandName
const foundCommand = commands.find(({ name }) => name === commandName)

if (!foundCommand) return

foundCommand.exec(interaction)
}
and intents that I'm currently using const client = new Client({ intents: [IntentsBitField.Flags.Guilds] }) Changed to that, and same bug appears anyways :)
Amgelo
Amgelo11mo ago
probably why you're getting "random people", it's picking interactions from other components share your updated code
secre
secreOP11mo ago
On this example noone was executing command
const componentCollector = message.createMessageComponentCollector({
filter: (int) => int.user.id === interaction.user.id,
componentType: ComponentType.Button,
time: 60_000,
max: 1,
})
const componentCollector = message.createMessageComponentCollector({
filter: (int) => int.user.id === interaction.user.id,
componentType: ComponentType.Button,
time: 60_000,
max: 1,
})
the message:
const message = await interaction.deferReply({
ephemeral: true,
fetchReply: true,
})
const message = await interaction.deferReply({
ephemeral: true,
fetchReply: true,
})
Amgelo
Amgelo11mo ago
can you share your "handleSelectedConvertType"?
secre
secreOP11mo ago
async function handleSelectedConvertType(
interaction: ButtonInteraction,
initialInteraction: ChatInputCommandInteraction
) {
await interaction.deferReply({ ephemeral: true })

const moderationChannel = await interaction.guild?.channels.fetch(
process.env.APPROV_CHANNEL_ID!
)

if (!moderationChannel || moderationChannel.type !== ChannelType.GuildText) {
return interaction.editReply({
content: "Ой.. произошла ошибка во время выполнения команды...",
})
}

const valentineText = initialInteraction.options.getString("текст", true)
const attachment = initialInteraction.options.getAttachment("картинка")
const user = initialInteraction.options.getUser("юзер", true)

const randomSelectedEmbed = getRandomResponse()

randomSelectedEmbed.description = randomSelectedEmbed.description.replace(
"%link%",
initialInteraction.user.toString()
)

const buildedEmbed = new EmbedBuilder(randomSelectedEmbed).setColor("#2b2d31")

const moderationEmbed = new EmbedBuilder()
.setDescription(valentineText)
.setFooter({
text: `${getConvertType(interaction.customId)} ${initialInteraction.user.id} ${
user.id
}`,
})
.setColor("#2b2d31")
.setAuthor({
name: initialInteraction.user.username,
iconURL: initialInteraction.user.displayAvatarURL(),
})

if (attachment) {
moderationEmbed.setImage(attachment.url)
}

interaction.editReply({ embeds: [buildedEmbed] }).catch((err) => {
console.log("Ошибка во время попытки ответить на выбор конверта", err)
})

moderationChannel
.send({
embeds: [moderationEmbed],
components: [createModerationRow()],
})
.catch((err) => {
console.log(`Ошибка во время отправки валентинки на модерацию`, err)
})
}
async function handleSelectedConvertType(
interaction: ButtonInteraction,
initialInteraction: ChatInputCommandInteraction
) {
await interaction.deferReply({ ephemeral: true })

const moderationChannel = await interaction.guild?.channels.fetch(
process.env.APPROV_CHANNEL_ID!
)

if (!moderationChannel || moderationChannel.type !== ChannelType.GuildText) {
return interaction.editReply({
content: "Ой.. произошла ошибка во время выполнения команды...",
})
}

const valentineText = initialInteraction.options.getString("текст", true)
const attachment = initialInteraction.options.getAttachment("картинка")
const user = initialInteraction.options.getUser("юзер", true)

const randomSelectedEmbed = getRandomResponse()

randomSelectedEmbed.description = randomSelectedEmbed.description.replace(
"%link%",
initialInteraction.user.toString()
)

const buildedEmbed = new EmbedBuilder(randomSelectedEmbed).setColor("#2b2d31")

const moderationEmbed = new EmbedBuilder()
.setDescription(valentineText)
.setFooter({
text: `${getConvertType(interaction.customId)} ${initialInteraction.user.id} ${
user.id
}`,
})
.setColor("#2b2d31")
.setAuthor({
name: initialInteraction.user.username,
iconURL: initialInteraction.user.displayAvatarURL(),
})

if (attachment) {
moderationEmbed.setImage(attachment.url)
}

interaction.editReply({ embeds: [buildedEmbed] }).catch((err) => {
console.log("Ошибка во время попытки ответить на выбор конверта", err)
})

moderationChannel
.send({
embeds: [moderationEmbed],
components: [createModerationRow()],
})
.catch((err) => {
console.log(`Ошибка во время отправки валентинки на модерацию`, err)
})
}
Damn my I should upload it to pastebin or something? It's a bit large in here :DEAD:
Amgelo
Amgelo11mo ago
we're on a thread so ig it's fine
secre
secreOP11mo ago
I sent you code where I already changed initialInteraction to interaction, edited it to be more correct with info I provided Testing code with buttonInteraction that we receive in collector, and it putting different user anyway, lol
secre
secreOP11mo ago
I have this embed in moderation channel that as you can see getting ids, name, avatar from initiailInteraction and ids are correct, avatar and username correct too but in response embed it's different :Starege:
No description
Amgelo
Amgelo11mo ago
the only thing that comes to mind is an issue by passing the reference instead of a copy of your "random embed" could be solved with
const newDescription = randomSelectedEmbed.description.replace(
"%link%",
initialInteraction.user.toString()
)

const buildedEmbed = new EmbedBuilder(randomSelectedEmbed).setDescription(newDescription).setColor("#2b2d31")
const newDescription = randomSelectedEmbed.description.replace(
"%link%",
initialInteraction.user.toString()
)

const buildedEmbed = new EmbedBuilder(randomSelectedEmbed).setDescription(newDescription).setColor("#2b2d31")
instead of directly editing randomSelectedEmbed
secre
secreOP11mo ago
But how it can be a problem? I will test your example fs but I can't understand why :yM_kekw: Let me show you example of those "embeds"
{
"description": `%link%, __Ваша__ валентинка получена, топаем к пункту распределения! ${process.env.RESPONSE_EMOJI}`,
"footer": { "text": "Отделение Yume №3 → Проверка → Валентинки." },
"thumbnail": { "url": "https://i.imgur.com/xntg0cd.png" },
},
{
"description": `%link%, __Ваша__ валентинка получена, топаем к пункту распределения! ${process.env.RESPONSE_EMOJI}`,
"footer": { "text": "Отделение Yume №3 → Проверка → Валентинки." },
"thumbnail": { "url": "https://i.imgur.com/xntg0cd.png" },
},
that's one of them. simple object of embed with %link% to put mention in the future
Amgelo
Amgelo11mo ago
it would depend on how your getRandomResponse() actually works but you could try just in case if not no idea, maybe someone else could help try logging and see where it fails down the line ig
secre
secreOP11mo ago
export function getRandomResponse() {
return RESPONSES[Math.floor(Math.random() * RESPONSES.length)]
}
export function getRandomResponse() {
return RESPONSES[Math.floor(Math.random() * RESPONSES.length)]
}
I logging IDS and ITS all the way correct :KEKL: Just embed description where everything breaks
secre
secreOP11mo ago
Here my friend executed command 5 times, and 4 times he saw mention of me instead of him in response :yM_kekw: But as you can see here is no ID of mine
No description
secre
secreOP11mo ago
weird thing
Amgelo
Amgelo11mo ago
yeah that seems to be passing a reference instead of a copy if you pass a reference, you're directly editing your responses object so your random embed would now be
{
"description": `<@shysecre>, __Ваша__ валентинка получена, топаем к пункту распределения! ${process.env.RESPONSE_EMOJI}`,
"footer": { "text": "Отделение Yume №3 → Проверка → Валентинки." },
"thumbnail": { "url": "https://i.imgur.com/xntg0cd.png" },
},
{
"description": `<@shysecre>, __Ваша__ валентинка получена, топаем к пункту распределения! ${process.env.RESPONSE_EMOJI}`,
"footer": { "text": "Отделение Yume №3 → Проверка → Валентинки." },
"thumbnail": { "url": "https://i.imgur.com/xntg0cd.png" },
},
secre
secreOP11mo ago
Oh wait :Deadge:
Amgelo
Amgelo11mo ago
https://www.geeksforgeeks.org/pass-by-value-and-pass-by-reference-in-javascript/
In Pass by Reference, Function is called by directly passing the reference/address of the variable as an argument. So changing the value inside the function also change the original value. In JavaScript array and Object follows pass by reference property.
GeeksforGeeks
Pass by Value and Pass by Reference in Javascript - GeeksforGeeks
A Computer Science portal for geeks. It contains well written, well thought and well explained computer science and programming articles, quizzes and practice/competitive programming/company interview Questions.
Amgelo
Amgelo11mo ago
you could solve it by doing this or passing a shallow copy in your getRandomResponse instead
d.js docs
d.js docs11mo ago
:mdn: Shallow copy A shallow copy of an object is a copy whose properties share the same references (point to the same underlying values) as those of the source object from which the copy was made. As a result, when you change either the source or the copy, you may also cause the other object to change too. That behavior contrasts with the behavior of a deep copy, in which the source and copy are completely independent.
Amgelo
Amgelo11mo ago
a shallow copy would work unless you also edit your footer objects (since it's nested), for that you'd need a deep copy could also do this instead
export function getRandomResponse() {
return new EmbedBuilder(RESPONSES[Math.floor(Math.random() * RESPONSES.length)])
}
export function getRandomResponse() {
return new EmbedBuilder(RESPONSES[Math.floor(Math.random() * RESPONSES.length)])
}
secre
secreOP11mo ago
What a newbie mistake goddammit :Deadge: Thanks, will fix
Amgelo
Amgelo11mo ago
I don't blame you much since I also had a dumb issue like that once lol
secre
secreOP11mo ago
I guess we all had problems like this xd
Amgelo
Amgelo11mo ago
it also messed up my brain for a while
Amgelo
Amgelo11mo ago
I think this is the easiest way since you don't need to remember to make a copy every time or something
A cup of tea "Richard"
I was the one who tested this problem with him. I knew something was wrong with getRandomResponse() function 😭 It also was the promblem who didn't showed up immediatly, because we have like 3 messages in random pool. So somitems it can just take two different ones and it will work like a charm 💀
Amgelo
Amgelo11mo ago
:kek:
A cup of tea "Richard"
Anyway thank u man for helping us fix this problem 🤝
Amgelo
Amgelo11mo ago
np :blobreachReverse:
Want results from more Discord servers?
Add your server