1
votes

I'm making a bot for my Discord server using discord.py . I'm trying to make a command that gives a user a role named "Muted". But when I try and mute the user (by sending "0mute @user#0000"), I get errors. My code for giving the role is this:

@client.command(pass_context=True)
@commands.has_any_role("Admin")
async def mute(ctx, user: discord.Member):
  await user.add_roles("Muted", atomic=False)

Note: I'm using regular discord.py, NOT discord.py rewrite.

Edit: Recently found out I'm not allowed to post images of errors or code, as such I'll past the errors here as text instead of an image.

Ignoring exception in command mute:
Traceback (most recent call last):
  File "/opt/virtualenvs/python3/lib/python3.8/site-packages/discord/ext/commands/core.py", line 85, in wrapped
    ret = await coro(*args, **kwargs)
  File "main.py", line 43, in mute
    await user.add_roles("Muted", atomic=False)
  File "/opt/virtualenvs/python3/lib/python3.8/site-packages/discord/member.py", line 669, in add_roles
    new_roles = utils._unique(Object(id=r.id) for s in (self.roles[1:], roles) for r in s)
  File "/opt/virtualenvs/python3/lib/python3.8/site-packages/discord/utils.py", line 287, in _unique
    return [x for x in iterable if not (x in seen or adder(x))]
  File "/opt/virtualenvs/python3/lib/python3.8/site-packages/discord/utils.py", line 287, in <listcomp>
    return [x for x in iterable if not (x in seen or adder(x))]
  File "/opt/virtualenvs/python3/lib/python3.8/site-packages/discord/member.py", line 669, in <genexpr>
    new_roles = utils._unique(Object(id=r.id) for s in (self.roles[1:], roles) for r in s)
AttributeError: 'str' object has no attribute 'id'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/opt/virtualenvs/python3/lib/python3.8/site-packages/discord/ext/commands/bot.py", line 902, in invoke
    await ctx.command.invoke(ctx)
  File "/opt/virtualenvs/python3/lib/python3.8/site-packages/discord/ext/commands/core.py", line 864, in invoke
    await injected(*ctx.args, **ctx.kwargs)
  File "/opt/virtualenvs/python3/lib/python3.8/site-packages/discord/ext/commands/core.py", line 94, in wrapped
    raise CommandInvokeError(exc) from exc
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: AttributeError: 'str' object has no attribute 'id'
1
Looks to me like user.add_roles() takes a Role, and you're giving it a string. My guess is that the library then tries to get the id attribute of that argument. Which would be fine if it were a Role, but not if it's a string. As you've provided. Also, genuinely curious, how many people are in your class?blueteeth
It looks like you will want to have a Guild object (representing the server), and then call create_role on it, to create a Role, which you can then give to users as you are trying to. That's what I've gathered from a quick look at the docs, at leastFricative Melon

1 Answers

0
votes

Member.add_roles takes discord.Role instances as the arguments, you're passing a string.

@client.command()
@commands.has_any_role("Admin")
async def mute(ctx, user: discord.Member):
    role = discord.utils.get(ctx.guild.roles, name="Muted") # Getting the role
    await user.add_roles(role, atomic=False)

Also the pass_context kwarg is not necessary in discord.py rewrite, the context is always passed

Reference: