User assigned roles using discord.py - discord.py

I am trying to program a bot using discord.py for a discord server. I want to make a command that would allow users to assign themselves name colors (i.e Red or Blue) I tried to achieve this by creating roles. But I am having some trouble assigning roles using the newest form of discord.py.
#client.command()
async def role(ctx, * role: discord.Role):
user = ctx.message.author
await user.add_roles(role)
Does anyone know how to fix the error I'm getting. The error is given below:
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: AttributeError: 'tuple' object has no attribute 'id'

It seems to me that the issue is the '*'...
If you use your code and add a print line to see what is actually passed to your method you will see this result:
Code
#client.command()
async def role(ctx, * role: discord.Role):
print(role)
user = ctx.message.author
await user.add_roles(role)
Output
(<Role id=671750373761089546 name='Red'>,)
Ignoring exception in command role:
Traceback (most recent call last):
File "/home/dual/PyProjects/Discord/Chandler/env/lib/python3.7/site-packages/discord/ext/commands/core.py", line 79, in wrapped
ret = await coro(*args, **kwargs)
File "main.py", line 57, in role
await user.add_roles(role)
File "/home/dual/PyProjects/Discord/Chandler/env/lib/python3.7/site-packages/discord/member.py", line 616, in add_roles
await req(guild_id, user_id, role.id, reason=reason)
AttributeError: 'tuple' object has no attribute 'id'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/home/dual/PyProjects/Discord/Chandler/env/lib/python3.7/site-packages/discord/ext/commands/bot.py", line 863, in invoke
await ctx.command.invoke(ctx)
File "/home/dual/PyProjects/Discord/Chandler/env/lib/python3.7/site-packages/discord/ext/commands/core.py", line 728, in invoke
await injected(*ctx.args, **ctx.kwargs)
File "/home/dual/PyProjects/Discord/Chandler/env/lib/python3.7/site-packages/discord/ext/commands/core.py", line 88, in wrapped
raise CommandInvokeError(exc) from exc
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: AttributeError: 'tuple' object has no attribute 'id'
If you remove the '*' and keep everything else the same this is what it looks like:
Code
#client.command()
async def role(ctx, role: discord.Role):
print(role)
user = ctx.message.author
await user.add_roles(role)
Output
Red
Without the '*' the role is added to the user who called the command. This only works if the role is spelled correctly and is case sensitive so I would advise implementing some sort of input validation.
Edit:
This article explains about *args and **kwargs in python. It may be useful to check it out to get a better understanding of how to pass arguments to a function :D

Related

Discord.py new timeout command error: "AttributeError: 'User' object has no attribute 'timeout_for'"

Hello all and happy new year 2022!!
Since the recent add of "timeouts" for discord, I have tried to make the timeout command following some tutorials like:
https://docs.pycord.dev/en/master/api.html?highlight=timeout#discord.Member.timeout
https://youtu.be/c5V4OaTNDtM
But I may get the following error for a reason I don't know:
Ignoring exception in command timeout2:
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 "/home/runner/Russia-Bot/moderator.py", line 42, in timeout2
await member.timeout_for(time)
AttributeError: 'Member' object has no attribute 'timeout_for'
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 939, in invoke
await ctx.command.invoke(ctx)
File "/opt/virtualenvs/python3/lib/python3.8/site-packages/discord/ext/commands/core.py", line 863, 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: 'Member' object has no attribute 'timeout_for'
Here's the command code, i have made 2 different commands but both give the same issue:
Variant 1:
#client.command()
async def timeout(ctx, member: discord.Member, time=None, reason=None):
time = humanfriendly.parse_timespan(time)
await member.timeout(until = discord.utils.utcnow() + datetime.timedelta(seconds=time), reason=reason)
await ctx.send (f"{member} callate un rato anda {time}")
Variant 2
#client.command(pass_context =True)
async def timeout2(ctx, member:discord.User=None, time=None):
#time = humanfriendly.parse_timespan(time)
# tiempo = datetime.timedelta(seconds=time)
user = await client.fetch_user(member)
#await ctx.send (f"{user}")
#await ctx.send (f"{member}")
await user.timeout_for(time)
await ctx.send (f"{user} callate un rato anda {time}")
Best Regards,
Engineer
Update your py-cord library by using pip install -U git+https://github.com/pycord-development/pycord
If works , pls consider accepting answer

