let ticket = new Map()
module.exports = {
commands: ['ticket'],
description: "open a new ticket",
callback: (message, async, text) => {
const ticketChannel = message.guild.channels.cache.find(c => c.name.toLowerCase() === `${message.author.username}--ticket`.toLowerCase())
if(ticketChannel || ticket.get(message.author.id) === true) return message.channel.send("You already have a ticket currently open!")
const ticketCreated = await message.guild.channels.create(`${message.author.username}-ticket`, {
type: 'text',
permissionOverwrites: [
{
allow: 'VIEW_CHANNEL',
id: message.author.id
},
{
deny: 'VIEW_CHANNEL',
id: message.guild.id
}
]
})
ticket.set(message.author.id, true)
let embed1 = new Discord.MessageEmbed()
.setAuthor(message.member.displayName, message.member.user.displayAvatarURL())
.setTitle(`Your Ticket has been created!`)
.setTimestamp()
.setColor('RANDOM');
let embed3 = new Discord.MessageEmbed()
.setAuthor(message.member.displayName, message.member.user.displayAvatarURL())
.setTitle(`Why have you created this ticket?`)
.setDescription('Give a brief explanation on why you created this ticket.')
.addField('Staff will be here shortly', 'Please wait without pinging anyone.')
.setTimestamp()
.setColor('RANDOM');
ticketCreated.send(embed3)
message.channel.send(embed1)
}
}
i have this code and this is give me const ticketCreated = await message.guild.channels.create(${message.author.username}-ticket, {
error, what this is mean?
It's important to note that this is not my code, but I've made some changes to it for it to work, I'd love help
Related
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 wanted to create my bot for economics, but I ran into a problem. What do I want to do: after writing one question, the bot waits for an answer and then asks another question and so on. Can someone help me with my problem? Currently I have something like this:
const config = require('../../config.json');
const { MessageEmbed } = require('discord.js');
const shopEconomy = require('../../database/shopEconomy');
module.exports = {
name: 'create-item',
aliases: [],
description: '',
run: async(client, message, args) => {
const items = require('../../items.json');
const item = items[Math.floor(Math.random() * items.length)];
const filter = response => {
return response.content.toLowerCase();
};
const embed = new MessageEmbed()
.setColor(`${config.correct}`)
.setAuthor({ name: `Item` })
.addFields(
{ name: `Name`, value: `---`}
)
return message.channel.send(item.question, { fetchReply: true, embeds: [embed] })
.then(() => {
message.channel.awaitMessages({ filter, max: 1, time: 10000, errors: ['time'] })
.then(async collected => {
const embed = new MessageEmbed()
.setColor(`${config.correct}`)
.setAuthor({ name: `Item` })
.addFields(
{ name: `Name`, value: `${collected.first()}`}
)
await shopEconomy.findOneAndUpdate(
{
guildID: message.guild.id,
},
{
name: `${collected.first()}`,
},
{
upsert: true,
}
);
return message.channel.send({ embeds: [embed] });
})
.catch(collected => {
const embed = new MessageEmbed()
.setColor(`${config.false}`)
.setDescription(`Timeout.`)
message.channel.send({ embeds: [embed] });
});
});
}
}
You almost got it, as you collect the message, send a reply and await messages again
//An Example of await messages
let questions = {
first_question: "Hello what is your name?",
second_question: "how old are you",
}
const filter = m => m.author.id === message.author.id
message.channel.send({content: `${questions.first_question}`}).then(async msg=>{
await msg.channel.awaitMessages({filter: filter, time: 60000, max:1 }).then(collected=>{
const msg1 = collected.first().content
message.channel.send({content: `${questions.second_question}`}).then(async msg=>{
await msg.channel.awaitMessages({filter: filter, time: 60000, max:1}).then(collected=>{
const msg2 = collected.first().content
return message.channel.send({content: `${questions.first_question}\nAns: ${msg1}\n${questions.second_question}\nAns: ${msg2}`})
})
})
})
})
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
I'm trying to make categories in my discord bot and I'm also trying to make categories help command, but It's not working well, so I need some help. Its not an error and there is nothing showing in my console of DiscordAPIErrors, Syntax Errors, or any error. It should display the chosen category and itβs commands in an embed message, but Itβs not. It only display the specific commands help, for example, when I type (prefix)help kick it shows the kick command help, but when I type (prefix)help utility it only says that the command provided is invalid. So it only reacts with commands not categories. here's my code:
Code:
const Discord = require('discord.js')
const fs = require('fs')
const { prefix, owner_id } = require('../../configs.json')
module.exports.run = async (message, args, client) => {
const data = [];
const allCategories = ['general','currency','premium','settings'];
const categoryName = {
"general": 'General Commands',
"currency": 'Currency Commands',
"settings": 'Settings Commands'
}
const user = await client.users.fetch('685079477629485093');
const colors = [
'WHITE','#add8e6','#e0ffff','#d3d3d3',
'#20b2aa','#5d8aa8','#f0f8ff','#f2f3f4',
'#b2beb5','#007fff','#f0ffff','#89cff0',
'#a1caf1','#21abcd','#848482','#bcd4e6',
'#f5f5dc','#318ce7','#ace5ee','#a2a2d0',
'#6699cc','#0d98ba','#0095b6','#e3dac9',
'#0070ff','#1dacd6','#08e8de','#e7feff'
]
const randomColor = colors[Math.round(Math.random()*colors.length)];
if (!args[0]) {
let firstHelp = new Discord.MessageEmbed()
.setColor(randomColor)
.setDescription(`
Commands Usage: \`${prefix}(command)\`\nYou're asking for help,
**${message.author.username}**? I'm here to help!
`, { split: true })
.addFields(
{ name: `βοΈ General`, value: `${(client.generalCommands.map(command =>
`\`${command.help.name}\``).join(', ')) || '\`coming soon...\`'}`, inline: true },
{ name: `π° Currency`, value: `${(client.currencyCommands.map(command =>
`\`${command.help.name}\``).join(', ')) || '\`coming soon...\`'}`, inline: true },
)
.setFooter(`For more information about a specific command, ${prefix}help <command>`)
.setThumbnail(`${message.guild.iconURL({ dynamic: true })}`)
.setTitle(`E-Mod Command List`);
if (!message.guild.iconURL()) {
firstHelp.setThumbnail(`${client.user.displayAvatarURL({ dynamic: true })}`)
}
return message.channel.send(firstHelp)
}
const name = args[0].toLowerCase();
const command = client.generalCommands.get(name)
|| client.generalCommands.find(cmd => cmd.help.aliases && cmd.help.aliases.includes(name))
|| client.currencyCommands.get(name)
|| client.currencyCommands.find(cmd => cmd.help.aliases && cmd.help.aliases.includes(name))
|| client.premiumCommands.get(name)
|| client.premiumCommands.find(cmd => cmd.help.aliases && cmd.help.aliases.includes(name))
if (!command) {
const categorySelected = allCategories.map(category => category.startsWith(name));
if (name == categorySelected) {
let { categoryCommands } = message.client.get(name + 'Commands')
let categoryHelp = new Discord.MessageEmbed()
.setColor(randomColor)
.addFields(
{ name: `${categoryName.map(category => category.startsWith(name))}`, value:
`${(categoryCommands.map(command => `\`${command.help.name}\``).join(', ')) || '\`coming
soon...\`'}`, inline: false },
)
.setFooter(`Premium commands can be used by specific users!`);
return message.channel.send(categoryHelp);
} else {
return message.reply(`it seems you\'ve supplied an invalid command.\nPlease use
\`${prefix}help\` to check out what commands do I support.`)
}
}
let commandHelp = new Discord.MessageEmbed()
.setColor(randomColor)
.addFields(
{ name: 'Description:', value: `${command.help.description}`, inline: false },
{ name: 'Triggers:', value: `${((command.help.aliases).join(', ')) || 'No triggers found'}`,
inline: true },
{ name: 'Usage:', value: `\`${command.help.usage}\``, inline: true },
)
.setFooter(`Premium commands can be used by specific users!`)
.setTitle(`Help | ${command.help.name}`);
return message.channel.send(commandHelp);
}
module.exports.help = {
name: 'help',
description: 'Get a list of all commands or info about a specific command.',
usage: `${prefix}help <command>`,
aliases: ['commands', 'cmds'],
cooldown: 3,
}
You can try making an array and make an object that you can push. If you use a command handler, it can be even easier to use. Heres an Example with the command handler:
const roleColor =
message.guild.me.displayHexColor === "#000000" ?
"#ffffff" :
message.guild.me.displayHexColor;
if (!args[0]) {
let categories = [];
//Use below for each category emoji, may pop up as Undefined
const dirEmojis = {
Category: 'πββοΈ'
}
const ignoredCategories = [`moderation`, `Other`, `suggest`, `Warn`, `Mute`, `ReactionRoles`, `Economy`, `Ticket`, `Welcome_Message`, `Welcome-Message`]
fs.readdirSync("./commands/").forEach((dir) => {
if (ignoredCategories.includes(dir)) return;
const editedName = `${dirEmojis[dir]} ${dir.toUpperCase()}`;
const commands = fs.readdirSync(`./commands/${dir}/`).filter((file) =>
file.endsWith(".js")
);
// If your handler does not use a folder for categories remove the dir, the dir is what the category name will be
const cmds = commands.filter((command) => {
let file = require(`../../commands/${dir}/${command}`);
return !file.hidden;
}).map((command) => {
let file = require(`../../commands/${dir}/${command}`);
if (!file.name) return "No command name.";
let name = file.name.replace(".js", "");
return `\`${name}\``;
});
let data = new Object();
data = {
name: editedName,
value: cmds.length === 0 ? "In progress." : cmds.join(" "),
};
categories.push(data);
});
const embed = new Discord.MessageEmbed()
.setTitle("Here Are My Commands:")
.addFields(categories)
.setDescription(
`Use \`${prefix}help\` followed by a command name to get more additional information on a command. For example: \`${prefix}help ban\`.`
)
.setFooter(
`Requested by ${message.author.tag}`,
message.author.displayAvatarURL({
dynamic: true
})
)
.setTimestamp()
.setColor(roleColor);
return message.channel.send(embed);
} else {
const command =
client.commands.get(args[0].toLowerCase()) ||
client.commands.find(
(c) => c.aliases && c.aliases.includes(args[0].toLowerCase())
);
if (!command) {
const embed = new Discord.MessageEmbed()
.setTitle(`Invalid command! Use \`${prefix}help\` for all of my commands!`)
.setColor("FF0000");
return message.channel.send(embed);
}
//This will show command info here
const embed = new Discord.MessageEmbed()
.setTitle("Command Details:")
.addField("PREFIX:", `\`${prefix}\``)
.addField(
"COMMAND:",
command.name ? `\`${command.name}\`` : "No name for this command."
)
.addField(
"ALIASES:",
command.aliases ?
`\`${command.aliases.join("` `")}\`` :
"No aliases for this command."
)
.addField(
"USAGE:",
command.usage ?
`\`${prefix}${command.name} ${command.usage}\`` :
`\`${prefix}${command.name}\``
)
.addField(
"DESCRIPTION:",
command.description ?
command.description :
"No description for this command."
)
.setFooter(
`Requested by ${message.author.tag}`,
message.author.displayAvatarURL({
dynamic: true
})
)
.setTimestamp()
.setColor(roleColor);
return message.channel.send(embed);
}
}
}
This was inspired by reconlx, but modified. github.com/reconlx
If you decide not to use the handler method, do what is shown below:
let category = []
let data = new Object()
data = {
name: category name/ category array
value: commands in the category
}
category.push(data)
let embed = new Discord.MessageEmbed()
.setTitle('Help')
.addFields(category)
Basic Command Handler Below (copy and paste into main file)
fs.readdirSync('./commands').forEach(dirs => {
const commands = fs.readdirSync(`./commands/${dirs}`).filter(files => files.endsWith('.js'));
for (const file of commands) {
const command = require(`./commands/${dirs}/${file}`);
console.log(`Loading command ${file}`);
if (command.name) {
client.commands.set(command.name.toLowerCase(), command);
} else {
continue;
}
}
});
I am trying to make a ticket system, but there is a problem. I want to make it when somebody opens a ticket, wait until the ticket closes, and then let them react again.
Here is my code:
const Discord = require('discord.js');
const client = new Discord.Client({
partials: ['MESSAGE', 'USER', 'REACTION'],
});
const enmap = require('enmap');
const { token, prefix } = require('./config.json');
const settings = new enmap({
name: 'settings',
autoFetch: true,
cloneLevel: 'deep',
fetchAll: true,
});
client.on('ready', () => {
console.log('Ticket System');
client.user.setActivity(`Community`, { type: 'WATCHING' });
});
client.on('message', async (message) => {
if (message.author.bot) return;
if (message.content.indexOf(prefix) !== 0) return;
const args = message.content
.slice(prefix.length)
.trim()
.split(/ +/g);
const command = args.shift().toLowerCase();
if (command == 'ticket-setup') {
if (message.author == '409327435188928526') {
let channel = message.mentions.channels.first();
if (!channel) return message.reply('Usage: `!ticket-setup`');
let sent = await channel.send(
new Discord.MessageEmbed()
.setTitle('Ticket System')
.setDescription(
'If you want to buy something from us,\n react withβββ ββββ β π« βββ ββββ βto open a ticket'
)
.setFooter(
'Community',
''
)
.setColor('00f8ff')
);
sent.react('π«');
settings.set(`${message.guild.id}-ticket`, sent.id);
message.channel.send('Ticket System Setup Done!');
}
}
if (command == 'close') {
if (!message.channel.name.includes('ticket-'))
return message.channel.send('You cannot use that here!');
message.channel.delete();
}
});
client.on('messageReactionAdd', async (reaction, user) => {
if (user.partial) await user.fetch();
if (reaction.partial) await reaction.fetch();
if (reaction.message.partial) await reaction.message.fetch();
if (user.bot) return;
let ticketid = await settings.get(`${reaction.message.guild.id}-ticket`);
if (!ticketid) return;
if (reaction.message.id == ticketid && reaction.emoji.name == 'π«') {
reaction.users.remove(user);
reaction.message.guild.channels
.create(`ticket-${user.username}`, {
permissionOverwrites: [
{
id: user.id,
allow: ['SEND_MESSAGES', 'VIEW_CHANNEL'],
},
{
id: reaction.message.guild.roles.everyone,
deny: ['VIEW_CHANNEL'],
},
],
type: 'text',
})
.then(async (channel) => {
channel.send(
`<#${user.id}> Welcome!`,
new Discord.MessageEmbed()
.setDescription(
'Support will be with you shortly.\n \n !close to close the ticket.'
)
.setColor('00f8ff')
.setFooter(
'Community',
''
)
.setTimestamp()
);
});
}
});
client.login(token);
Also, instead of having to use a command to close the ticket, I want the bot to add a yes and no reaction to the message, and ask me if I want to close it.