Voice Channel Detection Erorr - discord

When I'm Trying To Make My Discord Music Bot I Get An Error In Discord Not The Command Line Though, It Cannot Tell If I'm In A Voice Channel Or Not
Here's My Code
if (message.author.bot) return;
if (!message.content.startsWith(prefix)) return;
const serverQueue = queue.get(message.guild.id);
if (message.content.startsWith(`${prefix}play`)) {
execute(message, serverQueue);
return;
} else if (message.content.startsWith(`${prefix}skip`)) {
skip(message, serverQueue);
return;
} else if (message.content.startsWith(`${prefix}stop`)) {
stop(message, serverQueue);
return;
} else {
message.channel.send('You need to enter a valid command!')
}
});
process.on('unhandledRejection', error => console.error('Uncaught Promise Rejection', error));
async function execute(message, serverQueue) {
const args = message.content.split(' ');
const voiceChannel = message.member.voiceChannel;
if (!voiceChannel) return message.channel.send('You need to be in a voice channel to play music!');
const permissions = voiceChannel.permissionsFor(message.bot.user);
if (!permissions.has('CONNECT') || !permissions.has('SPEAK')) {
return message.channel.send('I need the permissions to join and speak in your voice channel!');
}
const songInfo = await ytdl.getInfo(args[1]);
const song = {
title: songInfo.title,
url: songInfo.video_url,
};
if (!serverQueue) {
const queueContruct = {
textChannel: message.channel,
voiceChannel: voiceChannel,
connection: null,
songs: [],
volume: 5,
playing: true,
};
queue.set(message.guild.id, queueContruct);
queueContruct.songs.push(song);
try {
var connection = await voiceChannel.join();
queueContruct.connection = connection;
play(message.guild, queueContruct.songs[0]);
} catch (err) {
console.log(err);
queue.delete(message.guild.id);
return message.channel.send(err);
}
} else {
serverQueue.songs.push(song);
console.log(serverQueue.songs);
return message.channel.send(`${song.title} has been added to the queue!`);
}
}
function skip(message, serverQueue) {
if (!message.member.voiceChannel) return message.channel.send('You have to be in a voice channel to stop the music!');
if (!serverQueue) return message.channel.send('There is no song that I could skip!');
serverQueue.connection.dispatcher.end();
}
function stop(message, serverQueue) {
if (!message.member.voiceChannel) return message.channel.send('You have to be in a voice channel to stop the music!');
serverQueue.songs = [];
serverQueue.connection.dispatcher.end();
}
function play(guild, song) {
const serverQueue = queue.get(guild.id);
if (!song) {
serverQueue.voiceChannel.leave();
queue.delete(guild.id);
return;
}
const dispatcher = serverQueue.connection.playStream(ytdl(song.url))
.on('end', () => {
console.log('Music ended!');
serverQueue.songs.shift();
play(guild, serverQueue.songs[0]);
})
.on('error', error => {
console.error(error);
});
dispatcher.setVolumeLogarithmic(serverQueue.volume / 5);
}
I Found It On This Website https://medium.com/free-code-camp/how-to-create-a-music-bot-using-discord-js-4436f5f3f0f8
And When I Start The Code It Says I'm Not In One,
Any Type Of Feedback Would Be Greatly Appreciated!

Try this
if (!message.member.voice.channel)
return message.reply('you are not in a voice channel'),

The problem comes from the fact that you're using the GuildMember.voiceChannel property, which exists only in discord.js#v11. The v12 equivalent is GuildMember.voice.channel, you can use it like this:
// You can use this as before, since it's the same VoiceChannel element
const voiceChannel = message.member.voice.channel

Related

Making only admins execute commands

