Is it possible for the list of choices of a SlashOption to depend on the value the user entered for the prior SlashOption? [nextcord.py][python 3.10]

Viewed 48

Let's assume there's a slash command /selectappointment you can use to make an appointment somewhere. As inputs we need: Year of appointment, Month of appointment (other parameters skipped for simplicity sake)

@client.slash_command()
async def selectappointment(interaction: nextcord.Interaction):

Now, we add a SlashOption + choices to only accept the current or next year as an input:

@client.slash_command()
async def selectappointment(interaction: nextcord.Interaction,
                            year: int = nextcord.SlashOption(name='year',
                                                             choices={'2022':2022, '2023':2023})):

Next, we want to add a 'month' SlashOption + choices. (Assume MONTHS = {'January':1, 'February':2} etc.)

@client.slash_command()
async def selectappointment(interaction: nextcord.Interaction,
                            year: int = nextcord.SlashOption(name='year',
                                                             choices={'2022':2022, '2023':2023}),
                            month: int = nextcord.SlashOption(name='month',
                                                              choices={MONTHS})):

This is where the problem occurs. There are twelve months/year. Say the person using the command selected '2022' as the year of the appoinment, but they still can select, let's say, February, although it is August already. It makes no sense to allow inputs to book appointments in the past.

That's where my question comes in: Is it possible that, in case the user selected 2022, the month parameter only displays the choices August-December? Is there something like 'dynamic slashOptions', based on the user's prior selection from the list of choices?

1 Answers

Unfortunately, the command choices must be hard-coded as part of the command sent to Discord, so can't be changed dynamically.

You can, however, use autocomplete for this purpose and show only the options relevant to their input.

Note that this does allow the user to submit text that is not a valid choice, so you may want to handle that in the command.

Also note that Discord does not force users to fill out options in a specific order, so they could fill out the month before choosing the year.

def valid_months(year: Optional[int]) -> List[str]:
    """Return a list of valid months for a given year."""
    months = [
        "January",
        "February",
        "March",
        "April",
        "May",
        "June",
        "July",
        "August",
        "September",
        "October",
        "November",
        "December",
    ]
    if year:
        now = datetime.now()
        if now.year == year:
            months = months[now.month - 1 :]
    return months


@client.slash_command()
async def selectappointment(
    interaction: nextcord.Interaction,
    *,
    year: int = nextcord.SlashOption(choices=[2022, 2023]),
    month: str,
):
    if month not in valid_months(year):
        await interaction.send("Please select a valid month", ephemeral=True)
    await interaction.response.send_message(f"Your selected year is {year} and month is {month}")


@selectappointment.on_autocomplete("month")
async def autocomplete_month(interaction: Interaction, month: str, year: Optional[int] = None):
    filtered_months = valid_months(year)
    if month:
        filtered_months = [m for m in filtered_months if m.lower().startswith(month.lower())]
    await interaction.response.send_autocomplete(filtered_months)
Related