Image for post
Image for post

Open-Sourcing our Slack Client for Scala

Ryan Brewster
May 10, 2016 · 3 min read

tl;dr:

To celebrate the release of , we‘re open-sourcing the Slack client we wrote for Scala. We’ve been using this client in production for several months, since the release of earlier this year.

It’s available on and has been published as a dependency on . If you are running SBT you can include the client and associated models with:

libraryDependencies += "com.kifi" % "slack-client" %% "0.2"

API overview

The Slack API is quite feature-rich and growing rapidly. Generally speaking, there are a lot of , all of which require an access token — a secure string that represents a Slack user who has given you permission to act on their behalf. An access token can only be used on a subset of the API methods determined by the set of the token’s user has granted.

To use the Slack API at all you need to ask a user for permission to act on their behalf and be granted an access token. Slack has detailed documentation of the .

Bidirectional Models

Invoking Slack’s API methods once you have an access token is simply a matter of sending a GET request to the desired API endpoint with the appropriate arguments. Almost every one of these arguments end up being represented as strings — from a user’s id to a message timestamp. In our codebase, we opted to use wrapper types around these to make it explicit exactly what each string represented.

Most of these wrapper classes are extremely simple — they wrap a string and do nothing else. Some of the more complex wrappers include SlackTimestamp (which can be converted to a Joda DateTime) and SlackChannelId (which has subclasses for public, private, direct message, and user channels).

The parse function is type-selective, so it can be used to write Play! JSON formatters that are aware of what kind of channel id is expected (e.g., the channels.list API is expected to return only public channels).

Data Models

Working with any remote API can be a challenge, but Slack’s API has a lot of pleasant features; first and foremost among these is the extremely consistent and unambiguous interface. Every API method endpoint will reply with a JSON object, and that object will always have an “ok” field in it telling you whether your request succeeded or not.

Thus, regardless of which method you are invoking, the same basic structure applies: specify a route and a deserializer for the return type, hit the route, check the “ok” field, then try to deserialize the payload.

Handling Errors

There are two broad categories of things that can go wrong when calling the Slack API:

  1. Everything went fine, but Slack refused to fulfill the request for any number of reasons: you’re missing a required auth scope, or the request you’re making is impossible to fulfill, etc. In this case you will receive an object with “ok”: false, and an informative error.
  2. Some technical malfunction prevented Slack from even responding to your request: Slack is temporarily out of service or encountered an internal error, your request URI was too large, etc. In this case you won’t get an object back at all, and you’ll have to figure out what went wrong.

These failures are all captured by the SlackFail trait, which extends Exception. A call to Slack will generally have a type of Future[T], and if something goes wrong it will yield a failed future containing a SlackFail. It is common in our codebase to recover from specific SlackAPIErrorResponses (#1 above) using the SlackErrorCode unapply method.

The call will still fail if anything else goes wrong (e.g., invalid access token, non-existent message, Slack is temporarily down, etc).

We wrote this post while working on Kifi — Connecting People with Knowledge. Learn more about .

Keep It Up

The Kifi Engineering Blog

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store