Chat

Build A Simple Slackbot with Serverless Functions

4 min read Syed Ahmed on Dec 12, 2018

Everyone is using Slack. From sharing code to sending cat memes to your coworker at 2 am, Slack has become the go-to chat and collaboration platform for businesses. Unfortunately, messaging isn’t at the top of the productivity food chain.

What’s really rocking the minds of number-crunchers and thought leaders is the ubiquitous need for chatbots. Namely, Slackbots. The reasoning behind this is that a bot allows for 24-hour access to either task handling or information lookup without the need of another person. Think of it this way, without Slackbots, we’d be forced to schedule our own meetings. Oh, the humanity!

So You Want to Build a Slackbot?Slackbot PubNub

To get started, head over to the Slack API resource center and create a new Slack app. We’ll need to set a name and also a development Slack group. In my case, I’ve named mine PNbot and have assigned it to one of my groups.

Once our application is created, we’re given the option to add different functionality to our app. Since we’re focusing on creating a Slackbot, click into the option of Bots.

Creating a Slackbot

Inside the Bots section, we’ll be given the opportunity to add the username and display name for our bot. In both situations, I’ve chosen to name the bot pnbot. Keep in mind that there is a toggle near the bottom, that when selected, keeps the bot online. This makes sense in our scenario since, thanks to PubNub, our bot will be available approximately 99.999% of the time.

So we have our bot set now, but how will we get it working in our workspace? Simply click into the install app subheading in the settings section located in the sidebar. That’s it! Our bot should now be available in our demo workspace.

And with that, our bot is up and running! Now the next step is to check out the features section in the sidebar on the Slack API site. In that section, we’re going to look for the Event Subscriptions button and navigate to that. This will lead us to an empty page, but have no fear because if we click the toggle button, we can enable the feature.

Once enabled, notice that there is a space for a redirect URL. Don’t worry too much about that as we’ll be diving more into it as we build out our serverless Function. What we will be looking at is the workspace events just below the redirect URL. Here we can choose a number of events which have been properly outlined in the documentation. In our case, to make things simple, we’ll choose the mention event. This means that when the bot is mentioned in any channel that it’s present in, it will send a JSON payload with relevant information to the redirect URL. So far this is all we need for now.

Creating a Serverless Slackbot Function

First things first, you’ll have to sign up for a PubNub account. In this order, we’ll need to -> Create an app ->Navigate to the keyset -> click on the functions tab on the left. Here we’re going to create a new on-request module. What this means is that our module will act as a web-hook that the Slackbot can redirect to.

Now we have our Function configured, we’re going to need to set a path and copy the URL to set in the redirect URL field we were avoiding earlier. This will make it so that every time the bot is mentioned our function will receive a payload similar to this:

"request"
 {
    "verb": "rest",
    "pubkey": "your pub key",
    "subkey": "your sub key",
    "timetoken": null,
    "timetoken_v1": null,
    "timetoken_v2": null,
    "version": "v1",
    "meta": {
        "clientip": "100.25.152.207",
        "origin": "pubsub.pubnub.com",
        "useragent": "Slackbot 1.0 (+https://api.slack.com/robots)"
    },
    "params": {},
    "uri": "/your-path/bot",
    "path": "/bot",
    "method": "POST",
    "body": "{\"token\":\"token\",\"team_id\":\"T0431NL8C\",\"api_app_id\":\"AEQFW5DFV\",\"event\":{\"client_msg_id\":\"4d282463-9622-4979-ae71-2b073895711c\",\"type\":\"message\",\"text\":\"<@UEQEUM144> <@UEQG0576F>\",\"user\":\"UA69Q4A64\",\"ts\":\"1544556685.000600\",\"channel\":\"DES1K0SGN\",\"event_ts\":\"1544556685.000600\",\"channel_type\":\"im\"},\"type\":\"event_callback\",\"event_id\":\"EvESLB9J4E\",\"event_time\":1544556685,\"authed_users\":[\"UEQG0576F\"]}",
    "headers": {
        "user-agent": "Slackbot 1.0 (+https://api.slack.com/robots)",
        "content-length": "418",
        "accept": "*/*",
        "accept-encoding": "gzip,deflate",
        "content-type": "application/json",
        "pfunc-original-uri": "/your url/bot",
        "x-forwarded-host": "sub-key_js-on-rest",
        "x-slack-request-timestamp": "1544556686",
        "x-slack-signature": "v0=signature"
    }
}

Our bot is now connected to our Function, now we want our bot to start sending messages. Looking at the Slack documentation, we can see that the best way is by sending our message to the Slack web API.

In this case we’re going to enable incoming webhooks for our bot. This will allow us to be able to post to that webhook to have our messages sent. We can enable this feature by navigating to the sub-heading in the features section where we enabled events subscriptions.Slack Incoming Webhook

Once the authorization is done, the  endpoint we’re going to post to will look like this:

https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX

To test the functionality, inside of our serverless function, send the XHR request to the incoming webhook Slack provided us with a message.

export default (request, response) => {
    const pubnub = require('pubnub');
    const kvstore = require('kvstore');
    const xhr = require('xhr');
    let body = JSON.parse(request.body);
    
    const http_options = {
        "method": "POST",
        "headers": {
            "Content-Type": "application/json"
         },
        "body": JSON.stringify({
            "text": "cool story bro!!!"
        })
    };
    
    const url = "https://hooks.slack.com/services/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";
    
    response.status = 200;
    
    response.headers['X-Custom-Header'] = 'CustomHeaderValue';
    return xhr.fetch(url, http_options).then((x) => {
        return response.send(body);
    });
};

In this case, whenever our bot is mentioned in a channel, it will reply with “cool story bro!!!”.

Bot

Next Steps

And that’s it! If I’ve piqued your interest in bots or serverless, I highly recommend having a looking a few of these articles:

  1. How to Build Serverless Microservices with Functions
  2. A Crash Course in Functions
0