I am trying to do a command that shows a user's badges. This is my code:
#bot.command(pass_context=True)
async def test(ctx, user: discord.Member):
test = discord.Embed(title=f"{user.name} User's Badges", description=f"{user.public_flags}", color=0xff0000 )
await ctx.channel.send(embed=test)
And the bot is responding like this
<PublicUserFlags value=64>
I want it to respond like this
Hype Squad ...
How do I do that?
You could do str(user.public_flags.all()) to obtain a string value of all the badges an user has. Although this is an improvement, your output will still be something like: [<UserFlags.hypesquad_brilliance: 128>]. But the advantage here is that the words hypesquad and brilliance are clearly indicated in the string. Now, all you have to do is to remove [<UserFlags., _ and : 128>] from the string.
Here is a way to re-define your code:
#client.command(pass_context=True)
async def test(ctx, user: discord.Member):
# Remove unnecessary characters
hypesquad_class = str(user.public_flags.all()).replace('[<UserFlags.', '').replace('>]', '').replace('_',
' ').replace(
':', '').title()
# Remove digits from string
hypesquad_class = ''.join([i for i in hypesquad_class if not i.isdigit()])
# Output
test = discord.Embed(title=f"{user.name} User's Badges", description=f"{hypesquad_class}", color=0xff0000)
await ctx.channel.send(embed=test)
user.public_flags is not the way to access the user's profile.
From the documentation, you need to use user.profile() to get attributes like premium,
staff, hypesquad.
Since discord.py 1.7 it is impossible to get info from the user's profile using await user.profile(). In the documentation it states that this functionality is deprecated. If you try it you get an error Forbidden: 403 Forbidden (error code: 20001): Bots cannot use this endpoint
Here a little correction from the code from #GGBerry
#client.command(pass_context=True)
async def test(ctx, user: discord.Member):
userFlags = user.public_flags.all()
for flag in userFlags:
print(flag.name)
user.public_flags.all() returns a list, that can be iterated. In the list are flag object from the type discord.UserFlag. This object contains all sorts of badges. Here is the documentation for the UserFlags: https://discordpy.readthedocs.io/en/stable/api.html?highlight=userflag#discord.UserFlags
Related
#bot.command()
async def id(ctx, a:str): #a = #user
how would I get the ID of a user mentioned in the command, and output it as:
await ctx.send(id)
Use a converter to get the User object:
#bot.command(name="id")
async def id_(ctx, user: discord.User):
await ctx.send(user.id)
Or to get the id of the author:
#bot.command(name="id")
async def id_(ctx):
await ctx.send(ctx.author.id)
Just realized that when you #someone and store it to the variable "a", it contains the user ID in the form of '<#userid>'. So a bit of clean up can get me the user ID
Here's the code:
#bot.command()
async def id(ctx, a:str):
a = a.replace("<","")
a = a.replace(">","")
a = a.replace("#","")
await ctx.send(a)
Since my command consists of "rev id #someone", the #someone gets stored in 'a' as the string '<#userid>' instead of '#someone'.
If you want to handle a mention within your function, you can get the mention from the context instead of passing the mention as a string argument.
#bot.command()
async def id(ctx):
# Loop through the list of mentioned users and print the id of each.
print(*(user_mentioned.id for user_mentioned in ctx.message.mentions), sep='\n')
ctx.message.mentions will return:
A list of Member that were mentioned. If the message is in a private
message then the list will be of User instead.
When you loop through ctx.message.mentions, each item is a mentioned member with attributes such as id, name, discriminator. Here's another example of looping through the mentioned list to handle each member who was mentioned:
for user_mentioned in ctx.message.mentions:
# Now we can use the .id attribute.
print(f"{user_mentioned}'s ID is {user_mentioned.id}")
It's up to you whether you want to require the argument a as shown in the question above. If you do need this, note that the string will sometimes include an exclamation in the mention depending on whether it is:
for a User or command was posted from mobile app: <#1234567890>
for a Nickname or command was posted from desktop app: <#!1234567890>
Which is why I prefer to get the id from a member/user attribute.
So I'm in the process of making a command that fake bans people, but looks like it bans them for real, just to freak people out and to troll them. It's quite convincing right now, but I want to add the tag of the user I have fake-banned in the command. Here is what I have so far:
#client.command(help = 'bans people trol')
async def ban(ctx, user : discord.Member, *, reason = None):
if reason == None:
reason = 'no reason lma-'
await ctx.send(f'Banned **{user.name}**. Reason: {reason}')
I used to have user.mention in the place of user.name, but that's a dead giveaway for the fake ban, so I changed the command to user.name, but this still only fetches and sends the username of the person. If I banned a person named #Kid#1111, the command would read "Banned **Kid**. Reason: no reason lma-"
How would I add the tag in? I'm assuming it's just a matter of changing the user.name to something else, but I can't find what that would be in documentation.
You can use discord.Member.discriminator to get the tag of the member. So you can put the name and the discriminator together.
#client.command(help = 'bans people trol')
async def ban(ctx, user : discord.Member, *, reason = None):
if reason == None:
reason = 'no reason lma-'
await ctx.send(f'Banned **{f'{user.name}#{user.discriminator}'}**. Reason: {reason}')
I want to have my bot respond to when a specific user starts typing (i.e. me)
#client.event
async def on_typing(channel, user, when):
member = client.get_user(id='user_id')
me = 'my_id'
if me == member.typing:
await channel.send('*cough* loser...')
If I use == to compare I get no response, if I use != the bot responds to everyone as expected.
If I run the if statement as:
if me.typing:
await channel.send('*cough* loser...')
The bot just responds to everyone again, what gives?
Your code as some errors:
client.get_user() only takes one argument, which is a single id and has to be an integer. You'd have to use it this way → user = client.get_user(id).
Reading the doc, member.typing() that allows you to have this xxxx is typing and returns a context manager, not an integer, that's why your first if statement isn't triggered.
As explained above, me != member.typing is always triggered because they will never be the same type and same value.
You don't really need to get a user object, you can just use user.id and compare it to the ID you want.
IDs must be integers, not strings or else, the if statement will never trigger.
#client.event
async def on_typing(channel, user, when):
if user.id == your_id: #Replace your_id with the id you want (must be an int)
await channel.send('*cough* loser...')
Reference: discord.py documentation → discord.on_typing
I have a simple questions about discord. I am trying to create an economy system, and it works well, but I want to customize it a bit. I am using this person's module: https://github.com/Rapptz/discord.py
How do I convert a username to a discord ID. For example if I have a discord "command" to allow people to gift each other money, like: james#0243 types !give 100 bob#9413.
How can I convert bob#9413 to a discord id like 58492482649273613 because in my database, I have people's users stored as their ID rather than their actual username as people can change their username.
Use a converter to get the Member object of the target, which will include their id.
from discord import Member
from dicord.ext.commands import Bot
bot = Bot(command_prefix='!')
#bot.command()
async def getids(ctx, member: Member):
await ctx.send(f"Your id is {ctx.author.id}")
await ctx.send(f"{member.mention}'s id is {member.id}")
bot.run("token")
Converters are pretty flexible, so you can give names, nicknames, ids, or mentions.
on_message callback function is passed the message.
message is a discord.Message instance.
It has author and
mentions attributes which could be instances of discord.Member or discord.User depending on whether the message is sent in a private channel.
The discord.Member class subclasses the discord.User and the user id can be accessed there.
You could use get_member_named to do something like
#client.command(pass_context = True)
async def name_to_id(ctx, *, name):
server = ctx.message.server
user_id = server.get_member_named(name).id
The name can have an optional discriminator argument, e.g. “Jake#0001” or “Jake” will both do the lookup. However the former will give a more precise result.
prefix_choice = "!"
bot = commands.Bot(max_messages=10000, command_prefix=commands.when_mentioned_or(prefix_choice))
#bot.command()
async def membersLog(ctx):
for i, member in enumerate(ctx.message.server.members):
list_mem_num = (f'{i}')
list_mem_id = (f'{member.id}')
list_mem = (f'{member}')
list_mem_name = (f'{member.name}')
list_all = (f'Number: {list_mem_num} ID: {list_mem_id} Name: {list_mem} ({list_mem_name})\n')
print(list_all)
You can use this to collect all memberinfo of the server where the call comes from. This is the code I use for this.
Say I want to make a bot with a "poke" feature (aka sends a pm to a user saying "Boop" when someone says "!poke #user#0000"), how would I do this? It works perfectly when I do this:
#bot.command(pass_context=True)
async def poke(ctx, message):
await client.send_message(ctx.message.author, 'boop')
but only if I want to poke the author of the message. I want to poke whoever's being #'d.
I know the discord.py documents say I can use this:
start_private_message(user)
but I don't know what to put in place of user.
It's actually simpler than that
#bot.command(pass_context=True)
async def poke(ctx, member: discord.Member):
await bot.send_message(member, 'boop')
send_message contains logic for private messages, so you don't have to use start_private_message yourself. The : discord.Member is called a converter, and is described in the documentation here
I might be necroing this post a bit, but the recent version of this would look like this:
#bot.command():
async def poke(ctx, user: discord.Member=None):
if user is None:
await ctx.send("Incorrect Syntax:\nUsage: `!poke [user]`")
await user.send("boop")
The if user is None: block is optional, but is useful if you want to have an error message if a command isn't used correctly.