How to find a message author's highest role? - discord.js

I would like to know how to get message author's highest role for my commands.
But whatever I do its always
A) undenfined or
B) Cannot read property 'name' of undefined
Its always one of these.
I looked on the documentation of discord.js and for them its easier. So I would need help.
I tried to search here but there was only one result that isnt working for me too.
My code that I try is:
var mod = message.author;
let rank = mod.highestRole.name;
var offence = message.content.slice(28);
if(!offence){
message.reply("Please put a reason for warning")
return;
}
var emb = new Discord.RichEmbed()
.setAuthor("Warn")
.addField("Staff:", mod.username)
.addField("Staff's ID:", mod.id)
.addField("Staff's rank:", rank)
.addField("Offender's username:", user.username)
.addField("Offender's ID:", user.id)
.addField("Offence:", offence)
.setColor("RED");
I would love to get it working and it would make my life much easier.

since discord.js v12 highestRole property of GuildMember was removed so you need to replace highestRole with roles.highest

Related

making discord bot command to store message content (python)

So this is my first time coding an actual project that isn't a small coding task. I've got a bot that runs and responds to a message if it says "hello". I've read the API documentation up and down and really only have a vague understanding of it and I'm not sure how to implement it.
My question right now is how would I go about creating a command that takes informationn from a message the command is replying to (sender's name, message content) and stores it as an object. Also, what would be the best way to store that information?
I want to learn while doing this and not just have the answers handed to me ofc, but I feel very lost. Not sure where to even begin.
I tried to find tutorials on coding discord bots that would have similar functions to what I want to do, but can't find anything.
Intro :
Hi NyssaDuke !
First of all, prefer to paste your code instead of a picture. It's easier for us to take your code and try to produce what you wish.
In second, I see an "issue" in your code since you declare twice the bot. You can specify the intents when you declare your bot as bot = commands.Bot(command_prefix="!", intents=intents)
Finally, as stated by #stijndcl , it's against TOS, but I will try to answer you at my best.
filesystem
My bot needs to store data, like users ID, language, and contents relative to a game, to get contacted further. Since we can have a quite big load of requests in a small time, I prefered to use a file to store instead of a list that would disappear on crash, and file allow us to make statistics later. So I decided to use pytables that you can get via pip install pytables. It looks like a small DB in a single file. The file format is HDF5.
Let say we want to create a table containing user name and user id in a file :
import tables
class CUsers (tables.IsDescription) :
user_name = StringCol(32)
user_id = IntCol()
with tables.open_file("UsersTable.h5", mode="w") as h5file :
groupUser = h5file.create_group("/", "Users", "users entries")
tableUser = h5file.create_table(groupUser, "Users", CUsers, "users table")
We have now a file UsersTable.h5 that has an internal table located in root/Users/Users that is accepting CUsers objects, where, therefore, user_name and user_id are the columns of that table.
getting user info and storing it
Let's now code a function that will register user infos, and i'll call it register. We will get the required data from the Context that is passed with the command, and we'll store it in file.
#bot.command(name='register')
async def FuncRegister (ctx) :
with tables.open_file("UsersTable.h5", mode="a") as h5file :
tableUser = h5file.root.Users.Users
particle = tableUser.row
particle['user_name'] = str(ctx.author)
particle['user_id'] = ctx.author.id
particle.append()
tableUser.flush()
The last two lines are sending the particle, that is the active row, so that is an object CUsers, into the file.
An issue I got here is that special characters in a nickname can make the code bug. It's true for "é", "ü", etc, but also cyrillic characters. What I did to counter is to encode the user name into bytes, you can do it by :
particle['user_name'] = str(ctx.author).encode()
reading file
It is where it starts to be interesting. The HFS5 file allows you to use kind of sql statements. Something you have to take in mind is that strings in the file are UTF-8 encoded, so when you extract them, you have to call for .decode(utf-8). Let's now code a function where a user can remove its entry, based on its id :
#bot.command(name="remove")
async def FuncRemove(ctx) :
with tables.open_file("UsersTable.h5", mode="a") as h5file :
tableUser = h5file.root.Users.Users
positions = tableUser.get_where_list("(user_id == '%d')" % ctx.author.id)
nameuser = tableUser[positions[0]]['user_name'].decode('utf-8')
tableUser.remove_row(positions[0])
.get_where_list() returns a list of positions in the file, that I later address to find the right position in the table.
bot.fetch_user(id)
If possible, prefer saving ID over name, as it complicates the code with encode() and decode(), and that bots have access to a wonderful function that is fetch_user(). Let's code a last function that will get you the last entry in your table, and with the id, print the username with the fetch method :
#bot.command(name="last")
async def FuncLast(ctx) :
with tables.open_file("UsersTable.h5", mode="r") as h5file :
tableUser = h5file.root.Users.Users
lastUserIndex = len(tableUser) - 1
iduser = tableUser[lastUserIndex]['user_id']
member = await bot.fetch_user(iduser)
await ctx.send(member.display_name)
For further documentation, check the manual of discord.py, this link to context in particular.

Scan full discord member list and change nicknames

I am looking for a way to scan my full server online member list every hour, and change any cancer nicknames. Like names with "!" at the start or "`" pretty much all non letter/number characters. I am using discord.js with all intents enabled. If you can help I will appreciate it :)
The GuildMemberManger.fetch() provides the functionality you require.
members = await <Guild>.members.fetch({query: 'querystring'})
All members with querystring in their username will be returned, in a collection.
After that you can iterate through the collection and do whatever you want.
If you want more control over the conditions you should filter the members cache collection with your own conditions.
condition = (member) => member.nickname.length == 3 //Finds members with 3 letter nicknames.
members = await <Guild>.members.cache.filter(condition)

