I have been trying to make a quick bot for a friend, however I have come across something I cant fix. Whenever I try to access the member from the message it returns null. I am trying to find the users roles so I can check if they have a certain one.
The root of this problem that member is null inside the message. Therefor I cannot read from a null value.
client.on('message', message => {
This is how I am declaring message, and here is a console log of message. https://pastebin.com/vrdg9Wvu
So please can someone help me find a way to compare the command users roles.
Which version of dicord.js are you using?
I don't know where this may come from, maybe if the user who sent the message has left the guild while sending, otherwise I don't know what's wrong. If it's still not working, consider using message.guild.members.cache.get(message.author.id).then(user => {}), that may work.
Related
I am currently writing a Discord bot.
If it doesn't exist, it is supposed to create a thread in a given channel and write some messages there.
My current way of checking is
private SocketThreadChannel ThreadIfExists(string id, SocketGuildChannel channel)
{
return Context.Guild.ThreadChannels.Where(t => t.ParentChannel == channel)
.FirstOrDefault(t => t.Name.Contains(id));
}
where id is a unique id given to each thread.
Most of the time, it works fine; if the thread doesn't exist, the function returns null, and I can create the thread myself later, and if it does, it just gets returned to me.
My problem is that if I manually delete one of said threads in discord later, the bot has them saved in cache, and it will still try to write in an unexistent thread.
The only function I could find to refresh the cache is Context.Client.PurgeChannelCache();, but it throws Object reference not set to an instance of an object, even if I check the client for null.
Restarting the bot does fix it, but that's clearly not viable after it gets released.
Is there something else I could try?
For now, I have just made a workaround with a try/catch, where I check if sending the message throws an Unknown Channel error and force the creation once again.
I am pretty sure that this is one of the worst ways of doing it, but it does work, I guess
I'm trying to make this command notify my admins of a bot test and need it to mention the user who called the command. How would I go about that? I don't fully understand how to get that information with slash commands.
#client.slash_command(name= "test", description="(For Deputies or Leader only) Checks the operational state of the client.", guild_ids=[806043206030589952])
#has_any_role(leader_id, deputy_id)
async def test(interaction:Interaction):
bot_log = channel_up(940125176723554394)
await bot_log.send(f'<#&806045254834847776>,{} has started diagnostics for the bot. Please ignore any possible disturbances for the next minute or so.')
Thanks in advance for the advice, it's the first discord bot I've ever created.
EDIT:
In documentation, I found the solution. I have to use interaction.user.mention to get it to mention the user who sent the command. Or at least in theory, I'm dealing with a different issue now. Hopefully this helps people who also were as confused as me out.
You can use the interaction.user.name function with an # at the beginning.
The code should look something like this:
await interaction.response.send_message("#"+str(interaction.user.name))
I need help reacting to the most recent message. This can be in a specified channel or just in the server. The main thing I need help with is getting the message id or info about the most recent message, the reacting part I can do.
Please let me know if there is a solution, as everything I have looked up hasnt produced any results.
Thanks!
There are quite a few methods to get the last message in a channel. Assuming you already have a specific channel in which you want to react. Use
last_message = channel.last_message #channel must be a discord.Channel
The docs specify that this could sometimes get the wrong message, hence we use
messages = await channel.history(limit=1).flatten()[0]
References:
last_message
history
Tip:
Try searching for the relevant class in the docs instead of googling
I'm trying to make commands that are exclusive to the guild's owner, how would i check that? The closest of what i want is the ADMINISTRATOR permission but not owner
D Pardal's answer is 100% correct.
I'm not sure how familiar with the docs you are, but it could be helpful to start getting a feel for how to find things like that from the Discord.js docs. It, at least for me, helps to gain an understanding of just what every object/class they provide does. If you already know this, and just had a bit of a mental block, just ignore this & have a nice day. Otherwise, I'm waiting on a question of my own, so I figured I'd help out with what I know. I invite you to step through the docs at Discord.js.org with me as I explain this to see exactly what I'm talking about. Until recently, I found the Discord.js.org docs crazily complicated and un-understandable, so I'm hoping I can make it a little easier for you, and anyone else down the line, who could benefit from them.
Something to glean from this is that data about members in a guild can be found in the Guild object representing the guild. How do we find that?
Well, the only place we have to start is (probably, assuming your bot just takes in messages and executes commands based on them) the message we take in, we'll call it message. Going to the Discord.JS docs, scrolling through the Classes on the side, eventually we see that there is, in fact, a Message class!
Now we can look and see what data ships with it, which is a wide variety of things that may be useful to you down the road. If we look close enough, the Message obj does have a property that sounds like what we're looking for, Message.Guild! The docs say that property is of of type Guild, & clicking the hyperlink, it takes us to the class definition for a Guild.
According to the definition, a Guild object represents a Guild on discord, so with any luck, we can get some information about things in said guild. Knowing that we're looking for a specific member in the guild, we might be tempted to look into the Guild#members property- and while that could be useful down the line, it doesn't get us
particulaly close to knowing who the owner is, just who all the members are.
Finally, if we scroll a bit further, we see that the Guild Class has a property called Owner, AND ownerID! Depending on what we want, either could be useful. Owner is a GuildMember object, a representation of a user that contains a lot of details (just like how a Guild object is a representation of a guild with lots of info about it). However, if we just need the ID for something like, say, checking the ID of the command sender to the ID of the owner, we can just get the ID property of the owner object.
In an expanded form you could visualize that like such
const guild = message.guild
const ownerID = guild.ownerID
Or condensed like
const ownerID = message.guild.ownerID
If there's anything I can clarify further let me know! I know I couldn't figure out the docs for the longest time, so I hope this helped at least somewhat.
Just use Guild#owner, like this:
msg.member.id === msg.guild.ownerID // Returns true if the message was sent by the guild owner.
I'm trying to create a simple command that quickly adds a certain role to all server members (or remove, depending on the command used), but I'm having a bit of an issue.
Current code:
try {
message.guild.members.filter(m => !m.user.bot).forEach((member) => {
member.removeRole(role)
});
console.log(`Role ${role.name} taken from everyone!`)
} catch {
error => console.log(error)
}
This works, but I get a lot. And I mean A LOT of errors. Mostly time errors, such as timeout: error removing role.
It says in the start that there's too much listeners, so I went online to find this .setMaxListeners(0);
But it doesn't do anything
Any help would be appreciated! Thank you
All of the behavior you described is because Discord.js needs to make so many calls to the same API endpoint concurrently, and only a certain amount can be processed at once. The loop is going through each member and calling your method again and again, and Discord.js winds up putting all these requests into a queue. When it has to wait too long to add the role, the error you see is returned. And about having too many listeners attached and the possible memory leak warning, Discord.js attaches a listener for when Discord says the role is actually removed. Because your code isn't waiting for the role to be removed for each member, a lot are attached at once.
Even if you wanted to await the member.removeRole() call, it wouldn't work in a forEach() loop because of the way it's built. It doesn't wait for your function to finish, so it just keeps going and then moves on. A for...of loop would fix this issue.
The best solution in this case might actually be to clone and then delete the role. By deleting it, it's automatically removed from every member, and you don't have to make all those calls to the API or wait for all of them. To "clone" it, you can create a new role using the old role instance as the data, adding 1 to the position (assuming the old role is there).
Also, just as a side note, the catch block of a try...catch statement doesn't use a callback function. The code inside of it is read and executed just like in the try block (only if there's an error of course). And, if you're not awaiting promises, your catch block won't actually catch rejections because everything may have already moved on (the promise is pending, so it just continues).