Making only admins execute commands - discord

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!`
};

Related

How to fix this.uuid is not a function discord.js

Hello actually I wanted to make minecraft playerinfo command but I wanted it and I got it on github it was a bit old but I tried to convert it to discord.js v14 code. But I got this error.
TypeError: this.getUuid is not a function
Can you help me please heres the original code: https://github.com/Jystro/Minecraft-info-bot/blob/master/commands/player.js
const mojang = require('mojang-api');
const https = require('https');
const {
EmbedBuilder
} = require('discord.js');
module.exports = {
name: 'playerinfo',
description: 'Diplays player\'s name, uuid, skin, cape and name history',
run: async (client, message, args) => {
//check that a value is sent
if(!args.length) {
message.reply('please specify the player\'s uuid');
return;
}
let uuid = args[0]
//get uuid
this.getUuid(args[0], (err, uuid) => {
if(err) {
message.channel.send('An error occurred. This might be because the player does not exist');
return;
}
//check that uuid exists
mojang.profile(uuid, (err, resp) => {
if(err) {
message.reply('that player\'s uuid does not exist');
return;
}
//get name history
mojang.nameHistory(uuid, (err, resp1) => {
if(err) {
message.reply('there was an error trying to retrieve the data');
console.log(err);
return;
}
let nameHistory = [];
resp1.forEach(element => {
nameHistory.push(element.name);
});
nameHistory = nameHistory.join(', ');
//create embed message
const embedMessage = new EmbedBuilder()
.setColor('Random')
.setTitle(resp.name)
.setDescription(resp.name + "'s profile")
.setThumbnail('https://crafatar.com/avatars/' + resp.id + '.png?overlay')
.addFields(
{
name: 'Name',
value: resp.name
},
{
name: 'UUID',
value: resp.id
},
{
name: 'Skin',
value: 'https://crafatar.com/skins/' + resp.id + '.png'
})
.setImage('https://crafatar.com/renders/body/' + resp.id + '.png?overlay')
//check if cape exists
let cape = 'https://crafatar.com/capes/' + resp.id + '.png';
const req = https.request(cape, res => {
if(res.statusCode == 200) {
embedMessage.fields.push({ name: 'Cape', value: cape });
}
embedMessage.fields.push({ name: 'Name history', value: nameHistory });
//send embed
message.channel.send({ embed: embedMessage });
});
req.on('error', err => {
console.log(err);
message.reply('there was an error while retrieving the cape');
})
req.end();
});
});
})
},
//function to get uuid from uuid/name
getUuid(value, cb) {
let error = false;
let regex = /^[a-f0-9]{32}$/i //regex for uuids
if(!value.match(regex)) {
mojang.nameToUuid(value, (err, resp) => {
if(err || !resp.length) {
error = true;
cb(error, null);
return;
}
cb(error, resp[0].id);
});
}
else { cb(error, value); }
}
}
The issue is your usage of the this keyword and arrow functions.
The main takeaway is this:
Arrow functions don't redeclare this, while anonymous functions do.
This means that when you call the run() method somewhere else in the code, the this keyword in the run method will refer to whatever this is in the current context of where it was executed, which isn't what you want.
To redeclare this to your object, you should rewrite your arrow function as an anonymous function.
module.exports = {
run: async function(client, message, args) {
// you can now safely use `this` in this method
}
}

How to read file with async/await?

const Discord = require('discord.js');
const { MessageEmbed } = require('discord.js');
const fs = require('fs');
module.exports = {
name: 'prefix',
aliases: ['setprefix'],
description: 'Установить новый префикс на вашем сервере',
execute(message, args) {
if (!message.member.hasPermission('MANAGE_SERVER'))
return message.reply(' Не не не.');
if (!args[0] || args[0 == 'help'])
return message.reply(`Использование: prefix <Тут ваш префикс> `);
let prefixes = JSON.parse(fs.readFileSync('./prefixes.json', 'utf8'));
prefixes[message.guild.id] = {
prefix: args[0]
};
fs.writeFile('./prefixes.json', JSON.stringify(prefixes), (err) => {
if (err) console.log(err)
})
let pEmbed = new MessageEmbed()
.setColor('#000001')
.setTitle('Префикс изменён!')
.setDescription(`Новый префикс на сервере **${args[0]}**`)
message.channel.send(pEmbed)
message.delete({ timeout: 10000 })
}}
let prefixes = JSON.parse(fs.readFileSync('./prefixes.json', 'utf8'));
if (!prefixes[message.guild.id]) {
prefixes[message.guild.id] = {
prefix: config.prefix
};
}
let prefix = prefixes[message.guild.id].prefix;
if i'm change prefix, bot stopping music.
Tried to do it via ' ReadFile`, it returns me a callback error
I know I could use readFileSync, but if I do, I know I'll never understand async/await and I'll just bury the issue.
UPD:
client.on('message', async (message) => {
if (message.author.bot) return;
if (!message.guild) return;
let prefixes = JSON.parse(fs.readFileSync('./prefixes.json', 'utf8'));
if (!prefixes[message.guild.id]) {
prefixes[message.guild.id] = {
prefix: config.prefix
};
}
let prefix = prefixes[message.guild.id].prefix;
// let msgArray = message.content.split(" ");
// let cmd = msgArray[0];
// if(cmd.slice(0, prefix.length) !== prefix) return;
// let args = msgArray.slice(1);
// let cmdFile = client.commands.get(cmd.slice(prefix.length))
// if(cmdFile) cmdFile.run(client, message, args);
const prefixRegex = new RegExp(`^(<#!?${client.user.id}>|${escapeRegex(prefix)})\\s*`);
if (!prefixRegex.test(message.content)) return;
const [matchedPrefix] = message.content.match(prefixRegex);
const args = message.content.slice(matchedPrefix.length).trim().split(/ +/);
const commandName = args.shift().toLowerCase();
const command =
client.commands.get(commandName) ||
client.commands.find((cmd) => cmd.aliases && cmd.aliases.includes(commandName));
if (message.content.startsWith(prefix) && commandFiles) {
if (message.deletable) {
try {
await message.delete();
} catch(e) {
console.error(e);
}
}
}
if (!command) return;
if (!cooldowns.has(command.name)) {
cooldowns.set(command.name, new Collection());
}
const now = Date.now();
const timestamps = cooldowns.set(command.name);
const cooldownAmount = (command.cooldown || 1) * 1000;
if (timestamps.has(message.author.id)) {
const expirationTime = timestamps.get(message.author.id) + cooldownAmount;
if (now < expirationTime) {
const timeLeft = (expirationTime - now) / 1000;
return message.reply(
`Пожалуйста подождите ${timeLeft.toFixed(1)} секунд перед повторным использованием \`${command.name}\` команд.`
);
}
}
timestamps.set(message.author.id, now);
setTimeout(() => timestamps.delete(message.author.id), cooldownAmount);
try {
command.execute(message, args);
} catch (error) {
console.error(error);
message.reply('Произошла ошибка при выполнении этой команды.')
.then(message => message.delete({ timeout: 5000 }))
.catch(console.error);
}
});
fs doesn't offer the possibility to give the Promise of a file, but it can read a file asynchronously with a callback instead of a promise. But in the fs module, you can use fs/promises (aka fs.promises). Here's the same code. I corrected 1 problem, added the fsp var (fs promises), and used it to read your prefixes.json file. fs.readFileSync is totally fine though.
const Discord = require("discord.js");
const { MessageEmbed } = require("discord.js");
const fs = require("fs");
const fsp = fs.promises; // ++
module.exports = {
name: "prefix",
aliases: ["setprefix"],
description: "Установить новый префикс на вашем сервере",
async execute(message, args) {
if (!message.member.hasPermission("MANAGE_SERVER"))
return message.reply(" Не не не.");
if (!args[0] || args[0] == "help") /** Correction */
return message.reply(`Использование: prefix <Тут ваш префикс> `);
let prefixes = JSON.parse(await fsp.readFile("prefixes.json", "utf8")); // Using fsp
prefixes[message.guild.id] = {
prefix: args[0],
};
fs.writeFile("./prefixes.json", JSON.stringify(prefixes), (err) =>
err ? console.error(err) : null
);
let pEmbed = new MessageEmbed()
.setColor("#000001")
.setTitle("Префикс изменён!")
.setDescription(`Новый префикс на сервере **${args[0]}**`);
message.channel.send(pEmbed);
message.delete({ timeout: 10000 });
},
};

