I want to make a command that changes the nickname of the person when they type afk on then the bot adds AFK to there nickname. When they type afk off its removes AFK from there name.
client.on('message', message => {
if (message.content.includes('changeNick')) {
client.setNickname({nick: message.content.replace('changeNick', '')});
}
});
I reffered to this code however it doesn't work. Also is there anyway you can reset nickname back when a user types changenickoff?
Yes, you need to use Member#setNickname:
client.on('message', message => {
if (message.content.includes('start-afk')) {
message.member.setNickname(`${message.author.username} [AFK]`);
}
if (message.content.includes('end-afk')) {
message.member.setNickname('');
}
});
Here's what you need to do:
Does the user's nickname already start with [AFK] ?
IF yes, remove it.
notify user
end
ELSE: add [AFK] to their nickname
notify user
end
You were doing client.setNickname, which, to my knowledge, wouldn't work since the client is not a GuildMember instance.
It's worth noting that a GuildMember is verry different to a Discord User. GuildMembers have access to roles and permissions; users do not.
You can view exactly what a User structure is by doing console.log(client.users.cache.get(message.author.id))
Here's the amended code.
Additionally, I have included a function that trims a string to ensure it does not exceed X chars in length.
client.on('message', message => {
//function to trim strings, ensuring they don't exceed X chars in length
trimStr = (str, max) => ((str.length > max) ? `${str.slice(0, max - 3)}...` : str);
if (message.guild) /* Ensure message is in a server; */ {
if (message.content.toLowerCase().startsWith('!afk')) {
const nick = message.member.nickname;
if (nick.startsWith('[AFK]')) {
//remove nick and notify user:
message.member.setNickname(null);
message.reply("Welcome back, I've removed your AFK status.");
} else { //If above condition is false:
//add [AFK] to the new nick along with the nickname
//trim new string to ensure it's not longer than 32 characters since Discord limits this.
const newNickname = trimStr(`[AFK] ${nick.length ? nick : message.author.username}`, 32);
message.member.setNickname(newNickname);
message.reply("Ight mate, I've set your AFK!");
};
};
};
});
If there are any errors, please provide them in full detail (stacktrace and error itself) in the comments so I can be of further assistance to you.
NOTE - You'll need to type !afk in order to trigger this code.
Related
I'm trying to make my Discord bot send an emoji when I tell it the name. E.g., say I send !emoji hello, I want the bot to send back the emoji called hello.
If I send an emoji the bot will send it back but I'm not sure how to grab an emoji from its name being sent to the bot.
I use discord.js v12 for reference.
You could try something like this
bot.on("messageCreate", (message) => {
const exampleEmoji = message.guild.emojis.cache.find(emoji => emoji.name === message.content);
channel.message.send(`Is this the emoji you want? ${exampleEmoji}`);
});
You can then nest it inside of your if statement as you please with whatever command you are using. This also should be v12/v13 compatible and I believe the only differences with older versions is whether you add cache or not to the find function.
You can also use the same function to find the emoji as a boolean to determine if the emoji exists or not and if not send a different message for feedback.
I also found this really interesting function which helped me when deciphering which emojis I have and which are not in the scope I am presenting.
if (message.content === "listemojis") {
const emojiList = message.guild.emojis.cache.map((e, x) => `${x} = ${e} | ${e.name}`).join("\n");
message.channel.send(emojiList);
}
Which will output this for every emoji within the scope you searched.
450661466287112204 = :image: | name
Which I found here.
Hope this helps
I started on this small project just for fun for my friend's server. She wanted to have the bot reply to her any time she said anything in her server and she wanted the bot to stop replying after an hour after saying "shut up" (no prefixes). I currently have this
client.on("message", function (message) {
const amyID = "blahblah";
const jayID = "blahblah";
if (message.author.id == (jayID)) {
if (message.content.includes("shut up")) {
message.reply("sorry...")
setTimeout(function () {
}, 60000)
} else {
client.commands.get('replyToAmy').execute(message);
}
}
})
setTimeout seems to only work with functions which I am confused on how I can apply it to the client.on bit. If I remove setTimeout the bot will start responding again. How can I make the bot stop responding for a set amount of time after "shut up" is said by the user?
One way to do that would be create a boolean variable outside the client.on('message') function. Then the bot will keep sending a message as long as the boolean variable is set to true. Once the user tells the bot to stop, the boolean variable is set to false and you can create a .setTimeout() for the specified time after which the boolean variable will turn back to true. And then all we have to do is check if the boolean variable is true or not every time we send the message. The code might look something like this:
let keepReplying = true
const userId = 'the users id'
client.on('message', message => {
if (message.author.id === userId) {
if (message.content === 'stop') {
keepReplying = false
setTimeout(() => { keepReplying = true }, 60000)
}
}
if (keepReplying) client.commands.get('replyToAmy').execute(message);
})
Maybe Create a list to contain the user who said shut up & timestamp
then function to check user from that list and compare time with timestamp?
well if user timestamp > 1 hr then delete that from the list
there's a better way tho but this is the easy route.
and not the most effective way
as it would be too much waste with many users
but from your code seem like you just made small project
for small group of users so there's no problem
I'm trying to make my discord bot pick up words I don't want people to use. I know how to make the bot delete the message containing the word and reply to the person appropriately. What I can't figure out is how to make the bot record the message containing the word and send it to the moderation log channel as an embed to log what message it just deleted and who sent it.
I've seen examples on how to log every deleted message but that's not what I want to do. I only want the bot to record messages it deleted whenever people use the word. (or log the message with the word before deleting it from the main channel)
this is the code i'm using so far, not sure how to add that part to it.
client.on('message', message => {
const args = message.content.split(" ").slice(1);
if(message.content.toLowerCase() === "word") {
message.delete()
message.reply("don't send that word here.");
}
});
if(message.content.toLowerCase().includes("word")) {
let badMsg = message.content;
let badMsgChan = message.guild.channels.cache.get(message.channel.id);
let badMsgUser = message.author;
let logChan = message.guild.channels.cache.find(ch => ch.name === "logs");
let emb = new Discord.MessageEmbed()
.setTitle("Blacklisted word used")
.addField("Content", badMsg, true)
.addField("Found in", badMsgChan, true)
.addField("Written by", badMsgUser, true)
.setTimestamp()
logChan.send(emb);
message.delete();
message.reply("don't send that word here.");
}
I would recommend using .includes() instead of ===, because === means it has to be exactly that value (word). .includes() checks if the value (word) is included in the message content.
So I've created some variables that store the information about that "bad" message. badMsg is storing the message content (the sentence or whatever the word was included in). badMsgChan stores the channel, the "bad" message was found in. badMsgUser stores the user who has sent the "bad" message. And logChan is the channel where you want to send the embed in. You can change everything exactly in your style, I just wanted to give an example of how you could solve your problem. So the embed has 3 fields with:
Content -> The "bad" message content.
Found in -> The Channel where the "bad" message was found in.
Written by -> The user who sent the message.
I am implementing a command to mute users. For example, the following command would mute the user #anon for 5 seconds:
!mute #anon 5
My program listens for the message event, mutes the user and sends a confirmation message like this:
#anon#1234 has now been muted for 5 s
Unfortunately Discord does not recognize the username in this message as a mention. How can I mention a specific user with the msg.channel.send function? This sample includes the code which sends the confirmation message:
bot.on("message", msg => {
let args = msg.content.substring(PREFIX.length).split(" ")
let time = args[2]
let person = msg.guild.member(msg.mentions.users.first() || msg.guild.members.fetch(args[1]))
// muting the user here and sending confirmation message
msg.channel.send(`#${person.user.tag} has now been muted for ${time} s`)
setTimeout(() => {
// unmuting the user after specified time and
// sending confirmation message
msg.channel.send(`#${person.user.tag} has been unmuted.`)
}, time * 1000);
})
The muting is not included in this sample, it works. The messages are being sent correctly but the user is not mentioned, meaning the username is not clickable and doesn't get highlighted.
The documentation recommends this way to mention a user:
const message = `${user} has been muted`;
The example above uses template strings, therefore the toString method of the User object is called automatically. It can be called manually though:
const message = user.toString() + "has been muted";
The documentation states:
When concatenated with a string, this [the user object] automatically returns the user's mention instead of the User object.
Which means that every time toString is invoked, either by templates, string concatenation or by manually calling toString, the user object will be converted to a mention. Discord will interpret the output correctly, highlights it and makes it clickable.
In your case you would use the above example like this:
msg.channel.send(`${person.user} has now been muted for ${time} s`)
setTimeout(() => {
...
msg.channel.send(`${person.user} has been unmuted.`)
}, time * 1000)
You can also tag users by
`<#${id}>` // users
`<#&${id}>` // roles
Of course you'd need to know the user id or role id to do that.
My code is currently:
if (message.content == ",test") {
if (message.member.roles.find("name", "images")) {
message.channel.send( {
file: "http://www.drodd.com/images14/black11.jpg" // Or replace with FileOptions object
});
}
if (!message.member.roles.find("name", "images")) { // This checks to see if they DONT have it, the "!" inverts the true/false
message.reply('You need the \`images\` role to use this command.')
.then(msg => {
msg.delete(5000)
})
}
message.delete(100); //Supposed to delete message
return; // this returns the code, so the rest doesn't run.
}
If the user has the role 'images' I want the bot to send the image when they say ",test" and I want the user's ",test" message to be deleted after some seconds. However, this doesn't seem to be working.
I have tried to send the image without the role checking and that works.
How can I fix this?
This is because message.member.roles.find("name", "images") checks if the roles EXISTS in the guild. In order to find if someone has a role, you would use message.member.roles.has(myRole). To find the ID of a role dynamically, you would use this:
let myRole = message.guild.roles.find("name", "Moderators").id;.