Writing a Slack app using Stdlib: “Serverless” Node (Function as a Service)

Justus Romijn
Frontmen
Published in
5 min readDec 18, 2017
Example of a response of my bot in case Bitcoin value has gone up. It displays the current market value, the change since the start of the day, and it attaches a chart of the trend of the last two months.

A lot of coworkers of mine have invested in Bitcoin, Ethereum and other blockchain currencies and are always bragging about the money they have gained on their investments. Since we use mainly Slack for communication, I thought it would be funny to create a simple Slack App that would trigger on the word “bitcoin” and would then fetch the development of the average market value, and respond with (silly) advice for either dumping or buying bitcoins.

Recently I’ve picked up on Stdlib, a cloud service that allows you to write simple Node (javascript) functions that are deployed on an endpoint. When you call that endpoint, the function is executed. Sounds simple? It is! This means that you don’t need to bother yourself to setup listeners with Express or Restify, and figure out what (Node) hosting provider you need, but you can just simply start coding right away! Of course when you need to do a lot of data persistence or maintain server state, this solution is not recommended. But for microservices and simple processes (think of functional programming), this is a really good way to get something up and running in a matter of hours.

So… When I want to create a simple, stateless Slack App that responds on some keywords, and throws out some market information and some nutty advice… Stdlib sounds just as the right tool for the right job!

A round trip from a Slack message to a response from my app

Creating a Slack App is just a matter of a couple of clicks and entering a name and some other details, and you‘re done. Of course now you have more or less a placeholder, that does nothing, so the next step is to configure it with service endpoints where Slack events should be forwarded to, and you can configure webhooks in the other direction as well (from external services to your App). After I’ve configured a Slack app (Bitcoin Advice in my case), and created an account at Stdlib with a service, with a simple function to create a message as a bot, we are good to try it out. It uses OAuth, but all the setup required for that is documented very well at the tools themselves so I left that out of the examples. Below I’ll outline the flow from a message from someone on slack, all the way to a response by my App.

  • Someone posts a message in Slack, where my Bitcoin Advice app is installed.

Slack works internally with events for almost everything that happens, and in this case the event payload would look like this:

{
"user": "U123456789", // user ID
"channel": "C123456789", // channel ID
"text": "Really happy I've bought a bitcoin a year ago!",
"event": "message", // type of event
"ts": "123456789.12345" // timestamp
}

As an app you can subscribe to some of these events. The events are differentiated based on type, where the message event is possibly the most simple one, but you can also tune in on things like new users joining a channel, replies to a thread, or even the unfolding of urls.

  • My Bitcoin Advice app gets a notification with the message payload.

My App receives this event, and I’ve configured it to forward this event to my service endpoint at stdlib:

Event configuration in my Slack App. The :bg parameter is used by Stdlib to respond immediately with an HTTP 202 Accepted status. This is documented at Stdlib.
  • The function at this Stdlib endpoint will be executed

At the /events endpoint, some code is running to handle this event. Stdlib works with a simple callback function. When this function is called, it will create an HTTP response for the original request.

Based on the event data that I receive, I will parse it to see if the text contains the phrase “bitcoin”. If that is the case, I will perform a fetch to an open source API for bitcoin value information, and reply with advice and value. This example is simplified for brevity, but it comes down to something like this:

module.exports = (context, callback) => {
// retrieve event from payload
// the context parameter is supplied by Stdlib exposes a bunch
// of stuff from the request, for example the params
let event = context.params.event;
// check if message contains the phrase "bitcoin"
if (event.text.match(/bitcoin/i){
// get realtime data about actual bitcoin value
fetch("https://www.bitstamp.net/api/v2/ticker/btceur/")
.then((result) => result.json())
.then((json) => {
// some calculations here...
// in my app I use the json to enhance the response text
// with some realtime market value information...
// the callback function will send a http response with the
// given payload. This will be used by our slack app.
callback(null, {
text: "Some advice to buy or sell!",
channel: event.channel,
botToken: getBotToken()
// required to post messages as your bot
});
});
}
}
  • Bitcoin Advice app receives the response.

Because I’ve configured my app with a Bot user, the response I get from the Stdlib service will be posted to the channel as this bot (the botToken makes this possible). The message that I’ve created in my app also has some attachments and Emojii, to make it a bit more interesting and appealing. Slack has excellent documentation how to create rich messages like this.

Example response of my app that gives some funky advice based on the bitcoin value change.
Example response if the bitcoin is going down. Once again, solid advice ;)

Inspired?

I hope this was an insightful article about how easy it is nowadays to get scripts wrapped and hosted with platforms like Stdlib or AWS lambda.

Stdlib already offers out-of-the-box templates for Slack Apps that showcase most of the functionalities available.

If you want to get started yourself with something like this, there is this really nice blogpost about how to set it up, including the OAuth, tokens and event forwarding.

Note on security awareness

As you can see, Slack apps, with only basic permissions, can already read a lot of stuff in your channels. And some apps are also capable of reading direct messages and private channels. Make sure to look at what apps you install in your workspace, as it is very attractive for hackers to create an innocent looking App that actually also listens for confidential information like passwords, urls, code samples, etc.

Let me know if this was interesting, and if you would like more articles that maybe go deeper into the API of Stdlib or something else!

--

--

Justus Romijn
Frontmen

I’m a frontend developer at Frontmen, a company that focuses on frontend only. Beside my work I also enjoy tennis & table tennis, music, movies and games!