These docs describe an outmoded approach to composing messages and interactive experiences. Learn how to more effectively communicate and help folks get work done by our new documentation and transitioning to "blocks".

Legacy: Attaching interactive message buttons

Simplify complex workflows and empower users to take decisive action by adding interactive buttons to your messages. Make your notifications, slash commands, and bot users more intuitive with progressively evolving responses. All you need is a Slack app.

An approval workflow powered by message buttons

Want to build rich interactions like this? Let's cover everything you need to know.

Overview

For an overview of how interactive messages work, message buttons included, see interactive messages. Everything that follows builds on the interactive message framework. And, yes, buttons can be delightfully combined with message menus.

Crafting messages with buttons

You'll be building messages that contain attachments and attachment actions. You may want to review how basic message formatting and message attachments typically work.

Interactive messages are made up of building blocks that can be combined, modified, and removed based on your server's responses to create interactive experiences.

Here's a message with buttons containing values for the most important fields you'll use when composing interactive messages. Your messages may get more complex than this, and we'll dive into a more complex example later.

An interactive message containing a list of games to play

This message has some light text, three specific buttons, including one that looks like a destructive action.

Here's the JSON used to compose this message:

{
    "text": "Would you like to play a game?",
    "attachments": [
        {
            "text": "Choose a game to play",
            "fallback": "You are unable to choose a game",
            "callback_id": "wopr_game",
            "color": "#3AA3E3",
            "attachment_type": "default",
            "actions": [
                {
                    "name": "game",
                    "text": "Chess",
                    "type": "button",
                    "value": "chess"
                },
                {
                    "name": "game",
                    "text": "Falken's Maze",
                    "type": "button",
                    "value": "maze"
                },
                {
                    "name": "game",
                    "text": "Thermonuclear War",
                    "style": "danger",
                    "type": "button",
                    "value": "war",
                    "confirm": {
                        "title": "Are you sure?",
                        "text": "Wouldn't you prefer a good game of chess?",
                        "ok_text": "Yes",
                        "dismiss_text": "No"
                    }
                }
            ]
        }
    ]
}

To identify a few key parts of this message, besides just the presentation:

If this message appeared within a channel or direct message, and a user clicked on Chess, your registered action URL would receive a payload of JSON identifying the specific set of message buttons:

  • the callback_id you set when creating the message. The callback_id is required. Without it, Slack can't show your app which message a user has interacted with.
  • the specific name of the clicked button
  • and the corresponding value of that same clicked button

For a comprehensive accounting of all the fields related to interactive messages, please consult the dedicated field guide.

If curious about other formatting opportunities, check out our formatting guide and these details on attaching content to messages.


Here's another example to consider from a local comic book shop that uses Slack for team collaboration:

For a message that looks like this: Looks like a great comic book is back in stock and it's time to ask employees what they think

Use JSON like this:

{
    "text": "New comic book alert!",
    "attachments": [
        {
            "title": "The Further Adventures of Slackbot",
            "fields": [
                {
                    "title": "Volume",
                    "value": "1",
                    "short": true
                },
                {
                    "title": "Issue",
                    "value": "3",
            "short": true
                }
            ],
            "author_name": "Stanford S. Strickland",
            "author_icon": "http://a.slack-edge.com/7f18https://a.slack-edge.com/80588/img/api/homepage_custom_integrations-2x.png",
            "image_url": "http://i.imgur.com/OJkaVOI.jpg?1"
        },
        {
            "title": "Synopsis",
            "text": "After @episod pushed exciting changes to a devious new branch back in Issue 1, Slackbot notifies @don about an unexpected deploy..."
        },
        {
            "fallback": "Would you recommend it to customers?",
            "title": "Would you recommend it to customers?",
            "callback_id": "comic_1234_xyz",
            "color": "#3AA3E3",
            "attachment_type": "default",
            "actions": [
                {
                    "name": "recommend",
                    "text": "Recommend",
                    "type": "button",
                    "value": "recommend"
                },
                {
                    "name": "no",
                    "text": "No",
                    "type": "button",
                    "value": "bad"
                }
            ]
        }
    ]
}

Responding to message actions

The time has come for your application to respond to a message action.

Your Action URL will receive a HTTP POST request, including a payload body parameter, itself containing an application/x-www-form-urlencoded JSON string.

Here's an example invocation you may receive for the comic book recommendation example above:

{
  "type": "interactive_message",
  "actions": [
    {
      "name": "recommend",
      "value": "recommend",
      "type": "button"
    }
  ],
  "callback_id": "comic_1234_xyz",
  "team": {
    "id": "T123ABC456",
    "domain": "watermelonsugar"
  },
  "channel": {
    "id": "C123ABC456",
    "name": "forgotten-works"
  },
  "user": {
    "id": "U123ABC456",
    "name": "brautigan"
  },
  "action_ts": "1458170917.164398",
  "message_ts": "1458170866.000004",
  "attachment_id": "1",
  "token": "xAB3yVzGS4BQ3O9FACTa8Ho4",
  "original_message": {"text":"New comic book alert!","attachments":[{"title":"The Further Adventures of Slackbot","fields":[{"title":"Volume","value":"1","short":true},{"title":"Issue","value":"3","short":true}],"author_name":"Stanford S. Strickland","author_icon":"https://api.slack.comhttps://a.slack-edge.com/80588/img/api/homepage_custom_integrations-2x.png","image_url":"http://i.imgur.com/OJkaVOI.jpg?1"},{"title":"Synopsis","text":"After @episod pushed exciting changes to a devious new branch back in Issue 1, Slackbot notifies @don about an unexpected deploy..."},{"fallback":"Would you recommend it to customers?","title":"Would you recommend it to customers?","callback_id":"comic_1234_xyz","color":"#3AA3E3","attachment_type":"default","actions":[{"name":"recommend","text":"Recommend","type":"button","value":"recommend"},{"name":"no","text":"No","type":"button","value":"bad"}]}]},
  "response_url": "https://hooks.slack.com/actions/T47563693/6204672533/x7ZLaiVMoECAW50Gw1ZYAXEM",
  "trigger_id": "13345224609.738474920.8088930838d88f008e0"
}

Once you receive this payload, it's up to your app to decide what to do next. It might trigger some incredible event like making sure someone gets paid or it might just mean it's time to ask further clarifying questions. Maybe the next message you attach won't have a button but a message menu instead.


At this point, there's nothing special about message buttons that isn't also true of message menus and any interactive message.

See responding to message actions to continue learning about the interactive message lifecycle.