Discord.py guild invite bot - python

If the code is correct, I want to make a bot where the bot invites me to a specific server.
but it has error.
Here's my code:
#client.command()
async def invite(ctx, *, code):
if code == "12320001":
guild = "851841115896152084"
invite = await ctx.guild.create_invite(max_uses=1)
await ctx.send(f"Here's your invite : {invite}")
else:
await ctx.send(f"Code is wrong!")
and error:
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: AttributeError: 'NoneType' object has no attribute 'create_invite'

ctx.guild is None, that is why you are getting this Exception.
You can check the value of ctx.guild before passing ctx as a parameter while calling invite function.

As the error suggests, ctx.guild is None. This usually occurs when invoking a command in a DM rather than in a server, as there obviously is no server in DMs.
Judging by the fact that you have a guild variable that you never used I assume that you're trying to invite people to that guild instead.
# Make sure the id is an int, NOT a string
guild = client.get_guild(85184111589615208)
# Invite users to the guild with the above id instead
invite = await guild.create_invite(max_uses=1)

You need a Channel object to create an invite as the Guild class doesn't have a create_invite() method. You can the code given below. Note that the server should have at least one channel.
#client.command()
async def invite(ctx, code):
if code == "12320001":
guild = client.get_guild(851841115896152084)
invite = await guild.channels[0].create_invite(max_uses = 1)
await ctx.send(f"Here's your invite: {invite}")
else:
await ctx.send("Invalid code!")

Related

How do I remove roles from a user?

I'm currently trying to add reaction roles to my bot, but I'm having trouble getting the bot to remove roles when the reactions are removed
#client.event
async def on_raw_reaction_add(payload):
print("Reaction Added")
if ((payload.message_id == 874372383736205343) and (payload.emoji.name == '🎓')):
guild = client.get_guild(payload.guild_id)
role = guild.get_role(874364790099836948)
await payload.member.add_roles(role)
#client.event
async def on_raw_reaction_remove(payload):
print("Reaction Removed")
if ((payload.message_id == 874372383736205343) and (payload.emoji.name == '🎓')):
guild = client.get_guild(payload.guild_id)
role = guild.get_role(874364790099836948)
await payload.remove_roles(role)
Adding roles works perfectly as intended but whenever I try removing a reaction I always get some kind of error. I've tried a few different things, but the code that I provided returns "Attribute Error: "RawReactionAddEvent" object has no attribute "remove_roles"
As I said, I've tried things other than remove_roles but none of them worked.
I'm pretty new to discord.py and python as a whole so this is probably a really obvious mistake but I just can't seem to find anything that works.
You'll need to retrieve a member object in order to remove the roles. You're currently trying to remove a role from payload instead of a valid member.
guild = client.get_guild(payload.guild_id)
member = await guild.fetch_member(payload.user_id)
role = guild.get_role(874364790099836948)
await member.remove_roles(role)
As Lukasz points out, you can't use payload.member when a reaction is removed because it is only available when a reaction is added. Docs.

Bot don't want to remove member's reaction

I have an authorization system on my server. When member reacts to message, he's getting access to stuff like chats etc. I want bot to remove reaction left by member, so number of reactions on the message will always=1
#client.event
async def on_raw_reaction_add(payload):
message=payload.reaction.message
if payload.channel_id==804320454152028170:
if str(payload.emoji) == '✅':
await message.remove_reaction("✅", payload.member)
else:
return
When I am leaving reaction under the message, I am getting this error:
message=payload.reaction.message
AttributeError: 'RawReactionActionEvent' object has no attribute 'reaction'
Ignoring exception in on_message
Read your error message! Looking at the docs you can easily find out that payload simply does not have such attribute.
To get a message from payload you will need to do something like this
guild = client.get_guild(payload.guild_id)
channel = guild.get_channel(payload.channel_id)
message = await channel.fetch_message(payload.message_id)

Checking for Multiple Guild ID's - Discord.py

I'm trying to send a welcome DM to users that join my discord server, but I have the bot setup in multiple servers. I'm trying to check the guild then send a message based on which guild it is in, but it's not working. I've looked and the popular question like this on stackoverflow uses commands and ctx, which cannot be used in on_member_join().
#client.event
async def on_member_join(member):
guild = client.get_guild(762921541204705321)
if guild == 762921541204705321:
await member.create_dm()
await member.dm_channel.send("Welcome!")
According to the documentation, when you call get_guild() it doesn't return the guild ID, it returns a Guild object. From the source code, it appears that this guild class does have its comparison operator overloaded, so it cannot deal with comparisons between a Guild object and an integer ID.
The solution to your problem is to just compare the number ID with the Guild.id attribute:
#client.event
async def on_member_join(member):
# client.get_guild returns a Guild object!
guild = client.get_guild(762921541204705321)
# Get the ID from the 'id' attribute on the guild object and compare.
if guild.id == 762921541204705321:
await member.create_dm()
await member.dm_channel.send("Welcome!")

