Go to Slack

Creating interactive messages

Transform your Slack app into a powerful workflow partner by making messages interactive.

In this guide we'll walk through how app interactivity applies to messages, and show you how to build a Slack app capable of interacting with users via message.


App interactivity in messages

We've already discovered how you can create rich message layouts using Block Kit. Beyond providing these visual composition tools, Block Kit also contains a subset of components that enable interactivity.

These interactive components can be inserted into messages, converting them from simple information relays into powerful partners for users.

Where once your Slack app might have just pulled in data from external services, interactivity allows your app to manipulate, update, and send back data to that same service, thanks to user action.


Getting started with interactive messages

Before you continue, complete our guide to handling user interaction in your Slack app to ensure your app is ready for interactivity, and to give you familiarity with the general flow of user-triggered interactions.

For this guide, you'll need to have created a Slack app, though you won't need to have built it out with any features yet.

When you're ready, it's time to get started.

1. Compose your interactive message

We previously showed you how to compose rich message layouts.

Producing an interactive message simply involves including Block Kit interactive components in these message layouts.

Consider this example from the rich message layouts guide:

{
  "channel": "C1H9RESGL",
  "blocks": [
    {
      "type": "section",
      "text": {
        "type": "mrkdwn",
        "text": "Danny Torrence left the following review for your property:"
      }
    },
    {
      "type": "section",
      "block_id": "section567",
      "text": {
        "type": "mrkdwn",
        "text": "<https://google.com|Overlook Hotel> \n :star: \n Doors had too many axe holes, guest in room 237 was far too rowdy, whole place felt stuck in the 1920s."
      },
      "accessory": {
        "type": "image",
        "image_url": "https://is5-ssl.mzstatic.com/image/thumb/Purple3/v4/d3/72/5c/d3725c8f-c642-5d69-1904-aa36e4297885/source/256x256bb.jpg",
        "alt_text": "Haunted hotel image"
      }
    },
    {
      "type": "section",
      "block_id": "section789",
      "fields": [
        {
          "type": "mrkdwn",
          "text": "*Average Rating*\n1.0"
        }
      ]
    }
  ]
}

The example above is composed entirely of 'static' blocks: purely visual elements that do not offer any sort of interaction.

You can add interactive components into blocks, letting you publish messages with inline buttons, date picker widgets, and more.

Let's add an actions block that contains a button element to the previous message payload:

{
  "channel": "C1H9RESGL",
  "blocks": [
    {
      "type": "section",
      "text": {
        "type": "mrkdwn",
        "text": "Danny Torrence left the following review for your property:"
      }
    },
    {
      "type": "section",
      "block_id": "section567",
      "text": {
        "type": "mrkdwn",
        "text": "<https://google.com|Overlook Hotel> \n :star: \n Doors had too many axe holes, guest in room 237 was far too rowdy, whole place felt stuck in the 1920s."
      },
      "accessory": {
        "type": "image",
        "image_url": "https://is5-ssl.mzstatic.com/image/thumb/Purple3/v4/d3/72/5c/d3725c8f-c642-5d69-1904-aa36e4297885/source/256x256bb.jpg",
        "alt_text": "Haunted hotel image"
      }
    },
    {
      "type": "section",
      "block_id": "section789",
      "fields": [
        {
          "type": "mrkdwn",
          "text": "*Average Rating*\n1.0"
        }
      ]
    },
    {
      "type": "actions",
      "elements": [
        {
          "type": "button",
            "text": {
                "type": "plain_text",
                "text": "Reply to review",
                "emoji": false
            }
        }
      ]
    }
  ]
}

View this example

You could replace this button with any of the available interactive components, or you could add it as the accessory element in a section block.

Browse the interactive components to see a full list of what's available, or try the Block Kit Builder tool to visually prototype a message with interactive components.


2. Publishing an interactive message

There's nothing special about the process of an app publishing an interactive message, compared to a regular message. Read our guide to sending messages to find the best publishing method for your app.

After you've chosen a sending method, try to send the message payload above, substituting a real channel ID.

Once you do, your app's message will be sitting in channel, waiting for someone to click the button within. Let's see what happens when they do.


3. Process the interaction payload

In our guide to handling user interaction in your Slack app, we explained how the use of an interactive component would send an interaction payload to your app.

An interaction payload is both a way of notifying your app about an interaction and a bundle of information containing the where and when (and many other Ws) of the interaction. It is vital to the interaction process, so your app has to be able to understand it.

The payload will be sent to your specified request URL in an HTTP POST. The body of that request will contain a payload parameter. Your app should parse this payload parameter as JSON.

The entirety of this payload will contain all the contextual info that your app needs to be able to figure out what kind of interaction occurred. Your app can use as much or as little of the info as needed.

For the purposes of this guide, you should grab the channel object, and store that channel's id for later. You'll also want to grab the response_url here too.

Now that your app can receive and understand interaction payloads, it needs to decide what it will do after one of them is sent.


4. Respond to the interaction

In our guide to handling user interaction we explained the different app responses to any interaction.

The most important is the required acknowledgment response. This response is sent back to the same HTTP POST that delivered the interaction payload.

In addition to this acknowledgment, your app can also choose to compose a message response, invoke a modal, or one of a multitude of asynchronous responses.


Through this guide you've learned how to add interactive components to messages, prepared your app to handle payloads, and created a simplified interactive flow. From here you can dive into our reference guides to learn more about the different types of blocks you can use, and deepen what your app is capable of doing for users.