Reason after blacklisting command Discord.js - javascript

I want to add a reason to my blacklists (with the command !blacklist {userid} {reason}) which are visible in the embeds below like .addField ("๐Ÿ’ฌ Reason:", somecode) how can I fix this?
if (command === "blacklist") {
if(!config["allowed-users"].includes(message.member.id)) return;
const user = client.users.cache.get(args[0]);
if(!user) {
return message.channel.send("This user does not exist")
}
if(blacklist.has(user.id)) {
return message.channel.send("This user is already on the blacklist")
}
blacklist.set(user.id, 'blacklisted');
let set = db.fetch(`g_${message.guild.id}`);
var embed = new Discord.MessageEmbed()
.setTitle(":warning: Blacklisted :warning:")
.setColor('#fc5a03')
.addField("๐Ÿ‘ฎ Moderator:", message.author.tag)
.addField("๐Ÿ‘ค User:", user.username)
.addField("๐Ÿ†” User ID:", user.id)
.addField("๐Ÿ•’ Blacklisted on:", message.createdAt)
.setFooter("ยฉ 2020 - 2021 GlobalChat", "https://cdn.discordapp.com/avatars/759021875962576916/cc32b2b08fdd52ae86294516d34532c5.png?size=128")
.setThumbnail(user.avatarURL({ dynamic:true }))
.addField("Unblacklist?", "Please contact <#267818548431290369> or <#331736522782932993>");
client.guilds.cache.forEach(g => {
try {
client.channels.cache.get(db.fetch(`g_${g.id}`)).send(embed);
} catch (e) {
return;
}
});
}

First you'll want to check if there is no reason, this can be simple done by checking, for both approaches, if the second argument is undefined, like so
if (args[1] === undefined) {
const reason = "No reason.";
}
This solution will work for both approaches, since if the second argument is undefined there can be no more after it
You could take reason as an argument.
Inside the command add
const reason = args[1];
OR if you wanted to have the rest of the blacklist args dedicated to the reason you could add something along the lines of
let reason = ""
for (let i = 1; i < args.length; i++) {
// It's very important that i starts as 1, so we do not take the first argument into account for the reason
reason += args[i];
}
And then you can add to the embed
.addField("๐Ÿ’ฌ Reason:", reason);
If you went with the first approach, the blacklist command would work like this
!blacklist 012345678910111213 the_reason_here
// or
!blacklist 012345678910111213 reason
The limitation to this approach is that a multi word reason isn't very intuitive.
If you went with the second approach though, the blacklist command would work like this
!blacklist 012345678910111213 The reason the user was banned and it can go on and on and on as long as the writer wants

