I have two buttons which I want them both to be disabled on the original message it was clicked on after one of them has been clicked. Even better than just disabling them I would like them to be removed from the original message, but that isn't something I need.
My current code:
import discord
from discord.ext import commands
from discord.ui import Button, button, View
# Class
class MyView(View):
def __init__(self):
super().__init__(timeout=None)
@button(label="Hello!", style=discord.ButtonStyle.blurple)
async def hello(self, interaction: discord.Interaction, button: Button):
button.disabled=True
embedHelloButton=discord.Embed(title="Hi There!", color=0x5865F2)
embedHelloButton.set_author(name=f"Requested by {interaction.user.name}", icon_url=interaction.user.avatar.url)
await interaction.response.send_message(embed=embedHelloButton, ephemeral=False)
@button(label="No. Bye.", style=discord.ButtonStyle.red)
async def bye(self, interaction: discord.Interaction, button: Button):
button.disabled=True
embedByeButton=discord.Embed(title="Bye :(", color=0xff0000)
embedByeButton.set_author(name=f"Requested by {interaction.user.name}", icon_url=interaction.user.avatar.url)
await interaction.response.send_message(embed=embedByeButton, ephemeral=False)
# Command
@client.hybrid_command(name="hello", description="Say hello to the bot!")
async def hello(ctx):
embedHello=discord.Embed(title="Say hello to me!", color=0xff0000)
embedHello.set_author(name=f"Requested by {ctx.author.name}", icon_url=ctx.author.avatar.url)
await ctx.send(embed=embedHello, view=MyView())
My Output: The output of my code
The buttons on the first message are still clickable and I want the buttons to either be disabled on that first message or for them to be removed completely. Any solutions?
You could simply make these changes to your view class to disable both buttons
class MyView(View):
# do what you just did
@button(label="Hello!", style=discord.ButtonStyle.blurple)
async def hello(self, interaction: discord.Interaction, button: Button):
# do sth
# example to disable both buttons by clicking 'hello' button
button.disabled = True # disable the 'hello' button
bye_btn = discord.utils.get(self.children, label="No. Bye.") # get the 'bye' button
bye_btn.disabled = True
# send a msg or sth else
If you would like to remove all buttons, it is even easier than disabling buttons
class MyView(View):
@button(label="Hello!", style=discord.ButtonStyle.blurple)
async def hello(self, interaction: discord.Interaction, button: Button):
# do sth
await interaction.response.edit_message(view=None) # this will remove all the components in the class
And I would suggest changing your slash command slightly
@client.hybrid_command(name="hello", description="Say hello to the bot!")
async def hello(ctx):
# do your embed stuff
# the good way to do this is that you could access your message (in your view class) by 'self.message'
# because functions like 'on_timeout' does not have 'interaction' param.
view = MyView()
view.message = await ctx.send(embed=embedHello, view=view)
And just as a quick reminder, you could only respond to the interaction once to avoid triggering interaction responded exception. So, if you would like to send a message and edit the view, you can switch to followup
class MyView(View):
@button(label="Hello!", style=discord.ButtonStyle.blurple)
async def hello(self, interaction: discord.Interaction, button: Button):
await interaction.response.defer()
# do sth
await interaction.followup.send(content='...', ...) # send the message you want
await interaction.followup.edit_message(message_id=self.message.id, view=None) # message_id is mandatory here
Hope this would help.