AFK command discord.js v12 - javascript

I have already made an AFK command that changes the user's nickname. Here is my code:
client.on('message', (message) => {
if (message.content.includes('start-afk')) {
message.member
.setNickname(`${message.author.username} [AFK]`)
.catch((error) => message.channel.send("Couldn't update your nickname."));
}
if (message.content.includes('end-afk')) {
message.member
.setNickname('')
.catch((error) => message.channel.send("Couldn't update your nickname."));
}
});
I want it to add an AFK reason to be shown whenever the AFK User is pinged and if the AFK user talks then his AFK is removed. I tried however I was unsure how to do it.

If you want the bot to remember who is AFK and maybe the reason for it, you'll have to use a database to store these pieces of information.
You could use npm i quick.db, which is a really simple database to use.
Here's an example code:
client.on('message', message => {
// checks if the message author is afk
if (db.has(message.author.id + '.afk')) {
message.reply("Oh you're back ! i removed your afk")
db.delete(message.author.id + '.afk')
db.delete(message.author.id + '.messageafk')
}
if (message.content.includes('start-afk')) {
message.member.setNickname(`${message.author.username} [AFK]`).catch(error => message.channel.send("Couldn't update your nickname."));
// then here you use the database :
db.set(message.author.id + '.afk', 'true')
db.set(message.author.id + '.messageafk', message.content.split(' ').slice(2))
// I made .slice(2) so that in the message array it also delete the command and the "start-afk"
}
if (message.content.includes('end-afk')) {
message.member.setNickname('').catch(error => message.channel.send("Couldn't update your nickname."));
// Here you delete it
db.delete(message.author.id + '.afk')
db.delete(message.author.id + '.messageafk')
}
});
Then, whenever the user gets pinged:
client.on('message', message => {
// If one of the mentions is the user
message.mentions.users.forEach(user => {
if (db.has(user.id + '.afk')) message.reply('the user ' + user.tag + ' is afk !')
})
})

Well first you would need a place to store the reason.
Then you get the reason from the end of the message.
Then store the reason with the user id of the user.
Then inside of the message listener, check if the author of the message is inside the array/map or whatever u choose to store the data in.
If the user doesnt exist inside the afk "list" just ignore
If the user exist inside the afk "list" just remove them from the afk "list".
Then just check if there is a mention inside the message by doing message.mentions.users.first() if a mentions exists just get the users afk reason from the list and send it to the channel.
Then if the user does end afk just remove them from the "list".
That's the idea anyways

Related

Discord.JS Message Edit

I want to edit the message over and over again.
So I made variable
this.msgRef = await channel.send({ embeds: [embedMessage] });
If I want to edit I use
this.msgRef.edit(...)
If the bot for some reason disconnects, he will lose msgReference.
Because of that, I saved it to DB.
How to create a message again because Message (object) in Discord.JS have a private constructor?
If you want to get the message again, you can simply fetch the channel's messages every time you bot connects (on the ready event for example) like so
client.on('ready', () =>{
const messages = await channel.messages.fetch()
client.msgRef = messages.find(msg => msg.author.id === client.user.id
&& msg.embeds[0]
// Etc.. Add as many conditions to make sure you choose the right message
);
})
This way, use client.msgRef.edit(...) whenever you want.

Don't delete message if user has admin?

