DEV Community

Cover image for Fun with APIs: Building a Slack pinboard app!
Corentin for Bearer

Posted on

Fun with APIs: Building a Slack pinboard app!

Notice: Parts of this article from 2019 mention using Bearer to connect to the Slack API. Instead, we now recommend checking out our open source project Pizzly. You can use it to handle the oAuth portions mentioned in this article.

Like everyone, we use Slack a lot at Bearer. We have tons of channels, some for the whole team, some only for the guilds. We even have some for #coffee that we take remotely.

Like any other team, information gets lost a lot on Slack. So one thing that we try to do well its to pin important messages in each channel.

It can be a command to get up and running quickly on a project or just a link to our favorite restaurant menu. Pinning a message turned to be a big part of our Slack routine now - and we even pin messages in DM.

6 pinned messages in the #engineering channel
6 pinned messages in the #engineering channel

On Slack, you can see pinned messages with the little ๐Ÿ“Œ on top of a channel. Clicking on it opens a sidebar with a truncated version of the messages. You then need to click on each message to see its context.

The thing is that the FREE version of Slack doesn't let you access old messages. Turns out that the API does! So, we built an app for that.

Let's see how we did?

Understanding the Slack API

Let's start by having a look on Slack's API documentation, which reference a pins.list endpoint having the following abstract:

Abstract of the pins.list endpoint

And that request takes the following arguments:
Arguments of the pins.list endpoint

The token in Slack documentation is a user token, more commonly known as an access token. And the channel argument is a channel identifier, which means that we need to first query another endpoint, channels.list.

From there we can deduct what our API call flow will be:

  • First, we will query the list of channels;
  • Then, we will use a channel identifier and list its pinned messages.

Now, time to play ๐Ÿค“!

Configuring the Slack API and generating a token

To help us use the Slack API, we will use Bearer below. First, we add the Slack API to Bearer's dashboard and follow the instructions provided:

The Slack API added to my Bearer account

We have to create a new Slack App:
Create a new Slack App

Then, we configure the OAuth callback URL:
Bearer OAuth callback URL

And the required scopes:
Required scopes

Finally, we grab our Slack credentials and add them to Bearer:
My Slack App credentials

Well, the Slack seems well configured! Let's start to make API requests. But first, we have to generate an access token, this is required for every OAuth APIs. This token represents a user identity.

Usually handling OAuth is tricky, but here we will generate this token with Bearer. Go back to your Slack API on the Bearer's dashboard and click on Bearer's Connect to Slack button:

Slack OAuth dance with Bearer's connect button
Slack OAuth dance with Bearer's connect button

Bearer retrieves and stores this token and in return provides an authentication identifier (authId). When calling the API with Bearer, we will use this authId instead of the token.

This way Bearer will always make sure to pass the token and manage the refresh token automatically when needed โœจ!

Calling the Slack API

We are ready to call the API. Here's how a request to the channels.list endpoint looks like:

$ curl "https://proxy.bearer.sh/slack/channels.list" \
-H "Authorization: _REPLACE-WITH-YOUR-BEARER-SECRET-KEY_"ย \
-H "Bearer-Auth-Id: _REPLACE-WITH-YOUR-AUTH-ID_"
Enter fullscreen mode Exit fullscreen mode

If you replace the above params with yours, Slack will successfully respond to your API call ๐ŸŽ‰!! It shall return a list of all your channels.

Now, we can send a request to the pins.list endpoint, using one of the channel ID previously retrieved (e.g. C4FE4TW9K).

$ curl "https://proxy.bearer.sh/slack/pins.list?channel=C4FE4TW9K" \
-H "Authorization: _REPLACE-WITH-YOUR-BEARER-SECRET-KEY_"ย \
-H "Bearer-Auth-Id: _REPLACE-WITH-YOUR-AUTH-ID_"
Enter fullscreen mode Exit fullscreen mode

I can hear some of you saying: don't we need to pass the token as well? Well, as we said previously, using the connect button, Bearer handles the token arguments. It knows where to pass it and what value it is!

The whole logic and API flow is working. It's time to implement this Slack API integration into a proper-application.

An application to retrieve pinned messages

We are going to use Vue.js, which is an awesome framework to build a simple app like this one. No backend, only plain HTML, CSS and a bit of JS.

If you add the Bearer's Javascript API client on top to perform the API calls, it's starting to look magical.

For instance, here's how the app fetches Slack channels:

slack
  .auth("AN-AUTH-ID-GENERATED")
  .get('/channels.list')
  .then(({ data }) => {
    if (data.ok && data.channels) {
      this.channels = channels
    }
  })
Enter fullscreen mode Exit fullscreen mode

And the function fetching pinned messages from a previously selected channel:

slack
  .auth("AN-AUTH-ID-GENERATED")
  .get(`/pins.list?channel=${this.selectedChannelId}`)
  .then(({ data }) => {
    if (data.ok && data.items) {
      this.messages = data.items
    }
  })
Enter fullscreen mode Exit fullscreen mode

A note on front-side API call: When calling an API from a client-side context, you need to be extra careful about security. Bearer gives you an option to enable client-side calls, using a publishable key.

We are almost done, but something is still missing on our application. So far, we've been using our own Slack identity, but we want to let anyone connect using their Slack identity and retrieve their own pinned messages. So it can work for any Slack's workspaces.

Adding Slack authentication

To let the user retrieves its own Slack channels and pinned messages, we need to let him/her connect using its Slack identity.

Bearer provides a JavaScript client (and a React component) that deals with such logic.

The Bearer's connect button for Slack

Once this component is added, our users are able to login using their Slack account. By using their identity, our application will perform API calls to Slack on behalf of their identity. That's exactly what we wanted.


Let's sum up! We just built a static app using Slack API. The entire OAuth flow and API calls are handled by Bearer. And it's deployed in production using Netlify ๐Ÿš€

Try it out right here and open the source code to have a full overview.

Top comments (0)