Add user ID to Array to be banned upon return to guild? - javascript

As stated in the title I'm wanting to extend the current code I have for a ban function (included below).
If a user has left the guild/server how would I add their userID into an Array? This way I can loop through it every time someone joins the guild and check if they were previously banned: if so, they will be properly banned.
So the process would be:
<prefix>ban <userid>
If the user is not in the guild then add the ID to an Array and display a ban message
When a new member joins, check them against the Array and if ID exists then ban them and remove them from Array.
switch (args[0]) {
case 'ban':
if (!message.content.startsWith(PREFIX)) return;
if (!message.member.roles.cache.find(r => r.name === 'Moderator') && !message.member.roles.cache.find(r => r.name === 'Staff')) return message.channel.send('You dont not have the required permissions').then(msg => {
msg.delete({ timeout: 5000 })
})
var user1 = message.mentions.users.first();
if (member) {
// There's a valid user, you can do your stuff as usual
member.ban().then(() => {
message.channel.send('User has been banned')
})
} else {
let user = message.mentions.users.first(),
// The ID will be either picked from the mention (if there's one) or from the argument
// (I used args, I don't know how your variable's called)
userID = user ? user.id : args[1]
if (userID) {
// Read the existing banned ids. You can choose your own path for the JSON file
let bannedIDs = require('./bannedIDs.json').ids || []
// If this is a new ID, add it to the array
if (!bannedIDs.includes(userID)) bannedIDs.push(userID)
// Save the file
fs.writeFileSync('./bannedIDs.json', JSON.stringify({ ids: bannedIDs }))
// You can then send any message you want
message.channel.send('User added to the list')
} else {
message.channel.send('No ID was entered')
}
}
}
}
);
bot.on('guildMemberAdd', member => {
let banned = require('./bannedIDs.json').ids || []
if (banned.includes(member.id)) {
// The user should be properly banned
member.ban({
reason: 'Previously banned by a moderator.'
})
// You can also remove them from the array
let newFile = {
ids: banned.filter(id => id != member.id)
}
fs.writeFileSync('./bannedIDs.json', JSON.stringify(newFile))
}
})

This can be done, but you'll need to grab the user ID manually since you can't mention someone that's not in the guild (you technically can, but you would need to grab the ID anyway).
If there's no user mention or if there's one, but the user isn't in the guild, you'll need to grab their ID and push it to an array. You may want to save that array in a JSON file so it's kept between reloads: you can use fs.writeFileSync() for that.
Here's an example:
let member = message.mentions.members.first()
if (member) {
// There's a valid user, you can do your stuff as usual
member.ban().then(() => {
message.channel.send('User has been banned')
})
} else {
let user = message.mentions.users.first(),
// The ID will be either picked from the mention (if there's one) or from the argument
// (I used args, I don't know how your variable's called)
userID = user ? user.id : args[0]
if (userID) {
// Read the existing banned ids. You can choose your own path for the JSON file
let bannedIDs = require('./bannedIDs.json').ids || [] // WRONG: read the edit below
// If this is a new ID, add it to the array
if (!bannedIDs.includes(userID)) bannedIDs.push(userID)
// Save the file
fs.writeFileSync('./bannedIDs.json', JSON.stringify({ ids: bannedIDs }))
// You can then send any message you want
message.channel.send('User added to the list')
} else {
message.channel.send('No ID was entered')
}
}
Remember that you have to import the fs module, which is included with Node:
const fs = require('fs')
Also, create a JSON file that looks like this:
{
ids: []
}
When a new user joins, you can check their ID:
client.on('guildMemberAdd', member => {
let banned = require('./bannedIDs.json').ids || [] // WRONG: read the edit below
if (banned.includes(member.id)) {
// The user should be properly banned
member.ban({
reason: 'Previously banned by a moderator.'
})
// You can also remove them from the array
let newFile = {
ids: banned.filter(id => id != member.id)
}
fs.writeFileSync('./bannedIDs.json', JSON.stringify(newFile))
}
})
Edit:
How to solve the problem with the array being cached:
You load the array only once, when starting the bot, and store it in a variable. Every time you need to read or write to the array you use that variable, and periodically you update the JSON file.
As you mentioned in your comment, you can replace the require() with fs.readFileSync(). You can read the file with this fs method, and then you can parse the JSON object with the JSON.parse() function.
Here's how you can do it:
// Wrong way to do it:
let bannedIDs = require('./bannedIDs.json').ids || []
// Better way to do it:
let file = fs.readFileSync('./bannedIDs.json')
let bannedIDs = JSON.parse(file).ids || []

