Im pretty new to discord.py and would like to get the ids of all the people in the discord server that the bot is used in.
Thanks,
Aarav
First use should get guild object from ctx.guild in command event, message.guild in on_message event, etc. Then choose the sample below.
The sample to go through all members and do some stuff
for member in guild.members:
id = member.id
# Do stuff here
The sample to get a list of all members ids
ids = [member.id for member in guild.members]
The sample to get an itterator of all members ids
def get_all_members_ids(guild):
for member in guild.members:
yield member.id
# And then use it like this
for id in get_all_members_ids(guild):
# Do stuff here
Related
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.
I tried to do it in different ways, but none gave the desired result. I need to use it in an embed.
I am new to this area and have not found any information.
Screenshot translation:
#name spit #name
Try to explain your question a bit more and show code you have tried, you can use {ctx.author.mention} to mention the member that used the command and {member.mention} to mention the member that was # make sure to call the member by useinf member :discord.Member in your async def ( )
Example:
async def hi(ctx, member : discord.Member):
await ctx.send(f"{ctx.author.mention} said hi to {member.mention}")
I want to remove the the role from the users in the server who have the corresponding role by using the role mention.
For example, '%remove_role#TEAM_A' removes 'TEAM_A' from the roles of people who have the role 'TEAM_A'.
I searched hard on Google, but I couldn't find an answer or a way to do it, so I made it myself, but I failed to complete it, so I wrote a question here.
1st. %rmrole team name
2nd. Check if the team name you entered is in 'role_list'.
3rd. Remove the role of the team name entered from users on the server.
this is my code.
#bot.command()
async def rmrole(ctx, team_name):
key = 0
role = get(ctx.guild.roles, name=team_name)
team_list = []
print(role)
# typo check
role_list = ["TEAM_A", "TEAM_B", "TEAM_C", "TEAM_D"]
if role in role_list:
type_error = 1
else:
type_error = 0
# remove_role
empty = True
if type_error == 1:
for member in ctx.guild.members:
if role in member.roles:
await member.remove_roles(role)
empty = False
if empty:
await ctx.send("anyone has this role.")
else:
await ctx.send("check the typos."
async def remove_role(ctx, role: discord.Role)
I was worried that if I write like this, users would get a lot of alarms.
Thus, in the body, I enter the name of the role in text, and I write it in a way that scans the role in the code.
The '#remove_role' part was searched and found.
The code was executed, but the role was not removed.
I wonder where the wrong part is, and I need help to make what I want.
Your mistake is simple:
role_list = ["TEAM_A", "TEAM_B", "TEAM_C", "TEAM_D"]
if role in role_list:
type_error = 1
else:
type_error = 0
This code will always fail and lead to type_error = 0, as role is a discord.role.Role class and not a string. This means comparing the role you got via get and a string representing its name will always fail : and so, that the second part of your code that removes the role is never accessed. It works otherwise.
Instead, you want:
if role.name in role_list:
type_error = 1
else:
type_error = 0
Or better yet, this instead:
if role is None:
return await ctx.send("Role doesn't exist")
...since I don't quite see the point of your code personally: if role = get(ctx.guild.roles, name=team_name) fails (i.e the role doesn't exist), role will be None, and you can easily check for it instead of comparing it against a hardcoded list.
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)
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.