Menu tools

This module holds functions for displaying different kinds of menus. All menus are reaction based.

class dpytools.menus.TextMenu(*, lock: Optional[Union[discord.member.Member, discord.role.Role, bool]] = True, stop: str = 'cancel', timeout: int = 60, cleanup: bool = False, retry_parse_fail: bool = False)

Constructs the menu instance

Parameters
  • lock (Union[discord.Member, discord.Role, bool, None]) –

    • If True (default)
      • the menu will only listen for the author’s reactions.

    • If False
      • ANY user can react to the menu

    • If member
      • Only target member will be able to react

    • If role
      • ANY user with target role will be able to react.

  • stop (str (Default ‘cancel’)) – If the users passes this string in the message content the menu will end, clean up and return False

  • timeout (int (Default 60)) – The amount of time to wait for each question. If a timeout is reached, the menu is cancelled and cleaned up and returns None

  • cleanup (bool (Default True)) – Whether to clean up messages or not

Note

If the users response matches the stop parameter the menu will return an explicit False

If timeout occurs however return value will be None

This way you can differentiate the output reasons

add_question(*, question: Optional[str] = None, embed: Optional[discord.embeds.Embed] = None, parser: Optional[Union[discord.ext.commands.converter.Converter, Callable]] = None, parse_fail_response: Optional[str] = None, parse_fail_embed: Optional[discord.embeds.Embed] = None)

Adds a question to the menu

Parameters
  • question (str) – The bot’s question’s text to display

  • embed (discord.Embed) – An embed to send with the question

  • parser (Union[Converter, Callable, None]) –

    • A function that takes a single string argument and returns something else

      The function will be passed the user’s message.content

    • Or a discord.ext.commands.Converter

      Which will be given the same string and context from the command

  • parse_fail_response (Optional[str]) – If the parser raises an exception and TextMenu .retry_parse_fail is enabled message content will be this

  • parse_fail_embed (Optional[discord.Embed]) – If the parser raises an exception and TextMenu .retry_parse_fail is enabled message embed will be this

Warning

Either question or embed are required. If you dont pass any ValueError will be raised

await call(ctx: discord.ext.commands.context.Context)

Activates the menu

Displays the menu one question at the time. The user can cancel the menu using the :param stop: passed in the constructor The menu will only listen for messages that pass the base lock An attepmpt to clear all menu messages will be made with errors excepted silently

Returns

Returns the list of answers from the user processed by the optional parser

The menu will return None if a TimeoutError occurs.

Return type

Optional[List[Any]]

Raises

Any – This menu will raise any exception derived from parsers

await dpytools.menus.arrows(ctx: discord.ext.commands.context.Context, embed_list: List[discord.embeds.Embed], content: Optional[str] = None, head: int = 0, timeout: int = 30, closed_embed: Optional[discord.embeds.Embed] = None, channel: Optional[discord.abc.Messageable] = None)

Sends multiple embeds with a reaction navigation menu.

Parameters
  • ctx (discord.ext.commands.Context) – The context where this function is called.

  • embed_list (List[Embed]) – An ordered list containing the embeds to be sent.

  • content (str) – A static string. This wont change with pagination. It will be cleared when its closed, but will persist on pause

  • head (int) – The index in embed_list of the first Embed to be displayed.

  • timeout (int (seconds)) – The time before the bot closes the menu. This is reset with each interaction.

  • closed_embed (Optional[Embed]) – The embed to be displayed when the user closes the menu. Defaults to plain embed with “Closed by user” in description

  • channel (discord.abc.Messageable) – The channel to be used for displaying the menu, defaults to ctx.channel.

Example

from dpytools.menus import arrows
@bot.command()
async def test(ctx):
    embed_list = [Embed(...), Embed(...), ...)
    await arrows(ctx, embed_list)
await dpytools.menus.confirm(ctx: discord.ext.commands.context.Context, msg: discord.message.Message, lock: Optional[Union[discord.member.Member, discord.role.Role, bool]] = True, timeout: int = 30)Optional[bool]

Helps to create a reaction menu to confirm an action.

Parameters
  • ctx (discord.ext.commands.Context) – the context for the menu

  • msg (Message) – the message to confirm or deny by the user.

  • lock (Union[discord.Member, discord.Role, bool, None]) –

    • True (default)
      • the menu will only listen for the author’s reactions.

    • False
      • ANY user can react to the menu

    • discord.Member
      • Only target member will be able to react

    • discord.Role
      • ANY user with target role will be able to react.

  • timeout (:class:ìnt` (seconds)) – Timeout before the menu closes.

Returns

  • True if the message was confirmed

  • False if it was denied

  • None if timeout

Return type

Optional[bool]

Example

from dpytools.menus import confirm
@bot.command()
async def test(ctx):
    msg = await ctx.send('Please confirm to this important message')
    confirmation = await confirm(ctx, msg)
    if confirmation:
        await msg.edit(content='Confirmed')
    elif confirmation is False:
        await msg.edit(content='Cancelled')
    else:
        await msg.edit(content='Timeout')
await dpytools.menus.multichoice(ctx: discord.ext.commands.context.Context, options: List[str], timeout: int = 60, base_embed: discord.embeds.Embed = <discord.embeds.Embed object>)Optional[str]

Takes a list of strings and creates a selection menu. ctx.author will select and item and the function will return it.

Parameters
  • ctx (Context) – The command’s context

  • options (List[str]) – List of strings that the user must select from

  • timeout (:class:ìnt` (seconds)) – Timeout before the menu closes.

  • base_embed (Optional[discord.Embed]) –

    An optional embed object to take as a blueprint.
    • The menu will only modify the footer and description.

    • All other fields are free to be set by you.

Example

from dpytools.menus import multichoice
@bot.command()
async def test(ctx):
    options = [str(uuid4()) + for _ in range(110)]
    choice = await multichoice(ctx, options)
    await ctx.send(f'You selected: {choice}')
Returns

The item selected by the user.

Return type

str

await dpytools.menus.try_clear_reactions(msg)

helper function to remove reactions excepting forbidden either by context being a dm_channel or bot lacking perms