How to build a Slack Bot with Python using Slack Events API & Django under 20 minute— Code Included

Slack is a great platform for team collaboration not just that it also has one of the best API interfaces to build Chatbots. Chatbots come in all size from reminding you to buy milk to help you send or receive money.

In this post, I will walk you through building a minimal Slack Bot with Python backend. The idea is to set up a Slack Bot that will greet you back when greeted, once we have it up and running then we can extend the Bots ability just by coding additional logic.

Minute 1: Slack

  1. If you are new to Slack, it’s a messaging platform focused on team collaboration. Slack lets you create custom applications, including bots (sort of Messaging Platform as a Service). You will run the application back end to process business logic in your own server.
  2. To startwith you need to be part of Slack team and have admin privilege to create a new Slack App. If you are not part of a Slack team you may create one.
  3. We will create a Slack App for the Slack team then we will add a Bot User to the app.
  4. We will create a Django based REST backend web application to process the Bot User requests.
  5. Since we will be running the backend in our local system, we will use ngrok to tunnel our local network and get a public url.
  6. Once the backend is ready we can submit the endpoint url to Slack for url verification by challenge. When you submit an endpoint for the first time Slack will send a challenge POST request with a secret token. To successfully complete the challenge you need to return the request with the challenge secret (you just have to echo the received message). This is a one time excercise for a given api endpoint.
  7. Once verified we can subscribe to events for which we want Slack to send a message to our backend. This is the best part you dont have to pool Slack to get new events, Slack will do the heavy lifting, which makes this an excellent use case for AWS Lambda. You can find the long list of events here.
  8. After setting up Slack App and have the backend ready to process events, we can write the bot logic to perform a specific task in response to an event. In this case when a user greets, our bot will respond with a greet message.

Lets dive into Bot Building…

Minute 2: Create a Slack App

Then you will be taken to App configuration where you need do following to get our Bot up and running.

  1. Create a Bot User
  2. Install Slack App to your Team
  3. Verify Back End
  4. Subscribe to Events

On the left pane click on Bot User then choose an user name for the Bot and set “Always Show My Bot as Online” slider to on. Since we are going to use Events API only, the bot will not appeare online otherwise. Click on Add Bot User to create our hello bot.

Minute 3: Install Slack App to Team

Once installed you will get Bot User OAuth Access Token, note down this token we will need it later while configuring Django app. This token is the passphrase for our Bot to interact with the Slack Team. We will refer to this token as SLACK_BOT_USER_TOKEN in rest of the tutorial.

Minute 4: Slack Client Credentials

Now we should have four key values with us

  1. Client ID — SLACK_CLIENT_ID
  2. Client Secret — SLACK_CLIENT_SECRET
  3. Verification Token — SLACK_VERIFICATION_TOKEN
  4. Bot User Token — SLACK_BOT_USER_TOKEN

We have one last step left in Slack App configuration, which is to submit our Bot’s REST API end point to Slack and get it verified.

Before we Verify our Bot and subscribe for the events, we need to have the Django app running.

Minute 5: Environment Setup

  1. Django
  2. Django REST Framework
  3. Slack Client for Python
  4. Slack Events API

We will use conda for virtual environment and pip for package management. Let us create new virtual environment “slack_bot” for our project with python version 3.5.x and activate the virtual environment.

conda create -n slack_bot python==3.5# windows
activate slack_bot
# mac os, linux
source activate slack_bot

Now lets install required packages

pip install django
pip install djangorestframework
pip install slackclient
pip install slackeventsapi

Minute 6: Create Django Application

django-admin startproject slack
cd slack
django-admin startapp events

Now your project folder structure should look like this. From now on all the file path I mention assumes slack, the project folder, as root.

└── slack
├── events
│ ├── admin.py
│ ├── apps.py
│ ├── __init__.py
│ ├── migrations
│ │ └── __init__.py
│ ├── models.py
│ ├── tests.py
│ └── views.py
├── manage.py
└── slack
├── __init__.py
├── __pycache__
│ ├── __init__.cpython-35.pyc
│ ├── settings.cpython-35.pyc
│ ├── urls.cpython-35.pyc
│ └── wsgi.cpython-35.pyc
├── settings.py
├── urls.py
└── wsgi.py

Minute 7: Configure Django Settings

# slack/settings.pyINSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework', # <== add this line
'events', # <== add this line
]

Then add following configurations in slack_bot/settings.py with your authentication keys from Slack.

# slack/settings.py# SLACK API Configurations
# ----------------------------------------------
# use your keys
SLACK_CLIENT_ID = '20xxxxxxxxxx.20xxxxxxxxxx'
SLACK_CLIENT_SECRET = 'd29fe85a95c9xxxxxxxxxxxxxxxxxxxxx'
SLACK_VERIFICATION_TOKEN = 'xpxxxxxxxxxxxxxxxxxxxxxxxxx'
SLACK_BOT_USER_TOKEN = 'xoxb-xxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxx'

Please do not check in your code into any public repository like Github with these values saved. Ideally these values should be exported as environment variables and read by startup scripts.

Now start the Django development server

python manage.py runserver

Once the server is started it will print something similar to this

