Using modal components
A modal is a form that opens in front of the member in answer to a command or a component press. It is how you ask for more than a slash command's options can hold: a paragraph of text, several fields at once.
Opening a modal
Answer the interaction with type 9:
Open a formJSON
json
{
"type": 9,
"data": {
"custom_id": "feedback",
"title": "Tell us what you think",
"components": [
{
"type": 1,
"components": [{
"type": 4, "custom_id": "subject", "label": "Subject",
"style": 1, "min_length": 3, "max_length": 60
}]
},
{
"type": 1,
"components": [{
"type": 4, "custom_id": "body", "label": "Your words",
"style": 2, "required": false, "placeholder": "Anything at all"
}]
}
]
}
}| Field | |
|---|---|
custom_id | 1 to 100 characters |
title | Up to 45 characters |
components | 1 to 5 rows (or labels, see below) |
A modal can only be opened in answer to a command or a component interaction, not to a form.
Text inputs
| Field | |
|---|---|
type | 4 |
custom_id | Unique in the form |
label | Up to 45 characters (in the row layout) |
style | 1 a line, 2 a paragraph |
min_length | 0 to 4000 |
max_length | 1 to 4000 (default 4000) |
required | Default true |
value | Prefilled text |
placeholder | Up to 100 characters |
Two layouts
Moymo accepts both layouts that bots are written for, and sends the answer back in the one you used:
- Rows (older): each input in a row,
{ "type": 1, "components": [ <text input with a label> ] }. - Labels (newer): each input or menu in a label,
{ "type": 18, "label": "Favourite", "description": "optional", "component": <text input or string select> }. A string select (type 3) can sit in a label, so a form can have menus as well as text.
Do not mix the two in one form.
Receiving the form
When the member sends it you get an interaction of type 5:
What your endpoint receives (shortened)JSON
json
{
"type": 5,
"data": {
"custom_id": "feedback",
"components": [
{
"type": 1,
"components": [{ "type": 4, "custom_id": "subject", "value": "Great bot" }]
},
{
"type": 1,
"components": [{ "type": 4, "custom_id": "body", "value": "" }]
}
]
}
}In the label layout each entry is { "type": 18, "component": { "type": 4, "custom_id": "name", "value": "Ada" } }, and a menu is { "type": 3, "custom_id": "pick", "values": [ "hades" ] }.
Moymo has checked the answers against your form before you see them: required inputs are filled, lengths are within min_length and max_length, and menu values are among your options. A form is sent once; if you need it again, open it again. A form that is not sent within 15 minutes expires.
Answer it as any interaction: a message (4), a deferred message (5), or, if the form came from a button, an update of the message (7).
Tips
- Keep forms short: every field is a reason to give up.
- Use
placeholderto show the format you expect, andrequired: falsefor what is optional. - A form has no way to show an error beside a field: answer with an ephemeral message (
flags: 64) and open the form again with the earlier text invalue.