discord bot adding roles to a user in python - python

I started out to make a bot that gives a role to all the users in a server. I decided to start by giving roles when a user enters a certain message in the server. This is the code I'm using:
if message.content == 'test':
member = message.author
role = discord.utils.get(member.guild.roles, name="test")
await discord.Member.add_roles(member, role)
But I'm getting an error as:
Ignoring exception in on_message
Traceback (most recent call last):
File "E:\Program File\Python38-32\lib\site-packages\discord\client.py", line 312, in _run_event
await coro(*args, **kwargs)
File "E:\folder for all folders\python\program\bot.py", line 73, in on_message
await discord.Member.add_roles(member, role)
File "E:\Program File\Python38-32\lib\site-packages\discord\member.py", line 641, in add_roles
await req(guild_id, user_id, role.id, reason=reason)
AttributeError: 'NoneType' object has no attribute 'id'
I feel lost on what to do here.

here is the correct code -
if message.content == 'test':
member = message.author
role = discord.utils.get(message.guild.roles, name="test")
await member.add_roles(role)
NOTE- Make sue the server has a role named test.
If this worked, please consider accepting this as an answer. Thanks!

I'm not really good at Python but when you go in the doc it tells you that add_roles has 3 parameters roles,reason and atomic. You don't have to put member. https://discordpy.readthedocs.io/en/latest/api.html#discord.Member.add_roles

Related

How to make a Discord bot add a role when a user joins?

[ SOLVED ]
The below code works, I had just not put the 'Bot' role high enough in the roles tab. Make sure to check that it is higher than the role you are trying to give.
Basically, I am trying to get my Discord bot to add a role to a user when they join the guild. I have looked it up, but all of them seem to be outdated. My current code looks like this:
#client.event
async def on_member_join(member):
role = discord.utils.get(getGuild().roles, name='ExampleRole')
await member.add_roles(role)
And the getGuild method looks like this:
def getGuild():
for guild in client.guilds:
if guild.name == GUILD_NAME:
return guild;
However, this prints an error, which looks like this:
Traceback (most recent call last):
File "discord\client.py", line 343, in _run_event
await coro(*args, **kwargs)
File "DiscordBot.py", line 36, in on_member_join
await member.add_roles(role)
File "discord\member.py", line 777, in add_roles
await req(guild_id, user_id, role.id, reason=reason)
File "discord\http.py", line 248, in request
raise Forbidden(r, data)
discord.errors.Forbidden: 403 Forbidden (error code: 50013): Missing Permissions
Obviously I removed the file path, but kept the file names.
I'm using the latest Discord.py, and any help would be appreciated.

How to make an addrole command in discord.py?

#bot.command(pass_context=True)
#commands.has_permissions(ban_members = True)
async def addrole(ctx, member : discord.Member, *,role="Members"):
role = discord.utils.get(ctx.guild.roles, name=role)
await member.add_roles(member, role)
await ctx.reply(f'I have added the {role} to {member}')
Last week, i was creating a bot and when i added this command, it gave me an error.
Ignoring exception in command addrole:
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 130, in addrole
await member.add_roles(member, role)
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)
File "/opt/virtualenvs/python3/lib/python3.8/site-packages/discord/http.py", line 250, in request
raise NotFound(r, data)
discord.errors.NotFound: 404 Not Found (error code: 10011): Unknown Role
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: NotFound: 404 Not Found (error code: 10011): Unknown Role
Can someone tell me why is this error happening?
#bot.command(pass_context=True)
#commands.has_permissions(ban_members = True)
async def addrole(ctx, member : discord.Member, *,role="Members"):
role = discord.utils.get(ctx.guild.roles, name=role)
await member.add_roles(role)
await ctx.reply(f'I have added the {role} to {member}')
guys the error was the member coming before the role, the working piece of code is here
The error that you're experiencing is because the bot cannot find the role. See the MDN documentation for more information on a status 404 error. Common causes of this issue with discord.py are that the bot isn't in the guild with the role, capitalization is wrong, or an assortment of other issues. It is easier to use role IDs to find roles rather than role names for this reason, however, this does not prevent the guild issue. Consult the documentation for more information on Member.add_roles.

