Skip to content

Instantly share code, notes, and snippets.

@thegamecracks
Last active February 8, 2025 03:58
Show Gist options
  • Select an option

  • Save thegamecracks/a7d824d2a0a890b01ea982fc89ba33f7 to your computer and use it in GitHub Desktop.

Select an option

Save thegamecracks/a7d824d2a0a890b01ea982fc89ba33f7 to your computer and use it in GitHub Desktop.
Structuring multiple prompts with discord.py message components
import datetime
import discord
from discord import app_commands
from discord.ext import commands
bot = commands.Bot(".", intents=discord.Intents.default())
@bot.command()
@commands.is_owner()
async def sync(ctx: commands.Context):
await bot.tree.sync()
await ctx.send("Synced!")
@bot.tree.command(description="Resolve a case.")
@app_commands.describe(case="The case code to be resolved.")
@app_commands.rename(case="case-code")
async def resolve(interaction: discord.Interaction, case: str):
view = ResolveCaseValidView(case)
await interaction.response.send_message(
f"Was case {case} valid?",
ephemeral=True,
view=view,
)
@resolve.autocomplete("case")
async def resolve_autocomplete_case(interaction: discord.Interaction, case: str):
return [app_commands.Choice(name="abcd-1234", value="abcd-1234")]
class ResolveCaseValidView(discord.ui.View):
def __init__(self, case: str):
super().__init__()
self.case = case
@discord.ui.button(label="Yes", style=discord.ButtonStyle.green)
async def yes(self, interaction: discord.Interaction, button: discord.ui.Button):
view = ResolveCasePunishmentView(self.case)
await interaction.response.edit_message(
content="What punishment should be applied?",
view=view,
)
@discord.ui.button(label="No", style=discord.ButtonStyle.red)
async def no(self, interaction: discord.Interaction, button: discord.ui.Button):
view = ResolveCaseCommentView(self.case, valid=False, punishment=None)
await interaction.response.edit_message(
content="Would you like to add any comments?",
view=view,
)
class ResolveCasePunishmentView(discord.ui.View):
def __init__(self, case: str):
super().__init__()
self.case = case
@discord.ui.select(
options=[
discord.SelectOption(label="Flag", emoji="🚩"),
discord.SelectOption(label="Kick", emoji="🥾"),
discord.SelectOption(label="Ban", emoji="🔨"),
]
)
async def punish(self, interaction: discord.Interaction, select: discord.ui.Select):
if select.values[0] == "Flag":
view = ResolveCaseCommentView(
self.case, valid=True, punishment=FlagPunishment()
)
await interaction.response.edit_message(
content="Would you like to add any comments?",
view=view,
)
elif select.values[0] == "Kick":
view = ResolveCaseCommentView(
self.case, valid=True, punishment=KickPunishment()
)
await interaction.response.edit_message(
content="Would you like to add any comments?",
view=view,
)
elif select.values[0] == "Ban":
view = ResolveCaseBanDurationView(self.case)
await interaction.response.edit_message(
content="How long should the ban last?",
view=view,
)
else:
raise RuntimeError(f"Invalid value {select.values[0]}")
@discord.ui.button(label="Skip")
async def skip(self, interaction: discord.Interaction, button: discord.ui.Button):
view = ResolveCaseCommentView(self.case, valid=True, punishment=None)
await interaction.response.edit_message(
content="Would you like to add any comments?",
view=view,
)
class Punishment: ...
class FlagPunishment(Punishment):
def __str__(self) -> str:
return "Flag"
class KickPunishment(Punishment):
def __str__(self) -> str:
return "Kick"
class BanPunishment(Punishment):
def __init__(self, duration: datetime.timedelta | None):
self.duration = duration
def __str__(self) -> str:
if self.duration is not None:
return f"Temporary ban for {self.duration}"
return "Permanent ban"
class ResolveCaseBanDurationView(discord.ui.View):
def __init__(self, case: str):
super().__init__()
self.case = case
@discord.ui.select(
options=[
discord.SelectOption(label="1 day", value="86400"),
discord.SelectOption(label="3 days", value="259200"),
discord.SelectOption(label="7 days", value="604800"),
discord.SelectOption(label="30 days", value="2592000"),
discord.SelectOption(label="Permanent", value="0"),
]
)
async def duration(
self, interaction: discord.Interaction, select: discord.ui.Select
):
seconds = int(select.values[0])
duration = datetime.timedelta(seconds=seconds) if seconds > 0 else None
punishment = BanPunishment(duration)
view = ResolveCaseCommentView(self.case, valid=True, punishment=punishment)
await interaction.response.edit_message(
content="Would you like to add any comments?",
view=view,
)
class ResolveCaseCommentView(discord.ui.View):
def __init__(self, case: str, valid: bool, punishment: Punishment | None):
super().__init__()
self.case = case
self.valid = valid
self.punishment = punishment
@discord.ui.button(label="Add Comment", style=discord.ButtonStyle.primary)
async def add(self, interaction: discord.Interaction, button: discord.ui.Button):
modal = ResolveCaseCommentModal(
self.case, valid=self.valid, punishment=self.punishment
)
await interaction.response.send_modal(modal)
await modal.wait()
@discord.ui.button(label="Skip")
async def skip(self, interaction: discord.Interaction, button: discord.ui.Button):
await resolve_case(
interaction,
case=self.case,
valid=self.valid,
punishment=self.punishment,
comment="",
)
class ResolveCaseCommentModal(discord.ui.Modal, title="Add Comment"):
comment = discord.ui.TextInput(
label="Comment",
placeholder="Insert comment here",
style=discord.TextStyle.paragraph,
)
def __init__(self, case: str, valid: bool, punishment: Punishment | None):
super().__init__()
self.case = case
self.valid = valid
self.punishment = punishment
async def on_submit(self, interaction: discord.Interaction):
await resolve_case(
interaction,
case=self.case,
valid=self.valid,
punishment=self.punishment,
comment=self.comment.value,
)
async def resolve_case(
interaction: discord.Interaction,
case: str,
valid: bool,
punishment: Punishment | None,
comment: str,
):
content = (
f"Resolved case {case}!\n"
f"\n"
f"Valid: {valid}\n"
f"Punishment: {punishment}\n"
f"Comment: {comment or '<no comment>'}\n"
)
await interaction.response.edit_message(content=content, view=None)
bot.run("token")
@thegamecracks
Copy link
Author

2025-02-07.22-16-34.mp4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment