Like many companies, we use Slack for internal messaging. It works great for quick messages and sharing content with colleagues, but it is also a wonderful development environment. Slack provides the platform for Spacepods to expand and get closer to where developers spend a lot of their time. SpaceBot is a Slack app built from scratch to take advantage of this platform. It interfaces with Spacepods and is now a key accessory for our CI/CD process and Pods infrastructure.
It Started with K.I.T.T.
SpaceBot is the successor to KITT, a legacy bot built on top of Lita. Spacepods was less integrated with KITT, and only had a rudimentary ability to proxy messages to Slack. In addition to some business-oriented functionality, the most popular KITT feature was dynamic meme generation.
KITT’s downfall was that the Lita library was built to be generic enough to connect to various chat apps. That sounds like a positive feature, but it limited our ability to fully integrate with Slack. We had to use a special Slack adapter for Lita, and the code became messy as a result.
SpaceBot was built from the ground up to overcome some of the issues of KITT’s legacy codebase. While KITT was able to send basic messages, SpaceBot is clearly an extension of Spacepods and provides enhanced functionality. TrueCar is a Ruby shop, so SpaceBot uses the slack-ruby-bot gem, the de facto, semi-official, open-source library for Slack apps written in Ruby. The fresh start with a library dedicated to working with Slack’s APIs gave us an opportunity to use all of Slack’s features and establish the bot as an accessory to Spacepods.
The clean slate also allowed this app to be built with an intuitive structure. A declarative commands section of code split out from web and API sections makes the code very easy to maintain. Commands each register one or more regular expressions to match incoming messages, similar to the way Rails routes web traffic. Built-in health checks also allow us to bid adieu to the legacy infrastructure that housed KITT and instead use Spacepods to deploy the bot in AWS.
Commands and Messages
SpaceBot operates on a two-way street. It responds to a wide range of commands, but also has webhooks that return information or send messages to Slack.
Some SpaceBot commands are simple. Send it the command
faqand it will provide a link to the Spacepods FAQ. Say hello in any of 25+ languages and it will reply in kind. Or to have a little fun, try asking a question.
Other commands are far more complex, providing ways to interact with Spacepods. You can retrieve information like a list of your personal Pods, the last 10 builds for an app, or the last successful deploy to a higher-level environment.
You can also go beyond retrieving information. One of the most popular commands lets users extend the life of their Pods. With two-factor authentication through Duo, users can even deploy their apps directly from Slack.
Responding to commands is really the lesser of SpaceBot’s two main functions. The other, more important one, is to provide an HTTP interface to Slack. Built into SpaceBot is a declarative API based on the grape gem. SpaceBot keeps an updated local store of data about the connected Slack team along with its channels and users, which can be queried through the SpaceBot API. This lookup API provides a mechanism for deep linking to Slack throughout the Spacepods application, since channel names and user emails have to be converted to their corresponding Slack IDs.
The message API is used to send messages through the bot that are then posted to Slack channels or users, sometimes with additional processing. Messages are sent for many use cases:
- Pod deployment has succeeded or failed
- A Pod is shared
- Pod auto-destroy will occur soon
- Deployment to a higher-level environment has succeeded or failed
- CI/CD messages
Such a useful API surely justifies a nice library to access it, right? Of course! And that was something we created even before attending a presentation titled Yes, You Should Provide a Client Library For Your API at last year’s RubyConf in Los Angeles. The bot_api gem, as it is called, does just that. With simple authentication setup, error handling, and methods for calling the API, it enables other apps at the company to connect to SpaceBot.
Tracking and Analytics
All transactions through SpaceBot, including commands invoked and API calls, are recorded and sent to New Relic for analytics. When this Slack app was first set up, we discovered that New Relic instrumentation already existed in the form of newrelic-slack-ruby-bot, another gem from the creator of slack-ruby-bot. Unfortunately, it had gone out of use and needed to be updated. Open source to the rescue! We made the necessary corrections, along with a few changes in the core slack-ruby-bot gem, to grant it new life. The New Relic instrumentation now automatically enriches transaction traces for commands with all available information about the command invocation, providing more in-depth analytics capabilities.
To recap, we now have a bot that can respond to Slack commands, respond to HTTP requests, and pass analytics information to New Relic. All of that is great for extending the functionality of Spacepods, but it has to be secure. On that front, all access to the SpaceBot API requires authentication via token auth, and all commands are tied to the user account of whomever calls the command. This is sufficient in most cases, as the majority of commands are not harmful and do not expose sensitive data. Dangerous operations, such as deploying to higher-level environments, require the user to pass two-factor authentication with Duo, which also serves as an extra confirmation from the user.
Crafting the Perfect Slack Message
Now that we have looked at what makes up SpaceBot, let’s take a deep dive into the feature that gets used more than all others throughout the day: deploy messages.
Phase 1: Manual Deploys
When Spacepods was built, it gave us push button deploys. KITT used to post Slack messages for each deploy, but when SpaceBot replaced KITT, the new bot really brought those messages to life.
Slack offers a limited set of formatting options, so providing information effectively through message attachments is almost an art form. We began by linking directly to deploy and build pages for easy Spacepods access. Inclusion of the app name, build number, and branch makes the content of the deploy crystal clear. The deployer and destination environment are emphasized and the deploy status is highly visible in the title.
The next addition was a list of contributors. Not only does this show who made changes since the last deploy, it also alerts those people when the deploy succeeds or fails. Finally, since sometimes a redeploy of the same code may occur in order to update an environment variable, we show that as well.
Phase 2: CI/CD
SpaceBot aims to increase efficiency throughout the company by improving the workflow involved in getting a set of changes to production. Nowhere is its role more important now than as a piece of the continuous deployment (CD) pipeline. As the process becomes more automated, developers have less need to spend time in Spacepods; they just need the most relevant information presented to them directly.
In our CD pipeline, deploys start automatically when a build is ready or automated tests pass. Since the process is entirely automated, we don’t have to bother developers with all the details. Instead, we focus on the two key actions: (1) the pipeline starts executing with their build, and (2) their build either succeeds or fails.
If a build fails, we say whether it was a deploy or Gatekeeper (test) failure and on which environment the failure occurred. We also provide a link to view detailed results.
When You Have Something Good, Share It
As we added Spacepods functionality to SpaceBot, some of the same features were added to our command line interface to support a different way of interacting with Spacepods. Learn more about that in our post on the Spacepods CLI.