Skip to main content

Show Modal

Instead of creating a message response you can also show a modal to the user to ask for further information. Modals can have a number of inputs which you can then access using the input(...) variables once the modal has been submitted.

Components​

A modal can hold up to 5 components, and at least one of them has to be an input.

  • Input: a label, an optional description below it, and one input. Every input has an identifier that you read its answer with, e.g. {{input('color')}}.
  • Text: markdown text shown between the inputs, e.g. to explain the form.

These inputs are available:

InputAnswer
Text InputThe entered text. Can be a single line or a paragraph.
Select MenuThe values of the picked options.
User SelectThe IDs of the picked members.
Role SelectThe IDs of the picked roles.
Mentionable SelectThe IDs of the picked members or roles.
Channel SelectThe IDs of the picked channels. You can limit it to channel types.
Radio GroupThe value of the picked option. Needs 2 to 10 options.
Checkbox GroupThe values of the picked options. Needs 1 to 10 options.
Checkboxtrue if it was checked, otherwise false.
File UploadThe IDs of the uploaded files. Up to 10 files.

An option without a value returns its label. Select menus let one option be picked unless you raise Max Picks, and checkbox groups allow all of their options. When several are picked, input(...) returns the first one, like interaction.value of a select menu in a message. inputs(...) returns all of them as a list:

ExampleResult if red and blue were picked
{{'red' in inputs('colors')}}true
{{len(inputs('colors'))}}2
{{join(inputs('colors'), ', ')}}red, blue

inputs(...) works for every input. For a text input, radio group or checkbox it returns a list with the one value.

Inputs that aren't required can be left empty, in which case input(...) returns an empty text and inputs(...) an empty list.

For user, role, mentionable and channel selects, picked(...) returns the picked member, role or channel instead of its ID, and pickedAll(...) all of them as a list. Their fields work like those of user, a role or channel:

ExampleResult
{{picked('reported').display_name}}The display name of the picked member
{{picked('reported')}}A mention of the picked member
{{join(map(pickedAll('roles'), #.name), ', ')}}The names of the picked roles

File Uploads​

A file upload lets the user upload files, like images or screenshots, when submitting the modal. It allows one file unless you raise Max Files, up to 10. input(...) returns the ID of the first file, and picked(...) the file itself, with its url, proxy_url, filename, content_type and size in bytes. On its own it shows as its URL. pickedAll(...) returns all files as a list:

ExampleResult
{{picked('image')}}https://cdn.discordapp.com/ephemeral-attachments/...
{{picked('image').content_type}}image/png
{{len(pickedAll('screenshots'))}}3
{{join(map(pickedAll('screenshots'), #.url), '\n')}}The URL of every file, one per line

You can put the URL in an embed's image to show an uploaded image, or in a message to share the file. Discord doesn't limit which kinds of files can be uploaded, so check content_type if you need an image.

warning

Uploaded files are temporary. Discord deletes them after a while, so the URLs stop working. Use them in the flow right after the modal is submitted instead of storing them in a variable for later.

Responding with a modal starts a sub-flow which is suspended until the user submits the modal. See Sub-Flows for more information on how modals work.

tip

The answers stay available as input(...), inputs(...), picked(...) and pickedAll(...) even after later buttons or modals. Command arguments keep working with arg(...) below the modal too.

Loading...