discord.js Javascript string manipulation - javascript

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

Related

How can I use the USER ID instead of using the mentions?

I recently made a discord command called -dm that basically DMs the user mentioned in the message. Something like: -dm #Omega Hello! and it would send "Hello!" to the user mentioned.
But some people find it annoying when they get pinged multiple times, so I want to know if there is a way I could use the USER ID instead of mentioning the user. That would make life a lot more easier. For whom it may concern, my code is given below.
const Discord = require('discord.js')
module.exports = {
name: 'dm',
description: 'DMs the person with the User ID mentioned',
execute(client, msg, args) {
if(!msg.member.permissions.has("ADMINISTRATOR")) return msg.channel.send("You cannot do that!")
//if(msg.author.id !== 'CENSORED') return msg.channel.send("You cannot do that!")
const user = msg.mentions.users.first()
if(!user) return msg.channel.send("That user ID doesn't exist OR that person isn't in the same server as me!")
const str = args.slice(1).join(" ")
user.send(str)
msg.channel.send("Message sent to the user!")
var dmLogger = new Discord.MessageEmbed()
.setTitle("DM Sent")
.setColor("RANDOM")
.addField("MESSAGE SENT BY", msg.author.tag)
.addField("MESSAGE SENT TO", user)
.addField("MESSAGE CONTENT", str)
.setTimestamp()
client.channels.cache.get('CENSORED_2.0').send(dmLogger)
}
}
You could add await message.guild.members.fetch(args[0]) but if you still want to keep the mentions thing you can just add that to your user variable.
const user = msg.mentions.users.first() || await msg.guild.members.fetch(args[0])
If you want only with user ID, remove the mentions part.

DiscordJS Verify command

I want to create a verify Command with discord.js v12 which gives you a verified Role which is defined in a Configfile.
Configfile:
{
"token": "my-token",
"status": "a game",
"statusurl": "",
"statustype": 0,
"botmanager": ["285470267549941761", "743136148293025864"],
"prefix": "m!",
"server": {
"343308714423484416": {
"active": true,
"hasBeta": true,
"adminroles": ["533646738813353984"],
"modroles": ["744589796361502774"],
"premiumtoken": "",
"welcomechannel": "653290718248435732",
"welcomemessage": "Hey Hey %user% at %server%",
"welcomemsgenabled": true,
"leavechannel": "653290718248435732",
"leavemessage": "Bye %user% at %server%",
"leavemsgenabled": true,
"verifiedrole": "533646700712296448",
"ruleschannel": "382197929605201920"
}
}
}
My Code:
const Discord = require('discord.js')
const client = new Discord.Client()
const config = require('./config.json')
client.on('ready', () => {
client.user.setStatus('online')
client.user.setActivity("m!help")
console.log(`Bot started successfully in ${client.guilds.cache.size} Guilds with ${client.users.cache.size} Users and ${client.channels.cache.size} Channels`)
})
client.on("message", async message => {
if(message.author.bot) return;
if(!message.content.startsWith(config.prefix)) return;
const args = message.content.slice(config.prefix.length).trim().split(/ +/g);
const command = args.shift().toLowerCase();
if(command === "verify") {
if(args.length == 0) {
let member = message.mentions.members.first();
if(message.member.roles.cache.some(r=>[config.server[(message.guild.id)].modroles].includes(r.id))) {
if(!member) {
return message.channel.send(new Discord.MessageEmbed().setColor(0xd35400).setTitle("Invalid User").setDescription("Please use the following Syntax:\n `m!verify <Nutzer>`"))
} else {
var role = message.guild.roles.find(role => role.id === config.server[(message.guild.id)].verifiedrole);
member.roles.cache.add(config.guild[(message.guild.id)].verifiedrole)
}
} else {
message.channel.send(new Discord.MessageEmbed().setTitle("Missing Perms!").setDescription("You're missing the permission to execute this command!").setColor(0xe74c3c))
}
}
}
console.log("Command used: " + command + " " + args + " | User: " + message.author.id + " | Guild: " + message.guild.id)
}
}
})
client.login(config.token)
I removed the most Code so only this command is left. Important is, that this Bot have to be able to use at multiple Servers at the time.
What is wrong here?
OK, so lets make this a multi part answer. First "What is wrong here?" Well, for the most part your current code does not work because you don't use the brackets correctly. You are trying to close brackets that you don't open anywhere. You also use a few too many "if" statements in places where you don't need them.
Next is your concern about multiple servers. This is really not a problem if you write the code to be dynamic. The execution of the command is quick enough that you don't need to worry about two people trying to use the command and the roles getting mixed up.
What I would really advise you to do is take a look at this https://discordjs.guide/ and this https://discord.js.org/#/docs/main/stable/general/welcome
Now to the topic of this question, this is how you could do such a "verify" command. I also added a few notations into the code to explain what we're doing ๐Ÿ™‚
client.on("message", message => { // You don't need the async here
// This is all working correctly
if (message.author.bot) return;
if (!message.content.startsWith(config.prefix)) return;
const args = message.content.slice(config.prefix.length).trim().split(/ +/g);
const command = args.shift().toLowerCase();
if (command === "verify") {
// We define the server constant as the part of the JSON that deals with the server the message came from
// This makes accessing those values easier
const server = config.server[message.guild.id];
// Your code here was also working
let member = message.mentions.members.first();
// Here we first define the moderator role
// Technicaly this is not needed but it makes the whole code a little easier to understand
// We need modrole[0] here because the modrole entry in your JSON is an array
let modrole = message.guild.roles.cache.find(r => r.id === server.modroles[0]);
// Here we check if the member who calls this command has the needed role
// We need to use the ID of the role to check
if (!message.member.roles.cache.has(modrole.id)) {
// If the user does not have the required role we return here
// That way you don't need to use the 'else' statement
// Creating the embed object in multiple lines improves readability
return message.channel.send(new Discord.MessageEmbed()
.setTitle("Missing Perms!")
.setDescription("You're missing the permission to execute this command!")
.setColor(0xe74c3c)
);
}
if (!member) {
// Here we check if a member was tagged in the command and if that user exists
// Same reasons as above
return message.channel.send(new Discord.MessageEmbed()
.setColor(0xd35400)
.setTitle("Invalid User")
.setDescription(`Please use the following Syntax:\n '${config.prefix}verify <Nutzer>'`)
);
}
// Now we define the role that we want the bot to give
// Here we also don't need to do this but it improves readability and makes working with the role a little easier
var role = message.guild.roles.cache.find(role => role.id === server.verifiedrole);
// Here we add the role to the specified member
// We don't need to use the .cache here
member.roles.add(role.id);
// We can use something called "template strings" here so we don't need to combine multiple strings
// They allow us to put predefined values into the string
console.log(`Command used: ${command} ${args} | User: ${message.author.id} | Guild: ${message.guild.id}`)
}
})
If you want, that the command can be executed at multiple servers at the time you need to write the code in async/await. If you want to learn more about async you can get very good help especially for discord.js v12 here: Understanding async/await
you can get a command for a specifiq channel and give a role for acces to the server

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>");

fetching audit logs in discord.js getting some error on trying to get the person who deleted message

i am trying to make a code that gives me log about who deleted the message but sometimes it gives me person other than the person who really deleted is that may be because of internet problem or there is something wrong with this code i am trying to get it from the audit logs
client.on('messageDelete', async msg => {
let logs = await msg.guild.fetchAuditLogs({type: "MESSAGE_DELETED"});
let entry = logs.entries.first();
let messageDeletedEmbed = new Discord.RichEmbed()
.setAuthor(`${msg.author.tag}`, msg.author.avatarURL)
.setThumbnail(msg.author.avatarURL)
.setColor("#e8de17")
.setTitle('A message has been deleted ๐Ÿงน')
.addField("**Message Sent By :**", "<#" + msg.author.id + ">")
.addField("**Message Channel :**", msg.channel)
.addField("**Message Content :**", msg.content)
.addField("**Deleted By :**", '<#' + `${entry.executor.id}` + '>')
.setTimestamp()
.setFooter(`${msg.guild.name}`,msg.guild.iconURL);
let LoggingChannel = msg.guild.channels.find(ch => ch.name === "logs")
if(!LoggingChannel) return;
if (msg.author == client.user) return;
LoggingChannel.send(messageDeletedEmbed);
});
Same thing happens to me, the only thing I could come up with was checking to see when the audit log was created, so if the log was created within say... the last 3 seconds, then it's very likely that it's the log you want, so you say the executor of that log deleted it. But if it wasn't, then it's not very likely at all that the audit log it finds is the right one, so you can say with decent certainty that the person who deleted it was the message.author.
`function deleteCheck() {
if (entry.createdTimestamp > Date.now() - 2000) {
return user;
}
else if (!entry.createdTimestamp > Date.now() - 1500) {
return message.author.username;
}
else {
return message.author.username;
}
}`
This may be a little inefficient, but I basically had this send the return value of the function. entry is defined as:
const entry = await message.guild.fetchAuditLogs({ type: 'MESSAGE_DELETE' }).then(audit => audit.entries.first()) and user is: let user = entry.executor.username.
I hope this helps you, and it may take a bit of experimenting, but I think you'll be fine :).

Adding Roles To A member With A command

okay so basically i tried to make a command that when i say .ar Admin #user
it give the user Admin or what ever the role name i mentioned after .ar but it makes me lose brain cells it took me so long plus my bot prefix didnt work because of the same problem so i bypass it by add the prefix my self in each command i need help and thanks in advance
i literally tried a lot of thing from arrow function to A normal code but the normal code only give the role to the new members (guildmembers)
`bot.on('message', message => {
let userToModify = message.mentions.members.first();
if (message.content.startsWith(".ar Admin" + userToModify)){
userToModify.addRole('Admin');
}
});`
Well Like i said before whenever i declare a var or string and then go to
.startwith("random command" + Var) it just never worked i tried doing
let prefix : "!"
and then .startwith(prefix + "command") but it never worked i had to add the prefix manually without using + and i dont want to do the same with adding roles
This is how I would do it. Define the role by grabbing it from the first argument in the message's content, and define the member how you did. Check if they exist.
When command is used, the role must be before the #mentioned user.
bot.on("message", message => {
const prefix = '!'; // just an example, change to whatever you want
if (!message.content.startsWith(prefix)) return; // ignores all messages that don't start with the prefix
const args = message.content.slice(prefix.length).trim().split(/ +/g) // creates an array of arguments for each word after the command
const cmd = args.shift().toLowerCase(); // this makes the command cASe iNseNsiTiVE
if (cmd === 'addroll' || cmd === 'ar') { // can use 'addrole', or 'ar' to run command
let roleToAdd = message.guild.roles.find(r => r.name === `${args[0]}`); // grab the role from the first argument
let userToModify = message.mentions.members.first(); // grabs the mentioned user
if (roleToAdd === null) {// if role doesn't exist(aka = null)
return message.reply(`I couldn't find the ${args[0]} role.`);
}
if (userToModify === undefined) {// if noone is mentioned after the role
return message.reply('You must `#mention` a user!');
}
userToModify.addRole(roleToAdd)// add the role
return message.reply(`${userToModify} has been given the ${roleToAdd} role.`)
// more code
}
});
Tried and tested.

Categories

Resources