Makashi
Makashi

Reputation: 15

Discord.py nickname changin

@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.

Upvotes: 0

Views: 282

Answers (1)

Bagle
Bagle

Reputation: 2346

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:

What will happen without the *

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))

above code working


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):

Works the same way as before, but better

Upvotes: 2

Related Questions