The problem is that I couldn't figure out a way to make this command only accessible by admins. I've tried using if statements, however, I failed. message. I am not sure if member. roles. cache. has( ' 732524984777572363 ' ) would allow members with the role ID 732524984777572363 to execute it since there's already an if statement.
const Discord = require('discord.js');
const fs = require('fs');
const cooldown = new Set();
module.exports.run = async (client, msg, args, config) => {
if(cooldown.has(msg.author.id)) {
msg.reply(`You need to wait ${config.COOLDOWN} minutes to use this command again!`)
.then((m) => {
msg.delete();
setTimeout(() => {
m.delete();
}, 5000);
});
} else {
fs.readFile('./accounts/crunchy.txt', 'utf8', function(err, data) {
if (err) throw err;
data = data + '';
var lines = data.split('\n');
let account = lines[Math.floor(Math.random() * 1)];
fs.writeFile('./accounts/crunchy.txt', lines.slice(1).join('\n'), function(err) {
if(err) throw err;
});
let embed = new Discord.RichEmbed()
.addField('Rate Us Here | قيمنا هنا ', `<#915***********80>`)
.addField('CrunchyRoll Account',`\n**${account}**`)
.setThumbnail('**************************')
.setColor("#363940")
.setFooter('Bot made by ******')
.setTimestamp();
msg.author.send(embed);
msg.reply('I\'ve sent you the account! Please check your DM!')
.then(m => {
setTimeout(() => {
m.delete();
}, 900000);
});
cooldown.add(msg.author.id);
setTimeout(() => {
cooldown.delete(msg.author.id);
}, config.COOLDOWN * 60 * 1000);
});
}
};
module.exports.help = {
name: `CrunchyRoll`,
description: `Sends you a CrunchyRoll account!`
};```
Simply adding a role check and a server check will prevent any issues!
The first line would be:
if(!msg.guild) return;
This line makes sure the user is running the command in a server(guild), this prevents a member role from being undefined or null.
The second line would be:
if(!msg.author.roles.cache.has('ROLE_ID_HERE')) return;
This prevents a user from running a command if they do not have a specific role.
The final code would be:
if(!msg.guild) return;
if(!msg.author.roles.cache.has('ROLE_ID_HERE')) return;
You will need to add this to the top of your code in order for it to work as you'd like.
const Discord = require('discord.js');
const fs = require('fs');
const cooldown = new Set();
module.exports.run = async (client, msg, args, config) => {
if(!msg.guild) return;
if(!msg.member.roles.cache.has('ROLE_ID_HERE')) return;
if(cooldown.has(msg.author.id)) {
msg.reply(`You need to wait ${config.COOLDOWN} minutes to use this command again!`)
.then((m) => {
msg.delete();
setTimeout(() => {
m.delete();
}, 5000);
});
} else {
fs.readFile('./accounts/crunchy.txt', 'utf8', function(err, data) {
if (err) throw err;
data = data + '';
var lines = data.split('\n');
let account = lines[Math.floor(Math.random() * 1)];
fs.writeFile('./accounts/crunchy.txt', lines.slice(1).join('\n'), function(err) {
if(err) throw err;
});
let embed = new Discord.RichEmbed()
.addField('Rate Us Here | قيمنا هنا ', `<#915***********80>`)
.addField('CrunchyRoll Account',`\n**${account}**`)
.setThumbnail('**************************')
.setColor("#363940")
.setFooter('Bot made by ******')
.setTimestamp();
msg.author.send(embed);
msg.reply('I\'ve sent you the account! Please check your DM!')
.then(m => {
setTimeout(() => {
m.delete();
}, 900000);
});
cooldown.add(msg.author.id);
setTimeout(() => {
cooldown.delete(msg.author.id);
}, config.COOLDOWN * 60 * 1000);
});
}
};
module.exports.help = {
name: `CrunchyRoll`,
description: `Sends you a CrunchyRoll account!`
};

How to create an embedded Queue list for discord bot the updates

