I have a bot that has a slash command that sends a message to a different channel than the one the command is on. The message has two buttons and when the button is pressed, it should console.log
the name of the user who clicked the button. Here is the entire slash command file:
const { SlashCommandBuilder, ButtonBuilder, ButtonStyle, ActionRowBuilder, ComponentType } = require('discord.js'); const { teamList } = require('../teamList'); const { Client, GatewayIntentBits } = require('discord.js'); const { token } = require('../config.json'); // 创建一个新的客户端实例 const client = new Client({ intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages, GatewayIntentBits.GuildMessageReactions] }); client.login(token); module.exports = { data: new SlashCommandBuilder() .setName('newaddgame') .setDescription('设置下注游戏。') .addStringOption(option => option.setName('team1') .setDescription('队伍1') .setRequired(true) .addChoices( { name: 'Bilibili Gaming', value: 'Bilibili Gaming'}, { name: 'JDG Gaming', value: 'JDG Gaming'}, { name: 'Gen.G', value: 'Gen.G'}, { name: 'T1', value: 'T1'}, { name: 'Cloud9', value: 'Cloud9'}, { name: 'Golden Guardians', value: 'Golden Guardians'}, { name: 'G2 Esports', value: 'G2 Esports'}, )) .addStringOption(option => option.setName('team2') .setDescription('队伍2') .setRequired(true) .addChoices( { name: 'Bilibili Gaming', value: 'Bilibili Gaming'}, { name: 'JDG Gaming', value: 'JDG Gaming'}, { name: 'Gen.G', value: 'Gen.G'}, { name: 'T1', value: 'T1'}, { name: 'Cloud9', value: 'Cloud9'}, { name: 'Golden Guardians', value: 'Golden Guardians'}, { name: 'G2 Esports', value: 'G2 Esports'}, )), async execute(interaction) { // 设置队伍信息 const team1 = interaction.options.getString('team1'); const team2 = interaction.options.getString('team2'); const teamArray = [team1, team2]; let teamMessage1 = ''; let teamMessage2 = ''; const team1Info = teamList.find(team => team.name === teamArray[0]); const team2Info = teamList.find(team => team.name === teamArray[1]); teamMessage1 = team1Info.emoji + ' ' + team1Info.name; teamMessage2 = team2Info.name + ' ' + team2Info.emoji; // 创建按钮 const team1Button = new ButtonBuilder() .setCustomId('team1Button') // .setLabel(team1Info.name) .setStyle(ButtonStyle.Secondary) .setEmoji(team1Info.emoji); const team2Button = new ButtonBuilder() .setCustomId('team2Button') // .setLabel(team2Info.name) .setStyle(ButtonStyle.Secondary) .setEmoji(team2Info.emoji); const row = new ActionRowBuilder() .addComponents(team1Button, team2Button); // 发送消息并添加按钮 await interaction.reply({content: '游戏已发布。', fetchReply: true}); const message2 = await client.channels.cache.get('1077612967639666738').send({ content: teamMessage1 + ' 对 ' + teamMessage2, components: [row], }); const collector = message2.createMessageComponentCollector({ componentType: ComponentType.StringSelect, time: 3_600_000 }); collector.on('collect', async i => { const selection = i.values[0]; console.log(`${i.user} 选择了 ${selection}!`); }); }, };
However, here’s the point:
// 发送消息并添加按钮 await interaction.reply({content: '游戏已发布。', fetchReply: true}); const message2 = await client.channels.cache.get('1077612967639666738').send({ content: teamMessage1 + ' 对 ' + teamMessage2, components: [row], }); const collector = message2.createMessageComponentCollector({ componentType: ComponentType.StringSelect, time: 3_600_000 }); collector.on('collect', async i => { const selection = i.values[0]; console.log(`${i.user} 选择了 ${selection}!`); });
Now when I press one of the message buttons, in Discord it just says "This interaction failed", but there are no errors in the console and the bot doesn't crash. It just does nothing. I've been following the documentation here: https://discordjs.guide/message-components/interactions.html#awaiting-components.
I'm wondering if it's because I'm collecting on a message
and not on a response
like in the documentation. But can you really only collect on the response? This doesn't seem right. What did i do wrong?
Your interaction fails because you are collecting a StringSelectMenu component, not a Button.
Please change the following lines:
change to:
To collect buttons, use
i.customId
.Reference: ComponentType