Slack Apps: Interactivity & Modals

Introduction

Continuing on with the theme of using Slack Apps, in this post I’ll be covering a bit about interactivity & modals in Slack Apps. Slack Apps can be incredibly helpful as a way for users to submit information and in order for that to happen, you need interactivity with your app!


Interactivity Explained

Interactivity can come from one of three main places:

  • Slash Commands

  • Shortcuts

  • Slack Blocks (buttons, input fields, etc.)

These interaction aspects are what Slack refers to as “Entry Points” for a Slack App. Each time a user uses one of these Entry Points a payload is sent with an important piece of information: a trigger ID. This trigger ID will be necessary later when we talk about Modals.

One issue I’ve run into repeatedly with Slack App Interactivity is that you can only have one Webhook URL set up, so every time a user interacts with your app, it is going to go to the same place. This can cause issues if you don’t have logic to account for the different actions a user can take within your app such as a button press, a dropdown selection, a date selection, or even something unexpected. To help combat this, it is critical that you create Block IDs and Action IDs. These IDs will help you filter out data you don’t want or need and make sure you’re only performing the next steps in your workflow when desired.

In this screenshot you can see I’ve labeled a timepicker block with the timepicker block ID and the action id as time-picked-action. This helps standardize my data so I know every time a time is picked, it will come from the time_picker block and have an action ID of time-picked-action.

An example of the workflow logic based on Action ID


Slack App Setup

One of the first things we need to do is create a Slack App. Open up the Slack Apps page at https://api.slack.com/apps/ and click “Create New App”. You’ll receive a pop-up asking you to name your App and select the workspace you want to develop it for. Don’t worry, you can re-name your App later if you aren’t happy with the one you’ve chosen.

(Wow this blurb is starting to sound very familiar if you’ve read my other posts!)

Slack App Naming Modal

Next let’s navigate to the Interactivity & Shortcuts page and toggle Interactivity on.

Once you’ve done this we’ll pause there as we’ll need to do a bit of work outside the Slack Apps page. If you’re using Okta Workflows you can move to the next section titled “Okta Workflows Setup”. If you’re going to be sending your workflow elsewhere, move to the next section titled “Slack Setup (cont.)”

Okta Workflows Setup

Again this will sound very familiar if you’ve followed my other posts, it’s copy and paste. We’re going to create a new Okta Workflow with the “API Endpoint” trigger card. Make sure you have “Expose as public service” selected, but don’t bother grabbing the URL yet as we need to enable and save our flow before that information will fill in.

This time, we’re going to use the following cards:

  • JSON Parse - We’ll have the body payload string as input

  • Object Get Multiple - We’ll use the JSON parsed object as input

  • If/ElseIf - This is the bulk of where our logic comes in to dictate what happens next.

In the screenshot below you can see some of the data I collect when a user interacts with my apps. Trigger ID, Action ID, Message Timestamp, Username, and more is all collected so that I can use additional logic to determine my next steps.

Your logic for Action IDs will look something like this with each horizontal stripe being the workflow you want to follow for that specified action. You need to account for each action a user might be able to take with your app, or have a catch-all “error” for any unexpected actions. As a handy tip, I use this error for any actions I don’t want to take action on.

Save the flow and enable it. Click the endpoint configuration button and copy the Invoke URL. You’ll need this when we return to Slack app setup.


Slack App Setup (cont.)

If you’ve gotten to this section I’m going to assume that you either followed along in my Okta Workflows setup or have your own API endpoint URL. Either way, let’s paste the API Endpoint URL into the “Request URL” field on the Interactivity page.

With that final piece in place, you’re ready to continue building your workflow. You’ve set up the groundwork for a user to interact with your app and collect data from it and can now move onto performing tasks based on the information supplied to you by a user.


Slash Commands

With Slash commands, Slack throws an extra wrench in your workflow with their expectation of a response within 3 seconds, otherwise the user will receive an error message. One way to get around this is to immediately reply with a 200 status code and some simple text acknowledging the user request. Once you’ve sent back that 200 status code you can then continue your workflow as you would normally.


Modals

Let’s talk a bit about modals. To open a modal we make a views.open API call which will open a modal view for the user. However, in order to use the views.open method, we need a trigger ID. The requirement for a trigger ID is how Slack ensures that a user wants to interact with your app and you aren’t just randomly spamming people with modals (though that would be a great April Fool’s Prank on your friends). Once a user interacts with your app, you retrieve the trigger ID and include it in your views.open API call.



If your modal has input fields, then the Submit option becomes available to users. When a user clicks “Submit” on a modal the event Slack sends will have a type of view_submission instead of block_actions which is what we’ve seen up until now so be sure to account for that in your “Action logic”. Slack expects a 200 status code response within 3 seconds of sending the view_submission payload in order to either load the next view, or if there are no additional views, to close the modal.

The logic will end up looking a little funny because as previously mentioned, Slack interactivity can only every go to a single endpoint. You’ll first need to check if the interaction you’ve received is a view_submission payload. If it is, then you can retrieve the submitted info and continue on with your workflow. If it is not, you can either discard the interaction or retrieve the trigger ID and send the user a modal which will end up causing the user to interact with your Slack App again when they click Submit on the modal.


One thing to note with Okta Workflows specifically is that I’ve seen some very weird behavior when trying to respond to the view_submission payload with a 200 status code. You can see in the screenshot below I’ve had to create an entirely separate logic check for if the payload is a view_submission payload or not. If you try to include it in a If/ElseIf I have seen it fail to close the modal. I’m unsure why Workflows has this unique characteristic.

Your JSON for opening a modal will end up looking something like the below:

{

"trigger_id":"{Insert Trigger ID}",

"view": {

"type": "modal",

"title": {

"type": "plain_text",

"text": "Example Modal",

"emoji": true

},

"close": {

"type": "plain_text",

"text": "Cancel",

"emoji": true

},

"submit": {

"type": "plain_text",

"text": "Submit",

"emoji": true

},

"blocks": [ {Insert Blocks JSON you’ve created here} ]

}

}

Previous
Previous

On mental health and the importance of community

Next
Next

Slack Apps: Utilizing the Home Tab