error 10011 Unknown role with present defined role - python

I'm trying to create a reactroles function for my server, I've gone through hundreds of stack overflow and reddit forums to find bits and pieces to make this work but nothing has fixed this last error.
The roles are present on my server and properly defined (as far as i know) in the code but still returns error 10011 Unknown Role
async def on_reaction_add(reaction, user):
ChID = '1018712244843970610'
ctx = await bot.get_context(reaction.message)
#user = ctx.reaction.author
Channel = bot.get_channel(1018712244843970610)
if reaction.message.channel != Channel:
await Channel.send("this is a test for ChID not....")
return
if reaction.emoji == "🏃":
await ctx.channel.purge(limit=1)
this_member = ctx.message.author
mem = str(this_member.display_name)
await Channel.send(mem+" - this is a test for running....🏃")
print(this_member)
this_guild = this_member.guild
this_role = discord.utils.get(this_guild.roles, id=1018802229341327370)
await this_member.add_roles(this_member, this_role)
if reaction.emoji == "🔨":
await ctx.channel.purge(limit=1)
this_member = ctx.message.author
mem = str(this_member.display_name)
await Channel.send(mem+" - this is a test for hammer....🔨")
this_guild = this_member.guild
this_role = discord.utils.get(this_guild.roles, id=1018802151679602798)
await this_member.add_roles(this_member, this_role)
if reaction.emoji == "🦆":
await ctx.channel.purge(limit=1)
this_member = ctx.message.author
mem = str(this_member.display_name)
await Channel.send(mem+" - this is a test for duck....🦆")
this_guild = this_member.guild
this_role = discord.utils.get(this_guild.roles, id=1018802188555927572)
await this_member.add_roles(this_member, this_role)
if reaction.emoji == "❤️":
await ctx.channel.purge(limit=1)
this_member = ctx.message.author
mem = str(this_member.display_name)
await Channel.send(mem+" - this is a test for heart....❤️")
this_guild = this_member.guild
this_role = discord.utils.get(this_guild.roles, id=1018802188555927572)
await this_member.add_roles(this_member, this_role)
I have tried replacing the ctx in ct.message.author with reaction.message.author but then throws the error 'reaction' has no attribute 'content'
I thought maybe the definition of this_member was the cause of it not being able to define the role but it doesnt seem to be the issue

I used this code, and it works:
#bot.event
async def on_raw_reaction_add(payload):
Channel_id = 1018712244843970610
Channel = bot.get_channel(Channel_id)
data = {"🏃":["running",1018802229341327370], "🔨":["hammer",1018802229341327370], "🦆":["duck",1018802229341327370], "❤":["heart",1018802188555927572]}
if payload.channel_id != Channel_id:
await Channel.send("this is a test for ChID not....")
return
if payload.emoji.name in data:
this_guild = await bot.fetch_guild(payload.guild_id)
all_roles = discord.utils.get(this_guild.roles, name="Bot")
text, role_id = data[payload.emoji.name]
await Channel.purge(limit=1)
this_member = await this_guild.fetch_member(payload.user_id)
mem = str(this_member.display_name)
await Channel.send(mem+" - this is a test for {0}....{1}".format(text, payload.emoji))
print(this_member)
this_role = discord.utils.get(this_guild.roles, id=role_id)
await this_member.add_roles(this_member, this_role)
Raw_reaction_add is for messages older than the start of the bot.
If this does not work, check the Ids of the role.

Related

Creating private channels and deleting them in the discord