Performing system checks…
System check identified no issues (0 silenced).
You have 13 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
Run ‘python manage.py migrate’ to apply them.
July 03, 2017–17:30:32
Django version 1.11.3, using settings ‘slack.settings’
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

Ignore the migration warnings and open the URL in your browser.

Minute 8: Create an API endpoint

# events/views.pyfrom rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from django.conf import settings

SLACK_VERIFICATION_TOKEN = getattr(settings, 'SLACK_VERIFICATION_TOKEN', None)

class Events(APIView):
def post(self, request, *args, **kwargs):
slack_message = request.data if slack_message.get('token') != SLACK_VERIFICATION_TOKEN:
return Response(status=status.HTTP_403_FORBIDDEN)
return Response(status=status.HTTP_200_OK)

In the code above we are importing the required python packages, retreiveing the token saved in configuration then defining an API view to handle POST request.

In the POST function we are checking if the token in message matches our Bot User’s verification token, this is to validate if the incomming request was actually from Slack. If there is match we are sending “OK” message else telling that the requester is “Forbidden” from accessing our server.

Minute 9: Configure Django Routes

Add following lines in slack/urls.py to tie Events API class to http://localhost:8000/events/

# slack/urls.pyfrom django.conf.urls import url
from django.contrib import admin
from events.views import Events #

urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^events/', Events.as_view()), #
]

Open the server url in your browser, you will find bowserable API interface.

Note: Usually we will create a separate routing file for each app and register it with the project route. To keep the code simple I have defined the events app url in the project route file.

Minute 10: Slack URL Verification Challenge

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from django.conf import settings

SLACK_VERIFICATION_TOKEN = getattr(settings, 'SLACK_VERIFICATION_TOKEN', None)


class Events(APIView):
def post(self, request, *args, **kwargs):

slack_message = request.data

if slack_message.get('token') != SLACK_VERIFICATION_TOKEN:
return Response(status=status.HTTP_403_FORBIDDEN)

# verification challenge
if slack_message.get('type') == 'url_verification': #
return Response(data=slack_message, #
status=status.HTTP_200_OK) #

return Response(status=status.HTTP_200_OK)

What we are doing here is checking if the request is an url verification, if yes then relaying the same message back.

Minute 11: The Greet Bot

In the Events API add following lines marked by #

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from django.conf import settings
from slackclient import SlackClient #1


SLACK_VERIFICATION_TOKEN = getattr(settings, 'SLACK_VERIFICATION_TOKEN', None)
SLACK_BOT_USER_TOKEN = getattr(settings, #2
'SLACK_BOT_USER_TOKEN', None) #
Client = SlackClient(SLACK_BOT_USER_TOKEN) #3


class Events(APIView):
def post(self, request, *args, **kwargs):

slack_message = request.data

if slack_message.get('token') != SLACK_VERIFICATION_TOKEN:
return Response(status=status.HTTP_403_FORBIDDEN)

# verification challenge
if slack_message.get('type') == 'url_verification':
return Response(data=slack_message,
status=status.HTTP_200_OK)
# greet bot
if 'event' in slack_message: #4
event_message = slack_message.get('event') #

# ignore bot's own message
if event_message.get('subtype') == 'bot_message': #5
return Response(status=status.HTTP_200_OK) #

# process user's message
user = event_message.get('user') #6
text = event_message.get('text') #
channel = event_message.get('channel') #
bot_text = 'Hi <@{}> :wave:'.format(user) #
if 'hi' in text.lower(): #7
Client.api_call(method='chat.postMessage', #8
channel=channel, #
text=bot_text) #
return Response(status=status.HTTP_200_OK) #9

return Response(status=status.HTTP_200_OK)

What we have done is

  1. Imported Slack Client package.
  2. Retrived Slack Bot User Token from settings.
  3. Created a Client instance to post bot response to Slack.
  4. If event data is available in the received message, then process the message.
  5. The message posted by bot to a channel will be received by the bot again as part of receipient. So the bot message must be ignored by bot.
  6. If the message is from a user then process the event. Extract user id, channel id and the user message to bot. Then build the bot’s greet message with user name.
  7. If the user message contains the greet word “hi”, then proceed with posting the greet message.
  8. We are invoking Slack Client API to post the Bot response message to the channel via chat.postMessage.
  9. Once the message is posted return OK to the Slack event.

Here a depiction of the bot logic.

Minute 12: Tunneling with ngrok

Once you have setup ngrok

  1. Start Django server with command
python manage.py runserver 0.0.0.0:8000

2. Use ngrok to bind your Django port to a public domain as follows

ngrok http 8000

ngrok will create a public URL and forward the requests to your server, you will see something like below on successful binding.

To access your Bot API go to http://<your-unique-id>.ngrok.io/events/

Minute 13: Submitting URL to Slack

Your URL should pass the verification challenge.

Then scroll down to subscribe for channel message and direct message.

Minute 14: Thats All Folks

freehunch

freehunch is an initiative to help data scientist build data products from abstract ideas. We will discuss tools and technologies that will enable data scientist to build cloud-native, containerized, high-performance data products.

Prabakaran Kumaresshan

Written by

data geek

freehunch

freehunch

freehunch is an initiative to help data scientist build data products from abstract ideas. We will discuss tools and technologies that will enable data scientist to build cloud-native, containerized, high-performance data products.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade