Username and args connecting? \\ Discord.js - javascript

The [text] is being combined with the [username] (you can place any username where "realdonaldtrump" is. anything after that is the actual message.
I've tried numerous things, only thing I ever got to work was having trump being the default tweet and not being able to change it so it would've been >tweet [message] instead of >tweet [username] [message] but I'd like to have custom usernames. Any clue on how to remove the [username] from the [text]
Here's the code
exports.exec = async (client, message, args, level, settings, texts) => {
const user = args[0];
// Fires Error message that the command wasn't ran correctly.
if (!user) {
return client.emit('commandUsage', message, this.help);
}
// Fires Error message that the command wasn't ran correctly.
const text = args.join(" ");
// Below is a self-deletion message prior to image sending when it's fetching the actual image.
message.channel.send({
embed: {
color: 0,
description: `${message.author} Generating image.`
}
}).then(msg => {
msg.delete(5000).catch(() => { });
}).catch(e => {
});
// Above is a self-deletion message prior to image sending when it's fetching the actual image.
try {
const { body } = await snekfetch.get(`https://nekobot.xyz/api/imagegen?type=${user.toLowerCase() === "realdonaldtrump" ? "trumptweet" : "tweet"}&username=${user.startsWith("#") ? user.slice(1) : user}&text=${encodeURIComponent(text)}`);
message.channel.send("", { file: body.message });
// Below is a automatic logger
} catch (err) {
const errorlogs = client.channels.get('480735959944527886')
const embed = new discord.RichEmbed()
.setAuthor("ERROR", "https://i.imgur.com/Omg7uJV.png")
.setDescription(`${message.author} An error has occured using this command, this has automatically be logged and sent to ${client.channels.get('480735959944527886')} to be reviewed.`)
.setColor(0)
.setTimestamp()
message.channel.send({ embed });
errorlogs.send(`Error with \`$tweet\` command!\n\nError:\n\n ${err}`)
}
// Above is a automatic logger
};

You are concatenating your args to set your text variable
const text = args.join(" ");
But as args value is ["realdonaltrump", "yeeet"] in your example, it results in text having the value "realdonaldtrump yeet".
Just do as you did for the uservariable:
const text = args[1]
You might need to validate the value of the argument.

You can use string.replace method and it will replace the username with nothing:
const text = args.join(" ").replace(new RegExp(`${user}`), "")
Hope it helps!!!

Related

delete a message if it contains a certain word discord js v14

I'm trying to delete a message on Discord from a user when it contains one or more words that are on a list.
const badWords = ["badword1", "badword2", "badword3"];
client.on("guildBanAdd", (guild, user) => {
const messages = guild.messages.cache.filter((m) => m.author.id === user.id);
for (const message of messages.values()) {
for (const badWord of badWords) {
if (message.content.match(badWord)) {
guild.members.ban(user);
break;
}
}
}
});
It tends to be useful to use some library for this as above suggested solutions do not have built in tokenizer. This means that if someone was to write stuff such as veryverynaughty it would not get catched because most likely veryverynaughty is not on word list while [very, naughty] are. Or alternative would be to run regex on that message.
But to your question, you delete messages using message.delete() beware, that this does not work on messages older than 14 days. I cannot find the resource now, but I think there was a workaround to it.
import Profanity from 'profanity-js'
const isMessageTextProfane = (message) => {
const customBadwords = ["overthrow", "dictator"]
const config = {
language: "en-us"
}
const profanityInstance = new Profanity(message.content, config)
profanityInstance.addWords(...customBadwords);
return profanityInstance.isProfane(message.content)
}
client.on('guildBanAdd', (guild, user) => {
const messages = guild.messages.cache.filter(m => m.author.id === user.id);
for (const message of messages.values()) {
for (const badWord of badWords) {
if (isMessageTextProfane(message)) {
message.delete()
guild.members.ban(user);
break;
}
}
}
});
const badWords = ["badword1", "badword2", "badword3"];
client.on("messageCreate", (message) => {
const words = message.split(" ");
for (const word of words) {
if (badWords.contains(word)) {
message.delete();
}
}
});
I would use the messageCreate Event because this keeps track of new messages. Second I would split up the message content in the words and then loop through and check if one of the words is in the bad word list. At the end I would delete the message.

Why does role.permissions.remove() not work?

I tried to make a command to remove the MENTION_EVERYONE permission from all roles. It didn't work for some reason. I tried console logging which roles have the permission, and it did, but the only thing is that the permission isn't being taken away. I get no error but here is my code.
client.on('message', msg => {
if(msg.content === 'checkroleperms' && msg.author.id === 'xxxxxxxxxx') {
var roles = msg.guild.roles.cache.array()
var all = '{Placeholder}'
roles.forEach(role => {
if(role.permissions.has('MENTION_EVERYONE')) {
all+= ', ' + role.name;
//RIGHT HERE IS THE WHERE THE PROBLEM IS!!
//Changed this to msg.guild.role.cache.get(role.id).permissions.re...
role.permissions.remove('MENTION_EVERYONE');
console.log(role.name);
}
})
setTimeout(() => msg.channel.send(all), 500);
}
})
Was there something I did wrong? Also, the bot has Admin perms and is the second highest role in the server (right under me). The point is that the command is running but the perms are not being removed.
EDIT: I realized I was only modifying the array, but nothing is happening even when I get it from msg.guild.roles.cache
You were pretty close, the problem is you remove the permission but you never update the role itself.
role.permissions.remove() removes bits from these permissions and returns these bits or a new BitField if the instance is frozen. It doesn't remove or update the role's permissions though.
To apply these changes, you need to use the setPermissions() method that accepts a PermissionResolvable, like the bitfield returned from the permissions.remove() method.
It's probably also better to use roles.fetch() to make sure roles are cached.
Check the working code below:
client.on('message', async (msg) => {
if (msg.content === 'checkroleperms' && msg.author.id === 'xxxxxxxxxx') {
try {
const flag = 'MENTION_EVERYONE';
const roles = await msg.guild.roles.fetch();
const updatedRoles = [];
roles.cache.each(async (role) => {
if (role.permissions.has(flag)) {
const updatedPermissions = role.permissions.remove(flag);
await role.setPermissions(updatedPermissions.bitfield);
updatedRoles.push(role.name);
}
});
const roleList = updatedRoles.join(', ') || `No role found with \`${flag}\` flag`;
setTimeout(() => msg.channel.send(roleList), 500);
} catch (error) {
console.log(error);
}
}
});

How do I make a user answer a question using reactions in Discord.js?

I want the user to answer a "yes or no" question using reactions. Here is my code below.
var emojiArray = ['🔥', '👍', '👎', '✅', '❌'];
client.on('message', (negotiate) => {
const listen = negotiate.content;
const userID = negotiate.author.id;
var prefix = '!';
var negotiating = false;
let mention = negotiate.mentions.user.first();
if(listen.toUpperCase().startsWith(prefix + 'negotiate with '.toUpperCase()) && (mention)) {
negotiate.channel.send(`<#${mention.id}>, do you want to negotiate with ` + `<#${userID}>`)
.then(r => r.react(emojiArray[3], emojiArray[4]));
negotiating = true;
}
if(negotiating == true && listen === 'y') {
negotiate.channel.send('Please type in the amount and then the item you are negotiating.');
} else return;
})
As you can see, the code above allows the user to tag someone and negotiate with them (the negotiating part doesn't matter). When the user tags someone else, it asks them if they want to negotiate with the user that tagged them. If the user says yes, they negotiate.
I want to do this in a cleaner way using reactions in discord. Is there any way to just add a yes or no reaction emoji and the user will have to click yes or no in order to confirm?
First of all, you kinda messed up while getting the user object of the mentioned user, so just so you know it's negotiate.mentions.users.first()!
While wanting to request user input through reactions, we'd usually want to use either one of the following:
awaitReactions()
createReactionCollector
Since I personally prefer awaitReactions(), here's a quick explanation on how to use it:
awaitReactions is a message object extension and creates a reaction collector over the message that we pick. In addition, this feature also comes with the option of adding a filter to it. Here's the filter I usually like to use:
const filter = (reaction, user) => {
return emojiArray.includes(reaction.emoji.name) && user.id === mention.id;
// The first thing we wanna do is make sure the reaction is one of our desired emojis!
// The second thing we wanna do is make sure the user who reacted is the mentioned user.
};
From there on, we could very simply implement our filter in our awaitReactions() function as so:
message.awaitReactions(filter, {
max: 1, // Accepts only one reaction
time: 30000, // Will not work after 30 seconds
errors: ['time'] // Will display an error if using .catch()
})
.then(collected => { // the reaction object the user reacted with
const reaction = collected.first();
// Your code here! You can now use the 'reaction' variable in order to check certain if statements such as:
if (reaction.emoji.name === '🔥') console.log(`${user.username} reacted with Fire emoji!`)
Finally, your code should look like this:
const filter = (reaction, user) => {
return emojiArray.includes(reaction.emoji.name) && user.id === mention.id;
};
message.awaitReactions(filter, {
max: 1,
time: 30000,
errors: ['time']
})
.then(collected => {
const reaction = collected.first();
if (reaction.emoji.name === '🔥') console.log(`${user.username} reacted with Fire emoji!`)
you should use a ReactionCollector:
var emojiArray = ['🔥', '👍', '👎', '✅', '❌'];
const yesEmoji = '✅';
const noEmoji = '❌';
client.on('message', (negotiate) => {
const listen = negotiate.content;
const userID = negotiate.author.id;
var prefix = '!';
var negotiating = false;
let mention = negotiate.mentions.user.first();
if(listen.toUpperCase().startsWith(prefix + 'negotiate with '.toUpperCase()) && (mention)) {
negotiate.channel.send(`<#${mention.id}>, do you want to negotiate with ` + `<#${userID}>`)
.then(async (m) => {
await m.react(yesEmoji);
await m.react(noEmoji);
// we want to get an answer from the mentioned user
const filter = (reaction, user) => user.id === mention.id;
const collector = negotiate.createReactionCollector(filter);
collector.on('collect', (reaction) => {
if (reaction.emoji.name === yesEmoji) {
negotiate.channel.send('The mentioned user is okay to negotiate with you!');
// add your negotiate code here
} else {
negotiate.channel.send('The mentioned user is not okay to negotiate with you...');
}
});
});
negotiating = true;
}
})
This allows you to listen for new reactions added to a message. Here is the documentation: https://discord.js.org/#/docs/main/stable/class/Message?scrollTo=createReactionCollector

Lost to where I've got a missing catch? // Discord.JS

I've been staring at this for the past 30 minutes or so and I'm lost to as where I've failed. It's probably obvious now but I'm extremely tired and need a second pair of eyes ;-;
I've gone through my own checklist and I've exhausted most.
CODE BELOW
module.exports.exec = async (Cuckbot, message, args, level, settings, texts) => {
const text = args.join(" ");
if (!text) return message.channel.send("You must provide some text to appear on the image.");
const msg = await message.channel.send("<a:loading:456928252502605834> Generating...");
try {
const { body } = await snekfetch.get(`https://nekobot.xyz/api/imagegen?type=changemymind&text=${encodeURIComponent(text)}`);
message.channel.send("", { file: body.message });
msg.edit("Done!");
}
Your brackets aren't balanced. You don't have a catch statement after try. You might have missed something when you copied your code out.
Should look like this:
module.exports.exec = async (Cuckbot, message, args, level, settings, texts) => {
const text = args.join(" ");
if (!text) return message.channel.send("You must provide some text to appear on the image.");
const msg = await message.channel.send("<a:loading:456928252502605834> Generating...");
try {
const { body } = await snekfetch.get(`https://nekobot.xyz/api/imagegen?type=changemymind&text=${encodeURIComponent(text)}`);
message.channel.send("", { file: body.message });
msg.edit("Done!");
} catch (err) {
// do something with err
}
}

Why doesn't kicking people work using discord.js

const Discord = require("discord.js"),
bot = new Discord.Client();
let pre = "?"
bot.on("message", async msg => {
var msgArray = msg.content.split(" ");
var args = msgArray.slice(1);
var prisonerRole = msg.guild.roles.find("name", "Prisoner");
let command = msgArray[0];
if (command == `${pre}roll`) {
if (!msg.member.roles.has(prisonerRole.id)) {
roll = Math.floor(Math.random()*6)+1;
msg.reply(`You rolled a ${roll}`)
} else {
msg.reply(`HaHa NOOB, you're in prison you don't get priveleges!`)
}
}
if (command == `${pre}kick`) {
var leaderRole = msg.guild.roles.find("name", "LEADER");
var co_leaderRole = msg.guild.roles.find("name", "CO-LEADER");
if (msg.member.roles.has(leaderRole.id) ||
msg.member.roles.has(co_leaderRole.id)) {
var kickUser = msg.guild.member(msg.mentions.users.first());
var kickReason = args.join(" ").slice(22);
msg.guild.member(kickUser).kick();
msg.channel.send(`${msg.author} has kicked ${kickUser}\nReason: ${kickReason}`);
} else {
return msg.reply("Ya pleb, you can't kick people!");
}
}
})
bot.login("token").then(function() {
console.log('Good!')
}, function(err) {
console.log('Still good, as long as the process now exits.')
bot.destroy()
})
Everything works except actually kicking the person. The message sends nut it doesn't kick people. For example, when I type in ?kick #BobNuggets#4576 inactive, it says
#rishabhase has kicked #BobNuggets
Reason: inactive
But it doesn't actually kick the user, which is weird, can you help me?
Change
msg.guild.member(kickUser).kick();
to
kickUser.kick();
also, make sure the bot is elevated in hierarchy
Use kickUser.kick();
I recommend using a command handler to neaten up your code. You don't want all your commands in one .js file.
Try something like this for the Ban command itself. I use this for my Bot:
client.on("message", (message) => {
if (message.content.startsWith("!ban")) {
if(!message.member.roles.find("name", "Role that can use this bot"))
return;
// Easy way to get member object though mentions.
var member= message.mentions.members.first();
// ban
member.ban().then((member) => {
// Successmessage
message.channel.send(":wave: " + member.displayName + " has been successfully banned :point_right: ");
}).catch(() => {
// Failmessage
message.channel.send("Access Denied");
});
}
});
That should work, set the role you want to use it (cAsE sEnSiTiVe) and change !ban to whatever you feel like using. If you change all "ban"s in this to kick, it will have the same effect. If this helped you, mark this as the answer so others can find it, if not, keep looking :)

Categories