I want to make a system where when a user enters the private creation channel, a text channel and a voice channel are created, in the text the creator can give and take away the rights to enter the private, and if the owner leaves the private, then in a minute the channels should be deleted, as well as data about them from the database. I use MongoDB.
I have done almost all the code, but the code with the removal of channels does not work, namely, checking for the channel id. I also want to make sure that the timer for 30 is canceled if the creator returns, but there is some more convenient way to create this timer.
#bot.event
async def on_voice_state_update(member, before, after):
if after.channel is not None:
if after.channel.id == 992120556256247808:
guild = bot.get_guild(642681537284014080)
category = discord.utils.get(guild.categories, name='Приват')
v_channel = await guild.create_voice_channel(name=f'Приват ({member.display_name})', category=category)
t_channel = await guild.create_text_channel(name=f'Выдача прав ({member.display_name})', category=category)
await v_channel.set_permissions(member, connect=True, speak=True, view_channel=True, stream=True, kick_members=True, mute_members=True, priority_speaker=True)
role = discord.utils.get(guild.roles, id=642681537284014080)
await v_channel.set_permissions(role, view_channel=False)
await t_channel.set_permissions(role, view_channel=False)
private_post = {
'_id': member.id,
'text_id':t_channel.id,
'voice_id':v_channel.id,
}
private.insert_one(private_post)
await member.move_to(v_channel)
if before.channel == v_channel: #This one and the lines below it don't work
await bot.get_channel(private.find_one({'_id':member.id})['text_id']).send(f'`[PRIVATE]`: {member.mention}, Your private will be deleted in 1 minute!')
time.sleep(60000)
await t_channel.delete()
await v_channel.delete()
roles.delete_one({'_id': member.id})
#bot.command()
async def perm(ctx, member: discord.Member):
if ctx.channel.id == private.find_one({'text_id': ctx.channel.id})['text_id']:
v_channel = bot.get_channel(private.find_one({'text_id': ctx.channel.id})['voice_id'])
await v_channel.set_permissions(member, connect=True, speak=True, view_channel=True, stream=True)
#bot.command()
async def unperm(ctx, member: discord.Member):
if ctx.channel.id == private.find_one({'text_id': ctx.channel.id})['text_id']:
v_channel = bot.get_channel(private.find_one({'text_id': ctx.channel.id})['voice_id'])
await v_channel.set_permissions(member, connect=False, speak=False, view_channel=False, stream=False)
if member in v_channel.members:
await member.move_to(None)
you're using normal sleep in async code. use async sleep.
try using discord.ext.tasks to create timer. instead of sleep.
and the channel deletion. This should work :
#bot.event
async def on_voice_state_update(member, before, after):
if after.channel is not None:
if after.channel.id == 992120556256247808:
guild = bot.get_guild(642681537284014080)
category = discord.utils.get(guild.categories, name='Приват')
v_channel = await guild.create_voice_channel(name=f'Приват ({member.display_name})', category=category)
t_channel = await guild.create_text_channel(name=f'Выдача прав ({member.display_name})', category=category)
await v_channel.set_permissions(member, connect=True, speak=True, view_channel=True, stream=True, kick_members=True, mute_members=True, priority_speaker=True)
role = discord.utils.get(guild.roles, id=642681537284014080)
await v_channel.set_permissions(role, view_channel=False)
await t_channel.set_permissions(role, view_channel=False)
private_post = {
'_id': member.id,
'text_id': t_channel.id,
'voice_id': v_channel.id,
}
private.insert_one(private_post)
await member.move_to(v_channel)
if before.channel is not None:
channels = private.find_one({'_id':member.id})
t_channel = bot.get_channel(channels['text_id'])
v_channel = bot.get_channel(channels['voice_id'])
if before.channel.id != v_channel.id:
return
await t_channel.send(f'`[PRIVATE]`: {member.mention}, Your private will be deleted in 1 minute!')
await asyncio.sleep(60000)
await t_channel.delete()
await v_channel.delete()
roles.delete_one({'_id': member.id})

Get informations in a function to use it in another function DISCORD.PY

i have a little problem with my code and i don't find any solutions,...
I write a code for my discord bot :
#client.event
async def on_message(message):
if message.content.startswith("!init"):
if message.content.split()[1] == 'règles':
id_channel = 893442599019511829
embed = discord.Embed(title = 'Création bot', description = "par Archi's modo")
embed.add_field(name="Règlement de la LSPD", value="En cliquant sur l'icône ✅ vous reconnaissez avoir blablabla,...")
mess = await client.get_channel(id_channel).send(embed=embed)
await mess.add_reaction('✅')
#client.event
async def on_raw_reaction_add(payload):
id_channel = 893442599019511829
id_message = ?????
role_a_donner = "zabloublou"
message_id = payload.message_id
member = payload.member
if message_id == id_message:
guild_id = payload.guild_id
guild = discord.utils.find(lambda g : g.id == guild_id, client.guilds)
if payload.emoji.name == '✅':
role = discord.utils.get(guild.roles, name=str(role_a_donner))
else:
role = discord.utils.get(guild.role, name=payload.emoji.name)
if role is not None:
if member is not None:
await member.add_roles(role)
channel = client.get_channel(id_channel)
await channel.send(member.mention)
And i don't know how can i get id of the message sended by the bot to use it in my function on_raw_reaction_add
Can someone help me please ?
You should consider using wait_for instead for this kind of use.Your method is mostly used for reaction roles.
Here is an example of wait_for reaction grabbed from discord.py docs for wait_for:
#client.event
async def on_message(message):
if message.content.startswith('$thumb'):
channel = message.channel
await channel.send('Send me that 👍 reaction, mate')
def check(reaction, user):
return user == message.author and str(reaction.emoji) == '👍'
try:
reaction, user = await client.wait_for('reaction_add', timeout=60.0, check=check)
except asyncio.TimeoutError:
await channel.send('👎')
else:
await channel.send('👍')