Related

Login system that checks out if the user already has an account. If they have one then they get to login, if they don't then they must try again

My overall problem is actually finding the values of the variables ''loginEmail'' and ''loginPass'' inside my ''arrayRegistros''. It only becomes TRUE when I write the email and password inside includes manually, however, it always ends up turning into FALSE when I use the variables themselves. I tried converting the variables into strings, then used document.getElementById alongside a few other ideas but until now, none of them completed the login system I had planned. The help I need is how one can find a certain variable's value/object, inside a certain array.
login(registro){
this.arrayRegistros;
var loginEmail = document.getElementById('userEmail');
var loginPass = document.getElementById('userPass');
var contaEmail = this.arrayRegistros.some((loginEmail) => {
return loginEmail.emailRegistro.includes(loginEmail)
})
var contaPass = this.arrayRegistros.some((loginPass) => {
return loginPass.passRegistro.includes(loginPass)
})
console.log(contaEmail)
console.log(contaPass)
}
you should get values from inputs like this:
const data = [
{
user : 'jhon',
password : 'asdf123'
},
{
user : 'bob',
password : 'asdf124'
}
]
const userName = document.getElementById('userEmail').value;
const passWord= document.getElementById('userPassword').value;
const findUser = data.filter( item => item.user === userName && item.password === passWord);
if(findUser.length > 0){
//user found
}
The first problem is that you are naming the parameter on the Array.prototype.some function the same as the variable you want to check outside of the predicate scope.
Second, suposing that this.arrayRegistros is a array with objects with the keys emailRegistro and passRegistro containing strings, DOM Elements CANNOT match with strings, but a element.value can.
Another thing you should have in mind is that includes is not an equality operator, 'a-very-strong-password'.includes('a'); will return true.
And, last, you should never validate login and password on the browser, because the user can edit the JavaScript code on-the-fly and get to login without any real credential.
With that in mind, I think the solution would be something like that (ignoring the browser validation problem):
const $userField = document.getElementById('userEmail');
const $passField = document.getElementById('userPass');
const registros = [
{
email: 'example#example.com',
password: 'a-very-strong-password'
},
...anotherUsers
];
function login(registro) {
const { value: user } = $userField;
const { value: pass } = $passField;
// You can use `Array.prototype.some` to just know if the specific user credentials exist, or use `Array.prototype.find` to know if exist AND grab the user, to further utilization
const item = registros.find(item => item.email === user && item.password === pass);
if (item) {
// User found
} else {
// User not found
}
}

discord.js Javascript string manipulation

