Skip to main content

Modal Dialogs

Modal Dialogs, also known as "modals", provide a form-like structure for bots to receive input from users. No extra permissions are needed for bots to send modal dialogs, so it becomes a convenient workaround for bots to receive longer input without needing the Message Content intent.

Concept

Modal Dialogs consist of a title, custom ID, and up to 5 discord.ui.InputText components. While creating modals, we generally subclass discord.ui.Modal, as we'll see later.

Unlike other UI Components, Modals cannot be sent with messages. They must be invoked by an Application Command or another UI Component.

Usage Syntax

class MyModal(discord.ui.Modal):
def __init__(self, *args, **kwargs) -> None:
super().__init__(*args, **kwargs)

self.add_item(discord.ui.InputText(label="Short Input"))
self.add_item(discord.ui.InputText(label="Long Input", style=discord.InputTextStyle.long))

async def callback(self, interaction: discord.Interaction):
embed = discord.Embed(title="Modal Results")
embed.add_field(name="Short Input", value=self.children[0].value)
embed.add_field(name="Long Input", value=self.children[1].value)
await interaction.response.send_message(embeds=[embed])

The ctx parameter we define in Application Commands receives an ApplicationContext object. Using its send_modal() coroutine, you can send a Modal dialog to the user invoking the Application Command.

@bot.slash_command()
async def modal_slash(ctx: discord.ApplicationContext):
"""Shows an example of a modal dialog being invoked from a slash command."""
modal = MyModal(title="Modal via Slash Command")
await ctx.send_modal(modal)

The above example uses an embed to display the results of the modal submission, but you can do anything you want with the text provided by the user. Each input field can be accessed in the order it was added to the modal dialog, via Modal.children.

Customization

A Modal can have up to 5 InputText fields. These fields offer some customization.

Each field has a label which is shown to the user. This is defined with label.

The style parameter is used to determine whether it should be a short (single-line) or long (multi-line) input field.

There are a number of aliases that can be used:

Single-line InputTextStyle values:
short
singleline
Multi-line InputTextStyle values:
paragraph = 2
multiline = 2
long = 2