Basically I have a custom bot that deletes invite link when they're sent in the chat by users.
However if a user who has administrator permissions sends an invite link, I want the bot to ignore it and not the delete message.
Here is what I have:
client.on("message", async message => {
if (message.content.includes('discord.gg/' || 'discordapp.com/invite/')) {
message.delete()
});
Try this
client.on("message", async message => {
if (message.content.includes('discord.gg') || message.content.includes('discordapp.com/invite/')) {
if(!message.member.hasPermission("ADMINISTRATOR")){
message.delete();
}
});
Note: On future Discord.js updates member.hasPermission() might be replaced with member.permissions.has()
But till now permissions.has() cheates an error for me. So I suggest using hasPermissions()
Inside the if statement, include a line to check if the user has admin permission. Eg:if(message.member.permissions.has('ADMINISTRATOR')) return; would check if the user has an admin permission, and would return/not delete the message if he does. Or you can do the other way around, deleting the message if the user does not have the perms.
Eg:
if(!message.member.permissions.has('ADMINISTRATOR')){
message.delete();
}
Note: These statements has to inside the if statements that check if the message has an invite link.
if (message.content.includes('discord.gg/' || 'discordapp.com/invite/')) {
message.delete()
As of now, this just deletes every message that comes in.
So, what you want to do is to check if the author of the message has the permissions.
You can do this with:
message.member.hasPermission(//permissions here)
So, to add that to your code, you can do:
if (message.content.includes('discord.gg/' || 'discordapp.com/invite/')) {
if(!message.member.hasPermission("ADMINISTRATOR")){
)message.delete()
}
If they don't have Administrator, it's auto deleted.
You Can Read More Here:
https://discordjs.guide/popular-topics/permissions.html

Discord.JS - Moving users in Discord to your VC using roles

I'm trying to move all users from a VC with a specific role, for example: !summon #role
With that, all users with that specific role should come to the VC where the user typed that command
At the moment my code looks like this:
else if (command === 'summon') {
const channel = message.member.voice.channel;
message.guild.members.cache.forEach(member => {
member.voice.setChannel(channel);
});
message.channel.send(`${message.author} users moved to your channel!`);
}
At the moment i'm moving all users, however I only want users with the informed role
I tried to use:
message.mentions.roles.forEach(member => {
member.setChannel(channel);
});
But without success... can someone help me with this problem?
You can try replacing
message.guild.members.cache.forEach(member => {
member.voice.setChannel(channel);
});
with
message.guild.members.cache.forEach(member => {
if(member.roles.cache.has(message.mentions.roles.first()) {
member.voice.setChannel(channel);
}
}
Since member.roles.cache is a Collection it has a function .has. We take the first role mention from the message using message.mentions.roles.first() and check if it exists in the user's current roles using member.roles.cache.has(). If the user does have the first role mentioned in the message, the function returns true and we can move the to the specified channel. Hope this helps, don't forget about https://discord.js.org/#/docs for some documentation, can be quite useful 😅.

Reaction event discord.js

I'm trying to make a starboard code with my bot, and everything else is working good. But I'm trying to make it to where the bot ignores reactions from the author of the actual message.
This is my current code:
client.on('messageReactionAdd', (reaction_orig, message, user) => {
if (message.author.id === reaction_orig.users.id) return
manageBoard(reaction_orig)
})
It returns the following error:
if (message.author.id === reaction_orig.users.id) return;
^
TypeError: Cannot read property 'id' of undefined
The problem is that messageReactionAdd takes two parameters; the message reaction as the first one, and the user that applied the emoji as the second one. When you write reaction_orig, message, user, reaction_orig is the reaction (which is correct), but message is the user who reacted as it's the second parameter. The user variable will be undefined.
Another issue is that reaction_orig.users returns a ReactionUserManager that doesn't have an id property. Luckily, the user is already passed down to your callback so you can use its ID.
Also, reaction_orig has a message property, the original message that this reaction refers to so you can get its authors' ID from it.
You can change your code to this to work:
client.on('messageReactionAdd', (reaction_orig, user) => {
if (reaction_orig.message.author.id === user.id) {
// the reaction is coming from the same user who posted the message
return;
}
manageBoard(reaction_orig);
});
However, the code above only works on cached messages, ones posted after the bot is connected. Reacting on older messages won't fire the messageReactionAdd event. If you also want to listen to reactions on old messages you need to enable partial structures for MESSAGE, CHANNEL and REACTION when instantiating your client, like this:
const client = new Discord.Client({
partials: ['MESSAGE', 'CHANNEL', 'REACTION'],
});
You can check if the message is cached by e.g. checking if its author property is not null. If it's null, you can fetch the message. Now, you have both the message author and the user who reacted, so you can compare their IDs:
// make sure it's an async function
client.on('messageReactionAdd', async (reaction_orig, user) => {
// fetch the message if it's not cached
const message = !reaction_orig.message.author
? await reaction_orig.message.fetch()
: reaction_orig.message;
if (message.author.id === user.id) {
// the reaction is coming from the same user who posted the message
return;
}
// the reaction is coming from a different user
manageBoard(reaction_orig);
});
Try doing this :
client.on('messageReactionAdd', (reaction, user) => {
if (!reaction.message.author.id === user.id){
//Do whatever you like with it
console.log(reaction.name)
}
});
Note: The message must be cached. For that you'll need to do this
Client.channels.cache.get("ChannelID").messages.fetch("MessageID");
I'm guessing you're using discord.js v12

Auto deleting messages in a specific channel

I have a suggestion channel, and i made it so users are only allowed to post links in it, with the ability for the bot to react on what they post.
I have done the auto react on links, but i could not make the bot deletes what is not a link.
So i want everything else that is not a link to be deleted.
bot.on('message', message => {
// whenever a message is sent
if (bot.id === '514484773171757061') {
return;
}
if (message.channel.id === "508606903740268545" ){
if (message.content.includes('playrust.io/')) {
message.react('✅').then( () =>{
message.react('❌')});
} else if (message.delete()) {
message.channel.sendMessage('Message has been Deleted ' + message.author)
}
}
});
It is kind working but not very well.
It deletes the message that is not a link million times and sends million notifications :/
I guess the problem is with else if part
I think the problem is that you are creating a sort of infinite loop. In your code you first check if the message send is in a specific channel, after which you check if it contains a link or not. If it doesn't you send a message to that same channel saying 'I didn't find a link'.
When you send this, your bot gets triggered again because a new message has been send. It checks whether it's in a specific channel and if it contains a link, which it doesn't, and thus the cycle repeats.
It can be fixed with one simple statement, which also happends to be very good practice when creating bots. To fix it, you need to include some code which checks if a message has been send by a bot or not. Look at the example below:
bot.on('message', message => {
// Ignore messages from all bots
if (message.author.bot) return;
/* All your other code here */
client.id is not a thing so it needs to be
if (message.author.bot) return;
Then instead of
else if (message.delete()) {
message.channel.send('Message has been Deleted ' + message.author)
}
Use
else {
message.delete(5000)
message.channel.send('Message has been Deleted ' + message.author)
}
Wich result in:
bot.on('message', message => {
// whenever a message is sent
if (message.author.bot) return;
if (message.channel.id === "508606903740268545" ){
if (message.content.includes('playrust.io/')) {
message.react('✅').then( () =>{
message.react('❌')});
} else {
message.delete(5000)
message.channel.send('Message has been Deleted ' + message.author)
}
}
});

Categories