'User' object has no attribute 'add_roles'

When trying to do await member.add_roles(role) where member is a User, it gives me the following error:
'User' object has no attribute 'add_roles'
However, when I look online, there is no mention of such an error, implying that this error isn't supposed to happen.
If it helps, this is the section of the code where this error happens:
#bot.event
async def on_raw_reaction_add(payload):
EMOJI = '✅'
guild = discord.utils.get(bot.guilds, name='The Molehill')
channel = bot.get_channel(740608959207047250)
member = await bot.fetch_user(payload.user_id)
message = await channel.fetch_message(payload.message_id)
MESSAGE = "{user.name} is now part of the Mole Workforce!"
rules_message = message=await channel.fetch_message(740891855666806866)
role = discord.utils.get(guild.roles, name="Worker Mole", id=739514340465705027)
if payload.emoji.name == EMOJI:
if message == rules_message:
await member.add_roles(role)
await bot.send(MESSAGE)
You are trying to add a role to a user object, however they can only be added to member objects. While a user represents a user on discord a member represents a member of a guild.
More information on members in the documentation
A user object is not directly linked with a guild. This is the reason it doesnt have functions to add roles to it. As roles are part of guild functionality.
If we want to fix this we need to get an object that is linked with a guild. The closest match is in this case the member object.
So instead of retrieving the user object and retrieving a member object instead should solve the problem:
#bot.event
async def on_raw_reaction_add(payload):
EMOJI = '✅'
guild = discord.utils.get(bot.guilds, name='The Molehill')
channel = bot.get_channel(740608959207047250)
member = await guild.get_member(payload.user_id)
message = await channel.fetch_message(payload.message_id)
MESSAGE = "{user.name} is now part of the Mole Workforce!"
rules_message = message=await channel.fetch_message(740891855666806866)
role = discord.utils.get(guild.roles, name="Worker Mole", id=739514340465705027)
if payload.emoji.name == EMOJI:
if message == rules_message:
await member.add_roles(role)
await bot.send(MESSAGE)
But when we read the documentation about the on_raw_reaction_add. We see that this can be much more efficient without needing lookups through the bot.
For example in the event documentation you see we get a payload object.
The payload object has the following data (and more just read the documentation):
a member object
guild id
channel id
user id
message id
Notice that we have a member object.
We can retrieve the following from it:
a guild object
So updating the old code to the following increases the performance as we dont need to look up stuff through the bot unnessecarily. Note: I removed some redundant code in this example, I assume you only run this bot in 1 guild, because you are using specific ID's that wont work in other guilds.
#bot.event
async def on_raw_reaction_add(payload):
EMOJI = '✅'
member = payload.member
guild = member.guild
# If you want to run your bot on multiple guilds. Then the code under this comment should be updated.
channel = guild.get_channel(740608959207047250)
MESSAGE = "{user.name} is now part of the Mole Workforce!"
role = guild.get_role(739514340465705027)
if payload.emoji.name == EMOJI:
await member.add_roles(role)
await bot.send(MESSAGE)

Issue with giving roles with a command Discord Py

I have made a command to set someone ROLE, However, it's throwing errors.
Command raised an exception: AttributeError: 'str' object has no attribute 'add_roles'
Is there anything wrong I have did? I am using the latest discord py version.
#bot.command()
async def set_role(ctx,member = None,val: int = None):
ab = member
ab = ab.replace("<","")
ab = ab.replace(">","")
ab = ab.replace("#","")
ab = ab.replace("!","")
user = bot.get_user(int(ab))
if val == 1:
role = discord.utils.get(ctx.guild.roles, name="Test")
await user.add_roles(role)
await ctx.send('Updated')
user = bot.get_user(int(ab))
This creates a user object. It is not affiliated to a guild / discord server. By design you cannot do add_roles.
Reason being your bot might not share a guild with this user. Or your bot might share multiple guilds with this user. But how does it know which guild you are actually adressing?
You need to create a member object. This could be done with:
member = ctx.guild.get_member(int(ab))
Now you have a member object and you can await add_roles.
await member.add_roles(role)
https://discordpy.readthedocs.io/en/latest/api.html#discord.Member.add_roles
to give a role to a member u need to give the member and the name of the role as inputs.
for example:
" ?set_role #clay#9871 example "
the bot gonna search for a role name 'example' from the guild roles
if the bot didn't find the role it will send "role not found" that's what the "try" and "except" for
#bot.command()
async def set_role(ctx,member :discord.Member,role):
try:
add_role= discord.utils.get(ctx.guild.roles, name=role)
await member.add_roles(add_role)
await ctx.send('Updated')
except:
await ctx.send("role not found!")

Categories