I am making a discord bot that plays music. Currently, the embedded list works fine and every time I add a song to the queue, the list deletes itself and creates a new embedded queue list updated with the new song. However, I can't figure out how to make this queue list update itself when I use the skip button I have implemented (I'm new to programming).
Example of how it works now:
Pressing the button skips the song, but as stated before, how would I refresh the list every time I press the button?
const ytdl = require('ytdl-core');
const ytSearch = require('yt-search');
process.setMaxListeners(1000000000000);
const { MessageEmbed } = require('discord.js');
ffmpeg_options = {
'options': '-vn',
"before_options": "-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5"
}
//Global queue for your bot. Every server will have a key and value pair in this map. { guild.id, queue_constructor{} }
const queue = new Map();
module.exports = {
name: 'play',
aliases: ['skip', 'stop'], //We are using aliases to run the skip and stop command follow this tutorial if lost: https://www.youtube.com/watch?v=QBUJ3cdofqc
cooldown: 0,
description: 'Advanced music bot',
async execute(message, args, cmd, button, skip, client, Discord){
//Checking for the voicechannel and permissions (you can add more permissions if you like).
const voice_channel = message.member.voice.channel;
if (!voice_channel) return message.channel.send('You need to be in a channel to execute this command!');
const permissions = voice_channel.permissionsFor(message.client.user);
if (!permissions.has('CONNECT')) return message.channel.send('You dont have the correct permissions.');
if (!permissions.has('SPEAK')) return message.channel.send('You dont have the correct permissions.');
//This is our server queue. We are getting this server queue from the global queue.
const server_queue = queue.get(message.guild.id);
let checker = false;
if (cmd === 'stop' && !server_queue){
return message.channel.send("The bot is not in the channel, you dont have to stop him.");
}
//If the user has used the play command
if (cmd === 'stop') stop_song(message, server_queue);
else if(skip === true) {
skip_song(message, server_queue);
}
else if (cmd === message.content){
//if (!args.length) return message.channel.send('You need to send the second argument!');
let song = {};
//If the first argument is a link. Set the song object to have two keys. Title and URl.
if (ytdl.validateURL(args[0])) {
const song_info = await ytdl.getInfo(args[0]);
song = { title: song_info.videoDetails.title, url: song_info.videoDetails.video_url }
message.delete({ timeout:1000 })
} else {
//If there was no link, we use keywords to search for a video. Set the song object to have two keys. Title and URl.
const video_finder = async (query) =>{
const video_result = await ytSearch(query);
return (video_result.videos.length > 1) ? video_result.videos[0] : null;
}
const video = await video_finder(args.join(' '));
if (video){
song = { title: video.title, url: video.url }
} else {
message.channel.send('Error finding video.');
}
message.delete({ timeout:1000 })
}
if (skip === true && server_queue) {
}
//If the server queue does not exist (which doesn't for the first video queued) then create a constructor to be added to our global queue.
if (!server_queue){
const queue_constructor = {
voice_channel: voice_channel,
text_channel: message.channel,
connection: null,
songs: []
}
//Add our key and value pair into the global queue. We then use this to get our server queue.
queue.set(message.guild.id, queue_constructor);
queue_constructor.songs.push(song);
//Establish a connection and play the song with the vide_player function.
try {
const connection = await voice_channel.join();
queue_constructor.connection = connection;
video_player(message.guild, queue_constructor.songs[0]);
} catch (err) {
queue.delete(message.guild.id);
message.channel.send('There was an error connecting!');
throw err;
}
} else {
server_queue.songs.push(song);
message.channel.bulkDelete(2)
.then(messages => console.log(`Bulk deleted ${messages.size} messages`))
.catch(console.error);
//where I actually make the embeded queue list
const queueList = server_queue.songs.map((song, i) => `[${++i}] - ${song.title}`);
const queueEmbed = new MessageEmbed()
.setDescription(queueList);
return message.channel.send(queueEmbed, button);
}
}
}
}
const video_player = async (guild, song) => {
const song_queue = queue.get(guild.id);
//If no song is left in the server queue. Leave the voice channel and delete the key and value pair from the global queue.
if (!song) {
song_queue.voice_channel.leave();
queue.delete(guild.id);
return;
}
const stream = ytdl(song.url, { filter: 'audioonly' });
song_queue.connection.play(stream, { seek: 0, volume: 0.5 })
.on('finish', () => {
song_queue.songs.shift();
video_player(guild, song_queue.songs[0]);
});
//await song_queue.text_channel.send(`🎶 Now playing **${song.title}**`)
}
const skip_song = (message, server_queue) => {
if (!message.member.voice.channel) return message.channel.send('You need to be in a channel to execute this command!');
if(!server_queue){
return message.channel.send(`There are no songs in queue 😔`,);
}
server_queue.connection.dispatcher.end();
//message.delete({ timeout:20000})
}
const stop_song = (message, server_queue) => {
if (!message.member.voice.channel) return message.channel.send('You need to be in a channel to execute this command!');
server_queue.songs = [];
server_queue.connection.dispatcher.end();
//message.delete({ timeout:20000})
}
return message.channel.send(queueEmbed, button);
That line above returns a Promise which resolves to a Message object. Change it to something like this:
const embeddedMessage = await message.channel.send(queueEmbed, button);
return embeddedMessage;
So when a user clicks the skip button you can simply call
embeddedMessage.edit(your_new_embed, button)

