Slack Score Bot

January 13, 2016

Let me start off with, there’s a TL;DR down below.

I’m hard pressed to think that there’s anybody out here who haven’t at least heard about Slack, but just to be on the safe side, here’s what wikipedia defines Slack as:

Slack is a cloud-based team collaboration tool co-founded by Stewart Butterfield, Eric Costello, Cal Henderson, and Serguei Mourachov. Slack began as an internal tool used by their company Tiny Speck in the development of Glitch, a now defunct online game

Wikipedia on Slack

Right, so that wasn’t very useful, let me try to define Slack:

Slack is basically IRC, but with a nicer frontend, in other words, it’s a chat application.

— Benjamin on Slack

Anyway, in one of the, eh, chat rooms (it’s called teams in Slack terms), we kept on giving points to people when we agreed, or removed points when we disagreed, we simply wrote Users->get(Username)->addPoint() (we’re a gang of developers, bare with me). This works in the sense that you understand if the person agrees or not with what you’ve said, but it didn’t take long before we needed wanted a way to see who’s acquired the most points in total.

After looking into the slack’s outgoing webhooks and incoming webhooks, we concluded it would be fairly simple to build something.

So off I went and built the “bot” (it’s not really a bot, since the only thing is keep track off score on different users), obviously all of the code is up on github.

I decided to use Dice as the IOC container, mostly because I like how easy it is to use, and the minimal amount of bloat, all the classes are configured /src/bootstrap.php.

Initially I was going to setup a database, but after thinking about it, I decided against it. There won’t ever be enough data to need a db, nor will the application have any relationships in the data set, plus, without the database, the app is a lot more portable.

Installation

It’s pretty simple how everything works, first and foremost, you need to set up a server which runs PHP (with curl), clone the code from github, point your webserver to the /public/ folder in the repo, and check that the app has a public url. You also need to make sure that the webserver user is able write in the folder /data/.

The server is probably going to throw an error at this point, but that’s because we haven’t yet configured the application.

Configuration

Slack’s Slash Commands

First we need to make slack understand our slash command, which is /score. You’ll need to go to your teams app page, which is located at https://[YOUR_TEAM_NAME].slack.com/apps/manage/custom-integrations, once there, click on slash commands and then add configuration. You should now be presented with a screen asking for the command, write “/score” and click Add slash command configuration.

Scroll down a bit on the page to Integration Settings and enter/verify the following data:

Command        = /score
Url            = http://URL_TO_YOUR_WEBSERVER
Method         = POST
Customize name = ScoreBot
Autocomplete help text
description    = Adds or subtracts score from a user
Usage hint     = [+1] [username]

There should be a field called “Token”, save the string that’s inside of that field, you’ll need it later.

Click on Save integration, now slack can communicate with the webserver.

Slack’s Incoming WebHooks

Now we need the server to be able to send data back to slack. You’ll need to go to your teams app page, which is located at https://[YOUR_TEAM_NAME].slack.com/apps/manage/custom-integrations, once there, click on Incoming WebHooks and then add configuration.

Set the channel to general and click Add Incoming WebHooks integration.

Scroll down a bit on the page to Integration Settings and enter/verify the following data:

Channel           = #general
Descriptive Label = Score bot
Customize Name    = ScoreBot

There should be a field called “Webhook URL”, save the URL that’s inside of that field, you’ll need it later.

Click on Save settings, now your server will be able to communicate with slack.

Server configuration

Since everything should be configured on slack’s end, you need to configure your webserver next. Copy the file config.example.php to config.php and open it up for editing.

The config file looks like this, now you need to add the token and the WebHook URL from the previous steps.

$config = array(
    /* Incoming webhook url */
	'posturl' => '',

    /* Name the bot should post as */
    'username' => 'scoreBot',

    /* Channel the bot should post in */
    'channel' => '#general',

    /* Slack command token, leave empty or set to false if you don't want to check the incoming values */
    'token' => '',

    /* Where the JSON file with the user data is stored */
    'users' => realpath(dirname(__FILE__)) . '/data/users.json',

    /* Phrases that the bot should post in #general when score is added/removed
     * :from - the one who issued the command
     * :to - the user targeted
     * :score - the score command -1/+1 */
    'phrases' => [

        // If score is added, random from this list
        'positive' => [
            ':from hugged :to with :score points'
        ],

        // If score is reduced, random from this list
        'negative' => [
            ':from slapped :to in the face with a :score reduction'
        ]
    ]
);

You can add more response phrases by adding them either to the negative or positive array, they’ll be randomly picked as a response when the scoreBot post back to slack with a response of score changes.

Commands

There’s not all too many commands to operate the score bot, it basically boils down to three commands. When it comes to increasing/decreasing score, you can only do so in steps ranging from -10 to +10, and you cannot issue the command on yourself.

1. Increase other user’s score

/score +1 @otherUser
This will add one point to @otherUser, if the user doesn’t previously exist in the scoring system, the user will be added automatically with zero points, before the score change.

The server will respond with a random positive phrase from the configuration and post it publicly to the #general channel.

2. Decrease other user’s score

/score -1 @otherUser
This will remove one point from @otherUser, if the user doesn’t previously exist in the scoring system, the user will be added automatically with zero points, before the score change.

The server will respond with a random negative phrase from the configuration and post it publicly to the #general channel.

3. See current stats

/score list
Outputs a list with all users and their corresponding current score. The output is posted in #general and will only be visible to the one who issued the command.

Storage

As I mentioned earlier, the application doesn’t use a database but instead stores everything in a file. The file in question is created if it doesn’t exist in /data/users.json. As you can tell from the filename, it’s a simple JSON object.

[
    {
        "name": "fooBar", // The slack name
        "score": -5, // The current score
        "alias": [ // additional names that this user should respond to
            "foo bar",
            "foo",
            "bar"
        ]
    },[...]
]

You generally won’t need to change anything in this file, but it’s worth mentioning that you can added aliases to users. A user can have an unlimited amount of aliases, and the increase/decrease will work with the alias, but the scoreBot will always respond with using the “official” name.

Currently the only way to add an alias is to edit the actual JSON file, there’s no commands for adding aliases.

TL;DR

Slack score bot is basically a scoring system that integrates with Slack. All of the code is available on github, https://github.com/beije/slack-score-bot, and it has a pretty good readme as is.

Fork it, clone it, use it, or don’t.

Tags