Building scalable Slack apps: A guide for developers

Build your first enterprise scalable Slack app successfully with 6 tips from a chatbot developer.

Updated 2/2/2024

My name is Anirudha Simha and I’m a senior software engineer at Capital One working on an internal chatbot. Its capabilities include answering FAQs using machine learning and natural language processing (NLP) and supporting API-driven actionable integrations with various popular services like Confluence, JIRA and Github. Our chatbot is primarily used as an app in Slack, where it supports over 150 different Slack channels and is used by thousands of employees across a wide range of internal teams within Capital One.

In my experience, these kinds of apps provide a great way to integrate various workflows and processes into Slack, allowing users to complete many tasks from a single environment. When implemented properly, Slack apps can provide a significant benefit, but there are some tricks involved. In this blog I will go over six considerations you should consider when building, owning  and maintaining a highly scalable enterprise Slack app.

A few words about Slack apps vs Slack bots. Though the terms are sometimes used interchangeably, they are different things; an app may contain a bot, or it may not, where the bot is just the piece of the app that interacts with the user. Most apps have a bot component, but it is not a required aspect of an app. The distinction is insignificant here, so I'll use the term 'Slack app' throughout.

PLEASE NOTE - This article uses Amazon Web Services (AWS) as the example cloud service, however other cloud providers may work or have equivalent services.

Why are you building a Slack app? What is its purpose and role?

First and foremost, your app's role in your organization will influence its design and development; as well as, ultimately, the value and utility it drives for you. Some reasons and roles to build a Slack app include:

  • Automating all of the things!

  • Integrating processes that are tailored to your organization's needs and considerations. 

  • Enabling users to perform actions without having to leave Slack.

  • Providing automated support.

  • Creating a fun tool that helps enable culture within your company. 😎

Tip #1: How to stay informed of Slack events - Slack events API vs Socket mode

While the end goal for your Slack app is to communicate and interact with your users in an impactful and value-driving manner, that ultimately relies on also knowing what’s going on in Slack. Using Slack's events-based system, through HTTP endpoints or WebSockets, will inform H3your application of what's happening in your workspace.

Slack events API

Slack provides several APIs to consume. The web API is used to query Slack for information and perform actions. The next question is, how do you get information about events to your application? This is done via the events API. By exposing a public endpoint and providing this to your Slack app, Slack can forward events to your endpoint for you to process and handle and only events that you choose to subscribe to will be sent. For example, you can choose to receive HTTP events about reactions being added in channels your app is part of, or you can sign up to get events for each time a new member joins a channel. You can see the full list of Slack events here.

Socket mode

Socket Mode is a feature from Slack that uses WebSockets to achieve the same functionality as the events API. Developers will not need to provide a public-facing URL to Slack as the WebSocket connection will replace this. In my experience Socket Mode is the best way to work within the restrictions of corporate proxies. Additionally, because Socket Mode is a WebSocket connection, it tends to have less latency than traditional approaches that expose a static HTTP endpoint. However, this is at the cost of a persistent connection needing to be made (so no serverless approaches).

Tip #2: Serverless vs. containers for Slack apps: How to decide which is right for you

When deploying your enterprise Slack app, you will want to strike the best balance between cost, availability and performance. For that end, I personally recommend using a serverless approach like AWS Lambda (if you are using Socket Mode, then read on below) since it is very cost effective, scales out quite well and is easy and simple to use.

PLEASE NOTE - as the intent of this article is not to walk through the minutiae of setting up infrastructure, I will instead leave links to articles that can help to set up the various infrastructure approaches I discuss below.

The serverless approach

Most implementations that take this serverless approach use an API gateway to expose a public URL that will then forward events to your lambda function. An example with AWS API gateway and a lambda function would look like the below:

AWS API gateway and a lambda function example

Image Source: https://docs.aws.amazon.com/lambda/latest/dg/services-apigateway.html

This serverless approach allows for easy scaling out of events while still being quite performant and cost efficient, which makes it quite handy since, as your organization grows AWS lambda can scale to your needs. 

