Python Discord BOT. Simple, but annoying error - python

I just discovered this site, and I wondered if someone could help me. I don't really know if this title is appropriate, but that'll do for the moment.
So, I've got a code that looks like this :
#client.command(pass_context=True)
async def member(self, *, member: discord.Member = None, role : discord.Role = None):
if member is None:
await client.say("You need to tag someone!")
elif role is None:
await client.say("You need to tag a role to add!")
else:
await client.add_roles(member, role)
await client.say("Role added!")
I think it's "working" quite well, because I do not see any errors when typing the !member #Dude command. The BOT just tells me that I need to tag a role to add. BUT! When I tag a role to add, then it doesn't work. In fact, the problem is, the BOT thinks that the role I tag is part of the name of the member. Maybe it will be better with the error.
The error I told you about is one the last line of this image.
As you can see, it says that the member wasn't found. But the second ID is supposed to be the role's one. What am I doing wrong? I'm really bad with discord.py so if someone could help me, it would be very nice of him! :)
(Also, sorry for my bad english and sorry if this is off-topic, it's just that I'm fed up with these errors, because I always get another when one is solved.)
EDIT : I just fixed this, but now I get the a perms error. "Forbidden: FORBIDDEN (status code: 403) : Missing Permissions"

Make sure that you have given the bot manage role permissions. If it doesn't have that then it can't add or remove roles. Also make sure that the bot is higher in the role hierarchy than the role you are getting it to add.

I just fixed this, but now I get the a perms error. "Forbidden: FORBIDDEN (status code: 403) : Missing Permissions"
Bot must have Manage Roles permission on server, and role to add must be lower then bot's top role

Related

Discord.py Automatically assign roles to users having specific keywords in a message or image

I'm extremely new to discord.py and I was wondering if there is an existing bot or if I could make a bot that can assign a role to a user based on keywords in a text and/or image to get a specific role through verification.
Is this possible and if so can I get some help with it?
I have tried looking for bots that may have this feature but I have been unsuccessful, I am somewhat willing to make a bot as well but I'm a beginner coder but I am willing to figure things out!
It is possible. But I'm unsure when you want this to be triggered;
checking every possible message?
messages in a certain channel?
some kind of response to a slash command/modal dialog?
etc
Let's role with "checking every possible message" for a basic example.
Let's say we have a server about people's favourite fruit and we want to assign users a role based on their favourite fruit as this gives them access to the private channel about that fruit.
import discord
# we have already created roles in our server for the fruits
# so we'll put the IDs here for ease of use
ROLES = {
"banana": 112233445566,
"apple": 123456123456,
"orange": 665544332211
}
# requires elevated privileges - but let's say we've ticked those
intents = discord.Intents.all()
client = discord.Bot(intents=intents)
# register a client event to trigger some code every time a message is sent
#client.event
async def on_message(message: discord.Message):
message_content = message.content.lower()
if "bananas are good" in message_content:
role = ROLES["banana"]
elif "apples are good" in message_content:
role = ROLES["apple"]
elif "oranges are good" in message_content:
role = ROLES["orange"]
else:
# make sure we have a case for when nothing we want is found
role = None
if not role:
# exit out if we don't have a role to assign
return
guild_roles = await message.guild.fetch_roles()
our_role = [gr for gr in guild_roles if gr.id == role]
await message.author.add_roles(our_role)
client.run(OUR_TOKEN)
This is a very basic example but it possible. Ideally, we'd have a better way of checking message content - either via regex or other form of analysis. Additionally, we'd probably only check messages in a certain channel (or another method entirely, like a modal dialogue or a slash command). Also, what we're not doing above, is removing the user from the other roles (provided you would want that). So it would be possible for a user to have the "banana", "oranges", and "apples" roles all at once.
Hopefully that gives some ideas of where to start. Images would be similar - triggering some kind of function when you want it, downloading the image and running whatever analysis you want on the image.
Disclaimer: I wrote this with the pycord library in mind and didn't see the discord.py tag - should mostly be similar though but might not be.

Discord.py Move Members Permission