Discord.py | How to assign someone a role?

I am trying to mute someone using a role Muted
The Code:
#bot.command()
async def mute(ctx, member:commands.MemberConverter):
role = discord.utils.find(lambda r: r.name == 'Muted', ctx.guild.roles)
await member.edit(roles=[role])
But I get this weird error:
Ignoring exception in command mute:
Traceback (most recent call last):
File "C:\Users\gathi\AppData\Local\Programs\Python\Python39\lib\site-packages\discord\ext\commands\core.py", line 85, in wrapped
ret = await coro(*args, **kwargs)
File "C:\Users\gathi\Vscode\Discord_Bot\tutorial.py", line 61, in mute
await member.edit(roles=[role]) # 848410518154117130
File "C:\Users\gathi\AppData\Local\Programs\Python\Python39\lib\site-packages\discord\member.py", line 681, in edit
await http.edit_member(guild_id, self.id, reason=reason, **payload)
File "C:\Users\gathi\AppData\Local\Programs\Python\Python39\lib\site-packages\discord\http.py", line 248, in request
raise Forbidden(r, data)
discord.errors.Forbidden: 403 Forbidden (error code: 50013): Missing Permissions
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "C:\Users\gathi\AppData\Local\Programs\Python\Python39\lib\site-packages\discord\ext\commands\bot.py", line 939, in invoke
await ctx.command.invoke(ctx)
File "C:\Users\gathi\AppData\Local\Programs\Python\Python39\lib\site-packages\discord\ext\commands\core.py", line 863, in invoke
await injected(*ctx.args, **ctx.kwargs)
File "C:\Users\gathi\AppData\Local\Programs\Python\Python39\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: Forbidden: 403 Forbidden (error code: 50013): Missing Permissions
I don't understand what to do.
Here is the perms of the bot:
The bots perms
The answer is within the bot Forbidden: 403 Forbidden (error code: 50013): Missing Permissions should instantly tell you it's a permissions issue.
The bot fails on await member.edit(roles=[role]) # 848410518154117130 which tells you the code works but it can't assign the role.
Make sure the bot:
Is higher than you in the role hierarchy
Has Manage Roles or the Administrator permission
If this continues to not work then consider going to my previous answer about intents.
You can use discord.Member.add_roles to assign a role.
#bot.command()
async def mute(ctx, member: commands.MemberConverter):
role = discord.utils.find(lambda r: r.name == 'Muted', ctx.guild.roles)
await member.add_roles(role)
And this is the unmute command.
#bot.command()
async def unmute(ctx, member: commands.MemberConverter):
role = discord.utils.find(lambda r: r.name == 'Muted', ctx.guild.roles)
await member.remove_roles(role)

discord.py how to assign roles to users v1.0 version

