I have a simple command that mentions a random user in a text channel. It worked perfectly for weeks, until today.
TL;DR:
channel.members is a map that used to contain all of the users of the text channel, but not anymore. Is there an error on my side or has something changed?
Before today, map would correctly contain all users that are in a text channel where message event happened. Now, for some reason, in this map there is an author and a bot itself + seemingly random people.
At first he seemed to also include people in a voice channel, and now nobody is in any of the voice channels and after the first message there was only me and a bot in the map, and when I asked someone to do a command, then he also has appeared in the map.
So that made me think that the channel property from message event's arg might have a map of people that messaged anything while bot was live, but how would that explain the people from the voice channel? Furthermore, before today, he would randomize anyone, even the people that have never posted a single message in any of the channels, ever.
Has Discord API changed recently? Because I cannot find any announcement or anything like that and I have no idea why it doesn't work anymore. I even checked out to few commits ranging from yesterday to couple days ago and it still behaves this way.
I double checked everything and I'm sure I have people that didn't say anything anywhere, and I see that bot has mentioned these people last time at 28 of October.
main.js
bot.on('message', message => {
if (!message.content.startsWith(prefix) || message.author.bot) return;
require(`./commands/random_member`).execute(message, null);
});
random_member.js
module.exports = {
name: 'random_member',
usage: 'random_member',
description: "random_member",
execute(message, args) {
const member = message.channel.members.random();
message.channel.send(`${member}`);
}
}
Worthy Alpaca helped me with his comment.
"Firstly, you must manually enable the intents from the Discord Developer site. Go to applications, select your app, and find the "bot" tab on the sidebar. Then you can scroll down until you see this:"
I've enabled both of the options and my issues have disappeared.
Source:
None of my discord.js guildmember events are emitting, my user caches are basically empty, and my functions are timing out?
Related
I am yet to code this but actually struggling to understand how to do this
There is a private server with paid membership. I am a member. There are many channels on that server. I am particularly interested in a specific channel. Once someone posts a message in that channel, I want to immediately extract that message from a different program automatically and then process it in downstream systems. How to do that?
I know I'm a bit late to this question, but I'm going to tell you the secrets the Discord elites don't want you to know: This is completely doable, and many people do it. It's called a "self-bot".
Disclaimer: As the other answer stated, this is against ToS. You probably won't be caught, but I'd keep this on the down-low. Definitely don't go around telling this to everyone you meet.
Ok, now here's the actual coding part:
Discord.js, the most common library for discord bots in JavaScript, no longer supports self-bots, so you'll need to use an older version of discord.js. The official old versions have some unresolved bugs when used with modern discord, so I like to go with discord.js.v11.patch. Using this patched package will fix any weird bugs you get. Note: this is still discord.js v11, so if you need documentation, be sure to look at the v11 docs.
Ok, so after you run npm install discord.js.v11.patch (or npm install -g discord.js.v11.patch if you want to install it globally), you'll need to start writing code. Everything is basically the same as any old discord.js bot, but this is v11 so some stuff might be different. Here's some code to get you started. It should do everything you want it to do:
const discord = require('discord.js.v11.patch');
const client = new discord.Client();
const USER_TOKEN = 'XXXXXXXXXXXXXX'; // change this to your token
const CHANNEL_ID = 'XXXXXXXXXXXXXX'; // change this to the chanel you want to listen to.
client.on('ready', () => {
console.log('bot is running');
});
client.on('message', msg => {
if (msg.channel.id != CHANNEL_ID) return;
const message_text = msg.content;
console.log(message_text); // just an example
// send message_text somewhere to process it.
});
client.login(USER_TOKEN);
Now, all you need to do is change USER_TOKEN to your discord token and CHANNEL_ID to the ID of the channel you want to listen to.
To get your token, I recommend using this gist. It is safe and minimal. If you are worried about accessing your token, don't be. As long as you don't give it to anyone else you're fine.
To get the channel ID, simply turn on developer mode, then right-click on the channel you want to listen to. You should see a Copy ID menu button at the bottom of the context menu.
You can only do this if you have permissions to add an actual bot to that server, or have a friend that can do this for you. Using your own account as a bot would be possible, but is against discord ToS and would get your account banned.
I'm new to .JS language and have been programming a discord bot using Discord.js v12.22.4, but I cannot find a way to filter the messages that are being deleted on a channel.
The line message.channel.bulkDelete(3); works for deleting all the last three messages, but I need to delete only the bot messages and keep the user's messages on that channel.
I have searched the entire internet trying to find a way around it, including the .js documentation, but no success. All the codes I tried gave me errors because the syntax is outdated. My question is: How can I delete a specific amount of messages, from a specific user's ID, from a specific discord channel?
Thanks
I found one website explaining the syntax I was looking for. Hope it helps someone else:
message.channel.messages
.fetch({
limit: 2
})
.then((messages) => {
const botMessages = messages.filter((msg) => msg.author.bot)
message.channel.bulkDelete(botMessages)
})
I know you can do it like this
bot.on('guildMemberAdd', member => {
member.guild.channels.get('channelID').send("Welcome"); });
But then you have to specify a channelID.
Welcome Channel
All members join through this link onto the welcome channel. Is there a way that discordjs sends a join message where ever the user got invited? Example: A join link for general so the welcome message is in general.
Thanks for the help :)
The guildMemberAdd event only returns a GuildMember object which doesn't seem to include a reference to the invite used. You can fetch all the generated invite links and guess which one was used, but I wouldn't recommend this option.
Here are three solutions I can think of:
Use the System Message Channel
This channel can be defined in the server settings without enabling the "Random welcome message". You can find it in Guild.systemChannelID.
https://discord.js.org/#/docs/main/stable/class/Guild?scrollTo=systemChannelID
With public bots, make this setting configurable by an admin
You can make your bot respond to a command that will allow an admin to select a channel, either by selecting the channel where the command was sent, or prompting a list of channels. This is not the most straightforward solution to implement, but this is the best in terms of UX for your users.
With private bots, hardcode the channel ID
This one will be the easiest to implement if your using your bot privately in one server or a limited number of servers.
Go into Discord settings
Appearance
Toggle "Developer mode" in the Avanced section
Then right click on the desired channel, and Copy ID
there is a event in the Client() class that called guildMemberAdd. It will return a GuildMember class that will store all informations about the newly joined member!
If you bot is private bot
then you can simple hard code your bot, by enable the developer mode and right-click on the specific channel that you want your bot send welcome messages to, chose get ID and then paste the copied ID to member.guild.channels.cache.get("THE_ID") and then simple send the message.
client.on('guildMemberAdd', member => {
const channel = member.guild.channels.cache.get("CHANNEL_ID"); // Getting the channel
if(channel){ // Checking if the channel exist
channel.send(`Welcome ${member} to ${member.guild.name}`); //Send the message
}
Else if your bot is public bot
Then you will need a setup command to helps others server owners setup their welcome message function with your bot.
You should need a database (google it, if you don't know) to store channel's IDs, then get the channel's ID and do the same thing that I mentioned before!
I have a discord bot that uses a leveling system. It listens to message.author.id, logs the latest message, gives the user XP and at certain levels, users are awarded a new role. Have been working fine for months.
Recently I added a few(10 to be exact) webhooks to the server to enable users to send in bug reports.
Problem is that my bot is reading those webhooks messages as well, and webhooks don't have an author ID, hence, bot crash every time a webhook is posting something.
I know we can except certain webhooks like this if (message.webhookID != 'X') return;
but its kinda inconvenient since I might add or delete webhooks in the future. Is there a way to make my bot ignore all webhooks similar to how it can ignore other bots?
EDIT
This is what I did,
client.on('message', (message) => {
//Check if its a webhook.
if (message.webhookID) {
// block of code to be executed if the condition is true
} else {
// block of code to be executed if the condition is false
if (message.guild.id != '335008833267040256')return;{
....
Yes, you can do if (message.webhookID) return;, that should return if the message is sent from any webhook.
I want to make a code which shows the history of you name changes, like NotSoBot
Can anybody help me with that?
These bots use their own database. Discord does not record these changes. You cannot do this only with discord.js. The only thing is that if your bot isn't very large, It will not be very efficient because your bot can't access every user that change username. And if your bot is offline or any username before your bot starting to record these changes cannot be tracked.
If you still want to do this, use a database and the discord.js event userUpdate and record all usernames. Just note that this event is triggering even if the avatar of the user is changed or discriminator.
If your intention is to use Audit Logs to fetch all name changes -- I recommend you do some Documentation research.
I will not provide you with the complete code you are looking for, but a stepping stone for you to figure it out on your own.
What you will want to do is fetch the audit logs, and specify the options based on given parameters that are implemented in your command. (i.e. the user who you want to search.)
A simple way of retrieving name changes:
message.guild.fetchAuditLogs({type: 'MEMBER_UPDATE', user: 'DESIRED USER ID'}).then(async (audit) => {
let log = audit.entries.first().changes
console.log(log)
})
OUTPUT:
[ { key: 'nick', old: , new: } ]
Key as in the nickname is what you are looking for. Old is the old nickname. New is the new nickname.
This should point you in the right direction, as the rest is not too complex.