I made an anti-invite command, however, the bot doesn't delete the link that is being sent in the guild where the command is enabled. v12.2
if(message.content.includes(["https://discord.gg/", "https://discord.io/", "https://discord.me/"]))
You need to check if message.content includes each possibility separately, as the method only accepts one string at a time.
Could use .some() with a callback which indexOf's to check, which is pretty short.
// mock
const message = {
content: 'Come join my room https://discord.gg/1234'
}
//
const links = ["https://discord.gg/", "https://discord.io/", "https://discord.me/"]
//
if (links.some(el => message.content.indexOf(el) !== -1)) {
// link/domain matched
}
There are other ways too do the same, like with simple regex match.
Related
I want to make a Ticket System and in the ticket when you react with ✅ makes the channel view only from admins. (Closes the ticket.)
Code:
if (reaction.emoji.name === "✅") {
if(!reaction.message.channel.name.includes('ticket-')) return
reaction.users.remove(user)
reaction.message.reactions.cache.get('✅').remove()
reaction.message.reactions.cache.get('❌').remove()
let channel = reaction.message
channel.updateOverwrite("user.id", { VIEW_CHANNEL: false });
}
Error:
TypeError: channel.updateOverwrite is not a function
First of all, channel is not an instance of GuildChannel but of Message, which is probably a mistake. To get the corresponding GuildChannel object, use the following: (as PerplexingParadox said in their comment.)
let channel = reaction.message.channel;
The next thing is that Collection.get() method accepts a key as its parameter, which is in this case the reaction id (or Twitter Snowflake). To find a reaction by its name, you could do this:
for (const emojiName of ["✅", "❌"]) {
reaction.message.reactions.cache.find((reaction) => {
return reaction.emoji.name === emojiName;
})?.remove();
}
And remove them if they are found using the optional chaining operator.
At last GuildChannel.updateOverwrite() accepts RoleResolvable or UserResolvable as its first argument. Passing in a user's id is correct, because it falls under UserResolvable. You probably accidentally added the quotation marks around the user.id. It is a variable, if you want it to be treated like one remove the quotation marks, otherwise it will be treated as nothing more but a string with a text inside. And won't work because text "user.id" is not a valid Twitter Snowflake.
channel.updateOverwrite(user.id, { VIEW_CHANNEL: false });
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());
Here is the code for the command:
if (command === "avatar") {
let user = message.mentions.users.first() || message.author;
let embed = new Discord.RichEmbed()
.setAuthor(`${user.username}`)
.setImage(user.displayAvatarURL)
.setColor(0x842cfc);
message.channel.send(embed),
}
This command shows the avatar of a specified user, but with how it is now, you have to tag the specified user (making them receive a notification) to show the avatar. Right now the command is .avatar #someuser but I want the command to be .avatar someuser, so it doesn't mention them.
Also, I'm pretty sure I need to use client.users.find() somehow but idk how to. Thank you for any help!
I would use Guild.members.find(). Since that contains the members, you will need to check whether the argument the user wrote matches the .nickname or the .user.username. To simplify things a little I will use .displayName instead of .nickname, so that I can always work with strings.
// argument: the string after the command, I don't know how you're currently getting it
let user = message.guild.members.find(m => [m.displayName.toLowerCase(), m.user.username.toLowerCase()].includes(argument.toLowerCase()));
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. :)