I am new here, and myself and my friend are very stuck with our Discord bot code where we are trying to have my discord bot check if someone is "streaming" to twitch by looping through members that have a Role called "Twitch Streamer". The problem is, we know the first half of the code works which checks if the owner, Me, is streaming, but for some reason, the second half of the code stopped working and is spitting out something in the console of "undefined". If I paste the code, could someone be willing to help us out? We are completely lost and running out of ideas.
My approach on task like this would be like this Discord.js v12 approach
Filter out the users with specific role - loop iteration decrease - optimization.
const streamers = server.members.cache.filter(user => user.roles.cache.has(StreamerRole);
To check if streamer is currently streaming at a time we are using loop. We are pushing streamers that are streaming to array with their IDs (d.js snowflakes).
const activeStreamers = [];
const IS_STREAMING = new Discord.Activity({
type: 'STREAMING',
...rest
})
streamers.forEach(streamer => {
const streamerActivity = streamer.presence.activities.has(IS_STREAMING);
if(streamerActivity) activeStreamers.push(streamer.user.id);
}
Related
I am building a Discord bot, more specific, a rolecolor command. I made a version of this command, that worked. Only problem was that it was extremly inefficient, it took like 5 minutes for it to respond. This was because there where a lot of 'if' statements and other things the bot had to check before executing anything. The file had 129K+ lines, and my whole editting program was lagging. I now have a new plan, that is probably much more efficient:
The bot checks if a member has any roles that start with "SRC -". SRC means server role color, just a name every role has that is dedicated to being cosmetic. All my colorrole names start with "SRC - name" If it detects any, delete them. Await this process, and after that, add the new color. I have like 205 roles for colors. I CAN just do:
message.guild.members.cache
.get(user.id)
.roles.remove(roleone);
message.guild.members.cache
.get(user.id)
.roles.remove(roletwo);
This works, but then again, inefficient. Discord isn't that fast with deleting and adding roles. When I ran a test, it didn't give me any errors. Despite this, I thought something was going wrong because my roles wheren't changing. When I was running a debug, and checked again, the roles where finally updated. It just takes a while before updating. I would like to have this more efficient. Here are some code samples:
Role adding, after the role removal:
if (args[0] === "1") {
message.guild.members.cache
.get(user.id)
.roles.add(roleone);
message.channel.send(errmsg);
console.log(logmsg);
else if (args[0] === "2") //etc
So my question is, does someone know how to detect if the member has any roles that start with name, so that only those roles can be deleted?
.remove() takes either a RoleResolvable, Array of RoleResolvables, or a Collection of RoleResolvables. You can filter the roles and pass it in
const member = message.guild.members.resolve(user.id)
const roles = member.roles.cache.filter(r => r.name.startsWith(`SRC -`))
await member.roles.remove(roles) // remove all roles from the member that start with "SRC -"
I am new to Discord.js which means I mostly copy the code and I've got a problem. I cant seem to find a way to get all my server member IDs in the serverUsers array. I know there are already a lot of questions that have answers, but the solutions don't seem to work for me, this one put in only the bot's, that is running the script, user ID.
client.on("ready", readyDiscord);
function readyDiscord() {
console.log("Authentication complete");
console.log("Going online");
var serverUsers = []
const MyServer = client.guilds.cache.get("MyServerID");
MyServer.members.cache.forEach(member => serverUsers.push(member.user.id));
console.log(serverUsers);
}
Thanks
You can easily do this without going through such trouble
const serverUsers = client.guilds.cache.get("Server ID").members.cache.map(member => member.id);
console.log(serverUsers);
Docs:
members
I am currently trying to create some sort of matchmaking command for my discord code.
The first half works fine, but the second part is giving me quite a headache. To explain how I want the code to work is for example, There are a number of users having the same role and with this command, I want it to choose two users. One being me (the user using the command) and another random from the list.
I got it to work but sometimes I might get chosen as the second member which if possible, I'd like to exclude myself from the list. Consider it some sort of myself finding a random duel.
Upon successful selection, the command will remove the queue role and add in the new matching role.
I hope my explanation is clear. Thanks in advance!
client.on("message", msg=> {
if(msg.content.toLowerCase() === "!queuepvp") {
const pvpqueue = ['713765272162402355'];
let membersList = msg.guild.members.filter(member => member.roles.some(role => pvpqueue.includes(role.id)));
console.log(membersList.size);
if(membersList.size < 2) {
msg.reply('Not enough PVP seekers in queue.');
return;
}
else{
let randMembers = membersList.random(1);
let firstMember = msg.member;
let secondMember = randMembers[1];
if (!secondMember === msg.member) {
msg.reply("You are matched up against " + secondMember + "!")
firstMember.addRole('713765226495082496');
secondMember.addRole('713765226495082496');
firstMember.removeRole('713765272162402355');
secondMember.removeRole('713765272162402355');
}}}
you can filter the randMembers like
randMembers = membersList.fileter(member => member.member !== msg.member).random(1)
I managed to pin this down through msg.member.id after countless trial and errors.
I'm trying to make a bot for voice applications for my server. I want it to have a command that picks a random user from a voice channel. I tried to do it in a few different ways, but none of them have worked, please help.
(edit)
Here is my not pretty code
else if (args[0].toLowerCase() === 'pick') {
const GuildMember = message.guild.members;
const channels = message.guild.channels.filter(c => c.ID === config.voiceChannel && c.type === 'voice');
const toCheck = Discord.Collection.array(channels.members);
message.reply(message.author + ', now pick ' + toCheck.random());
}
message.delete().catch(O_o=>{});
(another edit)
This is an error i'm getting "TypeError: Discord.Collection.array is not a function"
Your error is telling you that you are not using Collecion.array() properly. It looks as though you are trying to use it as a constructor or factory method, but it's a converter function. It needs an existing collection to work.
Secondly, your filter method will return a collection. Since you are filtering by an ID, it should be a collection of 1, but still a collection. Collections do not have a members property so channels.members is undefined. You need to extract the first (and what should be only) channel from the collection.
Fortunately, all of this can be handled by replacing a single line. You don't even need to convert it to an array because VoiceChannel.members is also a collection, and Collection has a random function of it's own.
const toCheck = channels.first().members;
On another note, because you are filtering the channel by it's unique ID, filtering by c.type is redundant. It will always be a voice channel unless you misconfigured config.voiceChannel.
Update
It also occured to me after posting that you could use this instead of your filter:
const channel = message.guild.channels.get(config.voiceChannel);
This returns the single channel, rather than a collection, by ID and is better because you aren't iterating over the collection and it simplifies the code. If you do this you don't need to use the changed line above at all, remove that line and use the following:
message.reply(message.author + ', now pick ' + channel.members.random());
Tarazed, thanks for your answer it helped me to figure it out.
For people that want to pick a random person from a voice channel too, here is the code that you can put in you command:
const GuildMember = message.guild.members;
const channel = message.guild.channels.get('voiceChannelID'); //replace voiceChannelID with your voice Channel ID
let toCheck = channel.members;
message.reply('a random person: ' + toCheck.random());
let staffrole = ['383874699941117952', '149622819158884353', '149622998180036608'];
How do you make a command that only people who have one of the roles can use it?
Thank you!
What you can do is that, on a message event, you run the command, and you can check the member's roles for one of the ones in the array.
Heres what that would look like:
client.on("message", msg => {
if(command === "whateverItIs") {
let staffrole = ['383874699941117952', '149622819158884353', '149622998180036608'];
for(i=0;i<staffrole.length;i++) {
if(msg.member.roles.filter((role) => role.id == staffrole[i]).size > 0) {
//run the code
return;
}
}
}
})
On a message event, with the determined command, the bot will check through each of the staff roles and if the message author 's roles includes one of the staffrole's then the command will run.
I would recommend doing something like this:
First, set your command name in the client's message listener:
// ... (in client message listener)
switch(command) {
case '<your command>':
runIfRoleIncluded(message);
break;
}
Next, get the role Id from the message that was sent and check if that message's role Id is in your staffrole array:
function runIfRoleIncluded(message) {
let rolesCollection = message.member.roles;
let staffrole = ['383874699941117952', '149622819158884353', '149622998180036608'];
// only 1 member can send a message, so get role collection's first key (id)
let messageRoleId = rolesCollection.firstKey();
// check if message's role id is in staff role array
if (staffrole.includes(messageRoleId)) {
// do stuff here
// ...
}
}
The .roles property of the .member object is a Collection, which is why you have to use the .firstKey() method. You can also turn the Collection into a normal js Array, but the way I outlined above is easier.
Started looking at this... Don't know the discord space very well but got an example bot and with a hello world ping, also found this pretty sweet Github gist that lays out fairly well how to build what amounts to a command switch statement. Making a lot of guesses here -- as a note for future questions it would be very helpful for you to add in some code on what you are trying to do -- a single variable set to an array isn't much to go on...
After Reading what #Raymond Zhang said, because, yeh that's what I was doing...
this is straight out of the Github gist I linked ->
...
if(command === "kick") {
if(!message.member.roles.some(r=>["Administrator","Moderator"].includes(r.name)) )
return message.reply("Sorry, you don't have permissions to use this!");
...
I have tested this and it works great, although it checks against the roles name not a number. It would help if you updated you answer to explain your process. More info = better answer. :)