I'm trying to make a game ban appeal, using the Discord-Modals package, and it seems to work good so far, however, the modal looks odd on phones, which will be a problem.
There are no errors, Here is what it looks like:
On PC, and On Phone1 Phone2
As you can see, On PC there was the Do you think the ban was fair? select drop down, but on both phones, it wasn't there.
I'm not sure of this is fixable, but I sure hope it is.
Code:~
// Main requirements
const { CHANNEL_SSU, CHANNEL_ROLESEL, BOT_PREFIX, ROLE_DEV } = require('../../config.json')
const commandName = '2gba'
// Optional Requirements
const { MessageEmbed, MessageActionRow, MessageButton, MessageCollector, InteractionType } = require('discord.js')
const { Modal, TextInputComponent, showModal, SelectMenuComponent } = require(`discord-modals`)
// Main Code
module.exports = client => {
client.on('messageCreate', async message => {
if (message.author.bot) return;
if (!message.content.toLowerCase().startsWith(BOT_PREFIX)) return;
const command = message.content.split(' ')
const args = message.content.substring(1).split(' ')
if (command.toString().toLowerCase().replace(BOT_PREFIX, '').startsWith(commandName)) {
if (!message.member.roles.cache.has(ROLE_DEV)) return message.reply("Only Developers can use this command!")
const buttonsRow1 = new MessageActionRow().addComponents(
new MessageButton()
.setCustomId('GBAempty5')
.setLabel(' ')
.setStyle('SECONDARY')
.setDisabled(true),
new MessageButton()
.setCustomId('GBA2')
.setLabel('Appeal')
.setStyle('DANGER')
.setDisabled(false),
new MessageButton()
.setCustomId('GBAempty6')
.setLabel(' ')
.setStyle('SECONDARY')
.setDisabled(true)
)
const GBAEmbed = new MessageEmbed()
.setTitle('Appeal Your Game Ban! 222')
.setColor('DARK_BLUE')
.setFooter({ text: 'ASRP | System Bot' })
.setThumbnail(message.guild.iconURL({ dynamic: true, size: 512 }))
message.delete()
message.channel.send({ embeds: [GBAEmbed], components: [buttonsRow1] })
}
})
client.on(`interactionCreate`, async (interaction) => {
if (!interaction.isButton) return
if (interaction.customId == 'GBA2') {
const modal = new Modal()
.setCustomId(`gbamodal`)
.setTitle(`ASRP | Game Ban Appeal`)
.addComponents(
new TextInputComponent()
.setCustomId("RobloxUsername-gba")
.setLabel("Roblox Username")
.setStyle("SHORT")
.setMinLength(1)
.setPlaceholder('Please check for any typos.')
.setRequired(true),
new TextInputComponent()
.setCustomId("Moderator-gba")
.setLabel("Who banned you?")
.setStyle("SHORT")
.setMinLength(1)
.setPlaceholder('This field is optional.')
.setRequired(false),
new TextInputComponent()
.setCustomId("unbanreason-gba")
.setLabel("Why should we unban you?")
.setStyle("LONG")
.setMinLength(1)
.setPlaceholder('Give us a reason to unban you.')
.setRequired(true),
new TextInputComponent()
.setCustomId("banreason-gba")
.setLabel("Why were you banned from asrp?")
.setStyle("LONG")
.setMinLength(1)
.setPlaceholder('Give us the reason you were banned for.')
.setRequired(true),
new SelectMenuComponent()
.setCustomId('fair-gba')
.setPlaceholder('Do you think your punishment was fair?')
.addOptions(
{
label: "Yes",
description: "You think the punishment was fair.",
value: "Yes",
emoji: "✅"
},
{
label: "No",
description: "You think the punishment was unfair.",
value: "No, I think it's unfair.",
emoji: "❌"
}
)
);
showModal(modal, {
client: client,
interaction: interaction
})
}
});
client.on('modalSubmit', async modal => {
if (modal.customId === 'gbamodal') {
const RBXuser = modal.getTextInputValue('RobloxUsername-gba');
let BanMod = modal.getTextInputValue('Moderator-gba');
if (!BanMod) BanMod = 'None Stated';
const ReasonUnban = modal.getTextInputValue('unbanreason-gba');
const ReasonBan = modal.getTextInputValue('banreason-gba');
const Fairness = modal.getSelectMenuValues('fair-gba');
const user = modal.user
const appealEmbed = new MessageEmbed()
.setTitle(`New Game Ban Appeal`)
.setAuthor({ name: `User: ${user.tag} (${user.id})` })
.addFields(
{name: `Q: Roblox Username`, value: `A: ${RBXuser}`},
{name: `Q: Who banned you?`, value: `A: ${BanMod}`},
{name: `Q: Why should we unban you?`, value: `A: ${ReasonUnban}`},
{name: `Q: Why were you banned?`, value: `A: ${ReasonBan}`},
{name: `Q: Do you think the ban was fair?`, value: `A: ${Fairness}`}
)
.setFooter({ text: `This is beta, please report any errors.` })
.setThumbnail(user.displayAvatarURL({ dynamic: true, size: 512 }))
await modal.reply({ content: 'Your submission was recieved successfully!', ephemeral: true }).then(() => {
client.guilds.cache.get(`954881682429853726`).channels.cache.get('998833987810246666').send({ embeds: [appealEmbed] });
})
console.log(modal.getTextInputValue('RobloxUsername-gba'))
console.log(modal.getTextInputValue('Moderator-gba'))
console.log(modal.getTextInputValue('unbanreason-gba'))
console.log(modal.getTextInputValue('banreason-gba'))
console.log(modal.getSelectMenuValues('fair-gba'))
}
});
}
Extra Information:
Node Version: 'v16.14.2'
NPM Version: '8.5.0'
Discord.js Version: '^13.7.0'
Thank you in advance.
Select Menu's within Modals are unsupported and not documented by Discord - this is not a user issue nor an issue with the code.
Select Menu's just don't show up on mobile and only partially work within Modals (as of August 2022).
Related
I was wondering if it was possible to make it so that you can have the bot search for more than one server when putting in the command.
for example !mc server.com
bot: server.com
playercount: ?/?
other info
onst { Client, Intents, Message} = require('discord.js');
const util = require('minecraft-server-util');
const {EmbedBuilder} = require('discord.js');
const options = {
timeout: 1000 * 5,
enableSRV: true
};
const prefix = "!mcstatus";
const client = new Client({
intents: [
"Guilds",
"GuildMessages",
"MessageContent"
]
});
client.on('ready', () => {
console.log('bot started');
client.user.setPresence({ activities: [{ name: `${server_ip}`, type: 'WATCHING' }], status: 'active' });
});
const server_ip = "mc.hypixel.net";
const server_port = 25565;
client.on('messageCreate', (message) => {
if (!message.content.startsWith(prefix) || message.author.bot) return;
if(message.content.startsWith(prefix)){
util.status(server_ip, server_port, options)
.then((result) => {
const embed = new EmbedBuilder()
.setColor("#FF0000")
.setTitle("mcdonalds")
.setDescription(`This will show the status and info about the minecraft server \n **Server ip:** ${server_ip} \n **Server port:** ${server_port}`)
.addFields(
{name:"Server Version", value: `${result.version.name}`},
{name:"Server Protocol Version", value:`${result.version.protocol}`},
{name:"Players Online", value:`${result.players.online}`},
{name:"Max Players", value:`${result.players.max}`},
{name:"MOTD (May Not Display Accurately)", value:`${result.motd.clean}`},
{name:"Latency", value:`${result.roundTripLatency}`},
)
.setTimestamp()
message.channel.send({embeds: [embed]})
})
.catch((error) => {
console.log(error);
const embed = new EmbedBuilder()
.setColor("#808080")
.setTitle("mcdonalds")
.setDescription(`The server was unable to be pinged or you mis-typed the info`)
.setTimestamp()
message.channel.send({embeds: [embed]})
})}});
client.login("okent");
if there is a way this would be very cool
You can use the String.prototype.split() method to turn your string into an array of strings, for example:
let args = message.content.split(" "); // Splitting with a blank space.
args = args.slice(1); // Remove the first argument which would be the command itself.
const server_port = 25565; // Leave the default port for MC servers.
if (args.length < 1) return message.reply("Didn't provide arguments.")
// Run a forEach loop for every argument.
args.forEach((arg) => {
util
.status(arg, server_port, options)
.then((result) => {
const embed = new EmbedBuilder()
.setColor("#FF0000")
.setTitle("Results")
.setDescription(
`This will show the status and info about the minecraft server \n **Server ip:** ${arg} \n **Server port:** ${server_port}`
)
.addFields(
{ name: "Server Version", value: `${result.version.name}` },
{
name: "Server Protocol Version",
value: `${result.version.protocol}`,
},
{ name: "Players Online", value: `${result.players.online}` },
{ name: "Max Players", value: `${result.players.max}` },
{
name: "MOTD (May Not Display Accurately)",
value: `${result.motd.clean}`,
},
{ name: "Latency", value: `${result.roundTripLatency}` }
)
.setTimestamp();
message.channel.send({ embeds: [embed] });
})
.catch((error) => {
const embed = new EmbedBuilder()
.setColor("#808080")
.setTitle("Error")
.setDescription(
`${arg} was unable to be pinged or you mis-typed the info`
)
.setTimestamp();
message.channel.send({ embeds: [embed] });
});
});
(Make sure to review the code before pasting it in)
The snippet above simply splits the message.content string into an array of strings then runs a loop for each string in the array which runs the util status check and then returns a new embed, or an error.
Make sure to mark this as the answer if it helped.
Is anyone able to show me how I could add the discord Interactive Buttons onto this embed. I'm looking for just a simple button that will link somewhere. Thanks for the help
const Discord = require("discord.js")
const { Client, Message } = require('discord.js');
const { MessageEmbed } = require('discord.js');
module.exports = {
name: 'text',
cooldown: 1000,
run: async(client, message, args) => {
message.delete()
const exampleEmbed = new MessageEmbed()
.setColor('#000')
.setAuthor("Text")
.setDescription('Text')
.addFields(
{
name: `TextTitle`,
value: `Text`,
inline: true
},
{
name: `TextTitle`,
value: `Text`
} )
message.channel.send(exampleEmbed)}
}
First of all, you should call the MessageButton and MessageActionRow:
const { MessageEmbed, MessageActionRow, MessageButton } = require('discord.js');
Then we make a simple embed:
const exampleEmbed = new MessageEmbed()
.setColor('#000')
.setAuthor({ name: "Text" })
.setDescription('Text')
.addFields(
{
name: `TextTitle`,
value: `Text`,
inline: true
},
{
name: `TextTitle`,
value: `Text`
})
After that, We make a row and add some buttons to it:
const row = new MessageActionRow()
.addComponents(
new MessageButton()
.setLabel('Invite') // label of the button
.setEmoji('➕') // emoji
.setURL('https://https://stackoverflow.com') // URL of where the button leads the user
.setStyle('LINK') // style of the button
)
Then we send them:
message.channel.send({ embeds: [exampleEmbed], components: [row] })
There are 5 styles of building buttons:
PRIMARY,
SECONDARY,
SUCCESS,
DANGER,
LINK
Final Result:
You can visit Discordjs guides for More Info on Buttons
UPDATE: Discord.js v12
For creating buttons in discord.js v12, We should import buttons from the discord-buttons package.
const { MessageButton } = require('discord-buttons');
Then we make the button:
let button = new MessageButton()
.setStyle('url')
.setURL('https://stackoverflow.com')
.setLabel('invite');
Then we send it:
message.channel.send('test',button)
discord buttons v12 styles:
green
red
blurple
url
I'm trying to make a interaction based questionnaire, the user gets a DM with a button, by clicking the button, the user starts a message collector and the bot asks questions, however, the message collector seems to be setup wrong, it fails to read.
I haven't worked with interactions much, so I stick to classic commands, I'm trying to read the interaction channel and start a message collector in the DM, I hope I explained everything, any questions please ask.
Error:
Cannot read properties of null (reading 'createMessageCollector')
Code:
// Main requirements
const { CHANNEL_SSU, CHANNEL_ROLESEL, BOT_PREFIX, ROLE_DEV } = require('../../config.json')
const commandName = 'gba'
// Optional Requirements
const { MessageEmbed, MessageActionRow, MessageButton, MessageCollector } = require('discord.js')
// Main Code
module.exports = client => {
client.on('messageCreate', async message => {
if (message.author.bot) return;
if (!message.content.toLowerCase().startsWith(BOT_PREFIX)) return;
const command = message.content.split(' ')
const args = message.content.substring(1).split(' ')
if (command.toString().toLowerCase().replace(BOT_PREFIX, '').startsWith(commandName)) {
if (!message.member.roles.cache.has(ROLE_DEV)) return message.reply("Only Developers can use this command!")
const buttonsRow1 = new MessageActionRow().addComponents(
new MessageButton()
.setCustomId('GBAempty1')
.setLabel(' ')
.setStyle('SECONDARY')
.setDisabled(true),
new MessageButton()
.setCustomId('GBA')
.setLabel('Appeal')
.setStyle('DANGER')
.setDisabled(false),
new MessageButton()
.setCustomId('GBAempty2')
.setLabel(' ')
.setStyle('SECONDARY')
.setDisabled(true)
)
const GBAEmbed = new MessageEmbed()
.setTitle('Appeal Your Game Ban!')
.setColor('DARK_BLUE')
// .addFields(
// {name: 'Goal:', value: 'Help with development of the **System Bot**.'},
// {name: "Notice:", value: `If you're found **Inactive**, you **will** be removed.`}
// )
.setFooter({ text: 'ASRP | System Bot' })
.setThumbnail(message.guild.iconURL({ dynamic: true, size: 512 }))
message.delete()
message.channel.send({ embeds: [GBAEmbed], components: [buttonsRow1] })
}
})
client.on(`interactionCreate`, async (interaction) => {
if (!interaction.isButton) return
if (interaction.customId == 'GBA') {
await interaction.deferReply({
ephemeral: true
})
const appealEmbed = new MessageEmbed()
.setTitle(`Started Appeal.`)
.setDescription(`Please check your DM for the appeal.`)
// .addFields(
// {name: 'User', value: `${interaction.user} \`(${interaction.user.id})\``},
// {name: 'Action:', value: `\`\`\`${actionDone}\`\`\``}
// )
.setFooter({ text: 'ASRP | System Bot' })
.setTimestamp()
.setColor('ORANGE')
await interaction.editReply({ embeds: [appealEmbed], ephemeral: true })
let user = client.users.cache.get(interaction.member.user.id);
const buttonsRow2 = new MessageActionRow().addComponents(
new MessageButton()
.setCustomId('GBAempty3')
.setLabel(' ')
.setStyle('SECONDARY')
.setDisabled(true),
new MessageButton()
.setCustomId('GBAStart')
.setLabel('Appeal')
.setStyle('DANGER')
.setDisabled(false),
new MessageButton()
.setCustomId('GBAempty4')
.setLabel(' ')
.setStyle('SECONDARY')
.setDisabled(true)
)
const GBAstart = new MessageEmbed()
.setTitle(`Start Appeal.`)
.setDescription(`Press 'Start' to start appealing your game ban.`)
.setFooter({ text: 'ASRP | System Bot' })
.setThumbnail(interaction.guild.iconURL({ dynamic: true, size: 512 }))
user.send({ embeds: [GBAstart], components: [buttonsRow2] })
}
if (interaction.customId == 'GBAStart') {
await interaction.deferReply({
ephemeral: true
})
const questions = [
"How old are you?",
"How are you?",
"What time is for you?"
]
let counter = 0
const filter = m => m.author.id === message.author.id
const collector = await interaction.channel.createMessageCollector({ filter, time: 1000 * 1200, max: 3, min: 3 });
await interaction.channel.send(questions[counter++])
collector.on('collect', (m) => {
if (counter < questions.length) {
m.reply(questions[counter++])
}
if (counter == questions.length + 1) {
collector.stop()
}
})
collector.on('end', collected => {
console.log(`Collected ${collected.size} messages`)
if (collected.size < questions.length) {
interaction.channel.send('You didn\'t answer in time, please restart the appeal.')
return
}
let counter = 0
collected.forEach((value) => {
console.log(questions[counter++], value.content)
})
});
}
})
}
Extra Information:
Node Version: 'v16.14.2'
NPM Version: '8.5.0'
Discord.js Version: '^13.7.0'
Thank you in advance.
I am making a ticket system, everything works fine except when I go onto a different account to test out what the ticket system looks like for the people using it, I try to react to the "Player Report", "Bug Report", etc... as seen in the code, it just says i am unable to use the buttons and then throws this error.
Full error:
C:\Users\wrigh\Documents\Discord Bots\Practice Bot - Copy\node_modules\discord.js\src\structures\interfaces\InteractionResponses.js:90
if (this.deferred || this.replied) throw new Error('INTERACTION_ALREADY_REPLIED');
^
Error [INTERACTION_ALREADY_REPLIED]: The reply to this interaction has already been sent or deferred.
at ButtonInteraction.reply (C:\Users\wrigh\Documents\Discord Bots\Practice Bot - Copy\node_modules\discord.js\src\structures\interfaces\InteractionResponses.js:90:46)
at C:\Users\wrigh\Documents\Discord Bots\Practice Bot - Copy\Events\Ticket\initialTicket.js:86:24
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async C:\Users\wrigh\Documents\Discord Bots\Practice Bot - Copy\Events\Ticket\initialTicket.js:79:9
at async Object.execute (C:\Users\wrigh\Documents\Discord Bots\Practice Bot - Copy\Events\Ticket\initialTicket.js:20:9) {
[Symbol(code)]: 'INTERACTION_ALREADY_REPLIED'
Ticket.js Code:
const { MessageEmbed, CommandInteraction, MessageActionRow, MessageButton } = require("discord.js");
const { OPENTICKET } = require("../../Structures/config.json");
module.exports = {
name: "ticket",
description: "Setup your ticket",
permission: "ADMINISTRATOR",
/**
*
* #param {CommandInteraction} interaction
*/
async execute(interaction) {
const { guild } = interaction;
const Embed = new MessageEmbed()
.setAuthor(
guild.name + " | Ticketing System",
guild.iconURL({ dynamic: true})
)
.setDescription(
"Open a ticket to discuss any of the issues listed on the button."
)
.setColor("BLUE");
const Buttons = new MessageActionRow();
Buttons.addComponents(
new MessageButton()
.setCustomId("player")
.setLabel("Player Report")
.setStyle("PRIMARY")
.setEmoji("🏮"),
new MessageButton()
.setCustomId("bug")
.setLabel("Bug Report")
.setStyle("SECONDARY")
.setEmoji("✔"),
new MessageButton()
.setCustomId("other")
.setLabel("Other Report")
.setStyle("SUCCESS")
.setEmoji("❤"),
);
await guild.channels.cache
.get(OPENTICKET)
.send({ embeds: [Embed], components: [Buttons] });
interaction.reply({ content: "Done", ephemeral: true });
},
};
InitialTicket.js Code:
const { ButtonInteraction, MessageEmbed, MessageActionRow, MessageButton } = require("discord.js");
const DB = require("../../Structures/Handlers/Schemas/Ticket");
const { PARENTID, EVERYONEID } = require("../../Structures/config.json");
const Ticket = require("../../Structures/Handlers/Schemas/Ticket");
module.exports = {
name: "interactionCreate",
/**
*
* #param {ButtonInteraction} interaction
*/
async execute(interaction) {
if(!interaction.isButton()) return;
const { guild, member, customId } = interaction;
if (!["player", "bug", "other"].includes(customId)) return;
const ID = Math.floor(Math.random() * 90000) + 10000;
await guild.channels
.create(`${customId + "-" + ID}`, {
type: "GUILD_TEXT",
parent: PARENTID,
permissionOverwrites: [
{
id: member.id,
allow: ["SEND_MESSAGES", "VIEW_CHANNEL", "READ_MESSAGE_HISTORY"],
},
{
id: EVERYONEID,
deny: ["SEND_MESSAGES", "VIEW_CHANNEL", "READ_MESSAGE_HISTORY"],
},
],
})
.then(async (channel) => {
await DB.create({
GuildID: guild.id,
MemberID: member.id,
TicketID: ID,
ChannelID: channel.id,
Closed: false,
Locked: false,
Type: customId,
});
const Embed = new MessageEmbed()
.setAuthor(
`${guild.name} | Ticket: ${ID}`,
guild.iconURL({ dynamic: true })
)
.setDescription(
"Please wait patiently for a response from the Staff team, in the mean while, describe your issue in as much detail."
)
.setFooter("The buttons below are staff only buttons.");
const Buttons = new MessageActionRow();
Buttons.addComponents(
new MessageButton()
.setCustomId("close")
.setLabel("Save and close")
.setStyle("PRIMARY")
.setEmoji("💾"),
new MessageButton()
.setCustomId("lock")
.setLabel("lock")
.setStyle("SECONDARY")
.setEmoji("🔒"),
new MessageButton()
.setCustomId("unlock")
.setLabel("unlock")
.setStyle("SUCCESS")
.setEmoji("🔓"),
);
channel.send({
embeds: [Embed],
components: [Buttons],
});
await channel
.send({ content: `${member} here is your ticket` })
.then((m) => {
setTimeout(() => {
m.delete().catch(() => {});
}, 1 * 3000);
interaction.reply({
content: `${member} your ticket has been created: ${channel}`,
ephemeral: true
});
});
});
},
};
If you need to see any other parts of the bot please just ask, any help is rlly appreciated.
Any questions feel free to ask and I will try answer them to the best of my ability.
I am somewhat new to JavaScript and Node.js so please be patient with me.
Are these executed from the same button press/same interaction? If so, then set the reply that happens second to interaction.followUp() or interaction.editReply (depending on whether you want a second message (followUp) or to edit the existing message (editReply)).
So I made a discord selection menu ticket that when I select that category it makes a channel and send a message with a button. The button is supposed to delete the channel when pressed, but it doesn't seem to work. I think I have found the error but I don't know how to fix it. It is probably easy to fix but I'm stuck.
The code: (I think the error is located in the end here)
} else if (Discord.MessageButton.customId === 'del') {
const channel = message.guild.channel
channel.delete();
const Discord = require("discord.js");
const { MessageSelectMenu, MessageActionRow } = require("discord.js");
module.exports = {
name: "ticket",
author: "Falcone",
run: async(client, message, args) => {
if (!message.member.permissions.has("ADMINISTRATOR")) return message.reply('You Dont Have the `ADMINISTRATOR` permision');
message.delete();
let embed = new Discord.MessageEmbed()
.setColor("RANDOM")
.setDescription(`Test`)
.setThumbnail(message.guild.iconURL({ dynamic: true }))
.setAuthor(message.guild.name, message.guild.iconURL({ dynamic: true }));
let painel = new MessageActionRow().addComponents( new MessageSelectMenu()
.setCustomId('menu')
.setPlaceholder('Test') // Mensagem estampada
.addOptions([
{
label: 'Support',
description: '',
emoji: '🙋♂️',
value: '1',
},
{
label: 'Test',
description: '',
emoji: '⛔',
value: '2',
},
{
label: 'Test',
description: '',
emoji: '🤖',
value: '3',
}
])
);
message.channel.send({ embeds: [embed], components: [painel] }).then(msg => {
const filtro = (interaction) =>
interaction.isSelectMenu()
const coletor = msg.createMessageComponentCollector({
filtro
});
coletor.on('collect', async (collected) => {
let ticket = collected.values[0]
collected.deferUpdate()
if (ticket === "1") {
const embed = new Discord.MessageEmbed()
.setTitle('Ticket')
.setDescription('Hello there, \n The staff will be here as soon as possible mean while tell us about your issue!\nThank You!')
.setColor('GREEN')
.setTimestamp()
const del = new MessageActionRow()
.addComponents(
new Discord.MessageButton()
.setCustomId('del')
.setLabel('🗑️ Delete Ticket!')
.setStyle('DANGER'),
);
message.guild.channels.create(`${collected.user.id}`, {
type : 'GUILD_TEXT',
permissionOverwrites : [
{
id : message.guild.id,
deny : ['VIEW_CHANNEL']
},
{
id : collected.user.id,
allow : ['VIEW_CHANNEL', 'SEND_MESSAGES', 'ATTACH_FILES']
}
]
}).then(async (msg) => {
msg.send({ embeds: [embed], components: [del] }).then(msg => msg.pin() );
})
} else if (Discord.MessageButton.customId === 'del') {
const channel = message.guild.channel
channel.delete();
}
})
});
}
}
MessageButton.customId is not a static property. That means it must be done on an instance, not the class. Something that you could try is this:
const msg = await message.channel.send({
content: "Which one?",
components: [
new Discord.MessageActionRow().addComponents([
new Discord.MessageButton().setLabel("Delete").setStyle("DANGER").setCustomId("DEL"), //delete button
new Discord.MessageButton().setLabel("Cancel").setStyle("DANGER").setCustomId("CAN") //cancel button
])
]
})
//Create button collector
const collector = msg.createMessageComponentCollector({
componentType: "BUTTON",
filter: (c) => c.member.id === msg.member.id,
max: 1
})
//Handle button click
collector.on("collect", i => {
if(i.customId === "CAN") return i.reply("Cancelled")
if(i.customId === "DEL") i.channel.delete() //or whatever channel you want to delete
})
Warning: I did not test this code. You can tell me any problems you have and I will try to modify this