Building a Karma Bot with Python and the Slack API

Bob, Sun 25 June 2017, Tools

API, bot, Counter, karma, logging, packaging, picle, Slack

We love Slack! But what if we can make it even cooler? Imagine: you are geeking out with your fellow developers on Slack and you want to give them credit. Or you can write "stupidsubject--" and it automagically shows "stupidsubject's karma decreased to -2". Enter Karma Bot. This is nothing new but building one myself was a great learning exercise and a fun tool we use on our Slack now.

I will show you how I implemented our Karma Bot using Slack's Real Time Messaging API. I hope to extend it into an open source package later on adding tests, docs, setup file, etc. I will document progress in future articles.


This exercise is similar to our How to Build a Simple Slack Bot article. First you create a bot user and get an API_KEY from Slack.

The bot user needs to be defined as ID so you need to retrieve it for which I made a helper script:

$ python3 -m utils.get_botid
Bot ID for 'karmabot' is xyz

(This calls the script in the utils package. More on packaging next week ...)

Then I stored the following two env variables in my bashrc:

export SLACK_KARMA_TOKEN=super-secret

As we will see next week makes a folder a package. You can use this file to do setup. I read env variables in, define my (regex) constants, instantiate the SlackClient object to talk to the Slack API, and setup logging and caching. See


The code for this project is here.

The script is the driver calling methods from the bot package (folder):


When we built our first Slack bot for How to Build a Simple Slack Bot we needed a way to keep the bot alive even if it crashed or the process was terminated by the OS. For Karma Bot I went with the same workaround as then: a wrapper that respawns. So if you want to use this code yourself, you would kick it off like this:

$ nohup ./ &


Test session in private Karma Bot channel:

karma example

You need to invite the bot to any channel you want to use this in.

More on packaging

My first attempt at this was one big script. I then splitted it out into different modules (responsabilities). Unfortunately I did not commit the initial script to compare. No worries though. Next week I go back to basics on modules and packaging, explaining how they work. I will explain how we import from them which often leads to confusion.

Update 07/08/2017

I refactored this project for Code Challenge 30 - The Art of Refactoring: Improve Your Code, see the review here.

Keep Calm and Code in Python!

-- Bob

PyBites Python Tips

Do you want to get 250+ concise and applicable Python tips in an ebook that will cost you less than 10 bucks (future updates included), check it out here.

Get our Python Tips Book

"The discussions are succinct yet thorough enough to give you a solid grasp of the particular problem. I just wish I would have had this book when I started learning Python." - Daniel H

"Bob and Julian are the masters at aggregating these small snippets of code that can really make certain aspects of coding easier." - Jesse B

"This is now my favourite first Python go-to reference." - Anthony L

"Do you ever go on one of those cooking websites for a recipe and have to scroll for what feels like an eternity to get to the ingredients and the 4 steps the recipe actually takes? This is the opposite of that." - Sergio S

Get the book