Slack Bot With a Django Backend — 101 Tutorial

How to familiarize yourself with building a bot for Slack using Django.

HarmonizeHQ
Chatbots Magazine

--

There are plenty of introductory tutorials on Slack bots but all of them seem to be overly simplistic that are extremely difficult to extend. We at Pep AI, have been building Slack bots like Pep and AttendanceBot that do substantial backend logic processing and we totally understand how daunting it is to extend a simple “hello world” to a backend heavy bot. This tutorial aims to bridge the gap between a simple hello world code snippet and a functional real world bot.

We assume that you are familiar with Django and that you have a Django project configured with an sqlite database (basically you have what django spits out after startproject).

The code for this tutorial is available on Github. Now, lets get coding.

1. Create a Slack App

Before you start, you will need a Slack Team (to test your bot on), a Slack App (a bot is always associated with an App). Once you create your app you will get a `client_id` and `client_secret` to use with OAuth.

Head to https://api.slack.com/apps/new to create a new app. You will be asked to specify a ‘redirect_uri’. Slack will send requests to this url when a user clicks on Add To Slack. Since we will be testing this bot on your local computer you can set the url as http://127.0.0.1:8000/slack/oauth/.

After you are done creating this app, go to the app settings page by going to https://api.slack.com/apps and then click on your app. Click on ‘Bot Users’ and add a bot user to your app. Give it a cool name like @cool_hand_luke :)

From the app settings page, copy your client id and client secret and add them to the Django settings file.

### tutorial/settings.pySLACK_CLIENT_ID = "YOUR CLIENT ID"
SLACK_CLIENT_SECRET = "YOUR CLIENT SECRET"

2. Add to Slack Button

Users can add your Slack bot to their team by clicking on the ‘Add To Slack’ button on your website. When a user clicks on Add To Slack button, a request is sent to https://slack.com/oauth/authorize with the following params:

  • client_id: Your client id
  • scope: The scope parameter is a space-separated list of OAuth scopes, indicating which parts of the Slack user’s account you’d like your app to be able to access. The complete list of scopes can be found here. We will only use ‘bot’ for the purpose of this tutorial.

There are more parameters and the recommended way is to add another ‘state’ parameter to avoid forgery attacks by passing in a value that’s unique to the user you’re authenticating and checking it when auth completes. But we’ll ignore this for now. Head to https://api.slack.com/docs/oauth see how Slack’s OAuth works.

Your “Add To Slack” button will look like this:

<a href=”https://slack.com/oauth/authorize?scope=bot&client_id=X">
Add To Slack
</a>

Step 3: Create a Django View For Adding Your Bot to the Team

We will create a simple landing page for our bot and place this button on that page.

### templates/landing.html<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Cool Hand Luke</title>
</head>
<body>
<h1>What we've got here is failure to communicate!</h1>
<a href="https://slack.com/oauth/authorize?scope=bot&client_id={{ client_id }}">
Add To Slack
</a>
</body>
</html>
### urls.py
from django.conf.urls import url
from . import viewsurlpatterns = [
url(r'^$', views.index),
]
### views.pyfrom django.conf import settingsdef index(request):
client_id = settings.CLIENT_ID
return render(request, 'landing.html', {'client_id': client_id})

When someone clicks on the button on your website, the OAuth process begins by asking them to choose their Slack team and account. If the user authorizes your app, Slack will redirect back to your specified redirect_uri (provided while creating the app) with a temporary code in a ‘code’ GET parameter.

Exchange this authorization code for an access token using the oauth.access API method (documentation) with the following params:

url: https://slack.com/api/oauth.access

  • client_id — issued when you created your app (required)
  • client_secret — issued when you created your app (required)
  • code — a temporary authorization code (required)

If all is well, Slack will approve the request and return the following JSON:

{ 
“access_token”: “xoxp-XXXXXXXX-XXXXXXXX-XXXXX”,
"user_id": "UXXXXXXXX",
“scope”: “bot”,
“team_name”: “Team Installing Your Hook”,
“team_id”: “XXXXXXXXXX”,
“bot”: {
“bot_user_id”:”UTTTTTTTTTTR”,
“bot_access_token”:”xoxb-XXXXXXXXXXXX-TTTTTTTTTTTTTT”
}
}

For any API request related to this team, like user info, channel info etc. you need to use the ‘bot_access_token’ from the above response. We will add a new Django model called Team to save details of this team.

# models.pyfrom django.db import modelsclass Team(models.Model):
name = models.CharField(max_length=200)
team_id = models.CharField(max_length=20)
bot_user_id = models.CharField(max_length=20)
bot_access_token = models.CharField(max_length=100)

Here is how the view.py and urls.py will look like:

### urls.pyfrom django.conf.urls import urlfrom . import viewsurlpatterns = [
url(r'^$', views.index),
url(r'^slack/oauth/$', views.slack_oauth),
]
### views.pyfrom django.conf import settingsdef slack_oauth(request):
code = request.GET['code']

params = {
'code': code,
'client_id': settings.CLIENT_ID,
'client_secret': settings.CLIENT_SECRET
}
url = 'https://slack.com/api/oauth.access'
json_response = requests.get(url, params)
data = json.loads(json_response.text)
Team.objects.create(
name=data['name'],
team_id=data['team_id'],
bot_user_id=data['bot']['bot_user_id'],
bot_access_token=data['bot']['bot_access_token']
)
return HttpResponse('Bot added to your Slack team!')

Now fire up ‘python manage.py runserver’ and add your bot to your Slack team. The bot is now ready to receive messages from your team.

Step 4: Listen For Events Using Python Slack Client

We will use Python Slack Client to listen to events. This plugin is a light wrapper around the Slack API. Almost everything that happens in Slack will result in an event being sent to all connected clients. The simplest event is a message sent from a user, which looks like this:

{     
"type": "message",
"ts": "1358878749.000002",
"user": "U023BECGF",
"text": "Hello",
"channel": "DXXXXXXXX"
}

Click here for a full list of events.

We’ll create a listener which look for ‘hi’ messages and reply with ‘hello world’. We will add this listener as a management command, so that you start it up with ‘python manage.py listener’.

Create a python package ‘management’ in ‘slackbot’ and ‘command’ in ‘management’. Create a new file ‘listener.py’ in this directory and add the following code to it.

### slackbot/management/commands/listener.pyfrom .models import Team
from slackclient import SlackClient
from django.core.management.base import BaseCommand
import time
class Command(BaseCommand):
help = 'Starts the bot for the first'
def start_listening(self):
team = Team.objects.first()
client = SlackClient(team.bot_access_token)
if client.rtm_connect():
while True:
events = client.rtm_read()
for event in events:
if event['type']=='message' and event['text']=='hi':
client.rtm_send_message(
event['channel'],
"Hello World!"
)
time.sleep(1)

Thats it!

Fire it up with ‘python manage.py listener’ and you should have a simple Slack bot working. Send direct messages to this bot from your slack team, the bot should now respond to ‘hi’ messages with “Hello World”.

That’s all folks! Of course we’re not using the real power of a Django backend here but since the bot works very closely with Django models, you can save contexts, states, run tasks etc and create a really smart experience.

Next up, we will introduce some user state and data models to extend this simple bot to a more powerful real world application.

👏👏Clap below to recommend this article to others👏👏

--

--