Slack is a great platform for team collaboration not just that it also has one of the best API interfaces to build Chatbots.
In this post, I will walk you through building a minimal Slack Bot with Django backend. The idea is to set up a Slack Bot that will notify event when greeted through a backend.
Before we start let us understand the Slack bots life cycle:
- 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.
- To start with, you need to be part of the 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.
- GIve the name of your company or team.
- Enter Channel Name.
- Click on See your channel in slack
- We will create a Slack App for the Slack team then we will add a Bot User to the app.
- We will create a Django based backend web application to post the messages into slack.
- After setting up the Slack App and have the backend ready to notified events.
Create a Slack App
Start by creating a Slack app here, click Create App. Then proceed with app creation, give it a name and select the Slack team.
Then you will be taken to App configuration where you need do following to get our Bot up and running.
- Create a Bot User
- Install Slack App to your Team
Create a BOT User
On the left pane click on Bot User then choose a user name for the Bot and set “Always Show My Bot as Online” slider to on. Click on Add Bot User to create our shipment bot.
Install Slack App to Team
Now on the left pane click Install App and install the app to your Slack 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.
Slack Client Credentials
Also, note down the App Credentials from Basic Information on the left pane. These credentials let us talk to Slack API, so every time we send a message to Slack we should send our Client ID(CLIENT_ID) & Client Secret(CLIENT_SECRET) to identify ourselves to Slack. Similarly, we can verify if an incoming message is sent by Slack checking if the Verification Token (VERIFICATION_TOKEN) in the message is the same as the one in App Credentials.
Now we should have four key values with us.
- Client ID — SLACK_CLIENT_ID/li>
- Client Secret — SLACK_CLIENT_SECRET
- Verification Token — SLACK_VERIFICATION_TOKEN
- Bot User Token — SLACK_BOT_USER_TOKEN
Environment Setup
Let us create a new virtual environment “venv” for our project with python version 3.6.x and activate the virtual environment.
1 |
virtualenv venv –python=python3.6 |
You need to activate the virtual environment before installation of other dependencies.
1 |
source venv/bin/activate |
Now let’s install required packages
1 2 3 |
pip install django pip install slacker pip install slacker-log-handler |
Create a Django Application
1 2 3 |
django-admin startproject shipment_portal cd shipment django-admin startapp shipment |
Configure Django Settings
we need to add our own application shipment as a dependency. Add the line mentioned below in the file slack/settings.py
# slack/settings.py
1 2 3 4 5 6 7 8 9 |
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'shipment', # <== add this line ] |
Then add following configurations in slack_bot/settings.py with your authentication keys from Slack.
# slack/settings.py
1 2 3 4 5 6 7 |
# 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' |
Now start the Django development server
1 |
python manage.py runserver |
Once the server is started it will print something similar to this
1 2 3 4 5 6 7 8 |
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 ‘shipment_portal.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.
Create an API endpoint
Now that we have our app server up and running we need to create an endpoint for Slack to send event messages. We will create an API view with Django as follows:
Shipment/view.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
class ShipmentCreate(LoginRequiredMixin, View): def post(self, request, *args, **kwargs): try: user = request.user.id =============== Your code goes here............ =============== response = { 'status': 200, 'type': '+OK', 'message': 'Shipment created', } message = 'Shipment created by' + user send_notification(message, channel='#general') except Exception as error: response = { 'status': 500, 'type': '-ERR', 'message': 'Internal Server Error', } return JsonResponse(response, status=response.get('status')) |
Configure Django Routes
If you are new to web applications, routing is the way to tell web server which functions to invoke when an URL is hit with a request. When the URL is hit with a request message the corresponding function will be invoked, passing the requester message as a parameter to the function.
Add following lines in shipment/urls.py to tie shipment API class to http://localhost:8000/shipment/
1 2 3 4 5 |
from .views import * from django.conf.urls import url urlpatterns = [ url(r'^shipment/$', Shipment.as_view(), name='shipment'), ] |
slackapi.py
Functions written in slackapi.py are used to post notification/messages to slack.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
import os from datetime import datetime from slacker import Slacker from django.conf import settings slack = Slacker(settings.SLACK_SECRET_KEY) TEST_CHANNEL = os.environ.get('TEST_SLACK_CHANNEL', None) channel_details = { "#general": { "username": 'shipment-' + settings.ENVIRON, "icon_url": None, "icon_emoji": ":email:" }, "@Jeenal": {}, } def post_to_slack(message, channel, username=None, icon_url=None, icon_emoji=None): try: channel = TEST_CHANNEL or channel channel_info = channel_details.get(channel, dict()) slack.chat.post_message( channel=channel, text=message, username=username or channel_info.get("username"), icon_url=icon_url or ((not icon_emoji) and channel_info.get("icon_url")) or None, icon_emoji=icon_emoji or ((not icon_url) and channel_info.get("icon_emoji")) or None, as_user=False ) except Exception as e: slack_logger.error('Error post message to slack\n', exc_info=True) def send_notification(message, channel): try: post_to_slack(message, channel) except Exception as e: slack_logger.error('Error send notification to slack\n', exc_info=True) |