Skip to main content

Confirmation modal

Construct a view with an input and submit button. Opening it requires a genuine interaction trigger ID; processing the submission belongs to your application.

Output

Local preview of the selected language’s tested example. Slack client appearance may differ; controls here do not send requests.

Serialized output
{
"type": "modal",
"blocks": [
{
"type": "section",
"block_id": "<generated-block-id>",
"text": {
"type": "mrkdwn",
"text": ":warning: This will permanently delete *production*."
}
},
{
"type": "input",
"block_id": "confirmation",
"label": {
"type": "plain_text",
"text": "Type the name to confirm"
},
"element": {
"type": "plain_text_input",
"action_id": "confirmation_text",
"placeholder": {
"type": "plain_text",
"text": "production"
}
}
}
],
"private_metadata": "production",
"callback_id": "confirm_delete",
"title": {
"type": "plain_text",
"text": "Confirm deletion"
},
"close": {
"type": "plain_text",
"text": "Cancel"
},
"submit": {
"type": "plain_text",
"text": "Delete"
}
}

Code​

Pass the constructed modal to views.open with an interaction trigger ID. The example only constructs the view; it makes no Slack request.

from slackblocks import (
InputBlock,
Modal,
PlainTextInput,
SectionBlock,
)


def confirmation_modal(target: str) -> Modal:
modal = Modal(
title="Confirm deletion",
submit="Delete",
close="Cancel",
callback_id="confirm_delete",
private_metadata=target, # round-tripped back to your handler on submit
blocks=[
SectionBlock(f":warning: This will permanently delete *{target}*."),
InputBlock(
label="Type the name to confirm",
element=PlainTextInput(
action_id="confirmation_text",
placeholder=target,
),
block_id="confirmation",
),
],
)

return modal

print(confirmation_modal("production").json())