Slack Bot Development Thoughts
Recently I had the opportunity to create a Slack bot for a work project, it was essentially a tool to trigger certain actions from other internal tools via their API. This post is primarily going to be discussing my experience and suggestions if you decide to venture down the path of creating one.
Tooling and Development
So previous to this experience I had only worked with a Discord bot for a prior project I did for a family member running a Discord server. That project was pretty simple and only really fetched data to provide back to the user using it, very little complexity. I figured Slack would be a little more polished on their SDKs or frameworks for this, so as a group my team decided on using the recommended Python framework Bolt.
I would highly recommend going through the initial tutorial here just to get a handle on how the API works, and how to get it up and running. I also would recommend socket mode as its just much easier to get started with and there didn’t seem to be many down falls.
Setup
Slack’s API UI is where you need to setup all of your permissions, what you want your bot to have access to in terms of events, as well as what fine grain actions you want it to be allowed to take. You can go really deep with this and it was nice to see that the API documentation always has the corresponding permission set listed so you can easily track and add what is necessary. There were a few other settings that were defined in the API UI such as slash commands (i.e. defining /bot as the command to action your bot). I would have preferred for this not to be in the UI configuration to make that something that could be set as an environment variable in the code which would reduce a bit of the logic if you wanted to run two bots for a staging environment, but, I made it work for our purposes. After that is all configured, the only changes you need to modify in this portal are if you need to add additional permissions or change something cosmetic like the avatar on the bot. You’ll generate your bot token and api token during this process which are the keys to getting it setup to your specific Slack account for use.
Development
Development using Bolt is pretty straight forward, the library handles most of the work with a few quirks, below are a few of my notes I took which can hopefully help you in the future.
- acks() are weird, but necessary
- browing through Bolt’s repository on Github, the issues contain a lot of useful information on what other users are building and how they’ve overcome some of the limitations
- slack’s output is difficult to work with if you are trying to do some sort of table, but slack block kit builder is really interesting
- async/await seems easy enough to work with
- getting familiar with the payload early was very beneficial
- testing is difficult past unit testing (think integration testing, etc)
- respond is great for private messages to users (think error messages that are syntax related), say is public, and everyone in the channel sees it
- responding to threads in Slack seemed overly complicated when trying to split up a payload response in multiple messages
Output
The output was my biggest enemy during this project. One of my commands was meant to display information in a table format. Think spread sheet style with a name, a function, and some sort of boolean all on one nice, neat table. Plain text displayed as a say()
looked bad and not organized well, the spacing was very off and the dividers I used were too disconnected looking to go forward with (think |
). I even tried to use some sort of Python generated table to text and that ended up somehow looking even worse. So I started down the path of using Slack’s recommended Block Kit Builder.
The block kit builder itself is really interesting, I don’t want to say it’s bad because theres a lot of potential there and it seems like its just missing some of the features that I needed for my specific project. A block is a single piece that displays (or contains blocks that display) on a response or say function in the Slack UI. It’s nice because you can write some functions that handle the repetition of creating an individual block, and you can stuff them into a response (such as the header/title of the response, the body, any styling or icons). Unfortunately where it falls short is the text fields are limited to 255 characters each, so a larger response is only going to work with a plain text response/say function and not in a richer format such as in a Slack Block. This is fine, easy enough to work around. I can split my text up so it isn’t taking that much anyways since I wanted to create a table. Well, Slack doesn’t have a way of natively creating a table, theres tons of bad workarounds on StackOverflow, but, as far as a native, neat, table it is really out of the question at this time. This brought me to look into just using a response block and dynamically generating blocks under that object to display the various output lines I wanted to display. That may be 5 lines, or 100 depending on the specific input. I hit another snag during the development here because the response object can only display 25 blocks maximum at a time which I found out after some heavy digging into the documentation after an odd error and no response message on only certain responses that were rather large. Hopefully this will be updated in the future, as I can see this being helpful to display more than an arbitrary value of 25.
I did look into the interactive modal displays which do seem a bit more involved both development wise and the actions they allow you to take, but, due to time constraints I pushed forward and was able to still use Slack blocks with a few limitations.
Overall
Overall I think they have a very easy framework to use and get started with (Bolt), the documentation was very easy to understand and get up and running quickly. I also think once you’ve tinkered with Discord or Slack’s bot development the other seems to click a bit easier. I’m excited to see how Slack continues to improve the Block Kit tooling and adding new features, and excited to dive a bit deeper into the interactive modal displays for some of the other commands in the near future. Hopefully these limitations are solved in the future or by the time you are reading this, but if not I hope this saves you some time on pain points and how I solved them.