Partially Finished Product So, essentially, I am trying to create a discord bot that will allow a staff member to request a role. That request will then be sent to an admin-only text channel with a button for approve and a button for decline. The part that I am stuck on is getting the bot to automatically add the role when the Approve button is pressed.
My code so far:
class Request(discord.ui.View):
def __init__(self):
super().__init__()
self.value = None
@discord.ui.button(label = 'Approve', style = discord.ButtonStyle.green, disabled=False, custom_id='Approve')
async def approve(self, interaction: discord.Interaction, button: discord.ui.Button):
member = interaction.user
approve_embed = discord.Embed(title='Request Approved!', description=f'Approved by {member.mention}')
button.style=discord.ButtonStyle.gray
await interaction.response.edit_message(embed = approve_embed, view=self)
self.value = True
self.stop()
@discord.ui.button(label = 'Decline', style = discord.ButtonStyle.red, disabled=False, custom_id='Decline')
async def decline(self, interaction: discord.Interaction, button: discord.ui.Button):
member = interaction.user
button.style=discord.ButtonStyle.gray
decline_embed = discord.Embed(title='Request Declined!', description=f'Declined by {member.mention}')
await interaction.response.edit_message(embed=decline_embed, view=self)
self.value = True
self.stop()
@client.command()
@commands.has_any_role('Mod', '1253697387051094136')
async def roleadd(ctx, role: discord.Role, user: discord.Member):
channel = client.get_channel(1253704722544853185)
view = Request()
await channel.send(f'**New Role Request!** \n {ctx.author.mention} requested to give {role.mention} to {user.mention}', view=view)
await ctx.reply('*Your request has been submitted*')
You can pass the context from the command to the callback by passing information through the view's arguments. In the Request view define one argument for the user whom you want to give the role and another one for the role itself and set both the arguments as the view's attributes. You can then use this in the callback function to do your desired actions.
Here is your reformed code:
class Request(discord.ui.View):
def __init__(self, user_to_give_role: discord.Member, role_to_give: discord.Role):
super().__init__()
self.value = None
self.user_to_give_role = user_to_give_role
self.role_to_give = role_to_give
@discord.ui.button(label='Approve', style=discord.ButtonStyle.green, disabled=False, custom_id='Approve')
async def approve(self, button: discord.Button, interaction: discord.Interaction):
member = interaction.user
approve_embed = discord.Embed(
title='Request Approved!', description=f'Approved by {member.mention}')
button.style = discord.ButtonStyle.gray
await interaction.response.edit_message(embed=approve_embed, view=self)
await self.user_to_give_role.add_roles(self.role_to_give)
self.value = True
self.stop()
@discord.ui.button(label='Decline', style=discord.ButtonStyle.red, disabled=False, custom_id='Decline')
async def decline(self, button: discord.Button, interaction: discord.Interaction):
member = interaction.user
button.style = discord.ButtonStyle.gray
decline_embed = discord.Embed(
title='Request Declined!', description=f'Declined by {member.mention}')
await interaction.response.edit_message(embed=decline_embed, view=self)
self.value = True
self.stop()
@client.command()
@commands.has_any_role('Mod', '1253697387051094136')
async def roleadd(ctx, role: discord.Role, user: discord.Member):
channel = client.get_channel(1253704722544853185)
view = Request(user_to_give_role=user, role_to_give=role)
await channel.send(f'**New Role Request!** \n {ctx.author.mention} requested to give {role.mention} to {user.mention}', view=view)
await ctx.reply('*Your request has been submitted*')