If you are running Socket Mode or using Bolt (SDK by Slack that makes it very easy to set up a server that listens for Slack events) without using the Serverless Framework, then the above serverless approach will not work for you. However, a container-based approach (e.g. ECS, Docker) will.

Here is an article on understanding Amazon Elastic Container Service (ECS)

Here is an article with step-by-step on deploying Docker containers in ECS

The advantages this container-based approach offers is that it is always running and will not suffer from cold starts or the 15 minute execution time limit that lambdas are limited to.

The container-based approach

If you are running Socket Mode or using Bolt (SDK by Slack that makes it very easy to set up a server that listens for Slack events) without using the Serverless Framework, then the above serverless approach will not work for you. However, a container-based approach (e.g. ECS, Docker) will.

The advantages this container-based approach offers is that it is always running and will not suffer from cold starts or the 15 minute execution time limit that lambdas are limited to.

Tip #3: Understand how Slack workspace organization may affect your app

The highest level of organization in Slack is the workspace, which contains all of the channels. If you are familiar with Discord, then it's analogous to Discord’s servers. An enterprise grid is a collection of workspaces that can communicate with each other. A small startup may have a single workspace that contains all of their channels. 

However, larger organizations are likely to have multiple workspaces each for different job functions (e.g. a workspace for the HR organization, and a workspace for tech, etc..). You can read more about enterprise grids and workspaces through Slack’s documentation.

We can see an example of an enterprise grid in the graphic below. There are various workspaces shown here like engineering or marketing, each with their own channels. However, there are some channels like #company-wide-announcements that are available across all workspaces in the company as well.

Slack enterprise grid example use case

Image Source: https://slack.com/resources/why-use-slack/slack-enterprise-grid

Slack apps are installed per workspace,so the app owner needs to make sure that the app is installed to each workspace that their intended users will be interacting from.

Single workspace

Organizations that are running across a single workspace will typically only have to worry about that single workspace (also referred to as team in the Slack API docs). This simplifies the process for the developer, as they only have to install to one workspace, and there is only a single app-token they need to worry about.

Multiple workspaces

Organizations across multiple workspaces will have to be aware that their app will need to be installed on each workspace. This means that the app will need to look at any incoming responses and use the “team” field to identify which workspace an event is coming from and then use the appropriate app token for that workspace.

Enterprise grid

If your organization is using an enterprise grid, then consider converting your app to an org-wide app and using its org-wide token. This lets you use a single app token that will work across all workspaces while providing simplified token management/usage.

Tip #4: Understand the building “blocks” of Slack’s UI

When designing the UI/UX for your Slack app you will want to be consistent with your design and obey good design principles. Really, the rules for UI/UX in a Slack app are universal to many applications, so this shouldn’t be too hard.

Slack helps you stay consistent with HCI principles by using a templating UI framework called block-kit (more details are found in the building with block kit documentation and Block basics guide). The foundational building blocks of block-kit are aptly named blocks. Blocks are simply JSON formatted with specific fields and values that are given as inputs to certain Slack web API calls. 

The output of these web API calls, when provided with blocks, results in a stacked visual layout of elements (text boxes, buttons, dropdowns, text, etc) in messages, modals and other surfaces in Slack. You can see an example of what block elements would look like in the image below.

Slack app block element example

*Source: Blockit-builder example generated template

While there are some options for the developer to change the colors of buttons, the placement and style of most elements is fixed, further reinforcing a consistent look and feel. However, since you have some leeway for how to position certain elements (e.g. have a button inline with a text section vs a text section with a button directly below it), you will want to stay consistent to make your app easy to use and visually on brand. This also includes usage of visuals like GIFs, images and emojis. I personally like using visual elements like emojis in my blocks, since they help to break up text. 

However, the decision to use elements such as these will vary based on your use case, app and preferences. Like all things though, it is a balancing act to find the right amount of text to interactive elements to visual elements to convey what you want while not being too overwhelming or too dense.

