I have a discord bot made with discord.js, and I've been trying to add a Russian roulette command to it for a while now. I want it to have a 1 in 6 chance of the gun "going off", and if that happens, I want the user to be muted for 30 seconds. The randomizer works, but for the life of me I can't get the bot to mute a user. I've tried looking at similar questions, but couldn't find anything helpful. Here's what I have so far. Be warned, I'm teaching myself js atm, so the code is super trashy. Thanks for any help!
var Command = require("../../plugins/Command System/command-system/command");
class russianCommand extends Command {
constructor(client, cs)
{
super(client, {
name: "russian",
memberName: "russian",
description: "Play a game of Russian Roulette"
});
this.cs = cs;
}
async load(msg, args)
{
const userToMute = msg.author;
const muteRole = msg.guild.roles.find("name", "Muted");
const MUTE_TIME = 30 * 1000;
const answer = [
'🚬🔫 You\'re safe... For now...',
'🚬🔫 You\'re safe... For now...',
'🚬🔫 You\'re safe... For now...',
'🚬🔫 You\'re safe... For now...',
'🚬🔫 You\'re safe... For now...',
'🔥🔫 You died.',
]
msg.channel.send(answer[Math.floor(Math.random() * answer.length)]
)
if (answer === '🔥🔫 You died.')
userToMute.addRole(muteRole);
setTimeout(() => {
msg.userToMute.removeRoles(muteRole);
}, MUTE_TIME);
}
}
module.exports = russianCommand;
First userToMute should be member not user, a way u finding role is deprecated, you also using removeRoles instead of removeRole method, check discord.js docs https://discord.js.org/#/docs/main/stable/class/GuildMember?scrollTo=removeRole
let userToMute = msg.member;
let muteRole = msg.guild.roles.find(r => r.name === 'Muted');
let muteTime = 30 * 1000;
let random = Math.random() * 100;
// console.log(random);
if (random < 100 / 6) {
msg.channel.send('🔥🔫 You died.');
userToMute.addRole(muteRole);
setTimeout(() => userToMute.removeRole(muteRole), muteTime);
} else {
msg.channel.send('🚬🔫 You\'re safe... For now...');
}
Related
My friend has a discord server called Find A Friend and he wants me to code a bot to type a command to ask a series of questions and put it in a channel. People can see if anybody interests them and becomes friends with them. I have already coded part of it.
One of the questions it asks is: What games do you like?
My friend wants to make it able that the bot searches the other answers to this same question and dm the user if they have a game in common. I want to do the same for another question: What are some shows, movies, and anime that you like?
Here is my code for the series of questions:
const { Client, Message, MessageEmbed } = require("discord.js")
module.exports = {
name: "faf",
/**
* #param {Client} client
* #param {Message} message
* #param {String[]} args
*/
run: async (client, message, args) => {
message.delete()
const questions = [
"What is your usernames for any games you have including discord (is fine if you dont put them all but you MUST include your discord)",
"What is your age (not required)",
"What is your gender",
"Do you talk in Voicechannel or through text?",
"What games do you like?",
"What are some shows, movies, and anime that you like",
"Where are you from (not required)",
"Please state anything else you want to say"
]
let collectCounter = 0;
let endCounter = 0;
const filter = (m) => m.author.id === message.author.id;
const appStart = await message.author.send(questions[collectCounter++]);
const channel = appStart.channel;
const collector = channel.createMessageCollector(filter);
collector.on("collect", () => {
if(collectCounter < questions.length) {
channel.send(questions[collectCounter++])
} else {
channel.send('Your Find A Friend thread has been sent, Good Luck!')
collector.stop("fulfilled");
}
});
const appsChannel = client.channels.cache.get("831292911437086760");
collector.on('end', (collected, reason) => {
if(reason === 'fulfilled') {
let index = 1;
const mappedResponses = collected
.map((msg) => {
return `${index++}) ${questions[endCounter++]}\n-> ${msg.content}`;
}).join('\n\n')
appsChannel.send(
new MessageEmbed()
.setAuthor(
message.author.tag,
message.author.displayAvatarURL({ dynamic: true })
)
.setTitle('Friend Thread')
.setDescription(mappedResponses)
.setColor('RED')
.setTimestamp()
)
}
});
},
};
TL;DR I currently have a message collector bot that records responses to questions. How can I make the bot recognize when two people share common interests, such as games, movies, shows, or anime, based on their responses?
I'm having trouble coding my bot for people who have MANAGE_MESSAGES to be able to say 'badword'. Here is my code:
const Discord = require('discord.js')
const bot = new Discord.Client()
const token = process.env.DISCORD_TOKEN
let set = new Set(['badword'])
bot.on('message', msg => {
if (msg.author.bot) {
return
}
let wordArray = msg.content.split(' ')
if (!msg.member.hasPermission('MANAGE_MESSAGES')) {
for(var i = 0; i < wordArray.length; i++) {
if(set.has(wordArray[i].toLowerCase())) {
msg.delete()
msg.channel.send(`${msg.author.username}, you said a bad word.`)
break
}
console.log('message filtered')
}
}
})
bot.login(token)
The .permissions.has() is not working as according to this website https://discordjs.guide/additional-info/changes-in-v12.html#permissions-haspermission-s, it says that .hasPermission() / .hasPermissions() is now completely removed from v11 and added permissions.has(). Yes, my bot is upgraded to v12 so please help.
The correct way to use it is .hasPermission('MANAGE_MESSAGES')
if (!msg.member.hasPermission('MANAGE_MESSAGES'))
You're using the GuildMember class which uses the hasPermission() method. You were looking at the permission class.
https://discord.js.org/#/docs/main/stable/class/GuildMember
So I have figured out how to set up a simple database with discord.js in a users.json file and my !start cmnd works to create the users database, but when me and my cousin tried the !daily cmnds, the cmnd seems to be fine but I get this error: TypeError: Cannot read property 'a number' of undefined. I believe the number refers to my user number or database number (a number means an actual long number, not "a number").
Also here is the code that goes along with this that is in my index.js file:
var UserJSON = JSON.parse(Fs.readFileSync('./DB/users.json'));
UserJSON[message.author.id] = {
bal: 0,
lastclaim: 0,
}
Fs.writeFileSync('./DB/users.json', JSON.stringify(UserJSON));
let SuccessEmbed = new Discord.MessageEmbed();
SuccessEmbed.setTitle("**SUCCESS**");
SuccessEmbed.setDescription("You have joined the economy! type !help to get started");
message.channel.send(SuccessEmbed);
return;
}
if (args[0] == "daily") {
let userJSON = JSON.parse(Fs.readFileSync('./DB/users.json'));
if (Math.floor(new Date().getTime() - UserJSON[message.author.id].lastclaim) / (1000 * 60 * 60 * 24) < 1) {
let WarningEmbed = new Discord.MessageEmbed()
WarningEmbed.setTitle("**ERROR**");
WarningEmbed.setDescription("You have claimed today already");
message.channel.send(WarningEmbed);
return;
}
UserJSON[message.author.id].bal += 500;
UserJSON[message.author.id].lastclaim = new Date().getTime();
Fs.writeFileSync('./DB/users.json', JSON.stringify(UserJSON));
let SuccessEmbed = new Discord.MessageEmbed();
SuccessEmbed.setTitle("**SUCCESS**");
SuccessEmbed.setDescription("You have claimed a daily reward of 500 coins!");
message.channel.send(SuccessEmbed);
}
}
})
Also to specify, the ./DB/users.json refers to the folder DB for database and users.json is the file that stores the databases.
Here is what the user.json file looks like:
{"*my database number*":{"bal":0,"lastclaim":0},"*my cousin's database number*":{"bal":0,"lastclaim":0}}
Is there any code I need to add into my index.js file to stop this from happening. If possible, answer as soon as possible so I can get this error worked out. Thank You!
Edit: I somehow figured this out by re-doing it and this is the finished product if anyone wants to start an economy bot:
const Discord = require("discord.js");
const client = new Discord.Client();
const Fs = require("fs");
const prefix = "!";
client.on("ready", () => {
console.log("Ready!");
});
client.on("message", async (message) => {
if(message.content.startsWith(prefix)) {
var args = message.content.substr(prefix.length)
.toLowerCase()
.split(" ");
if (args[0] == "start") {
let UserJSON = JSON.parse(Fs.readFileSync("./DB/users.json"));
UserJSON[message.author.id] = {
bal: 0,
lastclaim: 0,
}
Fs.writeFileSync("./DB/users.json", JSON.stringify(UserJSON));
let SuccessEmbed = new Discord.MessageEmbed();
SuccessEmbed.setTitle("**SUCCESS**");
SuccessEmbed.setDescription("You have joined the economy! type !help to get started");
message.channel.send(SuccessEmbed);
return;
}
if (args[0] == "daily") {
let UserJSON = JSON.parse(Fs.readFileSync("./DB/users.json"));
if (Math.floor(new Date().getTime() - UserJSON[message.author.id].lastclaim) / (1000 * 60 * 60 * 24) < 1) {
let WarningEmbed = new Discord.MessageEmbed()
WarningEmbed.setTitle("**ERROR**");
WarningEmbed.setDescription("You have claimed today already");
message.channel.send(WarningEmbed);
return;
}
UserJSON[message.author.id].bal += 500;
UserJSON[message.author.id].lastclaim = new Date().getTime();
Fs.writeFileSync("./DB/users.json", JSON.stringify(UserJSON));
let SuccessEmbed = new Discord.MessageEmbed();
SuccessEmbed.setTitle("**SUCCESS**");
SuccessEmbed.setDescription("You have claimed a daily reward of 500 discord coins!");
message.channel.send(SuccessEmbed);
}
}
})
client.login('your token');
also remember to make a DB folder with an users.json file
I realized that the problem with the code is that instead of vars, it needed to be let before the UserJSON, so the line of code should read:
let UserJSON = JSON.parse(Fs.readFileSync("./DB/users.json"));
UserJSON[message.author.id] = {
bal: 0,
lastclaim: 0,
}
if (!args[1]) return message.channel.send('You need to specify a person!')
if (!args[2]) return message.channel.send('Please specify a time for how long the ban council will last.')
var tim = args[2]
const sweden = message.mentions.users.first()
message.react('👍').then(() => message.react('👎'))
const mappo = ['👍', '👎']
if (!args[1]) return message.channel.send('Please specify a person!')
if(message.guild){ //this will check if the command is being called from a server
const embad = new Discord.MessageEmbed()
.setTitle('Ban Council')
.addField('The Convicted:', `${sweden.tag}`)
.addField('Rules:', 'Vote on whether the convicted is guilty or not with the prompted reactions. The ban will end automatically in 5 seconds.')
message.channel.send(embad)
setTimeout(function(){
if(sweden){
const lyft = message.guild.member(sweden)
if(lyft){
if(message.reactions.cache.map(r => `${'👍'} ${r.users.cache.size}`)[0] > message.reactions.cache.map(r => `${'👍'} ${r.users.cache.size}`)[1]){
lyft.ban({ ression: 'Majority has exiled you from server. '}).then(() => {
message.reply(`The user ${december.tag} was banned as a result of a majority vote.`)
})
} else {
message.channel.send('The ban was cancelled.')
}
}else{
message.reply('The user is not in this server.')
}
}else{
message.reply('You need to specify a person!')
}
}, tim)
} else {
message.channel.send('Banning does not work here!')
}
It sends the "Ban cancelled" before it actually has the chance to take input. I've tried collectors, and it doesn't work because of the max: part, how can I resolve this problem? (Also it returns no errors)
This is in a case. (appending onto what feedback I got)
Firstly you should beautify your code before you post on stackoverflow, you could have removed the break keyword and just explain it was inside of a switch case
The reason it does not work is because you are checking the message's reaction, and not the embed that you send, so to fix this you need to assign a variable to message.channel.send(embad), but this is a promise so you need to await it, which requires an async function
lastly awaitReactions and createReactionCollector are probably better options,
So here's the new code:
(async () => {
if (!args[1]) return message.channel.send('You need to specify a person!');
if (!args[2]) return message.channel.send('Please specify a time for how long the ban council will last.')
if (!message.guild) return message.channel.send('Banning does not work here');
var tim = args[2]
const sweden = message.mentions.member.first()
const mappo = ['👍', '👎']
message.react('👍').then(() => message.react('👎'))
const embad = new Discord.MessageEmbed()
.setTitle('Ban Council')
.addField('The Convicted:', `${sweden.tag}`)
.addField('Rules:', 'Vote on whether the convicted is guilty or not with the prompted reactions. The ban will end automatically in 5 seconds.')
const embedMessage = await message.channel.send(embad);
setTimeout(function () {
if (!sweden) return message.reply('You need to mention a person');
const filter = (reaction) => mappo.includes(reaction.emoji.name);
embad.awaitReactions(filter, { time: 5000 })
.then(collection => {
//not the most optimal way to do it
const emoji1 = collection.find(e => e.emoji.name === '👍');
const emoji2 = collection.find(e => e.emoji.name === '👎');
//both default to 0
const upvotes = emoji1 && emoji1.users.size || 0;
const downvotes = emoji2 && emoji2.users.size || 0;
if (upvotes > downvotes) {
lyft.ban({ reason: 'Majority has exiled you from server. ' })
.then(() => message.reply(`The user ${december.tag} was banned as a result of a majority vote.`));
} else {
message.channel.send('The ban was cancelled.');
}
})
.catch(console.error);
}, tim);
})();
It's been around 8 months since I made this post, and I found the answer, and an even more effective way to do it. I won't post the entire code, as it's pretty long and not very neat. However, this is a much more effective way of counting reactions.
My Original Code was:
const upvotes = message.reactions.cache.map(r => ${'👍'} ${r.users.cache.size})[0]
const downvotes = message.reactions.cache.map(r => ${'👎'} ${r.users.cache.size})[1]
It doesn't work very well either.
const [upvoteReaction, downvoteReaction] = message.reactions.cache.first(2);
const upvotes = upvoteReaction.users.cache.size;
const downvotes = downvoteReaction.users.cache.size;
It takes the number of reactions from the first two reactions on the message. Seeing as how the only reactions are thumbs up and thumbs down, it will get the numbers from both of them. From there, you can just compare the two.
Basically im trying to run this code
const Discord = require('discord.js');
const fs = require('fs');
const db = require("quick.db");
module.exports.run = async (bot, message, args) => {
let user = message.member;
let vic = db.get(`vic_${user.id}`);
console.log("Activating auto start command!");
let intro = new Discord.RichEmbed()
.setTitle("You have dosed on vicodin and you are now immune to all shots")
.setColor('#00cc00');
let nopill = new Discord.RichEmbed()
.setTitle("You do not own this drug")
.addField("Error", "<:bluepill:713790607901982780> --- **You do not own any `Vicodin Pills`, please purchase off of the black market** --- <:bluepill:713790607901982780>")
.setFooter("Must own first")
let pill = new Discord.RichEmbed()
.setTitle("You have already dosed")
.addField("Error", "<:bluepill:713790607901982780> --- **You have already dosed on `Vicodin Pills`, please wait until the effect wear off to dose again** --- <:bluepill:713790607901982780>")
.setFooter("Already dosed")
if (args[0].startsWith("testing")) {
if (vic === null) return message.channel.send(nopill)
} else if (args[0].startsWith("vicodin")) {
if (vic === 0) return message.channel.send(nopill)
if (vic === 2) return message.channel.send(pill)
message.channel.send(intro)
db.set(`vic_${user.id}`, 2)
console.log(`${user} just dosed vicodine`);
setTimeout(() => {
console.log(`this is a test by zuc`)
db.set(`vic_${user.id}`, 0)
}, 1800000);
}
}
What it dose is when a user run the Dose command it makes them dose on the pill, im trying to make the pill/dose remove after a certain amount of time using db.subtract, since im using glitch.com to do this, the setTimeout isnt doing what i want it to after that time.
Change the timeout code to:
setTimeout(() => {
console.log(`this is a test by zuc`)
db.delete(`vic_${user.id}`);
db.add(`vic_${user.id}`, 0);
}, 1800000);