New to coding and recently started making a discord bot using JS. It's a bot where a certain mp4 plays with a specific snippet.
I'm having trouble with the fact that the mp4 doesn't send when I input the command, just the embed message. Basically if I do -snip kratos the bot sends the embed message but not the mp4.
Here's what I have so far:
const fs = require('fs');
const { Client, MessageAttachment } = require('discord.js');
const config = require('./config.json');
const { prefix, token } = require('./config.json');
const client = new Client();
client.commands = new Discord.Collection();```
And here are the command events:
``` client.on('message', message => {
if (message.content === `${prefix}snip kratos`) {
if (message.author.bot) return
const kratos = new Discord.MessageEmbed()
.setColor('#ffb638')
.setTitle('Kratos')
.setDescription('Sending 1 snippet(s)...')
.setTimestamp()
.setFooter('SkiBot');
message.channel.send(kratos);
client.on('message', message => {
if (message.content === `${prefix}snip kratos`) {
if (message.author.bot) return
const attachment = new MessageAttachment('./snippets/kratos/Kratos.mp4');
message.channel.send(attachment);
}
});
}
});
client.on('message', message => {
if (message.content === `${prefix}snip johnny bravo`) {
if (message.author.bot) return
const kratos = new Discord.MessageEmbed()
.setColor('#ffb638')
.setTitle('Johnny Bravo')
.setDescription('Sending 1 snippet(s)...')
.setTimestamp()
.setFooter('SkiBot');
message.channel.send(kratos);
client.on('message', message => {
if (message.content === `${prefix}snip johnny bravo`) {
if (message.author.bot) return
const attachment = new MessageAttachment('./snippets/Johnny_Bravo/Johnny_Bravo.mp4');
message.channel.send(attachment);
}
});
}
});```
The issue is that you are nesting event listeners. Remove the nested client.on('message', ...) part and send the message attachment after sending the embed.
client.on('message', (message) => {
if (message.author.bot) {
return
}
if (message.content === `${prefix}snip kratos`) {
const kratos = new MessageEmbed()
.setColor('#ffb638')
.setTitle('Kratos')
.setDescription('Sending 1 snippet...')
.setTimestamp()
.setFooter('SkiBot')
message.channel.send(kratos)
const attachment = new MessageAttachment('./snippets/kratos/Kratos.mp4')
message.channel.send(attachment)
}
})
And you don't need multiple message event listeners. You can simplify the code by creating an object with the valid commands.
client.on('message', (message) => {
const { content, author, channel } = message
if (author.bot) {
return
}
const embeds = {
[`${prefix}snip kratos`]: {
title: 'Kratos',
attachmentPath: './snippets/kratos/Kratos.mp4',
},
[`${prefix}snip johnny bravo`]: {
title: 'Johnny Bravo',
attachmentPath: './snippets/Johnny_Bravo/Johnny_Bravo.mp4',
},
}
const embed = embeds[content]
if (embed) {
const { title, attachmentPath } = embed
channel.send(
new MessageEmbed()
.setColor('#ffb638')
.setTitle(title)
.setDescription('Sending 1 snippet...')
.setTimestamp()
.setFooter('SkiBot')
)
channel.send(new MessageAttachment(attachmentPath))
}
})
The above solution should be enough if you don't have a lot of commands. Check this guide to learn how to create individual command files to keep your code organized.
You should be able to do
message.channel.send({
files: [
"./snippets/kratos/Kratos.mp4"
]})
As referred to here https://discord.js.org/#/docs/main/stable/class/TextChannel?scrollTo=send
Also right here client.commands = new Discord.Collection(); right here you are calling Discord but Discord was not defined
Related
I'm watching a video (https://www.youtube.com/watch?v=ovIQqlXllWw&ab_channel=AnsontheDeveloper) to see how to make a discord poll bot. now Im at the point where the bot doesnt respond to some code and i cant find out the issue.
const { ContextMenuCommandBuilder } = require("discord.js");
const Discord = require("discord.js");
const client = new Discord.Client({intents: ['Guilds', 'MessageContent', 'GuildMessages', 'GuildMembers']});
const token = "token";
//Login with token
client.login(token);
const userCreatedPolls = new Map();
client.on('ready', () => console.log("The bot is online!"));
client.on('messageCreate', async message => {
if(message.author.bot) return;
if(message.content.toLowerCase() === '!createpoll') {
message.channel.send("Enter games to add");
let filter = msg => {
if(msg.author.id === message.author.id) {
console.log("test");
if(msg.content.toLowerCase() === 'done'){ collector.stop();}
else return true;
}
else return false;
}
let collector = message.channel.createMessageCollector(filter, { maxMatches: 20 });
let pollOptions = await getPollOptions(collector);
let embed = new discord.RichEmbed();
embed.setTitle("Poll");
embed.setDescription(pollOptions.join("\n"));
let confirm = await message.channel.send(embed);
I can turn the bot on and when i do !createpoll the bot show the correct message but when i type 'done' nothing happens. I found out the the bot cant access the if ( if(msg.author.id === message.author.id) ) but i dont know why it doesnt work.
I have such a question because I no longer know what to do. I have a BOT on Suggestion to a certain channel. When I run the bot via Visual Studio Code, the bot runs and everything works. But as soon as I load a boot on heroku.com, the program suddenly writes an error:
files = files.filter(f => f.endsWith(".js"))
Someone could help me, I would be very happy. Have a nice day
Index.js is here:
client.once('ready', () => {
console.log('Tutorial Bot is online!');
});
client.commands = new Discord.Collection()
const fs = require("fs")
fs.readdir("./commands/", (error, files) => {
files = files.filter(f => f.endsWith(".js"))
files.forEach(f => {
const command = require(`./commands/${f}`)
client.commands.set(command.name, command)
console.log(`Command ${command.name} was loaded!`)
});
});
client.on("message", message => {
if (message.author.bot) return;
if (message.channel.type === "dm") return;
if (!message.content.startsWith(config.prefix)) return;
const args = message.content.slice(config.prefix.length).split(" ")
const command = args.shift()
const cmd = client.commands.get(command)
if (cmd) {
cmd.run(client, message, args)
} else return;
});
bot.login(config.token);
Suggest.js is here
const { MessageEmbed } = require("discord.js");
module.exports = {
name: "suggest",
aliases: [],
description: "Make a suggestion and have the community vote",
category: "utility",
usage: "suggest <suggestion>",
run: async (client, message, args) => {
let suggestion = args.slice(0).join(" ");
let SuggestionChannel = message.guild.channels.cache.find(channel => channel.name === "suggestions");
if (!SuggestionChannel) return message.channel.send("Please create a channel named suggestions before using this command!");
const embed = new MessageEmbed()
.setTitle("New Suggestion")
.setDescription(suggestion)
.setColor("RANDOM")
.setFooter(`${message.author.tag} | ID: ${message.author.id}`)
.setTimestamp()
SuggestionChannel.send(embed).then(msg => {
msg.react("ππΌ")
msg.react("ππΌ")
message.channel.send("Your suggestion has been sent!");
});
}
}
You forgot to check for errors in your callback. In case of an error files will be undefined, thus resulting in the error you've observed. So you should do something like:
fs.readdir("./commands/", (error, files) => {
if(error) {
// handle error
} else {
files = files.filter(f => f.endsWith(".js"))
files.forEach(f => {
const command = require(`./commands/${f}`)
client.commands.set(command.name, command)
console.log(`Command ${command.name} was loaded!`)
});
}
});
I'm trying to create a discord bot that will where someone can enter the slash command /suggestion and the bot will take that suggestion and turn it into an embed and send it into a specific suggestions channel with two emojis, an X and Checkmark.
After getting it all written and doing node deploy-commands.js and getting no errors, I inputted node . with also no errors in the terminal.
But when I went into the discord and enter the /suggestions command, I get an error in the terminal which is:
TypeError: Cannot read properties of undefined (reading 'join')
and I have no idea how to follow the error to see where it's originating from.
Does anyone have any thoughts on this?
I'll leave my index.js, suggestions.js, and deploy-commands.js below.
index.js
// Require the necessary discord.js classes
const fs = require('fs');
const { Client, Collection, Intents, } = require('discord.js');
const { token } = require('./config.json');
const client = new Client({
intents: [
Intents.FLAGS.GUILDS,
Intents.FLAGS.GUILD_MESSAGES,
Intents.FLAGS.GUILD_MESSAGE_REACTIONS,
],
});
client.commands = new Collection();
client.events = new Collection();
const commandFiles = fs
.readdirSync('./commands')
.filter((file) => file.endsWith('.js'));
for (const file of commandFiles) {
const command = require(`./commands/${file}`);
client.commands.set(command.name, command);
}
// When the client is ready, run this code (only once)
client.once('ready', () => {
console.log("You are now connected to Boombap Suggestions!");
});
client.on('interactionCreate', async (interaction) => {
if (!interaction.isCommand()) return;
const command = client.commands.get(interaction.commandName);
if (!command) return;
try {
await command.execute(interaction);
} catch (error) {
console.error(error);
return interaction.reply({
content: 'There was an error while executing this command!',
ephemeral: true,
});
}
});
// Login to Discord with your client's token
client.login(token);
suggestions.js
module.exports = {
name: 'suggestions',
aliases: ['suggest', 'suggestion'],
permissions: [],
description: 'creates a suggestion!',
execute(message, args, cmd, client, discord) {
const channel = message.guild.channels.cache.find(c => c.name === 'suggestions');
if (!channel) return message.channel.send('suggestions channel does not exist!');
let messageArgs = args.join(' ');
const embed = new discord.MessageEmbed()
.setColor('5104DB')
.setAuthor(message.author.tag, message.author.displayAvatarURL({ dynamic: true }))
.setDescription(messageArgs);
channel.send(embed).then((msg) => {
msg.react('β');
msg.react('β
');
message.delete();
}).catch((err) => {
throw err;
});
}
}
deploy-commands.js
const { SlashCommandBuilder } = require('#discordjs/builders');
const { REST } = require('#discordjs/rest');
const { Routes } = require('discord-api-types/v9');
const { clientId, guildId, token } = require('./config.json');
const commands = [
new SlashCommandBuilder().setName('suggestions').setDescription('Submit A Suggestion!'),
]
.map(command => command.toJSON());
const rest = new REST({ version: '9' }).setToken(token);
rest.put(Routes.applicationGuildCommands(clientId, guildId), { body: commands })
.then(() => console.log('Successfully registered application commands.'))
.catch(console.error);
You're only passing the interaction at command.execute(interaction) yet you're expecting message, args, etc at execute(message, args, cmd, client, discord). As args is undefined you receive "TypeError: Cannot read properties of undefined (reading 'join')" .
Another problem is that you're using v13 of discord.js and still having some v12 syntax, just like in your previous post.
As you are using slash commands, you will have no args, you could add a string option in your deploy-commands.js file using the addStringOption() method. You should also mark this command option as required by using the setRequired() method.
Update commands in deploy-commands.js:
const commands = [
new SlashCommandBuilder()
.setName('suggest')
.setDescription('Submit a suggestion!')
.addStringOption((option) =>
option
.setName('suggestion')
.setDescription('Enter your suggestion')
.setRequired(true),
),
].map((command) => command.toJSON());
In your suggestions.js file, you can get this option from the CommandInteractionOptionResolver using interaction.options.getString('suggestion').
There are some changes to how setAuthor() works in v13. It now accepts an EmbedAuthorData object that has a name and an iconURL property.
Replace your suggestions.js with the following:
const { MessageEmbed } = require('discord.js');
module.exports = {
name: 'suggest',
aliases: ['suggest', 'suggestion'],
permissions: [],
description: 'creates a suggestion!',
async execute(interaction) {
let channel = interaction.guild.channels.cache.find((c) => c.name === 'suggestions');
if (!channel) {
await interaction.reply('`suggestions` channel does not exist!');
return;
}
let suggestion = interaction.options.getString('suggestion');
let embed = new MessageEmbed()
.setColor('5104DB')
.setAuthor({
name: interaction.member.user.tag,
iconURL: interaction.member.displayAvatarURL({ dynamic: true }),
})
.setDescription(suggestion);
let sentEmbed = await channel.send({ embeds: [embed] });
await interaction.reply({
content: 'π Thanks, we have received your suggestion',
ephemeral: true,
});
sentEmbed.react('β');
sentEmbed.react('β
');
},
};
I want to create an embedded welcome command and leave command. I would like an embedded DMS message for the person who joined the server.
This is the code I have so far:
const fs = require('fs');
const Discord = require('discord.js');
const {
prefix,
token
} = require('./config.json');
const client = new Discord.Client();
client.commands = new Discord.Collection();
const commandFiles = fs.readdirSync('./commands').filter(file => file.endsWith('.js'));
for (const file of commandFiles) {
const command = require(`./commands/${file}`);
client.commands.set(command.name, command);
}
const cooldowns = new Discord.Collection();
client.on('guildMemberAdd', member => {
if (!member.guild) return;
let guild = member.guild
let channel = guild.channels.cache.find(c => c.name === "welcome");
let membercount = guild.members
if (!channel) return;
let embed = new Discord.MessageEmbed().setColor("GREEN").setTitle("New Server Member!").setDescription(`Welcome, ${member.user.tag} to **${guild.name}!**`).setThumbnail(member.user.displayAvatarURL()).setFooter(`You are the ${membercount}th member to join`);
message.guild.channels.cache.find(i => i.name === 'sp').send(embed)
});
client.on("ready", () => {
console.log(`Logged in as ${client.user.tag}!`);
client.user.setPresence({
status: "idle", //You can show online, idle.... activity: {
name: "with lower lifeforms!", //The message shown type: "PLAYING", // url: "" //PLAYING: WATCHING: LISTENING: STREAMING:
}
});
});
client.on('message', message => {
if (!message.content.startsWith(prefix) || message.author.bot) return;
const args = message.content.slice(prefix.length).trim().split(/ +/);
const commandName = args.shift().toLowerCase();
const command = client.commands.get(commandName) || client.commands.find.Discord(cmd => cmd.aliases && cmd.aliases.includes(commandName));
if (!command) return;
if (command.guildOnly && message.channel.type === 'dm') {
return message.reply('I can\'t execute that command inside DMs!');
}
if (command.args && !args.length) {
let reply = `You didn't provide any arguments, ${message.author}!`;
if (command.usage) {
reply += `\nThe proper usage would be: \`${prefix}${command.name} ${command.usage}\``;
}
return message.channel.send(reply);
}
if (!cooldowns.has(command.name)) {
cooldowns.set(command.name, new Discord.Collection());
}
const now = Date.now();
const timestamps = cooldowns.get(command.name);
const cooldownAmount = (command.cooldown || 3) * 1000;
if (timestamps.has(message.author.id)) {
if (timestamps.has(message.author.id)) {
const expirationTime = timestamps.get(message.author.id) + cooldownAmount;
timestamps.set(message.author.id, now);
setTimeout(() => timestamps.delete(message.author.id), cooldownAmount);
if (now < expirationTime) {
const timeLeft = (expirationTime - now) / 1000;
return message.reply(`please wait ${timeLeft.toFixed(1)} more second(s) before reusing the \`${command.name}\` command.`);
}
}
}
try {
command.execute(message, args);
} catch (error) {
console.error(error);
message.reply('there was an error trying to execute that command!');
}
});
client.login(token);
Now on Discord, you will need to enable intents. To do this, go to the Discord Developer Portal, select your application, and go onto the Bot tab. If you scroll about half way down, you'll see a section called Privileged Gateway Intents. You need to tick Server Members Intent under that title. For what you're doing, Presence Intent shouldn't be required, but you can tick it in case you do ever need it.
making a discord bot in javascript with visual studio code but for some reason getting an error. I'll show you the code that is relevant first.
Overall trying to get a temporary mute function to work and I want to add it to the available commands which pops up when you hit !help. Table looks like this:
!help
classes I'm working with
Here is the index.js:
const { Client, Collection } = require("discord.js");
const { config } = require("dotenv");
const fs = require("fs");
const client = new Client({
disableEveryone: true
});
client.commands = new Collection();
client.aliases = new Collection();
client.categories = fs.readdirSync("./commands/");
config({
path: __dirname + "/.env"
});
["command"].forEach(handler => {
require(`./handlers/${handler}`)(client);
});
client.on("ready", () => {
console.log(`Hi, ${client.user.username} is now online!`);
client.user.setPresence({
status: "online",
game: {
name: "you get boostedβ€οΈ",
type: "Watching"
}
});
});
client.on("message", async message => {
const prefix = "!";
if (message.author.bot) return;
if (!message.guild) return;
if (!message.content.startsWith(prefix)) return;
if (!message.member) message.member = await message.guild.fetchMember(message);
const args = message.content.slice(prefix.length).trim().split(/ +/g);
const cmd = args.shift().toLowerCase();
if (cmd.length === 0) return;
let command = client.commands.get(cmd);
if (!command) command = client.commands.get(client.aliases.get(cmd));
if (command)
command.run(client, message, args);
});
client.login(process.env.TOKEN);
Here is tempmute:
bot.on('message', message => {
let args = message.content.substring(PREFIX.length).split(" ");
switch (args[0]) {
case 'mute':
var person = message.guild.member(message.mentions.users.first() || message.guild.members.get(args[1]));
if(!person) return message.reply("I CANT FIND THE USER " + person)
let mainrole = message.guild.roles.find(role => role.name === "Newbie");
let role = message.guild.roles.find(role => role.name === "mute");
if(!role) return message.reply("Couldn't find the mute role.")
let time = args[2];
if(!time){
return message.reply("You didnt specify a time!");
}
person.removeRole(mainrole.id)
person.addRole(role.id);
message.channel.send(`#${person.user.tag} has now been muted for ${ms(ms(time))}`)
setTimeout(function(){
person.addRole(mainrole.id)
person.removeRole(role.id);
console.log(role.id)
message.channel.send(`#${person.user.tag} has been unmuted.`)
}, ms(time));
break;
}
});
Here is the help.js which lists all commands
const { RichEmbed } = require("discord.js");
const { stripIndents } = require("common-tags");
module.exports = {
name: "help",
aliases: ["h"],
category: "info",
description: "Returns all commands, or one specific command info",
usage: "[command | alias]",
run: async (client, message, args) => {
if (args[0]) {
return getCMD(client, message, args[0]);
} else {
return getAll(client, message);
}
}
}
function getAll(client, message) {
const embed = new RichEmbed()
.setColor("RANDOM")
const commands = (category) => {
return client.commands
.filter(cmd => cmd.category === category)
.map(cmd => `- \`${cmd.name}\``)
.join("\n");
}
const info = client.categories
.map(cat => stripIndents`**${cat[0].toUpperCase() + cat.slice(1)}** \n${commands(cat)}`)
.reduce((string, category) => string + "\n" + category);
return message.channel.send(embed.setDescription(info));
}
function getCMD(client, message, input) {
const embed = new RichEmbed()
const cmd = client.commands.get(input.toLowerCase()) || client.commands.get(client.aliases.get(input.toLowerCase()));
let info = `No information found for command **${input.toLowerCase()}**`;
if (!cmd) {
return message.channel.send(embed.setColor("RED").setDescription(info));
}
if (cmd.name) info = `**Command name**: ${cmd.name}`;
if (cmd.aliases) info += `\n**Aliases**: ${cmd.aliases.map(a => `\`${a}\``).join(", ")}`;
if (cmd.description) info += `\n**Description**: ${cmd.description}`;
if (cmd.usage) {
info += `\n**Usage**: ${cmd.usage}`;
embed.setFooter(`Syntax: <> = required, [] = optional`);
}
return message.channel.send(embed.setColor("GREEN").setDescription(info));
}
ERROR:
Error message, bot not defined.
Overall trying to get a temporary mute function to work and I want to add it to the available commands which pops up when you hit !help. Table looks like this:
!help
I think the tempmute simply doesn't work because you use bot.on() instead of client.on(), which was defined in the index.js. I can't help you for the rest but everything is maybe related to this.