im trying to create a join role function and it doesn't work

so it basically goes like this:
I'm trying to create a function that can add a member from a specific role and also the function will see that if the member is in that role or if that is role is exist and if the max members of this role is five but the code doesn't seem to work
#commands.command()
async def join_team(self,ctx,rule:discord.Role):
role = ctx.guild.get_role(rule) # check this specific role
if ctx.author in role:
await ctx.send("you're already in that role !")
elif len(role.members) == 5:
await ctx.send("this specific role is full")
else:
await self.client.add_roles(ctx.author, role)
The error I get:
Ignoring exception in command join_team:
Traceback (most recent call last):
File "E:\PYTHON\lib\site-packages\discord\ext\commands\core.py", line 85, in wrapped
ret = await coro(*args, **kwargs)
File "c:\Users\Name\Desktop\scripts\python's\discordbot\cogs\cog1.py", line 29, in join_team
if ctx.author in role:
TypeError: argument of type 'NoneType' is not iterable
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "E:\PYTHON\lib\site-packages\discord\ext\commands\bot.py", line 939, in invoke
await ctx.command.invoke(ctx)
File "E:\PYTHON\lib\site-packages\discord\ext\commands\core.py", line 863, in invoke
await injected(*ctx.args, **ctx.kwargs)
File "E:\PYTHON\lib\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: TypeError: argument of type 'NoneType' is not iterable
You just have a logic error in your code.
What you are checking if the author is in the role which does not make any sense here.
Check it the other way around instead:
if role in ctx.author.roles:
# Do what you want to do
You're logic and the code both are wrong.
You're already getting role on parameter but still pass it to get_role() and you're also checking if the author is in a role object not members with the role.
Bot object does not have add_roles() function.
#commands.command()
async def join_team(self, ctx, role: discord.Role):
if role in ctx.author.roles:
await ctx.send("you're already in that role !")
elif len(role.members) == 5:
await ctx.send("this specific role is full")
else:
await ctx.author.add_roles(role)

Problem with *.shutdown* command on discord.py

