My Goals:
When the user tried to use the command but mentioning a roles, it will sends an errors to the users.
My Current Codes:
#bot.command()
async def say(ctx, *, message: str):
try:
take_roles = ctx.guild
roles = [role.mention for role in take_roles.roles]
if message in roles:
await ctx.send(
f"{ctx.author.mention}, Hm? Trying to Abusing Me? Mention `#roles` is **NOT** Allowed on Say Command!"
)
else:
await ctx.message.delete()
await ctx.send(message)
You were trying to find the whole message in roles. A better idea is to look for role mentions inside of the message.
#bot.command()
async def say(ctx, *, message: str):
for role in ctx.guild.roles:
if role.mention in message:
await ctx.send(f"{ctx.author.mention}, Hm? Trying to Abusing Me? Mention `#roles` is **NOT** Allowed on Say Command!")
return # stops function if the role mention is in message
# if it didn't match any roles:
await ctx.message.delete()
await ctx.send(message)
Related
#commands.command()
#commands.guild_only()
#commands.has_guild_permissions(ban_members=True)
async def ban(self, ctx, member: discord.Member, *, reason=None):
if member.top_role >= ctx.author.top_role:
await ctx.send(f"You can only ban members below your role.")
return
channel = self.bot.get_channel(864083000211406849)
embed = discord.Embed(title=f"{ctx.author.name} banned: {member.name}", description=reason)
await channel.send(embed=embed)
await ctx.send(embed=embed)
await member.send(f"You've been banned from : `{ctx.guild}` for `reason`: {reason}.")
await ctx.guild.ban(user=member, reason=reason)
#ban.error
async def ban_error(self,ctx, error):
if isinstance(error, commands.CheckFailure):
title=f"{ctx.author.mention} you do not have the required permission(s)/role(s) to run this command!"
await ctx.send(title)
So I want my code to basically kick a member that has left my server using their ID. Ive looked in to previous questions but it seems to be no help for me.
You are converting the member input to a discord.Member, which needs to be in the server. Instead convert it to a discord.User, who does not need to be in your server.
async def ban(self, ctx, member: discord.User, *, reason=None):
Please keep in mind that your top role lookup and comparison will not work when you use the discord.User, you will have to get the actual member beforehand, like this:
server_member = ctx.guild.get_member(member.id)
if server_member != None:
if server_member.top_role >= ctx.author.top_role:
await ctx.send(f"You can only ban members below your role.")
return
Also you will get an error trying to message someone who does not share a server with your bot, or has blocked your bot etc., I would just use a try/except block for this:
try:
await member.send(f"You've been banned from : `{ctx.guild}` for `reason`: {reason}.")
except discord.errors.Forbidden:
pass
So the entirety of this command works but I keep getting an error that says:
NotFound: 404 Not Found (error code: 10011): Unknown Role.
I have tried using so many things from the role id to discord.guild.get_role and I keep getting the same error. Any help is appreciated!
#bot.command(pass_context = True)
async def mute(ctx, member: discord.Member):
if ctx.message.author.guild_permissions.administrator:
role = discord.utils.get(ctx.guild.roles, name="Muted")
await member.add_roles(member, role)
embed=discord.Embed(title="User Muted!", description="**{0}** was muted by **{1}**!".format(member, ctx.message.author), color=0xff00f6)
await bot.say(embed=embed)
else:
embed=discord.Embed(title="Permission Denied.", description="You don't have permission to use this command.", color=0xff00f6)
await bot.say(embed=embed)
Your code is partly outdated and the reason you have this error is coming from:
await member.add_roles(member, role)
Before v1.0, you needed to pass member in the method's argument but it's no longer necessary. So here, you're trying to add a discord.Role that is a discord.Member.
Other parts that are outdated:
pass_context=True is also no longer necessary, you can remove it.
bot.say doesn't exist, you can use ctx.send(embed=embed).
You can read more about the v1.0 migration here : Migrating to v1.0
await member.add_roles(role)
That is what you are looking for, as MrSpaar just told you.
Another suggestion I would like to make is doing the following.
Change this
async def mute(ctx, member: discord.Member):
To this:
async def mute(ctx, member: discord.Member = None, *, reason=None):
if not member:
await ctx.send("You must specify a user.")
return
if not reason:
await ctx.send("You must specify a reason.")
return
If you have any further questions let me know.
I start creating a Discord bot with the Python API of Discord. So, I tried to make a command that give roles on a discord server. Here is my code :
client = commands.Bot(command_prefix = '/')
#client.command()
async def addrole(ctx, role: discord.Role, user: discord.Member):
if ctx.author.guild_permissions.administrator:
await user.add_roles(role)
await ctx.send(f"Successfully given {role.mention} to {user.mention}.")
When I try to use the command, any error happear. I try to make like the websearch I've done but still don't work. Can someone help me ?
I don't believe basic things like these would require Discords intents, especially the "member intent". What I have done is I've cleaned up your code and required a member to be passed before a multiple string role, if needed.
#client.command()
#commands.has_permissions(manage_roles=True)
async def addrole(ctx, member: discord.Member = None, *, role: discord.Role = None):
if role == None:
await ctx.send(f'Provide a role to add')
return
if member == None:
await ctx.send(f'Provide a member to add a role')
return
await member.add_roles(role)
await ctx.send(f"Successfully added role, {role} to {member.name}")
Here is the sendMessage function:
async def sendMessage(color, title, value, should_delete=True, channel=""):
embed = discord.Embed(color=color)
embed.add_field(name=title, value=value, inline=False)
if channel == "":
msg = await client.send_message(message_obj.channel, embed=embed)
else:
msg = await client.send_message(client.get_channel(channel), embed=embed)
if should_delete:
await delete_msg(msg)
The bot can mention anyone but everyone and here. Despite having mention everyone permission.
sendMessage(OK_COLOR_HASH, "title", "Hello #everyone")
Edit: When I converted the message type to the normal one instead of embed one, it worked.
You can try to sending a mention to everyone through the default_role attribute
#bot.command(pass_context=True)
async def evy(msg):
await bot.say(msg.message.server.default_role)
You can try this block code. roles return a list all guild's roles, but first role always a default guild role (default_role) and that's why you must use slicing function.
#bot.command()
async def test(ctx):
await ctx.send(ctx.message.guild.roles[0])
Or you can do something like this.
#bot.command()
async def test(ctx):
await ctx.send(ctx.message.guild.default_role)
I have tried and researched a lot of times but still could not find it. I want to make a command that deletes a selected role in the server. Here is what I came up with (Don't currently care about permissions):
#bot.command(pass_context=True)
async def delrole(ctx, role: discord.Role):
await bot.delete_role(role)
await bot.say("The role {} has been deleted!".format(role.name))
If you could help that would be awesome. I used role: discord.Role and delete_role(). Thank you for reading. If you have a solution, feel free to comment it.
NOTICE: This post was for the old version of discord.py and will no longer work. If you are looking for an equivalent solution for the rewrite (v1) version of discord.py, you can use the following code:
#bot.command(pass_context=True)
async def delrole(ctx, *, role_name):
role = discord.utils.get(ctx.message.guild.roles, name=role_name)
if role:
try:
await role.delete()
await ctx.send("The role {} has been deleted!".format(role.name))
except discord.Forbidden:
await ctx.send("Missing Permissions to delete this role!")
else:
await ctx.send("The role doesn't exist!")
You could do something like this to avoid being able to only delete roles that are mentionable
#bot.command(pass_context=True)
async def delrole(ctx, *,role_name):
role = discord.utils.get(ctx.message.server.roles, name=role_name)
if role:
try:
await bot.delete_role(ctx.message.server, role)
await bot.say("The role {} has been deleted!".format(role.name))
except discord.Forbidden:
await bot.say("Missing Permissions to delete this role!")
else:
await bot.say("The role doesn't exist!")
where you do !delrole name_of_role and use discord.utils.get to find the role by its name from the list of roles on the server.
Then if it's found you can delete it with bot.delete_role which takes 2 arguments, the server you want to delete the role from and the role itself
All you're missing is the server argument to delete_role, (which it shouldn't need, as every Role knows what Server it is from)
#bot.command(pass_context=True)
async def delrole(ctx, role: discord.Role):
await bot.delete_role(role.server, role)
await bot.say("The role {} has been deleted!".format(role.name))
You were already on the right track using converters
The above solutions will not work server has to be guild and the actual role deletion can be a lot easier.
#bot.command(pass_context=True)
async def delrole(ctx, *, role_name):
role = discord.utils.get(ctx.message.guild.roles, name=f"{role_name}")
await role.delete()
await ctx.send(f"[{role_name}] Has been deleted!")
This solution is working as of 28/08/2021.