import discord
import logging
from discord.utils import get
from discord.ext import commands
logging.basicConfig(level=logging.INFO)
bot = commands.Bot(command_prefix='!')
#bot.event
async def on_ready():
print('Logged in as')
print(bot.user.name)
print(bot.user.id)
print('------')
#bot.command(pass_context=True)
async def setrole(ctx, a: str):
member = ctx.message.author
role = discord.utils.get(member.guild.roles, name=a)
await member.add_roles(member, role)
This is the code i use trying to assign roles to people entering the command. The role available in my server is rs6 so the code should be !setrole rs6 but its not working.
Ignoring exception in command setrole:
Traceback (most recent call last):
File "C:\Users\Ruiyang(Harry)Wang\AppData\Local\Programs\Python\Python38-32\lib\site-packages\discord\ext\commands\core.py", line 83, in wrapped
ret = await coro(*args, **kwargs)
File "C:\Workshop\example_bot.py", line 19, in setrole
await member.add_roles(member, role)
File "C:\Users\Ruiyang(Harry)Wang\AppData\Local\Programs\Python\Python38-32\lib\site-packages\discord\member.py", line 641, in add_roles
await req(guild_id, user_id, role.id, reason=reason)
File "C:\Users\Ruiyang(Harry)Wang\AppData\Local\Programs\Python\Python38-32\lib\site-packages\discord\http.py", line 223, in request
raise NotFound(r, data)
discord.errors.NotFound: 404 Not Found (error code: 10011): Unknown Role
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "C:\Users\Ruiyang(Harry)Wang\AppData\Local\Programs\Python\Python38-32\lib\site-packages\discord\ext\commands\bot.py", line 892, in invoke
await ctx.command.invoke(ctx)
File "C:\Users\Ruiyang(Harry)Wang\AppData\Local\Programs\Python\Python38-32\lib\site-packages\discord\ext\commands\core.py", line 797, in invoke
await injected(*ctx.args, **ctx.kwargs)
File "C:\Users\Ruiyang(Harry)Wang\AppData\Local\Programs\Python\Python38-32\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: NotFound: 404 Not Found (error code: 10011): Unknown Role
I tried to do print(role) after line role = discord.utils.get(member.guild.roles, name=a)
and it printed rs6 which is correct. Someone please help me! Thanks!
You can do a snazzy thing using command decorators. In the same way that you've set the type of arg to be a str, you can also set it to be a discord object:
#bot.command() # Note that context is automatically passed in rewrite
async def setrole(ctx, role: discord.Role):
await ctx.author.add_roles(role)
await ctx.send(f"I gave you {role.mention}!")
You might want an error handler to deal with if the role isn't found:
#setrole.error
async def _role_error(ctx, error):
if isinstance(error, commands.errors.BadArgument):
await ctx.send("I couldn't find that role!")
References:
commands.BadArgument
Member.add_roles()
Error handler per command

Discord py forward messages(with embeds) sent on one channel to another and how to determine number of members in a server?

I want to forward messages sent on a particular channel to another channel based on number of reactions on 🔻 emoji reaction. The message has a few embeds and is being sent by the YAGPDB.xyz bot from a sub reddit. If the message in a particular channel gets more than one down vote reaction I want to forward that message to another channel and delete it on the current channel. Here's what a typical message from this bot looks like(with embeds),
I have written the following code,
#client.event
async def on_raw_reaction_add(payload):
if payload.channel_id in CHANNEL_LIST:
if payload.emoji.name=='\U0001F53C':
channel=client.get_channel(payload.channel_id)
message=await channel.fetch_message(payload.message_id)
reaction=get(message.reactions,emoji=payload.emoji.name)
if reaction and reaction.count>1:
await message.pin()
elif payload.emoji.name=='\U0001F53B':
channel=client.get_channel(payload.channel_id)
message=await channel.fetch_message(payload.message_id)
reaction=get(message.reactions,emoji=payload.emoji.name)
if reaction and reaction.count>1:
channel=client.get_channel(DELETED_MESSAGES_CHANNEL)
await channel.send('{}: {}'.format(message.author, message.content),embed=message.content.embeds)
await message.delete()
I get the following error,
Ignoring exception in on_raw_reaction_add
Traceback (most recent call last):
File "C:\Python\Python38\lib\site-packages\discord\client.py", line 312, in _run_event
await coro(*args, **kwargs)
File "s.py", line 46, in on_raw_reaction_add
await channel.send('{}: {}'.format(message.author, message.content),embed=message.content.embeds)
AttributeError: 'str' object has no attribute 'embeds'
If I use embed=message.embeds instead of message.content.embeds, i get the following error,
Ignoring exception in on_raw_reaction_add
Traceback (most recent call last):
File "C:\Python\Python38\lib\site-packages\discord\client.py", line 312, in _run_event
await coro(*args, **kwargs)
File "s.py", line 46, in on_raw_reaction_add
await channel.send('{}: {}'.format(message.author, message.content),embed=message.embeds)
File "C:\Python\Python38\lib\site-packages\discord\abc.py", line 828, in send
embed = embed.to_dict()
AttributeError: 'list' object has no attribute 'to_dict'
How do I get all the embeds in this message and forward it as it was sent here to another channel? And also, how do I get to know the number of members in my server who are NOT BOTS? Any suggestions are much appreciated!
await channel.send('{}: {}'.format(message.author,message.content),embed=message.embeds[0]) Typically, there is only one embed in the embeds list object. So, in most cases just use embeds[0]. I haven't seen messages with multiple embeds so far.

Categories