How do I make a bot that would give people roles when they reacted to a specific thing? So far I have this but it does not work
#client.event
async def on_ready():
channel = client.get_channel('513546504481406979')
role = discord.utils.get(user.server.roles, name="testrole")
message = await bot.send_message(channel, "React to me!")
while True:
reaction = await bot.wait_for_reaction(emoji="👍", message=message)
await bot.add_roles(reaction.message.author, role)
wait_for_reaction returns a (reaction, user) tuple. You only need the user portion to assign the role:
reaction, reactor = await bot.wait_for_reaction(emoji="👍", message=message)
await bot.add_roles(reactor, role)
Related
I'm making a simple game in discord.py/pycord and I would like my bot to be able to delete a specific reaction. Is there a way to do this?
I want the reaction to delete after I click.
Like this:
Here is my code (I'm using pycord):
import discord
from discord.ext import commands
intents = discord.Intents().all()
bot = commands.Bot(intents=intents)
#bot.event
async def on_message(message):
if message.author == bot.user:
return
if message.content == 'test':
me = await message.reply('Is this cool?')
await me.add_reaction("👎")
await me.add_reaction("👍")
try:
reaction, user = await bot.wait_for("reaction_add", check=lambda reaction, user:
user == message.author and reaction.emoji in ["👎", "👍"], timeout=30.0)
except asyncio.TimeoutError:
await message.reply("Tmieout bro")
else:
if reaction.emoji == "👍":
await message.reply('Like it.')
await reaction.delete()
else:
await message.reply("NO like")
await reaction.delete()
You first get the reaction object, then you remove it. Docs
Code:
#bot.slash_command(name='removereaction', description="I'm helping someone with their Stack post")
async def removereaction(ctx, message: discord.Option(discord.Message)):
print(message)
for i in message.reactions:
async for user in i.users():
await i.remove(user)
await ctx.respond(message.reactions)
How this works is it gets the message from the parameter message that has type discord.Option. The discord.Option is set so that you can use a message from a link or ID. Then, it uses this to cycle through all of the message's reactions. Then it cycles through each user that reacted with said reaction. It must be async, because i.users() is async (See here).
The full code that may help you:
import discord
from discord.ext import commands
intents = discord.Intents().all()
bot = commands.Bot(intents=intents)
#bot.event
async def on_message(message):
if message.author == bot.user:
return
if message.content == 'test':
me = await message.reply('Is this cool?')
await me.add_reaction("👎")
await me.add_reaction("👍")
try:
reaction, user = await bot.wait_for("reaction_add", check=lambda reaction, user:
user == message.author and reaction.emoji in ["👎", "👍"], timeout=30.0)
except asyncio.TimeoutError:
await message.reply("Tmieout bro")
else:
if reaction.emoji == "👍":
await message.reply('Like it.')
async for user in reaction.users():
await reaction.remove(user)
else:
await message.reply("NO like")
async for user in reaction.users():
await reaction.remove(user)
If you want to remove JUST the bot's reactions change the following line:
async for user in reaction.users():
await reaction.remove(user)
To:
await reaction.remove(bot.user)
For example, a person mentions the role of #role1 and the bot gives him this role. How to do it?
For the rewrite branch:
role = discord.utils.get(ctx.guild.roles, name="role to add name")
user = ctx.message.author
await user.add_roles(role)
For the async branch:
user = ctx.message.author
role = discord.utils.get(user.server.roles, name="role to add name")
await client.add_roles(user, role)
I think this is a good solution. Just make it so it requires a role, or a role mention.
We basically make a command where it requires two arguments: a role, and a mentioned member. You can configure this to make it so only administrators can run this command. If the Role doesn't exist, it will send a "This is not a correct role" message. Let me know if you face any issues!
from discord.ext import commands
from discord.utils import get
import discord
intents = discord.Intents.all()
client = commands.Bot(command_prefix = '!', intents=intents, case_intensitive=True)
#client.event
async def on_ready():
print('Bot is online!')
#client.command()
async def addrole(ctx, user: discord.Member, role: discord.Role):
try:
await user.add_roles(role)
await ctx.send(f'{user.mention} was given the role: {role.name}')
except commands.BadArgument:
await ctx.send('That is not a correct role!')
client.run('TOKEN')
I'm currently trying to build a discord.py mute command that sends an embed asking if the user is sure that they want to mute, and then when a reaction is added the mute is carried out and the embed is edited. I have run into some errors trying to do so.
#bot.command()
#commands.has_permissions(manage_guild=True)
async def mute(ctx, message, member: discord.Member = None):
guild = ctx.guild
user = member
if member == None:
await ctx.send(f'**{ctx.message.author},** please mention somebody to mute.')
return
if member == ctx.message.author:
await ctx.send(f'**{ctx.message.author},** you cannot mute yourself, silly.')
return
for role in guild.roles:
if role.name == "Muted":
if role in user.roles:
await ctx.send("**{}** is already muted.".format(user))
return
embedcheck=discord.Embed(title="Mute", colour=0xFFD166, description=f'Are you sure you want to mute **{user}?**')
embeddone=discord.Embed(title="Muted", colour=0x06D6A0,description=f'The mute has been done. **{user}** cannot talk in any channels anymore.')
embedfail=discord.Embed(title="Not Muted",colour=0xEF476F,description=f'The mute did not carry out as I did not receive a reaction in time.')
msg = await ctx.send(embed=embedcheck)
await message.add_reaction('✅','❌')
try:
def check(rctn, user):
return user.id == ctx.author.id and str(rctn) == '✅'
reaction, user = await bot.wait_for('reaction_add', timeout=60.0, check=check)
except asyncio.TimeoutError:
await msg.edit(embed=embedfail)
else:
for role in guild.roles:
if role.name == "Muted":
await member.add_roles(role)
await msg.edit(embed=embeddone)
When I run the command I always get the same output, "...please mention somebody to mute," even though I have mentioned somebody. When I don't mention anybody, I get the error
raise MissingRequiredArgument(param)
discord.ext.commands.errors.MissingRequiredArgument: message is a required argument that is missing.
Leave out message in async def mute(ctx, message, member: discord.Member = None) and change await message.add_reaction(...) to await msg.add_reaction(...).
#bot.command()
#commands.has_permissions(manage_guild=True)
async def mute(ctx, member: discord.Member = None):
guild = ctx.guild
user = member
if member == None:
await ctx.send(f'**{ctx.message.author},** please mention somebody to mute.')
return
if member == ctx.message.author:
await ctx.send(f'**{ctx.message.author},** you cannot mute yourself, silly.')
return
for role in guild.roles:
if role.name == "Muted":
if role in user.roles:
await ctx.send("**{}** is already muted.".format(user))
return
embedcheck=discord.Embed(title="Mute", colour=0xFFD166, description=f'Are you sure you want to mute **{user}?**')
embeddone=discord.Embed(title="Muted", colour=0x06D6A0,description=f'The mute has been done. **{user}** cannot talk in any channels anymore.')
embedfail=discord.Embed(title="Not Muted",colour=0xEF476F,description=f'The mute did not carry out as I did not receive a reaction in time.')
msg = await ctx.send(embed=embedcheck)
await msg.add_reaction('✅')
await msg.add_reaction('❌')
try:
def check(rctn, user):
return user.id == ctx.author.id and str(rctn) == '✅'
reaction, user = await bot.wait_for('reaction_add', timeout=60.0, check=check)
except asyncio.TimeoutError:
await msg.edit(embed=embedfail)
else:
for role in guild.roles:
if role.name == "Muted":
await member.add_roles(role)
await msg.edit(embed=embeddone)
You mentioned a user that went to message instead of member. Not mentioning anyone leaves message empty and sends you an error because it is a required argument.
I didn't check if it will mute but this should fix your MissingRequiredArgument error.
I need an efficent discord.py command for unban users by their tag, not their name and discriminator. how i can do?
This is the code that I made and it works with *unban name#1234.
#client.command()
#commands.has_any_role(702909770956406885, 545323952428417064, 545323570587369472)
async def unban(ctx, *, member):
banned_user = await ctx.guild.bans()
member_name, member_discriminator = member.split("#")
for ban_entry in banned_user:
user = ban_entry.user
if (user.name, user.discriminator) == (member_name, member_discriminator):
await ctx.guild.unban(user)
embed = discord.Embed(title="Fatto!", description=f"Ho sbannato {user.mention}!", color=discord.Color.green())
await ctx.send(embed=embed)
return
How can i make it work with tags? I know you can't directly tag a banned user but with his id you can do it. Thank you for answers!
Hope this helps
from discord.ext.commands import has_permissions
#bot.command()
#has_permissions(ban_members=True)
async def unban(ctx, userId: discord.User.id):
user = get(id=userId)
await ctx.guild.unban(user)
Use the member object as a parameter in your unban function.
Ex:
#client.command()
#commands.has_any_role(702909770956406885, 545323952428417064, 545323570587369472)
async def unban(ctx, *, member: discord.Member):
await ctx.guild.unban(member)
Then in discord you could execute the command by mentioning the user.
Ex: *unban #aleee
#client.command(description="bans a user with specific reason (only admins)") #ban
#commands.has_permissions(administrator=True)
async def ban (ctx, member:discord.User=None, reason =None):
try:
if (reason == None):
await ctx.channel.send("You have to specify a reason!")
return
if (member == ctx.message.author or member == None):
await ctx.send("""You cannot ban yourself!""")
else:
message = f"You have been banned from {ctx.guild.name} for {reason}"
await member.send(message)
await ctx.guild.ban(member, reason=reason)
print(member)
print(reason)
await ctx.channel.send(f"{member} is banned!")
except:
await ctx.send(f"Error banning user {member} (cannot ban owner or bot)")
Is it possible for on_reaction_add() to work with messages sent in on_ready()?
I'm trying to get users to verify they are human from a reaction that is on a message sent when the bot starts.
async def on_ready():
#delete msgs from verify chan
channel = client.get_channel("32133132")
msg=[]
async for x in client.logs_from(channel, limit = 100):
msg.append(x)
await client.delete_messages(msg)
#send verification msg w/ reaction
await client.send_message(channel, "**Verify you are human**")
verifymsg2 = await client.send_message(channel, "React with ✅ to gain access to Hard Chats.")
await client.add_reaction(verifymsg2, "✅")
#client.event
async def on_reaction_add(reaction, user):
channel = client.get_channel('32133132')
if reaction.message.channel.id != channel:
return
else:
if reaction.emoji == "✅":
unverified = discord.utils.get(user.server.roles, id="567859230661541927")
verified = discord.utils.get(user.server.roles, id="567876192229785610")
await client.remove_roles(user, unverified)
await client.add_roles(user, verified)
After messing with this code for a while, I went ahead and did it this way. Every time a new person joins the server, it adds a role of unverified with restricted permissions for each channel. Then it will clear the verify channel and sends the verification message. From there it will wait for a reaction. If reaction, then it will delete unverified role and add verified role.
#client.event
async def on_member_join(member):
#-------------------------ADD UNVERIFIED ROLE----------------------------#
role = discord.utils.get(member.server.roles, id="123456789")
await client.add_roles(member, role)
#---------------DELETE MSG FROM VERIFY---------------#
channel = client.get_channel("0987654321")
msg=[]
async for x in client.logs_from(channel, limit = 100):
msg.append(x)
await client.delete_messages(msg)
#---------------SEND VERIFY MSG / REACT TO VERIFY MSG---------------#
await client.send_message(channel, "**Verify you are human**")
verifymsg2 = await client.send_message(channel, "React with ✅ to gain access to Hard Chats.")
await client.add_reaction(verifymsg2, "✅")
unverified = discord.utils.get(member.server.roles, name="unverified")
verified = discord.utils.get(member.server.roles, name="verified")
reaction = await client.wait_for_reaction(emoji="✅", message=verifymsg2,
check=lambda reaction, user: user != client.user)
if reaction:
await client.remove_roles(member, unverified)
await asyncio.sleep(0.5)
await client.add_roles(member, verified)