Discord.py get member of the server without bots - python

Is there a way to get only the members without the bots of a server?
#bot.command()
async def stats(ctx):
guild = bot.get_guild("guild")
await ctx.send(f'{guild.member_count}')
When I run this code, it sends a message with the member count including bots. I want it to only send me the REAL member count (no bots)!

You could use:
members = 0
for member in ctx.guild.members:
if not member.bot:
members += 1
using .bot checks if the account is a bot or not.

You need to enable the members intent (so your bot can see the whole members list, not just itself), then count up the number of non-bots in the list of members. Here's how...
from discord import Intents
from discord.ext.commands import Bot
# Enable the default intents, then specifically enable "members".
intents = Intents.default()
intents.members = True
# Initialize the bot with our customized intents object.
bot = Bot(command_prefix='!', intents=intents)
#bot.command()
async def stats(ctx):
# Booleans can be added up; True is 1 and False is 0.
num_members = sum(not member.bot for member in ctx.guild.members)
# Sending an integer is fine; we don't need to convert it to a
# string first.
await ctx.send(num_members)
bot.run(TOKEN)
For most intents, your bot can freely opt in or out of them, straight from Python. However, members is a privileged intent. In order to subscribe to it, you'll also need to enable it in Discord's developer web interface:

You can use the discord.Guild.members property to get all of the members in the guild. Then, use discord.Member.bot to check if each member is a bot.
This would simply be:
humans = []
for member in ctx.guild.members:
if not member.bot:
humans.append(member)
num_humans = len(humans)
Or, for the list comprehension enthusiasts:
humans = [m for m in ctx.guild.members if not m.bot]
num_humans = len(humans)
Note: This assumes that you have all the necessary intents activate.

Related

Discord.py - How to get member count not including bots?

I want to make a command that shows member count but not including bots. My code:
#bot.command()
async def members(ctx):
await ctx.send(f"Members in {ctx.guild.name}: {ctx.guild.member_count}")
However this shows count of bots and members together. Is there a way I can do it show members only?
You can try something like this,
user_count = len([x for x in ctx.guild.members if not x.bot])
This should work
import random
import discord
from discord.ext import commands
intents = discord.Intents().all() # intents to see the members in the server
client = commands.Bot(command_prefix="--", intents=intents)
# Command
#client.command(pass_context=True)
# to make sure that this command will only work on a discord server and not DMs
#commands.guild_only()
async def pickwinner(ctx):
# What you did wrong
# for users in ctx.guild.members:
# `users` is a single item in the iterable `ctx.guild.names`
# Selecting a user from the iterable (this includes user)
# winner = random.choice(ctx.guild.members)
# Selecting a user from the iterable (this does not include bots)
# But the line below will be resource intensive if you are running the command
# on a server with a huge amount of members
allMembers_NoBots = [x for x in ctx.guild.members if not x.bot]
winner = random.choice(allMembers_NoBots)
await ctx.channel.send(f"Congratulations! {winner} won the price!")
client.run("TOKEN")

How to remove one role from everything on the server?

I have a code to remove one role from everyone on the server, but it doesn't work:
When I enter a command, the bot simply ignores it, there is nothing in the cmd and the bot does not do anything either
Code -
intents = discord.Intents()
intents.members = True
#client.command()
async def clearrole(ctx):
role = discord.utils.get(ctx.guild.roles, id = 795410455848812565)
members = ctx.guild.members
for member in members:
if role in member.roles:
await member.remove_roles(role)
Make sure the intents are enabled, otherwise your bot might not be able to get a list of all the members of your server : https://discordpy.readthedocs.io/en/latest/intents.html
Then, make sure the id indeed correspond to a role by typing <#795410455848812565> in your server, it should transform into the role mention, otherwise the ID is wrong

discord.py can't change the channel's name

