discord.py mute role permission adding - python

So i made mute command for discord bot. it works, but doesn't add any permissions to 'Muted' role? Any ideas what's wrong?
Code:
#client.command(name = 'mute')
#commands.has_permissions(manage_permissions = True)
async def mute(ctx, member: discord.Member, *, reason = None):
muted = discord.utils.get(ctx.guild.roles, name = 'muted')
perms = discord.Permissions(send_messages = False)
if muted not in ctx.guild.roles:
muted = await ctx.guild.create_role(name = 'muted', permissions = perms)
memroles = discord.utils.get(member.roles)
if muted in memroles:
await ctx.send(f':x: This person is already muted')
await member.add_roles(muted)
await ctx.send(f':white_check_mark: **User <#{member.id}> was muted!**')
print(f'User {member} was muted!')
Error:
Traceback (most recent call last):
File "C:\Users\endport\AppData\Local\Programs\Python\Python310\lib\site-packages\discord\ext\commands\core.py", line 85, in wrapped
ret = await coro(*args, **kwargs)
File "D:\endport_semegen\discordpy\smth.py", line 62, in mute
if muted in memroles:
TypeError: argument of type 'Role' is not iterable
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "C:\Users\endport\AppData\Local\Programs\Python\Python310\lib\site-packages\discord\ext\commands\bot.py", line 939, in invoke
await ctx.command.invoke(ctx)
File "C:\Users\endport\AppData\Local\Programs\Python\Python310\lib\site-packages\discord\ext\commands\core.py", line 863, in invoke
await injected(*ctx.args, **ctx.kwargs)
File "C:\Users\endport\AppData\Local\Programs\Python\Python310\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 'Role' is not iterable```

The issue is when you discord.utils.get on the member roles.
From the docs, emphasis mine:
A helper that returns the first element in the iterable that meets all the traits passed in attrs. This is an alternative for find().
Since you didn't provide anything for it to check, it will return the first role that satisfies the requirements - the first role the member has. Obviously, this is not the list of roles that you wanted.
The solution is to simply remove the get. There's no reason to do it. Now, member.roles will be a list that you can do checking with.
memroles = member.roles
if muted in memroles:
await ctx.send(f':x: This person is already muted')

Related

TempMute | NotFound: 404 Not Found (error code: 10011): Unknown Role

I'm trying to do something like the 'tempmute' command, but an error keeps popping up
:
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: NotFound: 404 Not Found (error code: 10011): Unknown Role
And here is the command code
#commands.command()
#commands.has_permissions(ban_members=True)
async def tempmute(self, ctx, member: discord.Member = None, * time):
if not member:
await ctx.send(embed=discord.Embed(title='Вы должны указать участника!', color=random.choice(colors)))
else:
LMUTED = discord.utils.get(ctx.message.guild.roles, name='LMUTED')
if not LMUTED:
perms=discord.Permissions(send_messages=False)
await ctx.guild.create_role(name='LMUTED',
colour=discord.Colour(0x0000FF),
permissions = perms)
await ctx.send(f'Я создал роль `{LMUTED}`!')
await member.add_roles(member, LMUTED)
await ctx.send(f'Я замьютил {member} на {time}!')
await s(time * 60)
await ctx.remove_roles(member, LMUTED)
Make sure you know how to read python errors.
But the main issue here is that you don't assign LMUTED a value after you create a new role, so it is still None and thus discord.py fails to add the role.
Also, keep in mind that when you do things that expire over time, simply sleeping/waiting in the method is not a good way to handle it, as the thread might be locked. Instead you should use some sort of scheduler. Basically a thing that waits a certain amount of time before running some code.

Async race condition problem in discord.py

I'm trying to make a simple command that allows a user to give themselves a role, but if the role doesn't exist, it will create the role first, then give them the role. Here is my current code:
#bot.command()
async def SetRole(ctx, arg):
roles = ctx.guild.roles
user = ctx.message.author
#check if role does not exist
if arg not in [role.name for role in roles]:
await ctx.guild.create_role(name=arg)
await user.add_roles(discord.utils.get(roles, name=arg))
The expected result when I run $SetRole test_role if test_role does not exist, would be that the bot creates the role and then gives me the role. However, the role is created but is not given to me. Here is there error and stack trace:
Ignoring exception in command SetRole:
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 17, in SetRole
await user.add_roles(discord.utils.get(roles, name=arg))
File "/opt/virtualenvs/python3/lib/python3.8/site-packages/discord/member.py", line 777, in add_roles
await req(guild_id, user_id, role.id, reason=reason)
AttributeError: 'NoneType' 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 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: 'NoneType' object has no attribute 'id'
If I run the command a second time, the role is successfully given to me. What I presume is happening is for some reason, the user.add_roles() is happening before the create_role most likely because of some weirdness with async. How can I make sure that it adds the role after its created?
This isn't a race condition, just that discord.py doesn't track and mutate objects everywhere
A better implementation would be:
from typing import Union
#bot.command()
async def SetRole(ctx, role: Union[Role, str]):
if isinstance(role, str):
role = await ctx.guild.create_role(name=role)
await user.add_roles(role)
Union is just a way to represent "any of the given types", so discord.py [cleverly] either return a role or a string as fallback, we can then create the role if it doesn't already exist by checking if role is a string

I am getting an error code when i try use (member.id)

