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])
- Sending Modals through Application Commands
- Sending Modals through UI Components
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 interaction
parameter we define in UI Components receives an Interaction
object. The response
attribute of the object contains an InteractionResponse
object, with various coroutines such as send_message()
and send_modal()
, which we utilize.
class MyView(discord.ui.View):
@discord.ui.button(label="Send Modal")
async def button_callback(self, button, interaction):
await interaction.response.send_modal(MyModal(title="Modal via Button"))
@bot.slash_command()
async def send_modal(ctx):
await ctx.respond(view=MyView())
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:
short
singleline
paragraph = 2
multiline = 2
long = 2