So recently I've tried to create a bot that could change the voice channel's name based on how many members are on the server, but I end up getting this error: await memberchannel.edit(name = ">> 👥ᴍᴇᴍʙᴇʀꜱ: " + guild.member_count) AttributeError: 'NoneType' object has no attribute 'edit'
Here's my code, I cannot figure out how to access the .edit attribute:
async def on_member_join(member):
guild = member.guild
memberchannel : discord.VoiceChannel = get(guild.channels, id=MemberCounterChannel)
await memberchannel.edit(name = ">> 👥ᴍᴇᴍʙᴇʀꜱ: " + guild.member_count)
I did the same thing in the on_member_remove function.
Events that use on_member_join or others related to member events, must require member intents to be enabled. This works to allow these events to run as they are private and should be used carefully.
Intents can be enabled from Discord developer portal, from there you only need to make sure you have enabled Member in intents within the "Bot" category. You'd then need to define and use the intents in your bot code in the section you define your bot or client:
intents = discord.Intents.default()
intents.members = True
client = commands.Bot(command_prefix='your bot prefix', intents=intents)
After you have enabled intents, the member events would work. With your code, memberchannel also isn't defined, nor is it a Discord parameter.
This would now get the channel you want to edit by it's ID and edit whenever a user joined to the current member count of the guild the user joined.
async def on_member_join(member):
member_channel = client.get_channel(channel id)
await member_channel.edit(name=f"Members: {member.guild.member_count}")
I had to toggle all of the intents in my application using discord developers panel and left the code like this (ConfigFile is a json file containing all of the variables):
memberchannel: discord.VoiceChannel = get(guild.channels, id=ConfigFile["MemberCounterChannelID"])
membercount = guild.member_count - 1
await memberchannel.edit(name="{0} {1}".format(ConfigFile["MemberCounterChannelName"], membercount))
Also I did the membercount = guild.member_count - 1 part because I only use this bot on my server and it's not made for commercial use so I don't really need it to actually count member-bots

Is there a way to list all members of a discord server with discord.py

I want to retrieve a list with all people which are part of the discord server.
import discord
from discord.ext import commands
TOKEN = 'my_token'
bot = commands.Bot(command_prefix = '!')
#bot.command()
async def members(ctx):
for member in ctx.guild.members:
await ctx.send(member)
bot.run(TOKEN)
Whenever using !members I just get a List of all members which are currently in a voice channel or in some way active on the server where but I'd like to get those just shown as online or even offline.
Does someone have any idea?
Since last updates you have to enable intents. Enable them from the dev portal and code it self.
intents = discord.Intents().all()
bot = commands.Bot(command_prefix="$", intents=intents)
Remove that line with server = bot.get_guild(SERVER_ID)
Guild.members will return a list of members in the guild.
Since >=1.5.0 requires elevated intents for Member/Presence events, you must enable the Member intents in the developer portal and in your code.
You're also checking for the number of members in which the command is invoked, so you would want to use the guild_only() decorator and remove the line with bot.get_guild()
Reason for having the guild_only() decorator is because if you invoke !members in a DM, guild would be None and will raise an error saying that 'NoneType' object has no attribute called 'members'

Discord.py rewrite get_member() function returning None for all users except bot

I made a stupid discord bot a few months ago to change my friends name every minute, but I updated it today and now the get_member function is returning none.
#client.event
async def on_ready():
print('bot is ready!')
status = discord.Activity(name="Sam be a loser", type=discord.ActivityType.watching)
await client.change_presence(activity=status)
name_change.start()
#tasks.loop(minutes=1)
async def name_change():
server = client.get_guild(id=584112137132048387)
user = server.get_member(376388277302984714)
global english_words
global wordNumber
wordNumber = wordNumber + 1
#changes nickname to current word
await user.edit(nick=f"{english_words[wordNumber]} lookin' ass")
print(f'Word number {wordNumber}: {english_words[wordNumber]}')
#updates number in file
file = open("currentWord.txt", "w")
file.write(str(wordNumber))
file.close
I tried the same function with every user in the server, but it returned none for all of them except when I put the bot's id in. I have no clue why this is happening since I didn't even edit this part of the code.
This is most likely due to the recent discord.py 1.5 update. You are required to configure your intents when you're declaring your Bot.
What are intents?
Version 1.5 comes with the introduction of intents. This is a radical change in how bots are written. An intent basically allows a bot to subscribe into specific buckets of events. The events that correspond to each intent is documented in the individual attribute of the Intents documentation. Here's an example:
import discord
from discord.ext import commands
intents = discord.Intents.default()
intents.members = True # Subscribe to the privileged members intent.
bot = commands.Bot(command_prefix='!', intents=intents)
You will also have to enable privileged intents for guild related events: Here
You can read more about intents: Here
You may be able to not use Intents, Privileged or otherwise, by not using get_member() and instead use
guild.fetch_member()

Categories

Resources