I am currently looking to fix this code. I am trying to make a .shutdown command, which basically logs out of the bot and takes the bot down. I have made a code, but it seems like it is not working. Here is my code. Help is very appreciated ;p
#client.command()
async def shutdown(ctx, *, reason):
if ctx.message.author.id(581457749724889102):
ctx.send('Bot is shutting down... ;(')
logs_channel = client.get_channel(825005282535014420)
logs_channel.send(f"Bot is being shutdown for: {reason}")
exit()
else:
ctx.send("I'm sorry, only officer grr#6609 can do that."
Thanks early for the help!
edit:
here is my error
Ignoring exception in on_command_error
Traceback (most recent call last):
File "C:\Users\USER\AppData\Local\Programs\Python\Python39-32\lib\site-packages\discord\ext\commands\core.py", line 85, in wrapped
ret = await coro(*args, **kwargs)
File "c:\Users\USER\Desktop\discord bot folder\Nuova cartella\connor.py", line 173, in shutdown
if ctx.message.author.id(581457749724889102):
TypeError: 'int' object is not callable
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "C:\Users\USER\AppData\Local\Programs\Python\Python39-32\lib\site-packages\discord\client.py", line 343, in _run_event
await coro(*args, **kwargs)
File "c:\Users\USER\Desktop\discord bot folder\Nuova cartella\connor.py", line 82, in on_command_error
raise error
File "C:\Users\USER\AppData\Local\Programs\Python\Python39-32\lib\site-packages\discord\ext\commands\bot.py", line 902, in invoke
await ctx.command.invoke(ctx)
File "C:\Users\USER\AppData\Local\Programs\Python\Python39-32\lib\site-packages\discord\ext\commands\core.py", line 864, in invoke
await injected(*ctx.args, **ctx.kwargs)
File "C:\Users\USER\AppData\Local\Programs\Python\Python39-32\lib\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: TypeError: 'int' object is not callable
Please always consider to await your functions. You also have some formation and comprehension errors in the code, maybe take another look at the docs
You can check whether the user executing the command is the owner of the bot. If he is not, there is of course an error message.
Have a look at the following code:
#client.command()
#commands.is_owner() # Checks if the bot owner exectued the command
async def shutdown(ctx):
await ctx.send("Logging out.")
await client.logout() # Logging out
#shutdown.error
async def shutdown_error(ctx, error):
if isinstance(error, commands.NotOwner):
await ctx.send("You are not the owner of the bot.") # Error message
What did we do?
awaited most of the functions.
Built in a check to check if the owner executed the command.
Built in an error handler which will give out a message if a non-owner tries to shutdown the bot.

How do i create a Ticket command in discord.py?

Hello so i want to make a discord bot that can create tickets but i am not sure on how do it i am using discord.py and i was wondering if anyone can help? i have tried this.
#bot.command()
async def ticket(ctx):
await create_text_channel(name, *, overwrites=None, reason=None, **options)
But it does not do anything and i get this error.
Traceback (most recent call last):
File "C:\Users\Robin\AppData\Roaming\Python\Python37\site-packages\discord\ext\commands\bot.py", line 903, in invoke
await ctx.command.invoke(ctx)
File "C:\Users\Robin\AppData\Roaming\Python\Python37\site-packages\discord\ext\commands\core.py", line 855, in invoke
await injected(*ctx.args, **ctx.kwargs)
File "C:\Users\Robin\AppData\Roaming\Python\Python37\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: NameError: name 'create_text_channel' is not defined```
There are three mistakes in the code you gave:
create_text_channel() is a discord.Guild class method so it only works with a Guild instance
The name variable isn't defined so you'd have an error.
If you don't need any overwrites or any reason, you don't need to write overwrites=None and reason=None, same goes for *.
In the end, your code would look like this:
#bot.command()
async def ticket(ctx):
await ctx.guild.create_text_channel('Channel Name')
I guess you looked at the documentation and copy pasted the method's title, which is unnecessary, you could have looked at the examples given, eg. channel = await guild.create_text_channel('cool-channel')
If you want to create a hidden channel, there's also this example:
overwrites = {
guild.default_role: discord.PermissionOverwrite(read_messages=False),
guild.me: discord.PermissionOverwrite(read_messages=True)
}
channel = await guild.create_text_channel('secret', overwrites=overwrites)

This code for changing roles doesn't work

I got this code to change a user's role, but it won't work.
#client.command(pass_context=True)
async def ruleBreak(ctx):
member = ctx.message.author
role = discord.utils.get(member.server.roles, name="RuleBreakers")
await client.add_roles(member, role)
But it's causing this error
Ignoring exception in command ruleBreak:
Traceback (most recent call last):
File "C:\Users\unkno\AppData\Local\Programs\Python\Python38\lib\site-packages\discord\ext\commands\core.py", line 85, in wrapped
ret = await coro(*args, **kwargs)
File "c:/Users/unkno/Desktop/Code_Tests/Python/discord_bot/WIP/bot2.py", line 19, in ruleBreak
role = discord.utils.get(member.server.roles, name="RuleBreakers")
AttributeError: 'Member' object has no attribute 'server'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "C:\Users\unkno\AppData\Local\Programs\Python\Python38\lib\site-packages\discord\ext\commands\bot.py", line 903, in invoke
await ctx.command.invoke(ctx)
File "C:\Users\unkno\AppData\Local\Programs\Python\Python38\lib\site-packages\discord\ext\commands\core.py", line 855, in invoke
await injected(*ctx.args, **ctx.kwargs)
File "C:\Users\unkno\AppData\Local\Programs\Python\Python38\lib\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: 'Member' object has no attribute 'server'
What do I do, why is this happening, and where do I change it?
Thanks in advance!
You don't need to pass context as it's done for you in the rewrite branch.
#client.command()
async def ruleBreak(ctx):
member = ctx.message.author
role = discord.utils.get(member.guild.roles, name="RuleBreakers")
await discord.Member.add_roles(member, role)
EDIT: The main issue here was that Client.add_roles changed to Member.add_roles() in the rewrite version. Migrating to v1.0

Resources