Member Count Channel discord.py - discord

The program should work in such a way that a channel named "members" will display the number of members on the server, but the program does not give errors and does not work itself.
Thanks in advance!
async def on_member_join(member):
guild = member.guild
channel = get(guild.channels, name = 'members')
await channel.edit(name = f'Учатники: {guild.member_count}')
#bot.event
async def on_member_remove(member):
guild = member.guild
channel = get(guild.channels, name = 'members')
await channel.edit(name = f'Учатники: {guild.member_count}')

I am not really sure if you have it in your program but just to be sure, define what is the attribute named "channel" so it knows what to edit, you can use get_channel to do it and put the channels ID afterward inside it ( https://discordpy.readthedocs.io/en/latest/api.html?highlight=get_channel#discord.Client.get_channel)
Maybe just try and use it the old way and use name = "Учатники: " + str(guild.member_count) (The member_count gives you an output of int so you may need to turn it into a string before displaying it.
(I have not tested anything and this answer is based on experience and reading documents and also you might want to take a look at https://discordpy.readthedocs.io/en/latest/api.html?highlight=member_count#discord.Guild.member_count)

Related

If I want to remove an ID-specified role within a function, how can I do that?

If I want to remove an ID-specified role within a function, how can I do that?
#bot.command()
async def aa(ctx,member:discord.Member):
role_muted = discord.utils.get(ctx.guild.roles, name='test01')
await member.remove_roles(role_muted)
What I want is to specify an ID in a function like this.
#bot.command()
async def aa(ctx):
member = 414087251992117211 #ID User
role_muted = discord.utils.get(ctx.guild.roles, name='test01')
await member.remove_roles(role_muted)
how can i do it The reason I have to do this is because I will continue to develop such as When you receive this Role within 3 days if not online it will remove your Role.
Use Guild.get_member(id) to get a member by their ID. You can get the Guild either from the ctx if you want it to run in the guild where you call the command, or from a Guild ID that you store somewhere using Bot.get_guild(id).
If you want to pass the ID in as an argument to the function and have it convert to a member automatically, use a Converter.
Can you give an example? I tried to do as you said. but an error occurred
#bot.command()
async def aa(ctx):
member = discord.Guild.get_member(414087251992117211)
role_muted = discord.utils.get(ctx.guild.roles, name='test01')
await member.remove_roles(role_muted)
Error
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: AttributeError: 'NoneType' object has no attribute 'remove_roles'
#UpFeR Pattamin, please comment on a reply instead of posting a new one. You're getting this error because you're not specifying which guild you are talking about. If you want to get the one that the command was executed in, I'm pretty sure you need to do ctx.guild.get_member().

Discord.py client.commands send mentioned user

I have this command called p!slap and I want it so that my bot will say {message.author} slapped {message.mention} and a random gif but I have no idea how to. Can anyone help? Thanks!
#client.command()
async def slap(ctx, message.mention):
embedVar = discord.embed(title=f"<#{message.author.id}> slapped {message.mention}")
list = [
#gif links and stuff
]
await ctx.channel.send(random.choice(list))```
Your code has a few problems.
At first, I couldn't understand what you're trying to do with naming a parameter message.mention but I guess what you're trying to do is "slapping" the person you mentioned in command. For that, you have to get the member object in parameter. Then, you can mention this member.
Also, you shouldn't define a variable named list. This might cause a error because of the built-in method list.
An another thing is, there's no embed method for discord module, it must be discord.Embed. You have to pay attention to the uppercase letters.
You never sent the embed you defined, you must send it for your command to work.
For the last one, I don't know what'll be in the list lst but I guess there will be files. If you're going to send a file, you cannot just send it. You have to pass a parameter in .send() method. But this is only for the files. If you're just going to send a link, then you don't have to pass any parameters.
#client.command()
async def slap(ctx, member: discord.Member):
embedVar = discord.Embed(title=f"{ctx.author.mention} slapped {member.mention}")
lst = [
#gif links and stuff
]
await ctx.channel.send(file=discord.File(random.choice(lst)), embed=embedVar)

Wait for Message on_member_join using checks (discord.py) | SOLVED

I want to wait for a private message that was sent only by the member. I am trying to use the check parameter for the client.wait_for() method but I can not seem to get it. I tried putting the check as the response.author but will not work since I just assigned response. Also I am executing this when a member joins using on_member_join which takes in a member argument (like this async def on_member_join(member). Anyone know how to properly do this? Any answers would be greatly appreciated!
Here is the code for this:
await member.send('What is your student number? ')
response = await client.wait_for('message')
student_number = response.content
When adding a check function to wait_for, that check function will get the received message as an argument. This means that it will check every single message the bot gets, pass all of them to your check function, and wait until one of them makes the check return True.
#client.event()
async def on_member_join(member):
def check(message):
return message.author.id == member.id and message.guild is None
await member.send('What is your student number?')
response = await client.wait_for('message', check=check)
student_number = response.content
Note how my example also makes sure the guild is None, as you explicitly mentioned waiting for a private message.

Discord Py - How can I add_role to user on_message?

I want to use regex to look at and accept literally ANY incoming message from a user and assign them a role. But ONLY if that user does not have a role already assigned to them. I don't get any errors when running the code, but it does not work.
Here is what I have:
#client.event
async def on_message(message):
match = re.search(r'(.*?)', message.content)
member = message.author
role = discord.utils.get(member.guild.roles, name="Creators")
if message.author == client.user:
return
if role not in member.roles:
if match and message.channel.id == target_channel:
# add member to role
# send message to to users
await message.channel.send(
f'Hi {message.author}, welcome to the server! Don\'t forget to choose your #roles'
)
await discord.Member.add_roles(member, role)
You wrote:
await discord.Member.add_roles(member, role)
https://discordpy.readthedocs.io/en/latest/api.html?highlight=add_role#discord.Member.add_roles
As you can see from the documentation the passed arguments is *roles, reason=None, atomic=True. roles is something you have to specify, reason and atomic are optional.
You tried passing member which is not a valid argument.
discord.Member is a class. You need to get an instance of that class. ctx.author is an instance of discord.Member.
So the final call should be:
await ctx.author.add_roles(role)
To get the Member object from on_message, you can use member = message.author.
Then simply do member.add_roles(role).
Thanks for the help guys, it turns out it was something very minor (and dumb on my part) that prevented it from working.
when comparing message.channel.id.id to target_channel, I forgot that the channel id object does not come in as a string, but target_channel was set up as a string, so it failed to see them as equal. Simply converting message.channel.id to string did the trick.

How to get GuildMember data from a User through a mention

I am making a "user info" command that returns the user's Discord username, their ID, their server join date and whether or not they are online. I am able to display all the information through user.id, user.username, and user.presence.status. But when I try to use user.joinedAt I get undefined in the display.
I know this is because the User class and the GuildMember class are not the same, and that the GuildMember class contains a User object.
But my problem is: how I could get the .joinedAt data from my user mention?
Here is my current code:
let user = message.mentions.users.first();
let embed = new Discord.RichEmbed()
.setColor('#4286f4')
.addField("Full Username:", `${user.username}#${user.discriminator}`)
.addField("User ID:", `${user.id}`)
.addField("Server Join Date:", `${user.joinedAt}`)
.addField("Online Status:", `${user.presence.status}`)
.setThumbnail(user.avatarURL);
message.channel.send(embed);
Here's the code for my user info command:
if (msg.split(" ")[0] === prefix + "userinfo") {
//ex `member #Rinkky
let args = msg.split(" ").slice(1) // gets rid of the command
let rMember = message.guild.member(message.mentions.users.first() || message.guild.members.get(args[0])) // Takes the user mentioned, or the ID of a user
let micon = rMember.displayAvatarURL // Gets their Avatar
if(!rMember)
return message.reply("Who that user? I dunno him.") // if there is no user mentioned, or provided, it will say this
let memberembed = new Discord.RichEmbed()
.setDescription("__**Member Information**__")
.setColor(0x15f153)
.setThumbnail(micon) // Their icon
.addField("Name", `${rMember.username}#${rMember.discriminator}`) // Their name, I use a different way, this should work
.addField("ID", rMember.id) // Their ID
.addField("Joined at", rMember.joinedAt) // When they joined
await message.channel.send(memberembed)
};
This will send an embed of their user info, this is my current code and
rMember.joinedAt
does work for me.
edit:
After looking at your question again, I found out I didn't need to post everything, you can't get the joined at because it's just the mention. Try this:
let user = message.guild.member(message.mentions.users.first())
Should work
You can technically find it by fetching getting the member from the guild and then using GuildMember.joinedAt: since the User class represents the user in every guild, you will always need the GuildMember to get info about a specific guild.
let user = message.mentions.users.first(),
member;
if (user) member = message.guild.member(user);
if (member) embed.addField("Server Join Date:", `${member.joinedAt}`);
With this said, I would not suggest you to do that, since it's not really efficient. Just take the mention from the members' collection and then take the user from that.
let member = message.mentions.members.first(),
user;
if (member) user = member.user;
The downside of this is that you can't use it if you want your command to be executable from the DMs too. In that case you should use the first method.
const member = message.channel.guild.members.cache.find(member => member.user == message.mentions.users.first())

Resources