Random Meme Command (discord.js v12)

I'm trying to make a 'random meme' command for my Discord Bot. I'm new to working with APIs, but I've tried my best.
The problem is, when I type the command, nothing happens. There are no errors, but the bot doesn't send anything in discord.
This is my code:
if (command === "meme")
async (client, message, args) => {
const subReddits = ["dankmeme", "meme", "me_irl"];
const random = subReddits[Math.floor(Math.random() * subReddits.length)];
const img = await randomPuppy(random);
const embed = new Discord.MessageEmbed()
.setColor(16776960)
.setFooter("test")
.setImage(img)
.setTitle(`Random Meme requested by <#${message.author.tag}>`)
.setURL(`https://reddit.com/r/${random}`)
message.channel.send(embed);
}
Here Is One That Will Show Info About The Meme
if(command === "meme") {
const subReddits = ["dankmeme", "meme", "me_irl"];
const random = subReddits[Math.floor(Math.random() * subReddits.length)];
try {
const { body } = await snekfetch
.get('https://www.reddit.com/r/${random}.json?sort=top&t=week')
.query({ limit: 800 });
const allowed = message.channel.nsfw ? body.data.children : body.data.children.filter(post => !post.data.over_18);
if (!allowed.length) return message.channel.send('It seems we are out of memes');
const randomnumber = Math.floor(Math.random() * allowed.length)
const embed = new Discord.RichEmbed()
.setColor(0x00A2E8)
.setTitle(allowed[randomnumber].data.title)
.setDescription("Posted by: " + allowed[randomnumber].data.author)
.setImage(allowed[randomnumber].data.url)
.addField("Other info:", "Up votes: " + allowed[randomnumber].data.ups + " / Comments: " + allowed[randomnumber].data.num_comments)
.setFooter("r/" + random)
message.channel.send(embed)
} catch (err) {
return console.log(err);
}
}
Let Me Know If It Don't Work, But I Should
client.on('message', message => {
if (!message.content.startsWith(prefix) || message.author.bot) return;
const args = message.content.slice(prefix.length).trim().split(/ +/);
const command = args.shift().toLowerCase();
if (command === "meme") {
async (client, message, args) =>
const subReddits = ["dankmeme", "meme", "me_irl"];
const random = subReddits[Math.floor(Math.random() * subReddits.length)];
const img = await randomPuppy(random);
const embed = new Discord.MessageEmbed()
.setColor(16776960)
.setFooter("test")
.setImage(img)
.setTitle(`Random Meme requested by <#${message.author.tag}>`)
.setURL(`https://reddit.com/r/${random}`)
message.channel.send(embed);
}
});
This should work, not quite sure, haven't tested it. (You can put in a command handler your self)
if (command === "meme")
async (client, message, args) => {
const fetch = require('node-fetch');
let userAvatar = message.author.avatarURL({ format: "png", dynamic: true, size: 2048 }); // this is just the users icon, u can remove it if you want.
fetch(`https://meme-api.herokuapp.com/gimme`)
.then(res => res.json())
.then(async json => {
const embed = new MessageEmbed()
.setAuthor(`${json.title}`, `${userAvatar + "?size=2048"}`, `${json.postLink}`)
.setImage(`${json.url}`)
.setFooter(`👍${json.ups} | ${json.subreddit}`)
.setColor("RANDOM")
message.channel.send(embed).catch((error) => {
console.log("An error has occured on the \"meme\" command\n", error)
})
}
Here you go! I've tested this on my own command handler.

Voice Channel Detection Erorr

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

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