My bot only replies undefined with two variables, although I actually defined them.
I dont know why it not works pls help
The command is: you press the button enter a reason and a game in the text input field and then you select a platform from the drop down menu. But instead of sending the embed it says undefined.
My Code:
const Discord = require('discord.js')
const Command = require('../../structures/CommandClass');
const { stripIndents } = require('common-tags');
const { SlashCommandBuilder, PermissionFlagsBits, EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle, TextInputStyle, StringSelectMenuBuilder, Events, ModalBuilder, TextInputBuilder } = require('discord.js');
module.exports = class spielersuche extends Command {
constructor(client) {
super(client, {
data: new SlashCommandBuilder()
.setName('sendspielersuche')
.setDescription('Sende das Spielersuche Embed')
.setDefaultMemberPermissions(PermissionFlagsBits.BanMembers)
.setDMPermission(false),
});
}
async run(client, interaction) {
let member = await interaction.member.fetch();
const anfragechannelID = '889302458906591344';
const anfragechannel = member.guild.channels.cache.get(anfragechannelID);
const createanfragechannelID = '1061113274130772058';
const createanfragechannel = member.guild.channels.cache.get(createanfragechannelID);
const pfmenü = new ActionRowBuilder()
.addComponents(
new StringSelectMenuBuilder()
.setCustomId('pfmenü')
.setPlaceholder('Plattform auswählen')
.addOptions(
{
label: 'PS4',
value: 'ps4',
},
{
label: 'PS5',
value: 'ps5',
},
{
label: 'PS4/PS5',
value: 'ps4ps5',
},
{
label: 'PC',
value: 'pc',
},
{
label: 'Switch',
value: 'switch',
},
{
label: 'Alle',
value: 'alle',
},
),
);
const modals = new ModalBuilder()
.setCustomId('minput')
.setTitle('Spielersuche 🔎');
const spielinput = new TextInputBuilder()
.setCustomId('spielinput')
.setLabel("Für welches Spiel?")
.setPlaceholder('GTA5, Fortnite, Call of Duty, Minecraft ...')
.setStyle(TextInputStyle.Short)
.setMinLength(2)
.setMaxLength(20)
.setRequired(true);
const grundinput = new TextInputBuilder()
.setCustomId('grundinput')
.setLabel("Der Grund der Anfrage?")
.setPlaceholder('Beispiel: Suche Spieler für Cayo Perico Heist.')
.setStyle(TextInputStyle.Short)
.setMinLength(10)
.setMaxLength(60)
.setRequired(true);
const firstActionRow = new ActionRowBuilder().addComponents(spielinput);
const secondActionRow = new ActionRowBuilder().addComponents(grundinput);
modals.addComponents(firstActionRow, secondActionRow);
const spielersucheerweitertEmbed = new EmbedBuilder()
.setTitle(`Spieler suchen Spieler 🔎`)
.setColor('#00ff0c')
.setDescription(stripIndents`Drücke auf denn Button um eine Spielersuche Anzufragen!`)
.setFooter({ text: 'YANKEEUNIT91 COMMUNITY'})
.setTimestamp();
const buttonsa = new ActionRowBuilder()
.addComponents(
new ButtonBuilder()
.setCustomId('buttonanfrage')
.setEmoji('🔎')
.setLabel('Spielersuche Anfragen')
.setStyle(ButtonStyle.Success),
);
client.on('interactionCreate', async interaction => {
if (interaction.isButton()) {
const buttonID = interaction.customId
if (buttonID === 'buttonanfrage') {
await interaction.showModal(modals);
}
}
});
createanfragechannel.send({ embeds: [spielersucheerweitertEmbed], components: [buttonsa] });
await interaction.reply({ content: 'Spielersuche Embed wurde versendet!', ephemeral: true });
client.on(Events.InteractionCreate, async (interaction) => {
if (interaction.isModalSubmit()) {
if (interaction.customId === "minput") {
await interaction.reply({ content:'**Wähle deine Plattform!**', components: [pfmenü], ephemeral: true });
var ginputdata = interaction.fields.getTextInputValue('grundinput');
var sinputdata = interaction.fields.getTextInputValue('spielinput');
}
} else if (interaction.isStringSelectMenu()) {
const selected = await interaction.values.join(', ');
const spielersucheerweitertEmbedfertig = new EmbedBuilder()
.setTitle(`${ginputdata}`)
.setColor('#00ff0c')
.setFooter({ text: 'YANKEEUNIT91 COMMUNITY'})
.setTimestamp()
.addFields(
{
name: '**Spiel:**',
value: `${sinputdata}`,
inline: true,
},
{
name: `**Plattform:**:`,
value: `${selected}`,
inline: false,
},
);
if (interaction.customId === "pfmenü") {
const member = await interaction.member.fetch();
await interaction.update({ content:'**Spielersuche erfolgreich Angefragt!**', components: [], ephemeral: true });
return await anfragechannel.send({ content: `**Anfrage von:** <#${member.id}>`, embeds: [spielersucheerweitertEmbedfertig] });
}
};
});
}
};
tried to define something else but it didn't work
You should focus on where your variables is saved. The variable sinputdata is saved inside the function. The function is like a piece of code that is extracted from the file and ran without really saving variables inside of the function. So every time the function is ran, all your variables are reset.
In other words, you need to save the data you want to keep outside of the function. Therefore, you should make a table at the beginning of your module. Every functions inside the module will be able to edit the table and read the values of it. In addition, everything will be saved (I mean, if you reload the bot, every data will be lost so you need to save everything in a database). Back to the table, the table will include the discordid and the sinputdata value. First, you will set the sinputdata value in the table when you receive it. Then, you will be able to use the sinputdata value when the function is ran a new time.
At the top (under const { SlashCommandBuilder, PermissionFlagsBits, EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle, TextInputStyle, StringSelectMenuBuilder, Events, ModalBuilder, TextInputBuilder } = require('discord.js');), write let sinputvalues = {};
Then, instead of var sinputdata = interaction.fields.getTextInputValue('spielinput');, write sinputvalues[interaction.user.id] = interaction.fields.getTextInputValue('spielinput');.
Finally, replace
{
name: '**Spiel:**',
value: `${sinputdata}`,
inline: true,
},
to
{
name: '**Spiel:**',
value: `${sinputvalues[interaction.user.id]}`,
inline: true,
},
Related
Respons Picture
Hi my Bot always replies one more message, The command works you press the button enter a reason in the text input field and then you select a platform from the drop down menu. But instead of sending the embed once, it sends it multiple times each time.
Error: Error [InteractionAlreadyReplied]: The reply to this interaction has already been sent or deferred.
Or: "Interaction has already been acknowledged."
const Discord = require('discord.js')
const Command = require('../../structures/CommandClass');
const { stripIndents } = require('common-tags');
const { SlashCommandBuilder, PermissionFlagsBits, EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle, TextInputStyle, StringSelectMenuBuilder, Events, ModalBuilder, TextInputBuilder } = require('discord.js');
module.exports = class spielersucheerweitert extends Command {
constructor(client) {
super(client, {
data: new SlashCommandBuilder()
.setName('sendspielersuche')
.setDescription('Sende das Spielersuche Embed')
.setDefaultMemberPermissions(PermissionFlagsBits.BanMembers)
.setDMPermission(false),
});
}
async run(client, interaction) {
let member = await interaction.member.fetch();
const pfmenü = new ActionRowBuilder()
.addComponents(
new StringSelectMenuBuilder()
.setCustomId('pfmenü')
.setPlaceholder('Plattform auswählen')
.addOptions(
{
label: 'PS4',
value: 'ps4',
},
{
label: 'PS5',
value: 'ps5',
},
{
label: 'PS4/PS5',
value: 'ps4ps5',
},
{
label: 'PC',
value: 'pc',
},
{
label: 'Switch',
value: 'switch',
},
{
label: 'Alle',
value: 'alle',
},
),
);
const modals = new ModalBuilder()
.setCustomId('minput')
.setTitle('Spielersuche 🔎');
const spielinput = new TextInputBuilder()
.setCustomId('spielinput')
.setLabel("Für welches Spiel?")
.setPlaceholder('GTA5, Fortnite, Call of Duty, Minecraft ...')
.setStyle(TextInputStyle.Short)
.setMinLength(2)
.setMaxLength(20)
.setRequired(true);
const grundinput = new TextInputBuilder()
.setCustomId('grundinput')
.setLabel("Der Grund der Anfrage?")
.setPlaceholder('Beispiel: Suche Spieler für Cayo Perico Heist.')
.setStyle(TextInputStyle.Short)
.setMinLength(10)
.setMaxLength(60)
.setRequired(true);
const firstActionRow = new ActionRowBuilder().addComponents(spielinput);
const secondActionRow = new ActionRowBuilder().addComponents(grundinput);
modals.addComponents(firstActionRow, secondActionRow);
const spielersucheerweitertEmbed = new EmbedBuilder()
.setTitle(`Spieler suchen Spieler 🔎`)
.setColor('#00ff0c')
.setDescription(stripIndents`Drücke auf denn Button um eine Spielersuche Anzufragen!`)
.setFooter({ text: 'YANKEEUNIT91 COMMUNITY'})
.setTimestamp();
const buttonsa = new ActionRowBuilder()
.addComponents(
new ButtonBuilder()
.setCustomId('buttonanfrage')
.setEmoji('🔎')
.setLabel('Spielersuche Anfragen')
.setStyle(ButtonStyle.Success),
);
client.on('interactionCreate', async interaction => {
if (interaction.isButton()) {
const buttonID = interaction.customId
if (buttonID === 'buttonanfrage') {
await interaction.showModal(modals);
}
}
});
client.on('interactionCreate', (modalSubmit) => {
if (!modalSubmit.isModalSubmit()) return;
const ginputdata = modalSubmit.fields.getTextInputValue('grundinput');
const sinputdata = modalSubmit.fields.getTextInputValue('spielinput');
modalSubmit.reply({
content:'**Wähle deine Plattform!**', components: [pfmenü], ephemeral: true });
client.on('interactionCreate', async interaction => {
if (!interaction.isStringSelectMenu()) return;
const selected = await interaction.values.join(', ');
const spielersucheerweitertEmbedfertig = new EmbedBuilder()
.setTitle(`${ginputdata}`)
.setColor('#00ff0c')
.setDescription(stripIndents`Spiel: \`${sinputdata}\`
Plattform: \`${selected}\``)
.setFooter({ text: 'YANKEEUNIT91 COMMUNITY'})
.setTimestamp();
await interaction.channel.send({ embeds: [spielersucheerweitertEmbedfertig] });
return await interaction.update({ content: '**Spielersuche wurde erfolgreich Angefragt!**', components: [] });
});
});
await interaction.channel.send({ embeds: [spielersucheerweitertEmbed], components: [buttonsa] });
return await interaction.reply({ content: 'Spielersuche Embed wurde versendet!', ephemeral: true });
}
};
I've looked at the code several times but have no idea why he's doing it more and more often
client.on('interactionCreate', async interaction => {
if (!interaction.isStringSelectMenu()) return;
const selected = await interaction.values.join(', ');
const spielersucheerweitertEmbedfertig = new EmbedBuilder()
.setTitle(`${ginputdata}`)
.setColor('#00ff0c')
.setDescription(stripIndents`Spiel: \`${sinputdata}\`
Plattform: \`${selected}\``)
.setFooter({ text: 'YANKEEUNIT91 COMMUNITY'})
.setTimestamp();
//executed when the button with the buttonanfrage custom ID is clicked
await interaction.channel.send({ embeds: [spielersucheerweitertEmbedfertig] });
return await interaction.update({ content: '**Spielersuche wurde erfolgreich Angefragt!**', components: [] });
});
});
//This block is executed when the function is run
await interaction.channel.send({ embeds: [spielersucheerweitertEmbed], components: [buttonsa] });
return await interaction.reply({ content: 'Spielersuche Embed wurde versendet!', ephemeral: true });
}
The issue you are experiencing is caused by the fact that both of these blocks of code are being executed, which is resulting in the same message and update being sent multiple times.
So you have 2 options:
Remove the second block of code that sends the message and updates
the interaction. This will prevent the message and update from being
sent multiple times.
Add a flag to track whether or not the message and update have
already been sent. You can then check the flag before sending the
message and update to ensure that they are only sent once.
I'm trying to make a draft bot that takes the player amount from an interaction in my draftSize.js file and uses that value in my join.js file as a maximum value for my MessageComponentCollector.
Here is draftSize.js
const { SlashCommandBuilder } = require('#discordjs/builders');
const { MessageActionRow, MessageButton } = require('discord.js');
module.exports = {
data: new SlashCommandBuilder()
.setName('size')
.setDescription('Sets the size of total players in your draft.')
.addIntegerOption(option =>
option.setName('players')
.setDescription('Amount of players participating in the draft.')
.setRequired(true)),
async execute(interaction) {
let playerSize = interaction.options.getInteger('players');
await interaction.reply({ content: `You\'ve selected a ${playerSize} player draft. \n Next, type: ` + "```" + '/captains {#FirstCaptain} {#SecondCaptain}' + "```"});
console.log("test " + playerSize)
},
};
And here is join.js:
const { SlashCommandBuilder } = require('#discordjs/builders');
const { MessageActionRow, MessageButton, Message } = require('discord.js');
const { playerSize } = require('./draftSize');
module.exports = {
data: new SlashCommandBuilder()
.setName('join')
.setDescription('Allow players to join your draft.'),
async execute(interaction, channel) {
const row = new MessageActionRow()
.addComponents(
new MessageButton()
.setCustomId('joinButton')
.setLabel('Join')
.setStyle('SUCCESS'),
);
await interaction.reply({ content: `To join the draft, click the button below. Once the specified player amount has joined, the draft will begin!`, components: [row] });
const filter = i => {
return i.customId === 'joinButton'
};
const playerList = []
const collectChannel = interaction.channel;
const collector = collectChannel.createMessageComponentCollector({
filter,
max: playerSize,
time: 1000 * 30
})
collector.on('collect', (i = MessageComponentInteraction) => {
i.reply({
content: 'you clicked a button',
ephemeral: true
})
console.log(playerSize)
})
collector.on('end', (collection) => {
collection.forEach((click) => {
playerList.push(click.user.username)
})
collectChannel.send({ content: 'testing'})
console.log(playerList);
})
},
};
In my draftSize.js I get my playerSize value, but whenever I try to import the value into my join.js file to use as my collectors max value it always returns undefined.
Sorry if any of this was unclear. Let me know if you need any clarification.
Thanks!
I have been getting an error as mentioned in the title. Whenever I use that command, the bot creates a channel that brings up a select menu, through which the user can "teleport" to another channel while deleting the newly created channel in the process. This code successfully works twice, after which it gives the error. What should be done to fix the error so that the user can use the command as many times as they'd like? I'll work on this code further once the solution is found, but until then, I'm really stumped here. (Questions shall be answered upon questioning; apologies for the messy coding)
module.exports.run = async (client, msg, args) => {
const guild = client.guilds.cache.get('855845132879921214')
const channel = guild.channels.cache.get('959851265456734319')
const newChannel = await msg.guild.channels.create(`teleporter`)
await newChannel.permissionOverwrites.edit(msg.author.id, {
SEND_MESSAGES: false,
VIEW_CHANNEL: true,
})
const {MessageActionRow, MessageSelectMenu, MessageEmbed} = require('discord.js')
const embed = new MessageEmbed()
.setTitle(`Teleporter!`)
.setDescription("Through this interaction, you can now teleport to the main channel of the desired category!")
const row = new MessageActionRow()
.addComponents(
new MessageSelectMenu()
.setCustomId('teleport')
.setPlaceholder('Choose a channel')
.addOptions([
{
label: 'Rules',
description: "Click to check the rules",
value: 'rules',
},
{
label: 'General',
description: "Click to go to the main chat",
value: 'general',
},
{
label: 'Media',
description: "Click to go to media channel",
value: 'media',
},
{
label: 'Bots',
description: "Click to go to the bots channel",
value: 'bots',
}
]),
)
await newChannel.send({content: `<#${msg.author.id}>`,embeds: [embed], components: [row]})
const wait = require('util').promisify
client.on('interactionCreate', async interaction => {
const member = await interaction.guild.members.fetch({
user: interaction.user.id,
force: true
})
if(!interaction.isSelectMenu()) {
interaction.deferUpdate()}
else if (interaction.values == 'general'){
msg.member.roles.add('958421069650337822')
msg.member.roles.remove('943159431800172584')
let tele = msg.guild.channels.cache.find(channel => channel.name == 'teleporter')
tele.delete()
msg.member.roles.add('943159431800172584')
msg.member.roles.remove('958421069650337822')
}
}
)
}
Don't cache.find and delete, do it like;
const newChannel = await client.channels.fetch("id")
newChannel.delete()
This code should be separated with the first section as your command and the second part as a separate listener, so I have coded as such.
const {
MessageActionRow,
MessageSelectMenu,
MessageEmbed,
} = require('discord.js');
module.exports.run = async (client, msg, args) => {
const guild = client.guilds.cache.get('855845132879921214');
const channel = guild.channels.cache.get('959851265456734319');
const newChannel = await msg.guild.channels.create(`teleporter-${msg.author.username}`, {
permissionOverwrites: [{
id: guild.id,
deny: ["VIEW_CHANNEL"],
}, {
id: msg.author,
deny: ["SEND_MESSAGES"],
allow: ["VIEW_CHANNEL"],
}],
});
// In the event that more than one person uses this command at once, you will need to be able to tell the diffrence when you look up the channel later. So I added the username to the channel name.
const embed = new MessageEmbed()
.setTitle(`Teleporter!`)
.setDescription("Through this interaction, you can now teleport to the main channel of the desired category!");
const row = new MessageActionRow()
.addComponents(
new MessageSelectMenu()
.setCustomId('teleport')
.setPlaceholder('Choose a channel')
.addOptions([{
label: 'Rules',
description: "Click to check the rules",
value: 'rules',
}, {
label: 'General',
description: "Click to go to the main chat",
value: 'general',
}, {
label: 'Media',
description: "Click to go to media channel",
value: 'media',
}, {
label: 'Bots',
description: "Click to go to the bots channel",
value: 'bots',
}]),
);
await newChannel.send({
content: `${msg.author}`,
embeds: [embed],
components: [row],
});
};
This section would go either in the main bot.js file, or if you have your events in seperate files, it would go in the interactionCreate file (may need to be changed a bit if you don't have one, let me know)
const wait = require('util').promisify;
client.on('interactionCreate', async interaction => {
const member = interaction.member;
const guild = interaction.guild;
if (interaction.isSelectMenu()) {
const menuName = interaction.customId;
interaction.deferUpdate();
if (menuName === 'teleport') {
const tele = guild.channels.cache.find(channel => channel.name == `teleporter-${member.user.username}`);
// lookup the channel using the previously mentioned channel name setup
const choice = interaction.value;
if (choice === 'general') {
member.roles.add('958421069650337822');
member.roles.remove('943159431800172584');
} else if (choice === 'rules') {
member.roles.add('roleID');
member.roles.remove('roleID');
} else if (choice === 'media') {
member.roles.add('roleID');
member.roles.remove('roleID');
} else if (choice === 'bots') {
member.roles.add('roleID');
member.roles.remove('roleID');
}
tele.delete();
}
}
});
I'm currently learning how to use Discords Buttons but I ran into a problem.
The following code should create a button with the command /startgame, when you press this button it should just say "hello".
const { SlashCommandBuilder } = require("#discordjs/builders")
const { MessageButton, MessageActionRow } = require("discord.js")
module.exports ={
data: new SlashCommandBuilder()
.setName("startgame")
.setDescription("Startet das Spiel"),
async execute(interactionCreate) {
if (interactionCreate.isCommand()) {
const row1 = new MessageActionRow()
.addComponents(
new MessageButton()
.setCustomId("start")
.setLabel(" Start ")
.setStyle(3)
.setDisabled(false),
)
await interactionCreate.reply({content: " ", components: [row1]})
}
else if(interactionCreate.isButton()) {
switch (interactionCreate.customId) {
case "start": {
return interactionCreate.reply("hello")
}
}
}
}
}
It creates the button, but when you press it, it only says: This interaction failed I appreciate any help.
OK so one of these parts should be under your event listener interactionCreate rather than in a command. So if you have that section in your main bot.js file it would look like this:
Command File
const {
SlashCommandBuilder
} = require("#discordjs/builders")
const {
MessageButton,
MessageActionRow
} = require("discord.js")
module.exports = {
data: new SlashCommandBuilder()
.setName("startgame")
.setDescription("Startet das Spiel"),
async execute(interaction) {
const row1 = new MessageActionRow()
.addComponents(
new MessageButton()
.setCustomId("start")
.setLabel(" Start ")
.setStyle(3)
)
return interaction.reply({
components: [row1]
})
}
}
bot.js file - could be named whatever you named it
client.on('interactionCreate', async interaction => {
if (interaction.isButton()) {
const buttonID = interaction.customId
if (buttonID === 'start') {
interaction.reply({
content: 'Hello'
})
}
}
})
I want to add info to database and I'm getting the "This interaction failed" error in discord
Using better-sqlite3, discord.js v13
For the code, I've used bits and pieces of tutorials and guides from around the internet and I think some of that may have interfered with what's already been written
const { MessageActionRow, MessageButton, MessageEmbed } = require('discord.js');
const db = require("better-sqlite3")("../../main.db")
module.exports = {
name: 'test',
description: "test buy",
options: [
{
name: 'buy',
description: 'ซื้อสคริป',
type: "SUB_COMMAND",
options: [
{
name: "link",
description: "ลิ้งซองเงิน 99 บาท",
type: "STRING",
required: true,
}
]
},
],
run: async(client, interaction, args) => {
if (interaction.options.getSubcommand() === 'buy') {
const button = new MessageActionRow()
.addComponents(
new MessageButton()
.setCustomId('confirm')
.setLabel('c')
.setStyle('SUCCESS'),
new MessageButton()
.setCustomId('cancel')
.setLabel('b')
.setStyle('DANGER'),
new MessageButton()
.setURL('https://www.youtube.com/')
.setLabel('a')
.setStyle('LINK'),
);
const embed = new MessageEmbed()
.setColor('#FF0000')
.setTitle('ShuShi')
.setDescription('info')
await interaction.reply({ephemeral: true, embeds: [embed], components: [button] });
const filter = i => i.user.id === interaction.member.id;
const collector = interaction.channel.createMessageComponentCollector({
filter,
time: 600000,
max: 1
});
collector.on('collect', async i => {
collector.stop();
if (i.customId === 'confirm') {
db.prepare(`INSERT INTO discorddata VALUES(:id,:own)`).run({
id: interaction.user.id,
own: 'true'
})
}
})
}
}}