Please note that when designing your blocks, you can visualize how they will look using block-kit builder (please note that this link will require you to sign into a Slack workspace to view it). This is a great way to see how things will actually look like to users and allow for rapid prototyping. I highly, highly recommend using this, as it makes visualizing messages and modals that much easier, and the included templates are great sources of inspiration.

Tip #5: Follow simple guidelines for Slack app interactions

Slack apps have a multitude of ways they can communicate information and factors that should be taken into account when designing them. This includes what the Slack app does, the urgency/importance of the information it conveys, or how much traffic a channel gets. These all affect how you want your app to interact with users and is something to be mindful of.

tl;dr

Don’t drag the user around from channel to channel, provide feedback when they do something, be aware of how and where you should display information, and don’t overwhelm them.

Do your work directly in the channel

If work can be done in the channel, then do it there. Don’t require the user to have to go to another specific channel or switch to a direct message (DM) with the app unless necessary. For example, if you have a Slack app that lets users make and send a poll to a channel it makes sense to be able to invoke the process in that channel, right there, as opposed to directing the user to a DM with the Slack app.

Offer informative user feedback

Provide feedback to the user after actions are taken so it is obvious to the user that something is happening. This is especially important if there are long running processes that may require the user to wait for a moment. E.g. “Hey we just received your application, sit tight while the bot works on it! You’ll hear back from the bot in a few minutes once it finishes processing it.” I also like adding visual elements like emojis or images to my messages so they stand out a bit more.

 For the above message, an emoji with a spinning loading icon may be appropriate to help reinforce the idea that something is still being processed. Again, the idea is to keep the user from having to guess if something is happening or if their interactions did something; however, that doesn’t mean you need to drown them with feedback either--but more on that later.

Who, what and where - context matters

When responding to the user, consider who you are talking to, what you are talking about, and where you are. If you are in a busy channel and have responses that only a singular user needs to see, then it may not be appropriate to have your app publish messages for everyone to see. Instead, it may be better to have your app either publish responses in a thread, ephemerally (so only a specific user can see), directly to the user in the messages tab (aka DM), or to the home tab. 

  • Threaded replies -  Work well when you want to follow up on something in the main channel or in an existing thread. A great example is if your Slack app answers a question posted by a user in the main channel, the app should post its response as a threaded reply to the user’s message.

  • Ephemeral messages - Are when a message (threaded or not) is only visible to a specific user. Ephemeral messages are not guaranteed to stick around and may “disappear” after a while, which should be considered when using them. A good use case for ephemeral messages would be if a user interacted with your app by clicking a thumbs-up button to give feedback and you wanted the app to respond with “Thank you, your feedback has been recorded!” The entire channel does not need to see the app’s response, just the user.

  • Direct messages/The Messages tab - Is a one-on-one channel between the user and your Slack app. This provides a great space for your app to send information to your user without being lost in a larger channel’s clutter. I would consider using the messages tab if you need to convey to the user some important historical information they may want to refer back to later. For example, let’s say a user is interacting with your app in your channel and you want to let them know that their operation was a success and give them some sort of confirmation number to be able to reference later. You could have your app respond back to the user in the channel (ephemerally) letting them know the operation was successful and that full details have been sent to them in a DM (at which point you will send the full details to them in a DM). This is a great use case since the user may not necessarily need the confirmation number, but if they do, they can see the associated date, time and information in their DMs instead of searching through a channel for it.

  • The Home tab - Is a “surface” that is part of an app’s one-on-one experience with a user. It is similar to the Messages tab/surface in that it’s a one-on-one experience. However, while direct messages tend to be more fluid and transient, changing as new information is added, the app Home only changes when specifically updated. Since the app Home is not dynamic in the same sense that the Messages tab is, it’s a great place to store blocks of information such as upcoming events or important info the app thinks the user should easily have on hand.

Slack app home modal example

Image Source: https://api.slack.com/tutorials/app-home-with-modal

Home is where the app is