discord.js Welcome message

yea hello I'm making a discord.js bot and I have this code currently and it REFUSES to send a message (it doesn't error either
let chx = db.get(`welchannel_${member.guild.id}`);
if (chx === null) {
return;
}
let data = await canva.welcome(member, { link: "https://i.pinimg.com/originals/f3/1c/39/f31c39d56512dc8fbf30f9d0fb3ee9d3.jpg" })
const attachment = new discord.MessageAttachment(
data,
"welcome-image.png"
);
client.channels.cache.get(chx).send("Welcome to our Server " + member.user.username, attachment);
});
and then i have welcome.js with this code but it aint sending and i cant figure out why ...
const db = require("quick.db")
module.exports = {
name: "setwelcome",
category: "moderation",
usage: "setwelcome <#channel>",
description: "Set the welcome channel",
run: (client, message, args) => {
let channel = message.mentions.channels.first()
if(!channel) {
return message.channel.send("Please Mention the channel first")
}
//Now we gonna use quick.db
db.set(`welchannel_${message.guild.id}`, channel.id)
message.channel.send(`Welcome Channel is set to ${channel}`)
}
}```
just a guess that your not checking for undefined on CHX
if (chx === null && chx === undefined) {
return;
}
This is my modified code from my discord bot (just to keep it general).
this.client.on('ready', () => {
if(botChannelID){
this.client.channels.fetch(botChannelID).then(ch => {
ch.send(`Welcome message here.`);
}).catch(e => {
console.error(`Error: ${e}`);
});
}
//Other stuff. Blah blah blah...
});

So I am trying to ask a question to retrieve a mentioned channel but doesn't work

So I am trying to make my giveaway bot but can't make a create command so the person can add more details about the giveaway! Thus, I need questions but everytime I try it never goes well!
message.channel.send("Please mention the channel you want the giveaway to be in! **e.g #channel**");
try {
let msgs = await message.channel.awaitMessages(u2=>u2.author.id===message.author.id, { time: 15000, max: 1, errors: ["time"]});
if(parseInt(msgs.first().content)==mention.channel) {
const Channel = message.mentions.channels.first();
await Channel.send("HEY")
}
else {
message.channel.send("You did not mentioned a channel!");
}
}catch(e) {
return message.channel.send("Command Cancel!")
}
It either returns to the catch(e) line or "You did not mentioned a channel!"!
This should be what you want i think. (works with mentioning the channel, providing a channel ID or providing a channel name)
message.channel.send("Please mention the channel you want the giveaway to be in! **e.g #channel**");
let channel;
let response;
try {
response = await message.channel.awaitMessages(msg => msg.author.id === message.author.id, { max: 1, time: 1000*60*3, errors: ['time'] })
} catch {
return message.channel.send("Command Cancel!")
}
if (response.first().mentions.channels.first()) {
channel = response.first().mentions.channels.first()
} else if (!isNaN(response.first().content) && message.guild.channels.cache.get(response.first().content)) {
channel = message.guild.channels.cache.get(response.first().content)
} else if (isNaN(response.first().content) && message.guild.channels.cache.find(c => c.name.toLowerCase() === response.first().content.toLowerCase())) {
channel = message.guild.channels.cache.find(c => c.name.toLowerCase() === response.first().content.toLowerCase())
}
if (channel) {
await channel.send("HEY")
} else {
return message.channel.send("You did not mentioned a channel!");
}

Discord.js command handler problems

I've been trying to fix a command handler for 3 hours now, but anytime I try to add a custom command nothing happens. It loads the command, but when the command is run it does nothing. Here's some code:
index.js:
const commandFiles = fs.readdirSync('./commands').filter(file => file.endsWith('.js'));
for (const file of commandFiles) {
const command = require(`./commands/${file}`);
console.log(`[LOG] Loaded command ${file}`);
client.commands.set(command.name, command);
}
commands/kick.js:
const fs = require('fs');
var moment = require('moment');
var logger = fs.createWriteStream(`./logs/${moment().format('MM-DD-YYYY')}.log`, {
flags: 'a'
});
module.exports = {
name: "kick",
category: "moderation",
description: "Kicks the mentioned user.",
usage: "<imputs>",
run: (client, message, args) => {
let reason = args.slice(1).join(' ');
let user = message.mentions.users.first();
if (message.mentions.users.size < 1) return message.reply('You must mention someone to kick them.').then(msg => { msg.delete(10000) }).catch(console.error);
if (user.id === message.author.id) return message.reply("You cannot kick yourself.").then(msg => { msg.delete(10000) });
if (user.id === client.user.id) return message.reply("You cannot kick me.").then(msg => { msg.delete(10000) });
if (!message.member.hasPermission("KICK_MEMBERS")) return message.reply("You don't have the **Kick Members** permission!").then(msg => { msg.delete(10000) });
if (reason.length < 1) reason = 'No reason supplied';
if (!message.guild.member(user).kickable) return message.reply('I could not kick that member').then(msg => { msg.delete(10000) });
message.delete();
message.guild.member(user).kick();
const embed = new Discord.RichEmbed()
.setColor(0x0000FF)
.setTimestamp()
.addField('Action:', 'Kick')
.addField('User:', `${user.username}#${user.discriminator} (${user.id})`)
.addField('Moderator:', `${message.author.username}#${message.author.discriminator}`)
.addField('Reason', reason)
.setFooter(`© NetSync by Towncraft Developers`);
let logchannel = message.guild.channels.find('name', 'logs');
if (!logchannel){
message.channel.send(`Successfully kicked ${user.username}#${user.discriminator}.`).then(msg => { msg.delete(10000) });
logger.log(`[LOG] [KICK] ${user.username}#${user.discriminator} (${user.id}) was kicked by ${message.author.username}#${message.author.discriminator}.`);
}else{
message.channel.send(`Successfully kicked ${user.username}#${user.discriminator}. I\'ve also logged the kick in <#${logchannel.id}>.`).then(msg => { msg.delete(10000) });
client.channels.get(logchannel.id).send({embed});
}
if(user.bot) return;
return message.mentions.users.first().send({embed}).catch(e =>{
if(e) return
});
}
}
Like I said, been trying to do this for 3 hours now, and I'm stumped. If someone could tell me what I did wrong that'd be awesome, thanks.
You need execute command in you main.js file on bot.on('message' block.
Like this:
client.on('message', message => {
if (message.channel.type === "dm") return;
let prefix = '!'
let messageArray = message.content.split(" ");
let cmd = messageArray[0];
let args = messageArray.slice(1);
if (!message.content.startsWith(prefix)) return;
let commandfile = client.commands.get(cmd.slice(prefix.length));
if (commandfile) commandfile.run(client, message, args, botconfig);
})

Resources