Last week I was invited to the AWS Popup Loft in Tel-Aviv to give a talk about creating Slack bots and integrations. I wanted to see if I could push the limits of the Arduino platform and connect it directly to the Slack Real-Time Bots API, without any intermediate server.
Four hours and one pull-request later, I finally created the first Arduino Slack Bot ever. I connected it to a slack channel where the meetup attendees hanged, and they were able to change the color of my shirt during my talk.
Now how cool is that?
For my project, I used the WeMos D1 Mini — A tiny ESP8266-based board that can run Arduino code, has built-in WiFi support, and is small enough to hide behind my shirt’s pocket. The best thing about the WeMos D1 Mini is the price: you can get it for just $4 USD from the official manufacturer’s shop.
The other ingredient you will need is a RGB LED Ring. I used a ring with 24 NeoPixel LEDs. These LEDs need only single digital pin for control, you can chain them together, and they come with an excellent Arduino library that allows you to control the color of each led individually. You can get the official 24-LED Ring from AdaFruit for $16.95 USD, or find cheaper ones on eBay (search for “24bit ring WS2812B”).
Configuring your Arduino Environment
First of all, make sure you have Arduino 1.6.7 or newer. You can download the latest version here. Then, you will need to set up your Arduino environment for ESP8266 development, as explained in this AdaFruit tutorial.
You can check you setup by running the ESP8266 Blink example. Make sure that the correct board is selected in the Board section of the Tools menu. If you use the WeMos board, choose “WeMos D1 & R2 Mini”. Also make sure to select the correct Serial port in the Port section of the Tools menu.
Next, open the File menu, and then select Examples > ESP8266 > Blink. Upload the Sketch to the board, and the on-board LED should start blinking.
Install the NeoPixel, ArduinoJson and WebSocket Libraries
We will use several open source libraries:
- WebSockets for conecting to Slack’s Real-Time Bot API
- ADAFRUIT_NeoPixel for controlling the LED Ring
- ArduinoJson for constructing JSON messages
You can install these libraries directly through the Arduino IDE by opening the Sketch menu, then clicking Include Library> Manage Libraries…, and installing the AdaFruit NeoPixel, ArduinoJson and WebSockets (v2.0.2 or newer) libraries:
Connecting the NeoPixel Ring
Connect the NeoPixel Ring to your WeMos D1 Mini as follows:
- NeoPixel VCC ↔ WeMos 5V
- NeoPixel GND ↔ WeMos G
- NeoPixel IN / DI ↔ WeMos D2 pin
The nice thing about the D1 Mini is that it can actually fit in the interior part of the ring:
Testing the Ring
To test the ring, copy the following program to your Arduino IDE and run it. It should animate the ring nicely between red, green and blue in a loop:
Setting up the Slack Bot
Let’s create our Slack Bot!
First of all, we need to set up a few things on the slack side.
- Open this link: https://slack.com/apps
- Click on “Build Your Own” (on the top-right corner)
- Click on “Make a Custom Integration” (right pane)
- Select the “Bots” option
- Choose a username for your bot - I went for “Shirley”, then click on “Add bot integration”
- Copy the API token of the bot, we will need it soon. Customize the bot details and avatar to your liking, and click “Save”.
Connecting Arduino with Slack
Connecting to Slack’s Real Time Messaging API comprises two steps:
- Performing an rtm.start API call via the Slack REST API — We send the API token from the previous step and get a JSON response with the URL of the Real Time Messaging API WebSocket
- Opening a WebSocket connection to the slack server
This is what it would look like in code:
Before running this code, make sure to set the three defines on the top: SLACK_BOT_TOKEN, WIFI_SSID and WIFI_PASSWORD.
Note that the JSON returned by the rtm.start API call can be very verbose and may not fit in memory. Thus, I decided to simply stream the reply until I see something that resembles a websocket URL, by looking for the text “wss://”, and then manually parse the host and the path out of the URL. This approach works well with only 4 lines of code.
When running this program, open the Serial Monitor and set the Baud Rate to 115200. You should see the program connecting to your WiFi, and then establishing connection with slack and start printing the JSON messages received from the Slack RTM API, such as:
If you PM your bot through slack, your message will also appear in the output.
The magic, however, lasts only for a few seconds — slack will quickly drop the connection, unless you start sending ping messages. Luckily, the code for sending ping messages is quite simple. I used the ArduinoJson library for constructing the ping messages:
Call this function immediately upon establishing the web socket connection, and then call it again every 5 seconds. This will ensure that your connection with slack stays alive.
Putting Everything Together
We managed to put together a simple Arduino program connects to Slack and listens for events through the Real Time Messaging API. By using the NeoPixel code we created above, we can now make the ring change colors according to commands received through slack.
You can find the final code for the bot in my GitHub repository:
The code implements a reconnect mechanism, as well as code to parse the color names out of slack messages. The bot will pick up any color name that appears in a message, and will animate the NeoPixel ring accordingly. You can include several colors, as well as the word “zebra”, to create interesting animations:
red green blue zebra yellow
You can also try the special “rainbow” effect.
What Will You Build Next?
We did it!
A functional Slack bot running on 4$ Arduino hardware. I showed you how I built mine, and now it is your turn to come up with awesome ideas for Slack device-bots and build them. Here are some ideas from the top of my head:
- A bot that has a temperature sensor and reports to slack. Then, connect it to the AC switch and control the AC directly from your slack channel!
- Connecting your Cat Feeder to Slack 🐱
- Use the Arduino-IRremote library to control your TV and switch channels through Slack
I am sure that you can come up with even more creative ideas. So please go ahead and share them in a comment :-)