** want to make reaction role which if user react message on specific channel will get role
but it doesn't work**
#client.event
async def on_reaction_add(member):
ChannelID = 932268491556405268
role = discord.utils.get(member.guild.roles, id=941124409341648957)
if member.message.channel.id != ChannelID:
return
if member.emoji == "1️⃣":
await member.add_roles(role, reason=None, atomic=True)
You can use the payload object from on_raw_reaction_add to do what you want
#client.event
async def on_raw_reaction_add(payload): # Requires Intents.reactions
channel = client.get_channel(...)
guild = client.get_guild(payload.guild_id)
role = discord.utils.get(guild.roles, id=...)
if str(payload.emoji) == "1️⃣":
await payload.member.add_roles(role, atomic=True)
await channel.send(...)
Related
Im trying to make a bot that send me a message with a reaction button, when I click it, give me a role in the server. Im trying to use on_raw_reaction_add event but I cant reach a solution to make it, Im always getting errors at getting guild roles and this stuff.
In this case, guild is none, I dont know what Im doing wrong.
My code:
#client.command()
async def test(ctx):
global member
global message__id
global channel_id
channel_id = (ctx.channel.id)
member = ctx.message.author
embed = discord.Embed(title="Verify your account", color=0x03fc14)
embed.add_field(name=f"Verification!", value=('React to this message to get verified!'), inline=False)
embed.set_footer(text=ctx.author, icon_url=ctx.author.avatar_url)
mesg = await member.send(embed=embed)
await mesg.add_reaction("✅")
message__id = mesg.id
print("EXECUTED")
#client.event
async def on_raw_reaction_add(payload):
print("reacted")
print("messageid accepted")
guild = client.get_guild(payload.guild_id)
if guild is not None:
print("messageid accepted")
reactor = payload.guild.get_member(payload.member.id)
role = discord.utils.get(guild.roles, name="Member")
if payload.emoji.name == '✅':
print("emoji accepted")
await reactor.add_roles(role)
EDIT:
I changed my on_raw_reaction_add event:
#client.event
async def on_raw_reaction_add(payload):
print("reacted")
print("messageid accepted")
guild = client.get_guild(payload.guild_id)
if guild is not None:
print("guild not none ")
reactor = payload.guild.get_member(payload.member.id)
role = discord.utils.get(guild.roles, name="Verified")
if payload.emoji.name == '✅':
print("emoji accepted")
await reactor.add_roles(role)
else:
print("guild none")
And this is what happen when I try the method:
First three words are the prints of the bot reacting his own message, the "EXECUTED" is the print of test method and the last three messages. are when I react the bot message
In this case, I suggest using a wait_for rather than on_raw_reaction_add.
Example, as seen in the docs:
#client.command(aliases=["t"])
async def test(ctx):
embed = discord.Embed(title="Verify your account", color=0x03fc14)
embed.add_field(name=f"Verification!", value=('React to this message to get verified!'), inline=False)
embed.set_footer(text=ctx.author, icon_url=ctx.author.avatar_url)
# sends message to command author
mesg = await ctx.author.send(embed=embed)
await mesg.add_reaction("✅")
#check if the reactor is the user and if that reaction is the check mark
def check(reaction, user):
return user == ctx.author and str(reaction.emoji) == '✅'
try:
#wait for the user to react according to the checks
reaction, user = await client.wait_for('reaction_add', timeout=60.0, check=check)
except asyncio.TimeoutError:
# 60 seconds without reaction
await ctx.send('Timed out')
else:
await ctx.send('✅')
docs- https://discordpy.readthedocs.io/en/stable/api.html?highlight=wait_for#discord.Client.wait_for
async def test(ctx):
global member
global message__id
global channel_id
channel_id = (ctx.channel.id)
member = ctx.message.author
embed = discord.Embed(title="Verify your account", color=0x03fc14)
embed.add_field(name=f"Verification!", value=('React to this message to get verified!'), inline=False)
embed.set_footer(text=ctx.author, icon_url=ctx.author.avatar_url)
mesg = await member.send(embed=embed)
await mesg.add_reaction("✅")
message__id = mesg.id
print("EXECUTED")
role = get(ctx.guild.roles, id=role id here)
done = False
while done == False:
reaction, user = await client.wait_for(“reaction_add”, check=check)
if user == client.user:
continue
await member.add_roles(role)
done = True
I am pretty sure something like this would work :D
When you do guild is not None, it will never fire because you are reacting in a DM channel context - where the guild is None. To access the guild information from the DM, you'll need to save it somewhere in the message (or save it yourself internally). Then, you have the guild object and you're able to add roles or do things to it.
#client.command()
async def testrole(ctx):
member = ctx.author
# ...
embed = discord.Embed(title="Verify your account", color=0x03fc14)
embed.add_field(name=f"Verification!", value=('React to this message to get verified!'), inline=False)
embed.set_footer(text=ctx.author, icon_url=ctx.author.avatar_url)
mesg = await member.send(str(ctx.guild.id), embed=embed) # we need the guild information somewhere
await mesg.add_reaction("✅")
#client.event
async def on_reaction_add(reaction, user): # there's really no need to use raw event here
if user.id == client.user.id:
return
if reaction.message.guild is None:
if reaction.emoji == '\u2705':
# we have to get the guild that we saved in the other function
# there is no other way to know the guild, since we're reacting in the DM
# that's why it was saved inside of the message that was sent to the user
guild_id = int(reaction.message.content)
guild = client.get_guild(guild_id)
member = guild.get_member(user.id)
await member.add_roles(...) # change this with your roles
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'm trying to make a discord bot that puts roles based on which emoji you choose. Up to here it works well, but what I want to do is always keep the emoji counter always at 1 and if a user presses the button the role is assigned and if he represses it the role will have to be removed but always keeping the counter at 1
import discord
from discord.ext import commands
class AutoRole(commands.Cog):
def __init__(self, client):
self.client=client
#commands.Cog.listener()
async def on_ready(self):
print("AutoRole: ON")
#commands.Cog.listener()
async def on_raw_reaction_add(self,payload):
messageID = 874997842748506112
if messageID == payload.message_id:
member = payload.member
guild = member.guild
emoji = payload.emoji.name
if emoji == '❤️':
role = discord.utils.get(guild.roles, name="Red")
elif emoji == '💛':
role = discord.utils.get(guild.roles, name="Yellow")
await member.add_roles(role)
#commands.Cog.listener()
async def on_raw_reaction_remove(self,payload):
messageID = 874997842748506112
if messageID == payload.message_id:
guild = await(self.client.fetch_guild(payload.guild_id))
emoji = payload.emoji.name
if emoji == '❤️':
role = discord.utils.get(guild.roles, name="Red")
elif emoji == '💛':
role = discord.utils.get(guild.roles, name="Yellow")
member = await(guild.fetch_member(payload.user_id))
if member is not None:
await member.remove_roles(role)
else:
print("Member not found")
#commands.command()
async def Modulo_AutoRole(self, ctx):
embed = discord.Embed(
title="Title",
description="Description",
color=0x1abc9c
)
msg = await ctx.send(embed=embed)
await msg.add_reaction('❤️')
await msg.add_reaction('💛')
def setup(client):
client.add_cog(AutoRole(client))
If you want the bot to remove the reaction from the message after their role has been assigned to them you add something like this to your code in on_raw_reaction_add after you assign the role.
msg = await self.bot.get_channel(payload.channel_id).fetch_message(payload.message_id)
await msg.remove_reaction(reaction, payload.member)
However because you want the emoji counter to stay at 1 (just the bot), you won't be able to have on_raw_reaction_remove. I'd make the on_raw_reaction_add method check the payload.member has the role, add it if they don't, and remove it if they do, then remove the reaction. Also another thing, while this isn't required, it's recommend to check the reaction was added by a bot (payload.member.bot)
Right after you get the role role = discord.utils.get(guild.roles, name="Red"), check if the user has the role like this:
role = discord.utils.get(guild.roles, name="Red")
has_role = False
for user_role in payload.member.roles:
if role.id == user_role.id:
has_role = True
if has_role:
await payload.member.remove_roles(role)
else:
await payload.member.add_roles(role)
The code above goes through all the roles the member has and checks if they have the role (has_role).
If they don't have the role (has_role is False), then the bot adds the role.
If they do have the role (has_role is True), then the bot removes the role from the Member.
Im making a command where a user can create and delete a private voice channel. For the part where i want to add or delete a channel it wants me to add a variable. I need it to delete the voice channel the user is in. Than you in advance
Code:
client.command()
async def room(ctx, activity=None, *, member : discord.Member = None):
if activity == "STREAMING".lower():
guild = ctx.guild
user = ctx.author
await guild.create_voice_channel(f"Streaming Room - {user}")
await ctx.send("Created streaming room!")
elif activity == "RECORDING".lower():
guild = ctx.guild
user = ctx.author
channel = await guild.create_voice_channel(f"Recording Room - {user}")
everyone = ctx.message.author.guild.default_role
disallow = discord.PermissionOverwrite()
disallow.read_messages = False
disallow.send_messages = False
await channel.set_permissions(everyone, overwrite=disallow)
await ctx.send("Created recording room!")
elif activity == 'ADD'.lower():
await ctx.send(f"{member.mention} has been added to your room")
allow = discord.PermissionOverwrite()
allow.connect = True
allow.speak = True
await channel.set_permissions(member, overwrite=allow)
else:
await ctx.send('Please specify what activity you would like to be doing [streaming, recording]')
General command for the task:
#client.command()
async def delvc(ctx, member: discord.Member):
vc = member.voice.channel
if vc:
await vc.delete()
await ctx.send(f"{member.name}'s voice channel - `{vc.name}` - was deleted!")
else:
await ctx.send(f"{member.name} isn't in a voice channel at the moment.")
References:
Member.voice
discord.VoiceChannel
VoiceChannel.delete()
I was trying to make an reaction menu to give roles, so far its working, but the problem is when I do the command !lol #[person here] and react to it, it adds the roles to the author (me) and not the user that I mentioned, please help
My Code is
import discord
#import secreto
import asyncio
from discord.utils import get
from discord.ext import commands
client = commands.Bot(command_prefix='!')
COR =0x690FC3
msg_id = None
msg_user = None
#client.event
async def on_ready():
print('BOT ONLINE!')
print(client.user.name)
print(client.user.id)
#client.command(pass_context=True)
async def lol(ctx, user = discord.Member):
message = ctx.message
embed1 =discord.Embed(title=f"Choose {user.name}'s rank", color=COR, description="🍍 - Pineapple\n🍎 - Apple\n🍉 - Watermellon")
botmsg = await client.send_message(message.channel, embed=embed1)
await client.add_reaction(botmsg, "🍍")
await client.add_reaction(botmsg, "🍎")
await client.add_reaction(botmsg, "🍉")
global msg_id
msg_id = botmsg.id
global msg_author
msg_author = message.author
global msg_user
msg_user = user
#client.event
async def on_reaction_add(reaction, user):
msg = reaction.message
if reaction.emoji == "🍍" and msg.id == msg_id: # and user == msg_user:
role = discord.utils.get(user.server.roles, name="Bronze")
await client.add_roles(user, role)
print("add" + user.name)
if reaction.emoji == "🍎" and msg.id == msg_id:
role = discord.utils.get(user.server.roles, name="Prata")
await client.add_roles(user, role)
print("add")
if reaction.emoji == "🍉" and msg.id == msg_id:
role = discord.utils.get(user.server.roles, name="Ouro")
await client.add_roles(user, role)
print("add")
user in on_reaction_add(reaction, user) is always the user who reacted to the message. What you need is mentioned_user = message.mentions[0] to get the user mentioned in your message and give him the according role.