You'll want to fetch the reason in the same way that you fetched the user id, like this:
const reason = args[1];
After that, in order to make sure that the reason doesn't show as undefined, you'll want to add a check in the form of an if statement, like this:
if (!reason) {
reason = "No reason";
}
After that, add .addField("๐Ÿ’ฌ Reason:", reason) in the position of fields you want it to be.
Your code should look something like this:
if (command === "blacklist") {
if (!config["allowed-users"].includes(message.member.id)) return;
const user = client.users.cache.get(args[0]);
const reason = args[1];
if (!user) {
return message.channel.send("This user does not exist")
}
if (blacklist.has(user.id)) {
return message.channel.send("This user is already on the blacklist")
}
if (!reason) {
reason = "No reason";
}
blacklist.set(user.id, 'blacklisted');
let set = db.fetch(`g_${message.guild.id}`);
var embed = new Discord.MessageEmbed()
.setTitle(":warning: Blacklisted :warning:")
.setColor('#fc5a03')
.addField("๐Ÿ‘ฎ Moderator:", message.author.tag)
.addField("๐Ÿ‘ค User:", user.username)
.addField("๐Ÿ†” User ID:", user.id)
.addField("๐Ÿ•’ Blacklisted on:", message.createdAt)
.addField(("๐Ÿ’ฌ Reason:", reason)
.setFooter("ยฉ 2020 - 2021 GlobalChat", "https://cdn.discordapp.com/avatars/759021875962576916/cc32b2b08fdd52ae86294516d34532c5.png?size=128")
.setThumbnail(user.avatarURL({
dynamic: true
}))
.addField("Unblacklist?", "Please contact <#267818548431290369> or <#331736522782932993>");
client.guilds.cache.forEach(g => {
try {
client.channels.cache.get(db.fetch(`g_${g.id}`)).send(embed);
} catch (e) {
return;
}
});
}

Related

Discord.js v13 why is my tempmute command not working?

I've made a tempmute command for my discord bot and it almost works. It has quite a few foolproofing measures like preventing the bot from muting themselves, not working if the time isn't specified and such. I am using the npm ms package to deal with the mute duration (https://www.npmjs.com/package/ms). when instead of specifying an amount of time I type in gibberish it works as intended and replies with the correct message. The problem is that when I type in a 100% correct command it responds asthough I didn't specify the time correctly instead of muting the user for that amount of time. here's how it looks. Any ideas as to why that is?
My code is here:
const ms = require('ms');
const { Permissions, MessageActionRow, UserFlags } = require('discord.js');
module.exports = {
name: 'tempmute',
description: "Temporarily mutes a user",
execute(message, args)
{
const target = message.mentions.members.first();
let muteRole = message.guild.roles.cache.find(role => role.name === "muted");
if(message.member.permissions.has(Permissions.FLAGS.MODERATE_MEMBERS))
{
if(target)
{
let memberTarget = message.guild.members.cache.get(target.id);
if(target.id == 'myBotsID')
{
message.reply("I can't mute myself.")
}
else if(message.member == target)
{
message.reply("You can't mute yourself!")
}
else if(memberTarget.permissions.has(Permissions.FLAGS.MODERATE_MEMBERS))
{
message.channel.send(`<#${memberTarget.user.id}> has been muted for ${ms(ms(args[1]))}`);
}
else
{
if(!args[1])
{
return message.reply("Time not specified.")
}
else
{
let time = ms(args[1])
memberTarget.roles.add(muteRole.id);
try {
message.reply("<#" + memberTarget.user.id + ">" + "has been muted for " + ms(ms(args[1])).catch(console.error))
setTimeout(function () {
memberTarget.roles.remove(muteRole.id);
}, time);
} catch (err) {
message.reply("Can't transform that into milliseconds `"+args[1]+"`")
return
}
}
}
}
else
{
message.reply("You have to mention a valid member of this server.")
}
}
else
{
message.reply("You can't use that.")
}
}
}
Okay so I figured it out. Here's the problematic code:
try {
message.reply("<#" + memberTarget.user.id + ">" + "has been muted for " + ms(ms(args[1])).catch(console.error))
setTimeout(function () {
memberTarget.roles.remove(muteRole.id);
}, time);
} catch (err) {
message.reply("Can't transform that into milliseconds `"+args[1]+"`")
return
}
IDK why but the ".catch(console.error))" (which is a leftover code and shouldn't be there in the first place) caused it to behave differently aka treat everything as an incorrectly specified time and returned the corresponding message instead of muting the member for the specified amount of time. After removing that short part of code everything is working as intended.

Discord JS, how to not allow user to execute a command while answering another command's question, unless it's finished

So, I have these two (kind of messy) commands.
Here are the codes, though their content doesn't really matter (I guess so):
This one is a find the hidden ball inside the boxes game.
client.on("message", async message => {
if (!message.content.startsWith(prefix) || message.author.bot) return;
const args = message.content.slice(prefix.length).trim().split(/ +/g);
const command = args.shift().toLowerCase();
const { MessageCollector } = require("discord.js-collector");
function randomIntFromInterval(min, max) {
return Math.floor(Math.random() * (max - min + 1) + min)
}
const rndInt = randomIntFromInterval(1, 5)
console.log(rndInt)
let answerBox = "";
if (command === "b" || command === "box") {
const user = message.author.id
switch(rndInt) {
case 1:
answerBox = 1;
break;
case 2:
answerBox = 2;
break;
case 3:
answerBox = 3;
break;
case 4:
answerBox = 1;
break;
case 5:
answerBox = 2;
break;
default:
message.channel.send("ERROR: If you received this message, please contact the support.");
};
message.channel.send(`A ball is hidden under the boxes below!!
:gift: โ”€โ”€ :one:
:gift: โ”€โ”€ :two:
:gift: โ”€โ”€ :three:`);
const botMessage = await message.channel.send(`<#${user}>, Type how many coins you wanna bet.`);
const userMessage = await MessageCollector.asyncQuestion({
botMessage,
user: message.author.id,
});
let coinsBet = userMessage.content;
if (coinsTotal < coinsBet) {
await message.channel.send("You don't have enough coins to bet.");
} else if (isNaN(coinsBet) == false) {
const botMessage = await message.channel.send("Type which box do you think the ball is (1, 2 or 3).");
const userMessage = await MessageCollector.asyncQuestion({
botMessage,
user: message.author.id
});
let bet = userMessage.content;
if (userMessage.content == answerBox) {
await message.reply("You got it right and won double the coins!");
coinsTotal += coinsBet * 2;
} else if (isNaN(bet) == true || bet >= 4) {
await message.channel.send("That wasn't a valid input, please type =b ou =box.");
} else {
await message.reply(`You got it wrong and lost all the coins which you bet. The right answer was ${answerBox}.`);
coinsTotal -= coinsBet;
}
} else {
await message.channel.send("That wasn't a valid input, please type =b ou =box.");
}
};
});
And this other one opens up a store:
client.on("message", (message) => {
if (!message.content.startsWith(prefix) || message.author.bot) return;
const args = message.content.slice(prefix.length).trim().split(/ +/g);
const command = args.shift().toLowerCase();
if (command === "store") {
message.channel.send(`โ•ญโ‹Ÿโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”€โ”€โ€ข~ Type the product code (number) to buy it.
โœฆโœงโœฆโœง STORE
ยป 1 - Green Seed: 0 coins.
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ‹ž`)
message.channel.awaitMessages(m => m.author.id == message.author.id,
{max: 1, time: 10000}).then(collected => {
if (collected.first().content.toLowerCase() == '1') {
message.reply(`You bought 1 "Green seed" with success!`);
seedGreen++;
seedTotal++;
}
else
message.reply(`Something happened, and it wasn't possible to complete your order..`);
}).catch(() => {
message.reply('Your order was cancelled due to lack of response.');
});
};
});
Notice how none of that is actually connected to a database, but that's not the point. Thing is, everything is actually working without any issues, except one thing.
In the store code, if an user type "=b" or "=box" instead of "1" or another wrong answer, the bot starts the box game, and whenever an user answers the box game questions with "=store", it also starts the store code.
I tried to figure out how to prevent this from happening, once I created a "let isActive = false" variable on top of the code, and set it to true whenever the bot started the store or box code, and set to false when it was finished, so I could put (&& isActive === false) at the first if of those codes and let them execute only if they are "inactive" (not doing any event I coded).
But it was all in vain, it didn't really work, so I'm pretty much stuck here, and I would gladly accept any kind of help to overcome this.
There are many ways to solve this issue. Here's one that I thought out: At the beginning of the script, you can provide some sort of state prop to the client. I called it userState and set it to a Collection:
client.userState = new Discord.Collection();
Then whenever a user starts a multi-step command that you don't want them to execute while still in the command, you can set that user's id to some descriptive state, e.g. "boxGame":
client.userState.set(message.author.id, "boxGame");
And whenever you need to check if they're in a multi-step command, you can check with:
client.userState.get(message.author.id);
Which will either return "boxGame" or undefined, and you can easily differentiate between them to stop them or let them execute a command, for example, using a switch statement:
if (client.userState.has(message.author.id)) {
const state = client.userState.get(message.author.id);
switch (state) {
case "boxGame":
message.channel.send("you have to complete the box game first bro");
break;
default:
message.channel.send("You're doing something, finish that something first!");
}
}
And when they complete the box game, you can
client.userState.delete(message.author.id);
to clear their state.
Edit: Just reminding you again that this is only one solution on how to solve it, and there are probably better solutions to this than mine.

How can you cancel your whole Discord Application

So I'm creating a Discord Application bot, Ban appeal Application that works within DM's only. I type the command p!apply and start the application, however whenever I try to cancel the application by typing cancel it only replies and does not actually cancel the whole form.
Here's my code:
let userApplications = {}
client.on("message", function(message) {
if (message.author.equals(client.user)) return;
let authorId = message.author.id;
if (message.content === prefix + "apply") {
if (!(authorId in userApplications)) {
userApplications[authorId] = { "step" : 1}
message.author.send("**__Team PhyZics Discord Ban Appeal Form__** \n If you're applying to get unbanned from our server, please fill this application out. We do not accept all applications, so take this application seriously and take your time when filling this out. \n \n - If you want to cancel this application please type `cancel`");
message.author.send("**Question 1: Which server did you get banned from?**");
}
} else {
if (message.channel.type === "dm" && authorId in userApplications) {
if (message.content.toLowerCase() === 'cancel') {
return message.author.send('Application Cancelled');
}
let authorApplication = userApplications[authorId];
if (authorApplication.step == 1 ) {
authorApplication.answer1 = message.content;
message.author.send("**Question 2: Why did you get banned/What reason did you get banned for?**");
authorApplication.step ++;
}
else if (authorApplication.step == 2) {
authorApplication.answer2 = message.content;
message.author.send("**Question 3: Why do you want to get unbanned?**");
authorApplication.step ++;
}
else if (authorApplication.step == 3) {
authorApplication.answer3 = message.content;
message.author.send("**Question 4: Any questions or concerns? If not, please type `no`.**");
authorApplication.step ++;
}
else if (authorApplication.step == 4) {
authorApplication.answer4 = message.content;
message.author.send("Your application has been submitted, please be patient and do not ask any staff member regarding to your ban appeal.");
client.channels.cache.get("790376360848785419")
.send(`**${message.author.tag}'s Application** \n **Q1**: ${authorApplication.answer1} \n **Q2:** ${authorApplication.answer2} \n **Q3:** ${authorApplication.answer3} \n **Q4:** ${authorApplication.answer4} `);
delete userApplications[authorId];
}
}
}
});
enter image description here
You're getting this problem because you're only returning a message Application cancelled without actually removing the user from your userApplications object.
To fix this, all you have to do is delete the entry from your object when the user cancels, like so:
if (message.content.toLowerCase() === 'cancel') {
delete userApplications[authorId];
return message.author.send('Application Cancelled');
}

Discord.js for loop behaving oddly

I'm working on a kick command for a Discord bot in Discord.js. How it works is a previous function passes an array of user IDs to attempt to kick from the server. For some reason, the for loop is repeating more than it should and the i value doesn't seem to change sometimes.
Here's my code:
exports.kick = async (guild, targets, member, reason, bot) => {
var modRoleQuery = await exports.queryModRole(guild, member, bot);
var outputMessage = '';
if (modRoleQuery === false && !member.hasPermission('ADMINISTRATOR') && member != guild.me) return `You do not have permission to execute this command.`;
else if (targets.length === 0) return `Command usage: ${config.prefix}kick <#mentions/IDs> [reason]`;
else if (!guild.me.hasPermission('KICK_MEMBERS')) return `I require the \`Kick Members\` permission to execute this command.`;
else if (targets.length > 10) return `You may only kick 10 members at a time.`;
else if (reason.length > 1000) return `The kick reason must not exceed 1000 characters. Currently, it is ${reason.length}.`;
for (i = 0; i < targets.length; i++) {
console.log(`checking ${targets[i]}, ${i}`);
let targetMember = guild.member(targets[i]);
if (targetMember) {
if (targetMember.kickable) {
let targetMemberModRole = await exports.queryModRole(guild, targetMember, bot);
if ((targetMemberModRole || targetMember.hasPermission('ADMINISTRATOR')) && !member.hasPermission('ADMINISTRATOR')) {
outputMessage += `Unable to kick \`${targetMember.user.tag}\`: Only administrators can kick people with the moderator role and/or admin perms.\n`
} else {
await targetMember.user.send(`You were kicked from ${targetMember.guild.name} by ${member.user.tag}:\nReason: \`${reason}\``).catch(err => {});
await targetMember.kick(`[${member.user.tag}] ${reason}`);
exports.modLogEvent(bot, guild, `KICK`, targetMember.user, member.user, reason);
outputMessage += `Successfully kicked \`${targetMember.user.tag}\`\n`;
}
} else {
outputMessage += `Unable to kick \`${targetMember.user.tag}\`: I don't have permission to kick them.\n`;
}
} else {
outputMessage += `Unable to kick \`${targets[i]}\`: They don't seem to be in this server.\n`;
console.log(`${targets[i]} is not a member`)
}
}
outputMessage += `**Kick Reason:**\n\`${reason}\``;
return outputMessage;
}
When the size of the array is 1, this works as expected, however when it is more than 1, it doesn't. I've put in some console.log() functions for debugging purposes.
For some reason, the i value gets stuck on 1. I also ran it a bit earlier (this is before I added the console.log()s) and it behaved even more oddly:
I've been trying to debug this for over a day now and I'm not getting anywhere. Any assistance would be greatly appreciated.

How to check if a variable is a number discord.js

I'm fairly new to discord bots coding and I would like to check if a variable is a number. My code looks like this, I've tried many options for the "if" statement.
const { DiscordAPIError } = require('discord.js');
const Discord = require('discord.js');
module.exports = {
name: 'givecookies',
description: 'Gives cookies to the mentioned user',
execute(message, args) {
let User = message.guild.member(message.mentions.members.first());
if (!User) return message.channel.send('Invalid User');
var cookiesAmount = args.join(' ').slice(22);
if (!cookiesAmount) {
message.reply('invalid amount of cookies');
}
if (typeof `${cookiesAmount}` === 'number') {
console.log('Amount of cookies is a number');
console.log(`USER = ${User}`);
console.log(`Amount of cookies = ${cookiesAmount}`);
var UserID = User.id;
console.log(`USER ID = ${UserID}`);
} else {
message.reply('invalid amount of cookies');
console.log('Amount of cookies is not a number');
console.log(`USER = ${User}`);
console.log(`Amount of cookies = ${cookiesAmount}`);
var UserID = User.id;
console.log(`USER ID = ${UserID}`);
}
},
};
I've also tried if (typeof(cookiesAmount) === 'number') and if (typeof cookiesAmount === 'number'), but none of them worked. Regardless what the value is, it acts like if it wasn't a number. I made it to log the value of cookiesAmount and it is always right, it logs '5', but it acts like if it wasn't a number. Any ideas of how to fix this? Thanks.
I'm using discord.js version 12
Since you are taking the variable from a Discord message, it will always be a string. However, you can convert it using the + operator.
var cookiesAmounts = 'notANumber';
if (Number.isNaN(+cookiesAmounts)) console.log('This is not a number');
else console.log('This is a number')
var cookiesAmounts = '1';
if (Number.isNaN(+cookiesAmounts)) console.log('This is not a number');
else console.log('This is a number')
JSFiddle
First, this is more of a JS question (it is not Discord specific). The reason it always returns false is that all the args are strings. You should convert the string to a number using the parseInt (or parseFloat) function and check if the result is NaN to know if it is a valid number.
If there is anything unclear with my answer, just ask me a question in the comments

Categories

Resources