I created a site (dashboard) with NextJs which allows a Discord user to connect with his account. So I was able to recover the different guilds of the user but I would like to sort them to keep only the one where he has (at least) the MANAGE_GUILD perm or if he is the owner of the guilds.
I started to create a function to sort the guilds but it doesn't seem to work
export function guildsperm(guilds) {
guilds.map((guilds) => {
if (guilds.owner === true) {
return guilds;
} else if (guilds.permissions <= 0x0000000020) {
return guilds;
} else {
return;
}
});
}
The doc : https://discord.com/developers/docs/topics/permissions#permissions
The way to check for the permissions is not to operate on them with "<.>,=" but rather with bitwise operators, as described in your docs!
For example, your specific case should be to change
else if (guilds.permissions <= 0x0000000020)
into
else if (guilds.permissions & 0x0000000020 == 0x0000000020)
Try it out and let us know if it works.
Related
As part of a bot I am making, I am making a config command which allows users to toggle certain features in their servers. To do this, I am using a simple JSON file called config.json to store the ID of the server along with several boolean variables to represent the features:
{
"servers": [
{
"id": INSERT_ID,
"delete": true
},
{
"id": INSERT_ID,
"delete": true
},
{
"id": INSERT_ID,
"delete": false
}
]
}
I am trying to get it so when the config command is run, the bot looks through this list to find the server which matches the ID of the server the message came from. I have made this code to do this:
let data = fs.readFileSync(__dirname + "/config.json");
let config = JSON.parse(data);
let found = false;
for(let server of config.servers) {
if (server.id === message.guild.id.toString()) {
found = true;
if (server.delete) {
server.delete = false;
message.reply("`Message Delete` has been toggled to `False`");
} else {
server.delete = true;
message.reply("`Message Delete` has been toggled to `True`");
}
}
}
if (!found) {
message.reply("I couldn't find this server in the database!");
}
let newData = JSON.stringify(config)
fs.writeFileSync(__dirname + "/config.jsom", newData);
If I console.log the message.guild.id it prints a number which matches the strings stored in my JSON file, however the IF statement if (server.id === message.guild.id) evaluates to false and I am not sure why.
I know your question has already been answered in the comments, but I just wanted to mention a different way of achieving the same result (and I also wanted to post a full answer to the question).
Instead of using a for/of loop to find the item that matches your specified criteria (matching guild IDs), you can simply utilize arrays' built-in find method to do so. Here's an example of how that would look in your code:
let found = config.servers.find(server => server.id == message.guild.id);
if (found) {
if (found.delete) {
found.delete = false;
message.reply("`Message Delete` has been toggled to `False`");
} else {
found.delete = true;
message.reply("`Message Delete` has been toggled to `True`");
}
}
else {
message.reply("I couldn't find this server in the database!");
}
I personally find this method to be cleaner than using the for/of loop by reducing the overall number of embedded conditionals/loops. And this code functions the same as your current code (in fact, the method probably utilizes a for/of loop itself). Of course, the main solution to the problem you were having is that you should use == instead of === due to their differing meanings in javascript, and it is also worth noting that you do not need to call toString() on message.guild.id when using ==.
I have this code:
const args = message.content.split(" ");
args.shift();
var mention = message.mentions.users.first()
const subject = args[0];
if (!subject) {
return message.say(`*you wand projects a stream of water*`)
} else if (subject === mention) {
return message.say(`*Your wand projects a stream of water at ${mention} and they are now soaked*`)
and I am trying to get it to pick up the mention.users.first() variable called mention so people can specify to shoot the spell at someone. I can't quite figure out how to get it to be checked. I've tried a couple of things like:
} else if (subject === mention) {
} else if (subject === 'mention') {
} else if (subject === {mention}) {
I knew this one probably wouldn't work but I tried it:
} else if (subject === ${mention}) {
I can't figure out if I'm not wording it properly or if it is just the wrong way to do entirely. Any pointers or ideas would be appreciated.
Well a role mention in <Message>.content would take the form of <#&ID>, it will be a sstring, discord.js already has a static property of the regex needed to validate role mentions which is: /<#&(\d{17,19})>/g, so now you just have to test if the string passes:
const regex = /<#&(\d{17,19})>/g;
if(regex.test(subject)) {
}
Also like I said you can get this regex by the static property
https://discord.js.org/#/docs/main/v12/class/MessageMentions?scrollTo=s-ROLES_PATTERN
const {MessageMentions} = require("discord.js");
const regex = MessageMentions.ROLES_PATTERN;
I'm setting up a whitelist and I want to use discord user IDs to use as a whitelist. I'm wondering if there is a way to make a command only work for certain user IDs?
I've tried many different methods from my own knowledge and other help forums with no luck.
const userId = message.guild.members.find(m => m.id === "212277222248022016");
if(!message.author === userId) {
message.author.send("Whitelisted")
}else{
message.author.send("Not whitelisted")
}
I wanted the user ID 212277222248022016 to get a dm saying "Whitelisted" but I always end up getting the dm "Not whitelisted".
I figured out the fix for this issue in case anyone comes across this thread and wants to know:
const userId = client.users.get("id here");
if (message.author === userId) {
message.author.send("Whitelisted")
} else {
message.author.send("Not whitelisted")
}
Remove the !
const userId = message.guild.members.find(m => m.id === "212277222248022016");
if (message.author === userId) {
message.author.send("Whitelisted")
} else {
message.author.send("Not whitelisted")
}
I have been wondering how can I send messages when someone invites my bot to their server.
Please help me in this area I can't figure it out it's there in Python but I have not used to it.
Thank you for your help
All the above answers assume you know something about the server and in most cases you do not!
What you need to do is loop through the channels in the guild and find one that you have permission to text in.
You can get the channel cache from the guild.
Take the below example:
bot.on("guildCreate", guild => {
let defaultChannel = "";
guild.channels.cache.forEach((channel) => {
if(channel.type == "text" && defaultChannel == "") {
if(channel.permissionsFor(guild.me).has("SEND_MESSAGES")) {
defaultChannel = channel;
}
}
})
//defaultChannel will be the channel object that the bot first finds permissions for
defaultChannel.send('Hello, Im a Bot!')
});
You can of course do further checks to ensure you can text before texting but this will get you on the right path
Update discord.js 12+
Discord.JS now uses cache - here is the same answer for 12+
bot.on("guildCreate", guild => {
let found = 0;
guild.channels.cache.map((channel) => {
if (found === 0) {
if (channel.type === "text") {
if (channel.permissionsFor(bot.user).has("VIEW_CHANNEL") === true) {
if (channel.permissionsFor(bot.user).has("SEND_MESSAGES") === true) {
channel.send(`Hello - I'm a Bot!`);
found = 1;
}
}
}
}
});
})
You can simply send the owner for example a message using guild.author.send("Thanks for inviting my bot");
Or you can also send a message to a specific user:
client.users.get("USER ID").send("My bot has been invited to a new server!");
I'm not sure if you're using a command handler or not since you seem new to JS I'm going to assume you're not. The following is a code snippet for what you're trying to do:
client.on('guildCreate', (guild) => {
guild.channels.find(t => t.name == 'general').send('Hey their Im here now!'); // Change where it says 'general' if you wan't to look for a different channel name.
});
bot.on('message', message => {
if (message.content === 'spam') {
message.channel.send('spam');
while (message.channel.send('spam')) {
if (message.content === 'stop spam') {
return message.channel.send('stopped');
}
}
}
});
im still fairly new to javascript so im not sure if this is even possible the way ive been trying to do it ive looked through w3schools developers.mozilla and even a few questions that are already on here; ive tried using do while, and for loops and ive tried multiple versions of the code i have up there
the ultimate goal is if a user sends the word 'spam' the bot should continuously send the word 'spam' and keep doing so till the bot is turned off or a user sends the words 'stop spam'
Here are some things you should know about the code you're working with:
message.channel.send returns a Promise, so you can't put that in a while loop, because you need to have something that is true or false (a Boolean).
Right now you're trying to check if a message's content is equal to 'stop spam' while you're inside the if-statement checking if the content is equal to 'spam' - So you'll never get inside the inner if-statement.
I would recommend practicing basic javascript a bit more, then moving to Node.js, then coming back to Discord.js - However, it might be cool for you to see a spammer work, so I wrote a some spam code you could use - check this out:
First, create a new file named spamCtrl.js that looks like this (see comments in code for descriptions of what's going on):
let spamming = false;
let spamChannel = undefined;
// spam function repeats until variable spamming is false
function spam() {
return new Promise((resolve, reject) => {
// add check to make sure discord channel exists
if (!spamChannel)
reject('Channel is undefined!');
// send message on spam channel
spamChannel.send('spam')
.then(msg => {
// wait 100 ms until sending next spam message
setTimeout(() => {
// continue spamming if spamming variable is true
if (spamming) {
spam()
.then(resolve) // not entirely necessary, but good practice
.catch(console.log); // log error to console in case one shows up
}
// otherwise, just resolve promise to end this looping
else {
resolve();
}
}, 100)
})
.catch(console.log);
});
}
// public functions that will be used in your index.js file
module.exports = {
// pass in discord.js channel for spam function
setChannel: function(channel) {
spamChannel = channel;
},
// set spam status (true = start spamming, false = stop spamming)
setStatus: function (statusFlag) {
// get current status
let currentStatus = spamming;
// update spamming flag
spamming = statusFlag;
// if spamming should start, and it hasn't started already, call spam()
if (statusFlag && currentStatus != statusFlag) {
spam();
}
},
// not used in my commands, but you may find this useful somewhere
getStatus: function() {
return spamming;
}
};
Next, import that file into your index.js file (Must be in the same directory as your spamCtrl.js file - unless you change the require statement below).
// in index.js file, get controller for spam messages
let spamCtrl = require('./spamCtrl');
Final step: In your index.js file (or wherever you're handling your spam commands) set up your commands (this can be renamed as you like):
// 2 commands together make spamming work :)
case '?SPAM':
spamCtrl.setChannel(message.channel);
spamCtrl.setStatus(true);
break;
case '?STOP-SPAM':
spamCtrl.setStatus(false);
break;
Let me know if you would like any additional explanations on anything, or if you want to see some tweaks here 'n there.
Try using a variable instead. You cannot use message.channel.send('spam') for the while loop.
var spam = false;
if (message.content === 'spam') {
if (message.author.id !== bot.user.id) { // Replace bot with the instance of your bot Client.
spam = true;
} else {
if(spam) {
message.channel.send('spam');
}
}
if (message.content === 'stop spam') {
if(spam) {
message.channel.send('stopped');
}
spam = false;
}
}