Discord.py get user object from id/tag
I’m using the discord.py library to build a discord bot. I’m trying to get a User object from an id or tag, however, I am using a user account not a bot account, so I can’t use get_user_info(). Is there any way to do this on a user account?
1,774 3 3 gold badges 16 16 silver badges 39 39 bronze badges
asked Feb 3, 2019 at 4:07
113 1 1 gold badge 1 1 silver badge 6 6 bronze badges
9 Answers 9
If you know the user id, I suggest using bot.get_user(user_id) instead.
answered May 3, 2019 at 9:42
BluePigeon BluePigeon
1,774 3 3 gold badges 16 16 silver badges 39 39 bronze badges
olny works if the cache has it. use fetch_user otherwise
Jan 15, 2021 at 11:51
If you’re using commands , you can use a converter:
@bot.command(pass_context=True) async def mycommand(ctx, user: discord.User): # user is a User object
Other wise, you can use Client.get_all_members to get all Member objects you can see.
from discord.utils import get user = get(bot.get_all_members(), user: # found the user else: # Not found the user
2,645 1 1 gold badge 30 30 silver badges 41 41 bronze badges
answered Feb 3, 2019 at 5:31
Patrick Haugh Patrick Haugh
59.5k 13 13 gold badges 88 88 silver badges 96 96 bronze badges
The id is guilds ids or user id?
Jan 30, 2022 at 3:35
ctx.message.server.get_member(id) or message.server.get_member(id) # id must be of type int
This will return you a discord.Member object.
2,645 1 1 gold badge 30 30 silver badges 41 41 bronze badges
answered Feb 9, 2019 at 18:56
Mahesh Mahi Mahesh Mahi
41 1 1 silver badge 5 5 bronze badges
Jan 12, 2021 at 15:09
This also will return your user object, but not your member object. If you want the member object, please follow AJ Lee’s answer
user = await client.fetch_user(user_id)
2,645 1 1 gold badge 30 30 silver badges 41 41 bronze badges
answered Aug 19, 2021 at 9:52
Deniz Karakay Deniz Karakay
11 4 4 bronze badges
ctx.message.server.get_member(id) or message.server.get_member(id)
I couldn’t write a comment to the previous answer (because of reputation) but make sure that id is int type here.
2,645 1 1 gold badge 30 30 silver badges 41 41 bronze badges
answered Mar 28, 2021 at 20:59
Yalchin Mammadli Yalchin Mammadli
454 4 4 silver badges 11 11 bronze badges
If you already have the id, call user = await ctx.bot.fetch_user(user_id) . No messing about with permissions.
If you only have the username and tag, you can use:
guild.fetch_members() user = guild.get_member_named("Example#1234")
Note you’ll also need to turn the Members intent on in your code and the Discord Developer Portal in order to call fetch_members()
intents = discord.Intents.default() intents.members = True super().__init__( command_prefix='!', intents=intents )
Как получить пользователя по id discord.py?
Я получаю id пользователя из папки, и переделываю в int.
elif n == ":": mesg = mesg.join(wordo) wordo.clear() wordo.append(mesg) print(wordo) member = bot.get_user(mesg) break else: await channel.send(f"Item ```` not found. ``>list`, to get list of items") else: await channel.send(f"u cant do it in this channel") if findor == 1: await author.send(f"U buying ```` from ````") await member.get_user(mesg).send(f"```` want buy your ````") elif findor == 0: await channel.send(f"Item ```` not in sell.")
f
и получаю ошибку
AttributeError: 'NoneType' object has no attribute 'get_user'
- Вопрос задан более двух лет назад
- 836 просмотров
Frequently Asked Questions¶
This is a list of Frequently Asked Questions regarding using discord.py and its extension modules. Feel free to suggest a new question or submit one via pull requests.
- Coroutines
- What is a coroutine?
- Where can I use await ?
- What does “blocking” mean?
- Where can I find usage examples?
- How do I set the “Playing” status?
- How do I send a message to a specific channel?
- How do I send a DM?
- How do I get the ID of a sent message?
- How do I upload an image?
- How can I add a reaction to a message?
- How do I pass a coroutine to the player’s “after” function?
- How do I run something in the background?
- How do I get a specific model?
- How do I make a web request?
- How do I use a local image file for an embed image?
- Is there an event for audit log entries being created?
- Why does on_message make my commands stop working?
- Why do my arguments require quotes?
- How do I get the original message ?
- How do I make a subcommand?
- How can I disable all items on timeout?
- My bot’s commands are not showing up!
Coroutines¶
Questions regarding coroutines and asyncio belong here.
What is a coroutine?¶
A coroutine is a function that must be invoked with await or yield from . When Python encounters an await it stops the function’s execution at that point and works on other things until it comes back to that point and finishes off its work. This allows for your program to be doing multiple things at the same time without using threads or complicated multiprocessing.
If you forget to await a coroutine then the coroutine will not run. Never forget to await a coroutine.
Where can I use await ?¶
You can only use await inside async def functions and nowhere else.
What does “blocking” mean?¶
In asynchronous programming a blocking call is essentially all the parts of the function that are not await . Do not despair however, because not all forms of blocking are bad! Using blocking calls is inevitable, but you must work to make sure that you don’t excessively block functions. Remember, if you block for too long then your bot will freeze since it has not stopped the function’s execution at that point to do other things.
If logging is enabled, this library will attempt to warn you that blocking is occurring with the message: Heartbeat blocked for more than N seconds. See Setting Up Logging for details on enabling logging.
A common source of blocking for too long is something like time.sleep() . Don’t do that. Use asyncio.sleep() instead. Similar to this example:
# bad time.sleep(10) # good await asyncio.sleep(10)
Another common source of blocking for too long is using HTTP requests with the famous module Requests: HTTP for Humans™ . While Requests: HTTP for Humans™ is an amazing module for non-asynchronous programming, it is not a good choice for asyncio because certain requests can block the event loop too long. Instead, use the aiohttp library which is installed on the side with this library.
Consider the following example:
# bad r = requests.get('http://aws.random.cat/meow') if r.status_code == 200: js = r.json() await channel.send(js['file']) # good async with aiohttp.ClientSession() as session: async with session.get('http://aws.random.cat/meow') as r: if r.status == 200: js = await r.json() await channel.send(js['file'])
General¶
General questions regarding library usage belong here.
Where can I find usage examples?¶
Example code can be found in the examples folder in the repository.
How do I set the “Playing” status?¶
The activity keyword argument may be passed in the Client constructor or Client.change_presence() , given an Activity object.
The constructor may be used for static activities, while Client.change_presence() may be used to update the activity at runtime.
It is highly discouraged to use Client.change_presence() or API calls in on_ready() as this event may be called many times while running, not just once.
There is a high chance of disconnecting if presences are changed right after connecting.
The status type (playing, listening, streaming, watching) can be set using the ActivityType enum. For memory optimisation purposes, some activities are offered in slimmed-down versions:
Putting both of these pieces of info together, you get the following:
client = discord.Client(activity=discord.Game(name='my game')) # or, for watching: activity = discord.Activity(name='my activity', type=discord.ActivityType.watching) client = discord.Client(activity=activity)
How do I send a message to a specific channel?¶
You must fetch the channel directly and then call the appropriate method. Example:
channel = client.get_channel(12324234183172) await channel.send('hello')
How do I send a DM?¶
Get the User or Member object and call abc.Messageable.send() . For example:
user = client.get_user(381870129706958858) await user.send('')
If you are responding to an event, such as on_message() , you already have the User object via Message.author :
await message.author.send('')
How do I get the ID of a sent message?¶
abc.Messageable.send() returns the Message that was sent. The ID of a message can be accessed via Message.id :
message = await channel.send('hmm…') message_id = message.id
How do I upload an image?¶
To upload something to Discord you have to use the File object.
A File accepts two parameters, the file-like object (or file path) and the filename to pass to Discord when uploading.
If you want to upload an image it’s as simple as:
await channel.send(file=discord.File('my_file.png'))
If you have a file-like object you can do as follows:
with open('my_file.png', 'rb') as fp: await channel.send(file=discord.File(fp, 'new_filename.png'))
To upload multiple files, you can use the files keyword argument instead of file :
my_files = [ discord.File('result.zip'), discord.File('teaser_graph.png'), ] await channel.send(files=my_files)
If you want to upload something from a URL, you will have to use an HTTP request using aiohttp and then pass an io.BytesIO instance to File like so:
import io import aiohttp async with aiohttp.ClientSession() as session: async with session.get(my_url) as resp: if resp.status != 200: return await channel.send('Could not download file. ') data = io.BytesIO(await resp.read()) await channel.send(file=discord.File(data, 'cool_image.png'))
How can I add a reaction to a message?¶
If you want to use unicode emoji, you must pass a valid unicode code point in a string. In your code, you can write this in a few different ways:
emoji = '\N ' # or '\U0001f44d' or '' await message.add_reaction(emoji)
In case you want to use emoji that come from a message, you already get their code points in the content without needing to do anything special. You cannot send ‘:thumbsup:’ style shorthands.
For custom emoji, you should pass an instance of Emoji . You can also pass a » string, but if you can use said emoji, you should be able to use Client.get_emoji() to get an emoji via ID or use utils.find() / utils.get() on Client.emojis or Guild.emojis collections.
The name and ID of a custom emoji can be found with the client by prefixing :custom_emoji: with a backslash. For example, sending the message \:python3: with the client will result in .
# if you have the ID already emoji = client.get_emoji(310177266011340803) await message.add_reaction(emoji) # no ID, do a lookup emoji = discord.utils.get(guild.emojis, name='LUL') if emoji: await message.add_reaction(emoji) # if you have the name and ID of a custom emoji: emoji = '' await message.add_reaction(emoji)
How do I pass a coroutine to the player’s “after” function?¶
The library’s music player launches on a separate thread, ergo it does not execute inside a coroutine. This does not mean that it is not possible to call a coroutine in the after parameter. To do so you must pass a callable that wraps up a couple of aspects.
The first gotcha that you must be aware of is that calling a coroutine is not a thread-safe operation. Since we are technically in another thread, we must take caution in calling thread-safe operations so things do not bug out. Luckily for us, asyncio comes with a asyncio.run_coroutine_threadsafe() function that allows us to call a coroutine from another thread.
However, this function returns a Future and to actually call it we have to fetch its result. Putting all of this together we can do the following:
def my_after(error): coro = some_channel.send('Song is done!') fut = asyncio.run_coroutine_threadsafe(coro, client.loop) try: fut.result() except: # an error happened sending the message pass voice.play(discord.FFmpegPCMAudio(url), after=my_after)
How do I run something in the background?¶
How do I get a specific model?¶
There are multiple ways of doing this. If you have a specific model’s ID then you can use one of the following functions:
- Client.get_channel()
- Client.get_guild()
- Client.get_user()
- Client.get_emoji()
- Guild.get_member()
- Guild.get_channel()
- Guild.get_role()
The following use an HTTP request:
- abc.Messageable.fetch_message()
- Client.fetch_user()
- Client.fetch_guilds()
- Client.fetch_guild()
- Guild.fetch_emoji()
- Guild.fetch_emojis()
- Guild.fetch_member()
If the functions above do not help you, then use of utils.find() or utils.get() would serve some use in finding specific models.
# find a guild by name guild = discord.utils.get(client.guilds, name='My Server') # make sure to check if it's found if guild is not None: # find a channel by name channel = discord.utils.get(guild.text_channels, name='cool-channel')
How do I make a web request?¶
To make a request, you should use a non-blocking library. This library already uses and requires a 3rd party library for making requests, aiohttp .
async with aiohttp.ClientSession() as session: async with session.get('http://aws.random.cat/meow') as r: if r.status == 200: js = await r.json()
How do I use a local image file for an embed image?¶
Discord special-cases uploading an image attachment and using it within an embed so that it will not display separately, but instead in the embed’s thumbnail, image, footer or author icon.
To do so, upload the image normally with abc.Messageable.send() , and set the embed’s image URL to attachment://image.png , where image.png is the filename of the image you will send.
file = discord.File("path/to/my/image.png", filename="image.png") embed = discord.Embed() embed.set_image(url="attachment://image.png") await channel.send(file=file, embed=embed)
Is there an event for audit log entries being created?¶
This event is now available in the library and Discord as of version 2.2. It can be found under on_audit_log_entry_create() .
Commands Extension¶
Questions regarding discord.ext.commands belong here.
Why does on_message make my commands stop working?¶
Overriding the default provided on_message forbids any extra commands from running. To fix this, add a bot.process_commands(message) line at the end of your on_message . For example:
@bot.event async def on_message(message): # do some extra stuff here await bot.process_commands(message)
Alternatively, you can place your on_message logic into a listener. In this setup, you should not manually call bot.process_commands() . This also allows you to do multiple things asynchronously in response to a message. Example:
@bot.listen('on_message') async def whatever_you_want_to_call_it(message): # do stuff here # do not process commands here
Why do my arguments require quotes?¶
In a simple command defined as:
@bot.command() async def echo(ctx, message: str): await ctx.send(message)
Calling it via ?echo a b c will only fetch the first argument and disregard the rest. To fix this you should either call it via ?echo «a b c» or change the signature to have “consume rest” behaviour. Example:
@bot.command() async def echo(ctx, *, message: str): await ctx.send(message)
This will allow you to use ?echo a b c without needing the quotes.
How do I get the original message ?¶
The Context contains an attribute, message to get the original message.
@bot.command() async def length(ctx): await ctx.send(f'Your message is len(ctx.message.content)> characters long.')
How do I make a subcommand?¶
Use the group() decorator. This will transform the callback into a Group which will allow you to add commands into the group operating as “subcommands”. These groups can be arbitrarily nested as well.
@bot.group() async def git(ctx): if ctx.invoked_subcommand is None: await ctx.send('Invalid git command passed. ') @git.command() async def push(ctx, remote: str, branch: str): await ctx.send(f'Pushing to remote> branch>')
This could then be used as ?git push origin master .
Views and Modals¶
Questions regarding discord.ui.View , discord.ui.Modal , and their components such as buttons, select menus, etc.
How can I disable all items on timeout?¶
This requires three steps.
- Attach a message to the View using either the return type of send() or retrieving it via Interaction.original_response() .
- Inside on_timeout() , loop over all items inside the view and mark them disabled.
- Edit the message we retrieved in step 1 with the newly modified view.
Putting it all together, we can do this in a text command:
class MyView(discord.ui.View): async def on_timeout(self) -> None: # Step 2 for item in self.children: item.disabled = True # Step 3 await self.message.edit(view=self) @discord.ui.button(label='Example') async def example_button(self, interaction: discord.Interaction, button: discord.ui.Button): await interaction.response.send_message('Hello!', ephemeral=True) @bot.command() async def timeout_example(ctx): """An example to showcase disabling buttons on timing out""" view = MyView() # Step 1 view.message = await ctx.send('Press me!', view=view)
Application commands do not return a message when you respond with InteractionResponse.send_message() , therefore in order to reliably do this we should retrieve the message using Interaction.original_response() .
Putting it all together, using the previous view definition:
@tree.command() async def more_timeout_example(interaction): """Another example to showcase disabling buttons on timing out""" view = MyView() await interaction.response.send_message('Press me!', view=view) # Step 1 view.message = await interaction.original_response()
Application Commands¶
Questions regarding Discord’s new application commands, commonly known as “slash commands” or “context menu commands”.
My bot’s commands are not showing up!¶
- Did you sync() your command? Commands need to be synced before they will appear.
- Did you invite your bot with the correct permissions? Bots need to be invited with the applications.commands scope in addition to the bot scope. For example, invite the bot with the following URL: https://discord.com/oauth2/authorize?client_id=&scope=applications.commands+bot . Alternatively, if you use utils.oauth_url() , you can call the function as such: oauth_url(, scopes=(«bot», «applications.commands»)) .