I want to delete only the voice channels in one category

Here is my code:
import discord, asyncio
app = discord.Client()
#app.event
async def on_voice_state_update(member, before, after):
username = str(member)
guild = app.get_guild(660213767820410893)
ch = guild.get_channel(660213767820410918)
category = guild.get_channel(660213767820410908)
if after.channel == ch:
channel = await guild.create_voice_channel(
name=username+"`s Room",
category=category,
user_limit=99
)
await member.move_to(channel)
await channel.set_permissions(member, manage_channels=True)
if not before.channel.members and before.channel != ch:
await before.channel.delete()
I want to delete only the voice channels in one category. For now, all channels are deleted.
Do you only want to delete the VoiceChannel if it's in the category ? If yes, you could just add the condition: before.channel.category == category in the last if block:
import discord, asyncio
app = discord.Client()
#app.event
async def on_voice_state_update(member, before, after):
username = str(member)
guild = app.get_guild(660213767820410893)
ch = guild.get_channel(660213767820410918)
category = guild.get_channel(660213767820410908)
if after.channel == ch:
channel = await guild.create_voice_channel(
name=username+"`s Room",
category=category,
user_limit=99
)
await member.move_to(channel)
await channel.set_permissions(member, manage_channels=True)
b_channel = before.channel
if b_channel: # If the user was connected to a voice channel before
if not b_channel.members and b_channel != ch and b_channel.category == category:
await b_channel.delete()

Poll command discord.py

