November 13, 2016 · Python Bots

Building a Slack Bot to Talk with a Raspberry Pi in Python

I. Introduction

In this guide, we'll build a simple Slack Bot using Python that will tell us about the Pi's CPU and memory usage. This would allow us to check on our Raspberry Pi while out of our home network, without having to configure our network for public access.

We'll also make use of the psutil library I used in my previous Arduino Tiny Dashboard project.

We can look at bot users as scripts that login to a Slack team just like a normal user would. They can be added and removed from a channel. They can listen to conversations in the channels they belong to. More importantly, they can be run on a Raspberry Pi!

II. Set up Slack

We start off by adding a new Bot to our Slack team.

To do this, login into your Slack team webpage (https://slack.com/).

Then, go to https://my.slack.com/services/new/bot and choose a username for your bot. In this example, I named my bot "pibot".

After submitting the form, we now have an API Token. Take note of this, we'll need it later.

And we're done with the configuration part.

III. The Python Client

We can now start building our Python client. This will be the script we run on our Pi.

A. Install Dependencies
pip install psutil
pip install slackclient
B. The Python Script

We can finally start coding! You can check out the full script here.

First, we import our dependencies

import re
import time
import json
import psutil
from slackclient import SlackClient

We then initialize our Slack client. Here, we use the API token we generated earlier.

slack_client = SlackClient("your-api-token")

Usernames mentioned in messages received by our bot are translated into a <@userid> format. Thus, the message @benjiao Hey! is received by the bot as <@12345> Hey!.

In this next step, we fetch pibot's User ID. We will use this later to know when somebody is talking to our bot. We keep it in slack_user_id.

user_list = slack_client.api_call("users.list")
for user in user_list.get('members'):
    if user.get('name') == "pibot":
        slack_user_id = user.get('id')
        break

We can now start a connection...

if slack_client.rtm_connect():
    print "Connected!"

...and start our main loop! Here, we'll read each Real Time Message received by our bot.

    while True:
        for message in slack_client.rtm_read():

We check if the message contains text and starts with our bot's username.

            if 'text' in message and message['text'].startswith("<@%s>" % slack_user_id):
                print "Message received: %s" % json.dumps(message, indent=2)

We use Python's regular expressions library to check if the message contains the word "cpu". If so, we get the CPU utilization percentage using psutil, then we post a message in the same channel where the request was made.

                if re.match(r'.*(cpu).*', message_text, re.IGNORECASE):
                    cpu_pct = psutil.cpu_percent(interval=1, percpu=False)

                    slack_client.api_call(
                        "chat.postMessage",
                        channel=message['channel'],
                        text="My CPU is at %s%%." % cpu_pct,
                        as_user=True)

Similarly, we check whether the message has the word "memory" or "ram" in it. We then post a message containing RAM usage percentage.

                if re.match(r'.*(memory|ram).*', message_text, re.IGNORECASE):
                    mem = psutil.virtual_memory()
                    mem_pct = mem.percent

                    slack_client.api_call(
                        "chat.postMessage",
                        channel=message['channel'],
                        text="My RAM is at %s%%." % mem_pct,
                        as_user=True)

We wait a second before repeating the entire loop.

        time.sleep(1)

We can now start the client on a command line.

$ python pibot.py

Login to Slack, and add pibot into your Slack channel by typing /invite pibot.

Start sending messages, and watch it respond!

C. Deployment

You can now copy this script onto your Raspberry Pi, install the dependencies, and run it there.

A simple way to keep it running even after closing your SSH window is to use screen.

Install screen

sudo apt-get install screen -y

Start a new screen named pibot

screen -S pibot

Run the script

python pibot.py

Detach from screen -- this will keep our script running in the background

CTRL+A D

We can check back on it by reattaching to our screen

screen -R pibot

IV. Conclusion

Aaaand we're done! Of course, for the sake of discussion, our example was simplified. It might be a good idea to keep things in separate modules when the bot gets bigger to keep our code neat. It's all up to you now.

There is so much more we can do with bots and this one is merely an introduction. Here's me talking with torrentbot. Another bot I made to manage my Transmission torrent downloads.