Getting the current timestamp for a video with a Discord.js music bot?

I am trying to create a music bot with discord.js & ytdl-core. I would like to display the current timestamp when using a command called !nowplaying. However, I am not sure how I get the time. My code:
//bot.queue is a collection, and contains some attributes, like songs (array) and connection (ytdl)
let queue = bot.queue.get(message.guild.id);
const time = queue.connection.streamTime; //Doesn't work!
//Convert time here, then output
message.channel.send(`Now Playing - ${queue.songs[0].title} - ${time}`);
I've tried using queue.connection.streamTime, and other methods, but they haven't worked
Use voiceConnection#dispatcher (it returns a StreamDispatcher) instead of voiceConnection:
//bot.queue is a collection, and contains some attributes, like songs (array) and connection (ytdl)
let queue = bot.queue.get(message.guild.id);
const time = queue.connection.dispatcher.streamTime; //Doesn't work!
//Convert time here, then output
message.channel.send(`Now Playing - ${queue.songs[0].title} - ${time}`);

How to find a role by name and add a user to it (discord.js)

So I'm trying to create a bot that is more universal and can be added to more than one server. I've managed to reformat commands like announce or join messages etc. by using .find("name", "announcements").
My problem is that the same does not work for roles.
I've tried what little I could find on the internet, such as member.guild.roles.find("name", "Member") or member.guild.roles.find(role => role.name === "Member") but none of these work. A variety of different ways return different errors, but they usually say something along the lines of it not being an integer (I think) or snowflake.
This is the function that I am currently wrestling with:
client.on('guildMemberAdd', (member) => {
var joinResponse = ("Hello **" + member.displayName + "**, welcome to **" + member.guild.name + "**!")
let role = member.guild.roles.find("name", "Member");
member.addRole(role).catch(console.error);
member.guild.channels.find('name', 'general').send(joinResponse);
In short summary, what I'm looking for is the ability to get a role by name and add a user to it.
(I'm nearly certain it's possible, since popular bots like Dyno are capable of using commands to add roles to users.)
client.on('guildMemberAdd', (member) => {
const joinResponse = `Hello **${member.user.username}**, welcome to: **${member.guild.name}**!`
let role = member.guild.roles.get('Member');
if(!role) return console.log("Role doesen't exist.");
member.addRole(role);
const ch = member.guild.channels.get('general');
if(!ch) return console.log("Channel doesen't exist.");
ch.send(joinResponse);
});//You didn't have closing brackets (Could've been a problem)
First of all your string joinResponse was a function and you completely messed up merging it, I recommend using Template literal.
I used get function since it's a lot easier to use and cleaner, you only pass ID or name as a string.
To check if channel exists I used if statements and exclamation mark which means doesen't exist/false.
If I helped you please mark this as answer, thanks <3. If you need anything add comment to answer or message me on Discord (You can find my discriminator on my stack overflow profile).
For further explanation click on Blue words.

How to mention mentioned users in a message?

I've been trying to figure this out in a while but honestly i can't seem to wrap my head around it, I've figured out that u can add roles to users by doing a simple add_roles with message.mentions[0] but i can't seem to figure out how to mention a mentioned user in a message, Here is my current code Any help would be great!
if message.content.lower().startswith('/slap'):
mention = message.mentions[0]
await bot.send_message(message.channel, mention + "got slapped by {0.author.mention}".format(message))
message.mentions returns a list of discord.Member objects. You can ping those members by using member.mention
So to ping the person you'd need
member = message.mentions[0] # Probably in a try block
content = "{0.mention} ... {1.author.mention}".format(member, message)
await bot.send_message(..., content)
or to get a list of mentions, you can probably get away with
# After checking the length of the list (2 or more)
mentions = [m.mention for m in message.mentions]
mention_list = ", ".join(mentions[:-1]) + " and " + mentions[-1]

Resources