my current code is
#client.command()
async def check_vouches(ctx, member : discord.User=None):
users = await get_vouch_data()
test = ctx.author
role = discord.utils.get(test.guild.roles, name="10 vouches")
vouches_gotten = users[str(member.id)]["vouches_gotten"]
if member is not None:
if vouches_gotten == 10:
await test.add_roles(role)
await ctx.send("you now have the {role} role")
else:
await ctx.reply("first get 10 vouches")
which does not give an error code when i start the bot but when i try use the command i get the following error code:
Ignoring exception in command check_vouches:
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 193, in check_vouches
vouches_gotten = users[str(member.id)]["vouches_gotten"]
AttributeError: 'NoneType' 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 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: 'NoneType' object has no attribute 'id'
i have already tried putting
async def check_vouches(ctx, member : discord.User=None,*, id):
but when i tried even with an id there it still didn't work. please help me as i am out of ideas as i have tried editing several things and it still gave me an error code
As said in the comments, you are only proceeding when the member is None, which shouldn't be the case.
If the member is None, you can do two things, give it a default value and proceed or stop the command and raise an error.
Stopping the command:
if member is None:
await ctx.send('You have to mention someone to check their vouches')
else:
# check and show vouch
Providing a default value: (author)
if member is None:
member = ctx.author
# don't check if member is None later
#check and show vouches

Discord.py sudo all command not responding

This might need a little explaining. I made a command that sudo's someone called p!sudo [member.mention] [message]. It works like this:
#client.command()
async def sudo(ctx, member: discord.Member, *, message=None):
await ctx.message.delete()
webhooks = await ctx.channel.webhooks()
for webhook in webhooks:
await webhook.delete()
webhook = await ctx.channel.create_webhook(name=member.name)
await webhook.send(str(message),
username=member.name,
avatar_url=member.avatar_url)
Now, I want to make another command that sudo's everyone in the server. Here's what I got:
#client.command()
async def sudoall(ctx, *, message=None):
for member in ctx.guild.member:
webhooks = await ctx.channel.webhooks()
for webhook in webhooks:
await webhook.delete()
webhook = await ctx.channel.create_webhook(name=member.name)
await webhook.send(str(message),
username=member.name,
avatar_url=member.avatar_url)
However, I get this error message:
Ignoring exception in command sudoall:
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 34, in sudoall
for member in ctx.guild.member:
AttributeError: 'Guild' object has no attribute 'member'
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 903, in invoke
await ctx.command.invoke(ctx)
File "/opt/virtualenvs/python3/lib/python3.8/site-packages/discord/ext/commands/core.py", line 859, 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: 'Guild' object has no attribute 'member'
Use ctx.guild.members to get the list of members belonging in a guild

'int' object has no attribute 'id'

I’ve been tormented by this error for a week, I seriously don’t understand what’s the matter, help plz
'int' object has no attribute 'id'
there is my code:
import discord
import random
import asyncio
from discord import Member
from discord.utils import get
from discord.ext import commands
from discord.ext.commands import Bot
from discord.ext.commands import check
from discord.ext.commands import has_role
ROLE = 730459135170183170
bot = commands.Bot(command_prefix='$')
#bot.command(pass_context = True)
#commands.has_role(730459135170183170)
async def use_shovel(ctx,user: discord.Member):
x = random.randint(1,50)
role = get(user.guild.roles, name =ROLE)
if x == 1:
await ctx.send("You've found REQUIEM ARROW!")
await bot.author.add_roles(731166197030322216)
else:
await ctx.send("meh, nothing")
await user.remove_roles(731166197030322216)
bot.run(TOKEN)
Ignoring exception in command None:
discord.ext.commands.errors.CommandNotFound: Command "use_shove" is not found
Ignoring exception in command use_shovel:
Traceback (most recent call last):
File "C:\Python\lib\site-packages\discord\ext\commands\core.py", line 83, in wrapped
ret = await coro(*args, **kwargs)
File "meh.py", line 24, in use_shovel
await user.remove_roles(731166197030322216)
File "C:\Python\lib\site-packages\discord\member.py", line 685, in remove_roles
await req(guild_id, user_id, role.id, reason=reason)
AttributeError: 'int' object has no attribute 'id'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "C:\Python\lib\site-packages\discord\ext\commands\bot.py", line 892, in invoke
await ctx.command.invoke(ctx)
File "C:\Python\lib\site-packages\discord\ext\commands\core.py", line 797, in invoke
await injected(*ctx.args, **ctx.kwargs)
File "C:\Python\lib\site-packages\discord\ext\commands\core.py", line 92, in wrapped
raise CommandInvokeError(exc) from exc
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: AttributeError: 'int' object has no attribute 'id'
I really cannot understand why this error happen. So,how can I fix this?I
There are multiple errors in your code :
First, you're looking for a role with 730459135170183170 as a name, so your role variable's value will be None.
ROLE = 730459135170183170
(...)
role = get(user.guild.roles, name =ROLE)
Then, both add_roles and remove_roles take a role object as argument, not an int.
await bot.author.add_roles(731166197030322216)
(...)
await user.remove_roles(731166197030322216)
Finally, never ever share your token on any website:
bot.run('TOKEN')
You should go to your discord bot app and create a new token, so you're the only one who can use your bot app.
To solve your problem, you can get rid of your ROLE variable and replaces these lines:
#commands.has_role("Exact role name")
(...)
role = get(user.guild.roles, name="Exact role name")
(...)
await bot.author.add_roles(role)
(...)
await user.remove_roles(role)

Categories

Resources