I want to draw special attention to the difference between the Home tab and Messages tab. While similar, some differences need to be understood. The Home tab is a surface that contains “blocks,” and the app will need to update it for each user. However, it will stay the same until it is updated again by the app. Meanwhile, the Messages tab is more dynamic and will contain messages between the user and app, or just the app if you don’t want the user to respond back. Since the Messages tab is more dynamic, it has a sense of history and preserves older information that may be helpful to refer back to; similar to referring back to an older email in your inbox. 

Collectively, the Home tab, the Messages tab, and the About tab comprise the “app Home”. A good example of an app that utilizes the app home well is the Google Calendar app. It uses the Home tab to display the schedule for a specific day. However, it uses the Messages tab to notify users about upcoming events and updates they may need to be aware of. The most important information is visible in the app Home, but other more dynamic and changing info is published in the DM/Messages tab for the user to see, with the advantage of this history being preserved in case the user needs to refer back to it for some reason.

Don't overwhelm your users

Another consideration when interacting with your users is to be careful not to overwhelm them with too much information, messages and notifications. Less is more sometimes. With that being said, keep in mind that if you have lots of options, buttons, text, etc to show, consider prioritizing the most important stuff first. You can use buttons or even modals to paginate through more information, depending on what you are showing. Buttons can work well if you are listing things, while modals can be good if you want to present a popup with more information or actionability.

Remember, context matters in busy channels. We don’t want everyone to see our app’s interactions with a specific user unless necessary. In such a scenario ephemeral messages can help.

Tip #6: Choose the right Slack library

When developing your Slack app there are many Slack libraries you can use, and Slack even publishes a full list of community driven open-source libraries and a list for tools built by Slack. Of these options I personally recommend using the Bolt libraries by Slack, which are available for JavaScript, Python and Java. 

Bolt is regularly updated to support new Slack features as they are released, and the documentation is also straightforward enough to assist in basic tasks like responding to messages or running the application serverless. In addition to the Bolt libraries by Slack, there are also official SDKs by Slack for Node.js, Python and Java.

Building Slack apps: Considerations for infrastructure, events and UI/UX

Slack apps are powerful tools that can lend deep integrations and automations to your organization’s workflows, improving the efficiency of your teams. When building these apps, you need to consider infrastructure, receiving events, and of course the UI/UX.

How you receive events and how your application is hosted are closely related considerations and are dependent on your own skill set, as well as your organization’s cloud and infrastructure policies. Ultimately, whether you go with Lambda using the Events API via a public HTTP endpoint or an ECS container running Socket-mode, or even some hybrid model of the two, the above considerations should allow you to receive Slack events in your app.

In regards to the UI/UX, remember these main points. Take advantage of Slack’s block-kit framework to build visually pleasing and usable GUIs for your app’s various touchpoints with users. Be conscious of where and how your app is interacting. This plays a factor into how your app should be directing users to interact with it, as well as how it should respond back. Finally, find the balance on how you provide feedback, making it informative without being overwhelming.

I hope that this introductory guide on building Slack apps helped provide some help and deeper insight into what to consider when building a Slack app!

Header photo by Bethany Legg on Unsplash.

*Source: Blockit-builder example generated template (please note that this link requires you to sign into your Slack workspace to view)


Anirudha Simha, Principle Associate Software Engineer, Kai Chatbot Team

Anirudha Simha is a passionate software engineer working on a full stack team that develops and supports a quality NLP & ML powered chatbot. He graduated from Virginia Tech in 2017 with a degree in Computer Engineering and minors in Math, Computer Science, and Cyber Security. Anirudha’s passion for technology can be summarized by the quote, “Innovation comes out of great human ingenuity and very personal passions”. Outside of work, Anirudha is pursuing a Masters in Computer Science and Machine Learning at Georgia Tech; constantly traveling; and enthusiastically following the latest mobile, tech, and gaming news. You can connect with Anirudha on LinkedIn (https://www.linkedin.com/in/anirudha-simha) or Twitter (https://twitter.com/__anirudha__).

Explore #LifeAtCapitalOne

Startup-like innovation with Fortune 100 capabilities.

Learn more

Related Content