I'm making a discord bot and it has a move command that moves all the members in a voice channel to another, well the main problem is this command should only work for those with move members permission but it does not! It doesn't work even if the user has that permission and it always show me an error. Here is the code:
def in_voice_channel():
def predicate(ctx):
return ctx.author.voice and ctx.author.voice.channel
return check(predicate)
#in_voice_channel()
#client.command()
#commands.has_permissions(move_members=True)
async def moveall(ctx, *, channel : discord.VoiceChannel):
author_ch = ctx.author.voice.channel.mention
for members in ctx.author.voice.channel.members:
await members.move_to(channel)
await ctx.send(f'Moved everyone in {author_ch} to {channel.mention}!')
The problem in this code is not with the permissions setup.
#commands.has_permissions(move_members=True) is the way to go.
What is the use of #in_voice_channel() decorator?
As far as I know this is not from discord.py
Update
After testing it myself, even though "Move Members" is the right permission to go for depending on discord.py docs, it does not seem to work properly.
You can instead use another check like #commands.has_role() to make this work or wait until the bug gets fixed.
#commands.has_permissions() checks the channel permissions, and text channels do not have move_members or mute_members permissions.
What you are looking for is #commands.has_guild_permissions() which checks to see if that user has server wide permissions to move/mute members.
This means that to check if the user has move_member you will need to put #commands.has_guild_permissions(move_members=True) before your function/command.

Programming a Discord bot in Python- How do I get the roles of a user that just left the server?

I want my bot to display some information about a user when they leave. Here's my code:
#client.event
async def on_member_remove(member):
channel = client.get_channel(810613415185350666)
mention = []
for role in member.roles:
if role.name != "#everyone":
mention.append(role.mention)
b = ", ".join(mention)
await channel.send(f"{member} has left the server. Roles: {b}")
Now when the event is triggered, it tells me that they've left (as expected). However, it does not show any roles even though they had several. I would assume this is because they are no longer in the server, which means they technically don't have any roles.
How would I fix this?
on the doc the return is member, but i think that when the member left the server the argument of on_member_remove from memberbecome user so it doesn't haves roles. So if that is correct you need to save in file/database the roles of the members at every on_members_update
MY BAD! This code works fine, but the user that was leaving simply didn't have any roles to display... I'm an idiot, sorry about that. Have a good day :)
(Would delete this question if it'd let me)

discord py - message.mentions "else" makes nothing

I want to get the user that was mentioned in a message and send him a private message. That's working without problems, but now I want to add a message for the case, that the mentioned member is not on the same server.
I searched a lot and try now for over 3 hours to find a solution.
Showcase of the problem: https://youtu.be/PYZMVXYtxpE
Heres my code:
#bot.event
async def on_message(message):
if len(message.mentions) == 1:
membe1 = message.mentions[0].id
membe2 = bot.get_user(membe1)
guild = bot.get_guild(message.author.guild.id)
if guild.get_member(membe1) is not None:
await membe2.send(content=f"you was mentioned in the server chat")
else:
embed2 = discord.Embed(title=f"ยป :warning: | PING not possible", description=f"not possible")
await message.channel.send(content=f"{message.author.mention}", embed=embed)
await message.delete()
return
The first part is working without problems, but at the "else" part, does the bot nothing. He still posts the message with the "invalid" ping in the chat and just ignores it. What can I do to fix that?
There is an error of design in what you are trying to do.
In Discord, you are not able to mention a user if he is not on that same server, so what you are checking will never work at all, currently your code is pretty much checking if the mentioned user exists, which will always happen unless he leaves the guild at the same time the command is executed.
Say for example, to make your command work you want to mention the user user123, who is in your server, you do the following:
#user123 blablabla
And that works because Discord internal cache can find user123 in your server and it is mentioned, which means that clicking on "#user123" will show us a target with his avatar, his roles or whatsoever.
But if you try to do the same for an invalid user, let's say notuser321:
#notuser321 blablabla
This is not a mention, take for example that you know who notuser321 is but he is in the same server as the bot is. Discord cannot retrieve this user from the cache and it is not considered a mention, just a single string, so not a single part of your code will be triggered, because len(message.mentions) will be 0.
Something that you could try would be using regular expressions to find an attempt to tag within message.content. An example would be something like this:
import re
message = "I love #user1 and #user2"
mention_attempt = re.findall(r'[#]\S*', message) # ['#user1', '#user2']

how do you mention

I need to mention a specific role with the id 631147065925173310. I have tried everything and a lot of people said to me that I don't know python, which is hard, but I am learning how to use discord.py for only 2 days.
if channel.name == "General":
await ctx.send(f"{ctx.author.mention}needs help at{channel.mention})
else:
await ctx.send(f"{ctx.author}needs help at an unknown place")
I want that whenever a person write 'h!' or help, it will say:
#user needs help at #channel #specific role
You can try
user = self.bot.get_user(ctx.author.id)
role = ctx.guild.get_role(631147065925173310)
await ctx.send(f"{user.mention} needs help in {ctx.channel.mention}, please attend {role.mention}")
If you are using this in a cog use my code and if you are using bot for commands.
If you are using this in the main command use bot.get_user(ctx.author.id) instead of what I have.
To mention a role or user you should use this syntax in your message:
<#id>
So change "id" for the id of the respective role, so your code would be:
awit ctx.send(f"<#{userId}>nedds help at<#{channelId}>)

Categories