so i am creating a bot with a kick command and would like to be able to add a reason for said action, i've heard from somewhere that i may have to do string manipulation. currently i have a standalone reason as shown in the code below:
client.on("message", (message) => {
// Ignore messages that aren't from a guild
if (!message.guild) return;
// If the message starts with ".kick"
if (message.content.startsWith(".kick")) {
// Assuming we mention someone in the message, this will return the user
const user = message.mentions.users.first();
// If we have a user mentioned
if (user) {
// Now we get the member from the user
const member = message.guild.member(user);
// If the member is in the server
if (member) {
member
.kick("Optional reason that will display in the audit logs")
.then(() => {
// lets the message author know we were able to kick the person
message.reply(`Successfully kicked ${user.tag}`);
})
.catch((err) => {
// An error happened
// This is generally due to the bot not being able to kick the member,
// either due to missing permissions or role hierarchy
message.reply(
"I was unable to kick the member (this could be due to missing permissions or role hierarchy"
);
// Log the error
console.error(err);
});
} else {
// The mentioned user isn't in this server
message.reply("That user isn't in this server!");
}
// Otherwise, if no user was mentioned
} else {
message.reply("You didn't mention the user to kick!");
}
}
});
Split message.content and slice the first 2 array elements, this will leave you with the elements that make up the reason. Join the remaining elements back to a string.
const user = message.mentions.users.first();
const reason = message.content.split(' ').slice(2).join(' ');
Here is something that could help:
const args = message.content.slice(1).split(" "); //1 is the prefix length
const command = args.shift();
//that works as a pretty good command structure
if(command === 'kick') {
const user = message.mentions.users.first();
args.shift();
const reason = args.join(" ");
user.kick(reason);
//really close to Elitezen's answer but you might have a very terrible problem
//if you mention a user inside the reason, depending on the users' id, the bot could kick
//the user in the reason instead!
}
Here's how you can take away that problem (with regex)
const userMention = message.content.match(/<#!?[0-9]+>/);
//you may have to do some more "escapes"
//this works since regex stops at the first one, unless you make it global
var userId = userMention.slice(2, userMention.length-1);
if(userId.startsWith("!")) userId = userId.slice(1);
const user = message.guild.members.cache.get(userId);
args.shift();
args.shift();
user.kick(args.join(" "))
.then(user => message.reply(user.username + " was kicked successfully"))
.catch(err => message.reply("An error occured: " + err.message))
I assume you want your full command to look something like
.kick #user Being hostile to other members
If you want to assume that everything in the command that isn't a mention or the ".kick" command is the reason, then to get the reason from that string, you can do some simple string manipulation to extract the command and mentions from the string, and leave everything else.
Never used the Discord API, but from what I've pieced from the documentation, this should work.
let reason = message.content.replaceAll(".kick", "")
message.mentions.forEach((mentionedUser) => reason.replaceAll("#" + mentionedUser.username, "")
// assume everything else left in `reason` is the sentence given by the user as a reason
if (member) {
member
.kick(reason)
.then(() => {
// lets the message author know we were able to kick the person
message.reply(`Successfully kicked ${user.tag}`);
})
}

How to create a vulnerability scanner ping #everyone? Discord.js

I had an idea to create a useful team for server administrators.
Thanks to this command, the bot shows in which channels you can ping #everyone #here.
Who has any suggestions on how to create this?
#user15517071's answer would work but only if #everyone has no 'MENTION_EVERYONE' permission by default. If you also want to check that, you will need to update your filter.
Check out the code below, I've added plenty of comments:
const textChannels = message.guild.channels.cache.filter((ch) => ch.type === 'text');
const canEveryoneMention = message.guild.roles.everyone.permissions.has('MENTION_EVERYONE');
const channelsWhereEveryoneCanBeMentioned = textChannels
.map((channel) => {
// if there are no overwrites, and everyone can mention #everyone by default
if (!channel.permissionOverwrites.size && canEveryoneMention)
return channel;
// a filter to check if the overwrites allow to mention #everyone
const overwriteFilter = (overwrite) => {
// only check if the overwrite belongs to the #everyone role
if (overwrite.id !== message.guild.id)
return false;
// check if MENTION_EVERYONE is allowed
if (overwrite.allow.has('MENTION_EVERYONE'))
return true;
// or it is allowed by default and it's not denied in this overwrite
if (canEveryoneMention && !overwrite.deny.has('MENTION_EVERYONE'))
return true;
// all other cases
return false;
};
const overwrites = channel.permissionOverwrites.filter(overwriteFilter);
// only return the channel if there are "valid" overwrites
return overwrites.size > 0 ? channel : null;
})
// remove null values
.filter(Boolean);
const channelList = channelsWhereEveryoneCanBeMentioned.join('\n');
message.channel.send(`People can mention everyone in the following channels:\n${channelList}`);
You can iterate through the TextChannels in a guild and look for channels where, say, #everyone has the MENTION_EVERYONE permission, allowing anyone to ping #everyone or #here.
For example, the below code finds all the TextChannels in a guild, then checks if there is a permission overwrite for #everyone and then checks if MENTION_EVERYONE is explicitly allowed.
const vulnerableChannels = [];
const channels = message.guild.channels.cache.array().filter(channel => channel.type === 'text');
for (const channel of channels) {
if (channel.permissionOverwrites.filter(overwrite => overwrite.id === message.guild.id && overwrite.allow.has('MENTION_EVERYONE')).array().length > 0) vulnerableChannels.push(channel.id);
}
let output = 'The following channel(s) are vulnerable:\n';
vulnerableChannels.forEach(channel => output = output.concat(` • <#${channel}>\n`));
message.channel.send(output);

How can I check If a message exists in discord.js

I would like to have some kind of reaction roles into my bot. For that I have to test If the message ID that the User sends to the bot is valid. Can someone tell me how to do that?
You can do that with .fetch() as long as you also know what channel you're looking in.
If the message is in the same channel the user sent the ID in then you can use message.channel to get the channel or if it's in another channel then you have to get that channel using its ID using message.guild.channels.cache.get(CHANNEL_ID).
So your code could be like this if it's in the same channel:
const msg = message.channel.messages.fetch(MESSAGE_ID)
or if it's in a different channel:
const channel = message.guild.channels.cache.get(CHANNEL_ID)
const msg = channel.messages.fetch(MESSAGE_ID)
This works for me (Discord.js v12)
First you need to define the channel where you want your bot to search for a message.
(You can find it like this)
const targetedChannel = client.channels.cache.find((channel) => channel.name === "<Channel Name>");
Then you need to add this function:
async function setMessageValue (_messageID, _targetedChannel) {
let foundMessage = new String();
// Check if the message contains only numbers (Beacause ID contains only numbers)
if (!Number(_messageID)) return 'FAIL_ID=NAN';
// Check if the Message with the targeted ID is found from the Discord.js API
try {
await Promise.all([_targetedChannel.messages.fetch(_messageID)]);
} catch (error) {
// Error: Message not found
if (error.code == 10008) {
console.error('Failed to find the message! Setting value to error message...');
foundMessage = 'FAIL_ID';
}
} finally {
// If the type of variable is string (Contains an error message inside) then just return the fail message.
if (typeof foundMessage == 'string') return foundMessage;
// Else if the type of the variable is not a string (beacause is an object with the message props) return back the targeted message object.
return _targetedChannel.messages.fetch(_messageID);
}
}
After this procedure, just get the function value to another variable:
const messageReturn = await setMessageValue("MessageID", targetedChannel);
And then you can do with it whetever you want.Just for example you can edit that message with the following code:
messageReturn.edit("<Your text here>");

Set channel id for DiscordBot for multiple servers

Could someone help me set command to set channel for specific server
so that it does not interfere with each other? Actually I have this:
var testChannel = bot.channels.find(channel => channel.id === "hereMyChannelID");
I want to set command which Owner can use to set channel id for his server.
You can accomplish this task by creating a JSON file to hold the specified channels of each guild. Then, in your command, simply define the channel in the JSON. After that, anywhere else in your code, you can then find the channel specified by a guild owner and interact with it.
Keep in mind, a database would be a better choice due to the speed comparison and much lower risk of corruption. Find the right one for you and your code, and replace this JSON setup with the database.
guilds.json setup:
{
"guildID": {
"channel": "channelID"
}
}
Command code:
// -- Define these variables outside of the command. --
const guilds = require('./guilds.json');
const fs = require('fs');
// ----------------------------------------------------
const args = message.content.trim().split(/ +/g); // Probably already declared.
try {
if (message.author.id !== message.guild.ownerID) return await message.channel.send('Access denied.');
if (!message.mentions.channels.first()) return await message.channel.send('Invalid channel.');
guilds[message.guild.id].channel = message.mentions.channels.first().id;
fs.writeFileSync('./guilds.json', JSON.stringify(guilds));
await message.channel.send('Successfully changed channel.');
} catch(err) {
console.error(err);
}
Somewhere else:
const guilds = require('./guilds.json');
const channel = client.channels.get(guilds[message.guild.id].channel);
if (channel) {
channel.send('Found the right one!')
.catch(console.error);
} else console.error('Invalid or undefined channel.');

Categories

Resources