#client.command(pass_context=True)
async def ani(ctx, member: discord.Member, nick):
if member == discord.Member:
member = ctx.message.author
await member.edit(nick=nick)
else:
member = ctx.message.author
await member.edit(nick=nick)
I have read multiple tutorials and the documentation. I do not understand why my code does not work as expected.
Please help, thank you in advance.
There are a few things wrong with your code, or things that could be done better. I will list them out here.
Originally define your variables as None: If a member isn't mentioned, your bot will throw an error telling you that you missed a variable. The same can be said if you don't include a nickname for nick. To combat this, you can make None the default variable by using =None after each of your variables (excluding ctx, of course). You can handle them later on.
Change if member == discord.Member to just if member: Since you already have member defined as a discord.Member object, this statement would not work. If you previously defined your variables as None, then you can simply use if member to check if this variable is not None. If it is, it will immediately go to the else statement.
Catch other errors with a try-except statement: To avoid errors from flooding in your console, you can instead tell the ctx.author what went wrong. Using try and except, you can catch errors such as Missing Permissions or Invalid Form Body.
Use * before nick: If you do not use an asterisk before your nick variable, you will find that the following will happen:
Here is the above expressed in the code below.
#client.command(pass_context=True)
async def ani(ctx, member: discord.Member=None, *, nick=None):
if nick == None:
nick = "A Cool Nickname"
try:
if member:
name_before = member.display_name
# Why not member.nick? If the member did not have a nickname to begin with,
# member.nick would return None
await member.edit(nick=nick)
else:
member = ctx.message.author
name_before = member.display_name
await member.edit(nick=nick)
await ctx.send(f"Changed {member.mention}'s nickname from {name_before} to {member.display_name}")
except Exception as e:
# 403 Forbidden (error code: 50013): Missing Permissions
# - You are above the bot in the role hierarchy
# - The bot does not have the ability to change nicknames
# 400 Bad Request (error code: 50035): Invalid Form Body
# - In nick: Must be 32 or fewer in length.
await ctx.send(str(e))
If you want to make it a bit more complex, you could include a typing.Optional (import typing), which would allow the ctx.author to change their own nickname without having to mention themselves (and avoiding nasty errors). All you have to do is replace a single line.
async def ani(ctx, member: typing.Optional[discord.Member]=None, *, nick=None):
Related
I'm trying to make a discord bot in python which gives the user a role if they enter the correct text.
The weird thing is, I have a code which, for some reason, doesn't work. I have imported member from discord, but when I run this specific code, it says NameError: Member Not Defined.
Imports:
from discord import Member
Code:
#client.event
async def on_message(message):
verify_channel = client.get_channel(#idgoeshere)
verify_role = get(member.guild.roles, id='#idgoeshere')
if message.content == 'Exo' in verify_channel:
await member.add_roles(message.author, verify_role)
await message.send(f'{message.author}, You have gained access to the other channels!')
I really don't know what the problem is, I have searched up on stackoverflow but there isn't much of these problems associating with this. My other discord bots work with the member function and importation.
Well, it's because member isn't defined.
In your code, you have an on_message event, and you're getting the message. You can try defining member as member = message.author. You don't import member directly from discord. Because you are just importing the member class. I hope this helps answer your question.
P.S, in the line if message.content == 'Exo' in verify_channel: that is not how you check if it is in that channel.
You need to have something like if message.content == 'Exo' and message.channel verify_channel:. I hope this helps too
As your error states, you have not defined member. Member is usually used in commands and is defined, as seen here:
#client.command()
async def test(ctx, member:discord.Member):
await member.add_roles(verify_role)
However, since you are not using commands, this is not going to be your approach. It would be best to replace member with message.author instead, as this also gives you a discord.Member object. Have a look at the revised code below.
#client.event
async def on_message(message):
verify_channel = client.get_channel(#idgoeshere)
verify_role = get(member.guild.roles, id='#idgoeshere')
if message.content == 'Exo' in verify_channel:
await message.author.add_roles(verify_role)
await message.send(f'{message.author}, You have gained access to the other channels!')
# alternatively, you could add a separate variable such as
# member = message.author
# but using message.author on its own can be cleaner and clearer in this case
This is a snippet code from my bot that is meant to get mine or a users pfp and post it in the discord channel. For some reason, it does nothing when I type !avatar in discord. I have all the correct imports and there is no syntax error when I run it. I'm using repl.it I'm that might be the problem as I have absolutely no idea why this doesn't work.
client = commands.Bot(command_prefix = "t!")
#client.command
async def avatar(ctx, member: discord.Member=None):
if member == None:
member = ctx.author
icon_url = member.avatar_url
avatarEmbed = discord.Embed(title = f"{member.name}\'s Avatar", color = 0xFFA500)
avatarEmbed.set_image(url = f"{icon_url}")
avatarEmbed.timestamp = ctx.message.created_at
await ctx.send(embed = avatarEmbed)
The command looks good for the most part. There are a few things I did notice, however.
First, there seem to be three backticks at the end of your message; these may have created a syntax error if they are present in your code. (If they were only used for pasting code, then that's perfectly fine.)
Second, you never closed your if-loop. Although this can be okay, it's good practice to close it with an else-statement, which should include the embed code. Here's what I made and tested (it worked fine):
#client.command(name= "embav", help="Send an embed of a member's avatar!")
async def avatar(ctx, member: discord.Member = None):
if member == None:
member = ctx.author
return #this just makes the code exit the loop
else:
icon_url = member.avatar_url
avatarEmbed = discord.Embed(title=f"{member.name}\'s Avatar", color=0xFFA500)
avatarEmbed.set_image(url=f"{icon_url}")
avatarEmbed.timestamp = ctx.message.created_at
await ctx.send(embed=avatarEmbed)
Third, you said:
For some reason, it does nothing when I type !avatar in discord. I have all the correct imports and there is no syntax error when I run it.
But in the code, you specified a prefix of t!. If you just made a typo when asking, that's also fine.
Finally, if none of these help out, then it may be a repl.it problem.
I'm new to python, so can someone help me with my code, because it is not working properly. When the user that I want joins it doesn't give it a role. I want to make it work for a specific user only to give a role when joining discord server.
#client.event
async def on_member_join(member):
member = get(member.id, id=member_id)
role = get(member.guild.roles, id=role_id)
await member.id(member)
await member.add_roles(role)
I don't even know why you're making this so complicated.
Since you already have the member as an "argument" you can work with it and don't have to define member again.
We can get the ID of member very easily with member.id. If we want to compare this with a real ID, we do the following:
if member.id = TheIDHere:
# Do what you want to do
The function for the role is correct, yet I cannot find a use for await member.id(member). What is the point of this/has it any use?
How you add the role at the end is also correct, but the code must be indented properly and best you work with an if / else statement, otherwise the bot will still give an error at the end in the console if always the wrong member joins.
The whole code:
#client.event
async def on_member_join(member):
role = discord.utils.get(member.guild.roles, id=IDOfTheRole) # Get the role from member.guild and the id
if member.id == TheIDHere: # If the member.id matches
await member.add_roles(role) # Add the role for the specific user
else: # If it does not match
return # Do nothing
You may also need to enable the members Intent, here are some good posts on that:
https://discordpy.readthedocs.io/en/stable/intents.html
How do I get the discord.py intents to work?
When I type !best it comes up with my username which also does it if I # someone else with the same command like !best #example and comes up with #nottheexample
if message.content.startswith('!best'):
await message.channel.send(message.author.mention)
To mention a user you have to define it beforehand. You do this as follows:
user = message.mentions[0]
To mention the user you can either use f-strings or format.
Based on the code above here is an example:
#client.event # Or whatever you use
async def on_message(message):
user = message.mentions[0]
if message.content.startswith('!best'):
await message.channel.send("Hello, {}".format(user.mention))
Please note that the code only works if you then also specify a user. However, you can add more if or else statements if you want to handle it differently.
message.author.mention always mentions the author of the message
you can solve this in multiple ways
Just send whatever comes behind !best
if message.content.startswith('!best'):
args = message.content.split('!best ')
if len(args) > 1:
await message.channel.send(args[1])
else:
await message.channel.send(message.author.mention)
same as number 1, but add some check if the thing behind !best is a real member - see Utility Functions in the docs
member = discord.utils.find(lambda m: m.name == args[1], message.guild.members)
member = discord.utils.get(message.guild.members, name=agrs[1])
Use Commands - I really recommend this one
from discord.ext import commands
bot = commands.Bot(command_prefix='!')
#bot.command()
async def best(ctx, member: discord.Member = None):
if member is None:
member = ctx.author
await ctx.send(member.mention)
I need when I run a command like /insult #name the bot #'s the person in the argument of the command and sends an image. I can do most of the rest but I can't seem to figure out of to have it #mention the person.
To mention a user in a command, you can use member: discord.Member. This helps you get a member object in the command itself. You can view more on how you can use a discord.Member object here. An example on how to use this in a command can also be found in the docs, view this: Discord Converters.
You can view how these can be incorporated below, including a None variable as a default to avoid errors in your console if the ctx.author does not mention a member.
#client.command() # or bot.command(), or whatever you're using
async def insult(ctx, member:discord.Member=None):
if member == None: # Happens if ctx.author does not mention a member..
member = ctx.author # ..so by default the member will be ctx.author
# You can use member.mention to mention/ ping/ # the person assigned as member
await ctx.send(f"Be insulted {member.mention}!")
# A not as good way to do it would be:
await ctx.send(f"Be insulted <#{member.id}>!")
# both methods work the same way, but member.mention is recommended