DISCORD.PY
I try to create an command for a poll system and encounter a problem. Command is as follows:
#commands.command(pass_context = True)
async def poll(self, ctx, question, *options: str):
author = ctx.message.author
server = ctx.message.server
if not author.server_permissions.manage_messages: return await self.bot.say(DISCORD_SERVER_ERROR_MSG)
if len(options) <= 1:
await self.bot.say("```Error! A poll must have more than one option.```")
return
if len(options) > 2:
await self.bot.say("```Error! Poll can have no more than two options.```")
return
if len(options) == 2 and options[0] == "yes" and options[1] == "no":
reactions = ['👍', '👎']
else:
reactions = ['👍', '👎']
description = []
for x, option in enumerate(options):
description += '\n {} {}'.format(reactions[x], option)
embed = discord.Embed(title = question, color = 3553599, description = ''.join(description))
react_message = await self.bot.say(embed = embed)
for reaction in reactions[:len(options)]:
await self.bot.add_reaction(react_message, reaction)
embed.set_footer(text='Poll ID: {}'.format(react_message.id))
await self.bot.edit_message(react_message, embed=embed)
My question is: How can I make the question I ask using the command to have more words. If I use more words now, I read them as options and get an error.
Ex 1: /poll You are human yes no (only read "you" as a question, and the rest are options.)
Ex 2: /poll You are human yes no (that's what I want)
Thank you!
When calling the command, putting a string in quotes will cause it to be treated as one argument:
/poll "You are human" yes no
You can do:
#bot.command()
async def poll(ctx, question, option1=None, option2=None):
if option1==None and option2==None:
await ctx.channel.purge(limit=1)
message = await ctx.send(f"```New poll: \n{question}```\n**✅ = Yes**\n**❎ = No**")
await message.add_reaction('❎')
await message.add_reaction('✅')
elif option1==None:
await ctx.channel.purge(limit=1)
message = await ctx.send(f"```New poll: \n{question}```\n**✅ = {option1}**\n**❎ = No**")
await message.add_reaction('❎')
await message.add_reaction('✅')
elif option2==None:
await ctx.channel.purge(limit=1)
message = await ctx.send(f"```New poll: \n{question}```\n**✅ = Yes**\n**❎ = {option2}**")
await message.add_reaction('❎')
await message.add_reaction('✅')
else:
await ctx.channel.purge(limit=1)
message = await ctx.send(f"```New poll: \n{question}```\n**✅ = {option1}**\n**❎ = {option2}**")
await message.add_reaction('❎')
await message.add_reaction('✅')
but now you must do /poll hello-everyone text text
if you want to to not have the "-" you must do:
#bot.command()
async def poll(ctx, *, question):
await ctx.channel.purge(limit=1)
message = await ctx.send(f"```New poll: \n✅ = Yes**\n**❎ = No**")
await message.add_reaction('❎')
await message.add_reaction('✅')
But in this one you can't have your own options...
use :
/poll "You are human" yes no
here, "You are human" is one string "yes" "no" are other two strings.
another better way to do it is:
#commands.command(pass_context = True)
async def poll(self, ctx, option1: str, option2: str, *, question):
or, you can use wait_for
#commands.command(pass_context = True)
async def poll(self, ctx, *options: str):
...
question = await self.bot.wait_for('message', check=lambda message: message.author == ctx.author)
...
it is working
#commands.has_permissions(manage_messages=True)
#commands.command(pass_context=True)
async def poll(self, ctx, question, *options: str):
if len(options) > 2:
await ctx.send('```Error! Syntax = [~poll "question" "option1" "option2"] ```')
return
if len(options) == 2 and options[0] == "yes" and options[1] == "no":
reactions = ['👍', '👎']
else:
reactions = ['👍', '👎']
description = []
for x, option in enumerate(options):
description += '\n {} {}'.format(reactions[x], option)
poll_embed = discord.Embed(title=question, color=0x31FF00, description=''.join(description))
react_message = await ctx.send(embed=poll_embed)
for reaction in reactions[:len(options)]:
await react_message.add_reaction(reaction)
#create a yes/no poll
#bot.command()
#the content will contain the question, which must be answerable with yes or no in order to make sense
async def pollYN(ctx, *, content:str):
print("Creating yes/no poll...")
#create the embed file
embed=discord.Embed(title=f"{content}", description="React to this message with ✅ for yes, ❌ for no.", color=0xd10a07)
#set the author and icon
embed.set_author(name=ctx.author.display_name, icon_url=ctx.author.avatar_url)
print("Embed created")
#send the embed
message = await ctx.channel.send(embed=embed)
#add the reactions
await message.add_reaction("✅")
await message.add_reaction("❌")
for your code to treat the text in the user's message as one string, use "content:str" in your command arguments
I know my code isn't very dynamic and pretty but i did that and it's functional.
#client.command()
async def poll(ctx):
options = ['1️⃣ Yes Or No', '2️⃣ Multiple Choice']
embed = discord.Embed(title="What type of poll you want ?" , description="\n".join(options), color=0x00ff00)
msg_embed = await ctx.send(embed=embed)
reaction = await client.wait_for("reaction_add", check=poll)
if (reaction[0].emoji == '1️⃣'):
user = await client.fetch_user(ctx.author.id)
msg = await user.send("What is your question ?")
question = await client.wait_for("message", check=lambda m: m.author == ctx.author)
answers = ['\n\u2705 Yes\n', '\u274C No']
new_embed = discord.Embed(title="Poll : " + question.content, description="\n".join(answers), color=0x00ff00)
await msg_embed.edit(embed=new_embed)
await msg_embed.remove_reaction('1️⃣', user)
await msg_embed.add_reaction('\N{WHITE HEAVY CHECK MARK}')
await msg_embed.add_reaction('\N{CROSS MARK}')
elif (reaction[0].emoji == '2️⃣'):
user = await client.fetch_user(ctx.author.id)
msg = await user.send("What is your question ?")
question = await client.wait_for("message", check=lambda m: m.author == ctx.author)
msg = await user.send("What are the choices ? (Four compulsory choices, separated by comma)")
choices = await client.wait_for("message", check=lambda m: m.author == ctx.author)
choices = choices.content.split(',')
if (len(choices) > 4):
await msg_embed.delete()
await user.send("You can't have more than four choices")
return
if (len(choices) < 4):
await msg_embed.delete()
await user.send("You can't have less than four choices")
return
answers = ['1️⃣ '+ choices[0] + '\n', '2️⃣ '+ choices[1] + '\n', '3️⃣ '+ choices[2] + '\n', '4️⃣ '+ choices[3] + '\n']
new_embed = discord.Embed(title=question.content, description="\n ".join(answers), color=0x00ff00)
await msg_embed.edit(embed=new_embed)
await msg_embed.remove_reaction('2️⃣', user)
await msg_embed.add_reaction('1️⃣')
await msg_embed.add_reaction('2️⃣')
await msg_embed.add_reaction('3️⃣')
await msg_embed.add_reaction('4️⃣')

Writing a Discord Bot using Discord.py Rewrite

So currently I have a discord Bot, and I want to make it welcome any new users in #joining and give them the nickname "[0] Member Name". I'm not getting any errors but neither of these functions are working!
EDIT: Re-Wrote Some Code and I'm Now Getting This Error:
EDIT 2: Still Unable to Edit Nicknames, but when a User Leaves the Server I get these errors from the Function to check if the User is a Staff Member. I don't get errors from the message.author, but when the message author leaves, I start getting this error. I tried resetting the message.author when anyone leaves the server but this didn't help! I don't have any ideas on how to stop these errors!
Ignoring exception in on_message
Traceback (most recent call last):
File "C:\Users\Evan\Anaconda3\envs\testing\lib\site-packages\discord\client.py", line 270, in _run_event
await coro(*args, **kwargs)
File "C:/Users/Evan/PycharmProjects/Bot/bot.py", line 107, in on_message
top_role = message.author.top_role
AttributeError: 'User' object has no attribute 'top_role'
My New Edited Code vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
import discord
import asyncio
import time
# id = 630529690792230923
messages = joined = 0
client = discord.Client()
#client.event
async def on_ready():
print(f'Logged in as: {client.user.name}')
print(f"User ID: {client.user.id}")
print('-----')
async def update_stats():
await client.wait_until_ready()
global messages, joined
while not client.is_closed():
try:
with open("stats.txt", "a") as f:
f.write(f"Time: {int(time.time())}, Messages: {messages}, Members Joined: {joined}\n"),
messages = 0
joined - 0
await asyncio.sleep(3600)
except Exception as e:
print(e)
await asyncio.sleep(3600)
#client.event
async def on_raw_reaction_add(payload):
message_id = payload.message_id
if message_id == 638155786559684608:
guild_id = payload.guild_id
guild = discord.utils.find(lambda g: g.id == guild_id, client.guilds)
if payload.emoji.name == 'Test':
role = discord.utils.get(guild.roles, name='new role')
else:
role = discord.utils.get(guild.roles, name=payload.emoji.name)
if role is not None:
member = discord.utils.find(lambda m: m.id == payload.user_id, guild.members)
if member is not None:
await member.add_roles(role)
print("done")
else:
print("Member Not Found")
#client.event
async def on_raw_reaction_remove(payload):
message_id = payload.message_id
if message_id == 638155786559684608:
guild_id = payload.guild_id
guild = discord.utils.find(lambda g: g.id == guild_id, client.guilds)
if payload.emoji.name == 'Test':
role = discord.utils.get(guild.roles, name='new role')
else:
role = discord.utils.get(guild.roles, name=payload.emoji.name)
if role is not None:
member = discord.utils.find(lambda m: m.id == payload.user_id, guild.members)
if member is not None:
await member.remove_roles(role)
print("done")
#client.event
async def on_member_join(member):
global joined
joined += 1
rule_channel = member.guild.get_channel(channel_id=630530486858547223)
newusermessage = f"""Welcome to CB:NL {member.mention}! Have a Great Time And Make Sure to Look At {rule_channel}"""
channel = member.guild.get_channel(channel_id=630563931412496434)
role = member.guild.get_role(role_id=630533613947060244)
if member is not None:
await member.add_roles(role)
print("done")
await member.edit(str([f"[0] {member.display_name}"]))
await channel.send(newusermessage)
#client.event
async def on_member_remove(member):
discord.message.author = member
#client.event
async def on_message(message):
global messages
messages += 1
id = client.get_guild(630529690792230923)
bad_words = ["test"]
channels = ["bot-commands", "staff-general"]
pn = 1
author = message.author
top_role = message.author.top_role
staff_role = message.author.guild.get_role(role_id=630532857655328768)
if top_role > staff_role:
if message.content.startswith == "-clean":
pass
if str(message.channel) in channels:
if message.content.find("-hello") != -1:
await message.channel.send("Hi")
elif message.content == "-status":
await message.channel.send(f"""# of Members: {id.member_count}""")
else:
if message.author.bot is not 1:
print(f"""{message.author} tried to do command {message.content}""")
await message.channel.send(f"Error, {message.author.mention}. You Cannot Do That!")
client.loop.create_task(update_stats())
I'll respond in answer, because there are multiple mistakes in your code and it's hard to put into the comment. You can comment under this post if you get another error.
role = discord.utils.get(discord.Guild.roles, name="Member")
The error is where you retrieve the role by name Member. It's better to get the role by ID, you can do that using member.guild.get_role(630533613947060244). The error is that discord.Guild.roles is not an iterable property.
nick = discord.utils.get(str(member.nick))
Not sure what is your intention there, you can use nick = member.nick to get a string with member's nickname.
To edit the nickname you should use:
await member.edit(nick=f"[0] {member.display_name}")
AttributeError: 'User' object has no attribute 'top_role'
You get this error because you want to access top_role attribute on instance of discord.User, but only discord.Member has this attribute defined. When someone leaves the server you get the User instance instead of the Member instance.
if isinstance(message.author, discord.Member):
top_role = message.author.top_role
else:
top_role = None # top role not available, user has no roles

Categories