This is a sample application I made for teaching how to integrate Slack with Django.
With these principles, you can :
- Interact with your Django application directly from Slack using a Slash Command.
- Send the content of a form in Slack instead of using Emails using Django Forms
- Send a message in Slack based on Django Signal in your application (ex: when a new user signs up)
- And many more
All this code comes with unit tests, enjoy!
This is the Django project folder containing the settings.py
and the main urls.py
.
Once you created a Slack App and have written your credentials in .env
(see below) you can install the dependencies and run the project mostly like any other Django project.
source .venv/bin/activate
pip install -r requirements.txt
python manage.py runserver
In settings.py
, along with the regular Django Settings, I've added
SLACK_TOKEN = os.getenv("SLACK_TOKEN")
SLACK_SIGNING_SECRET = os.getenv("SLACK_SIGNING_SECRET")
These variables are found in Slack API App Dashboard. Instead of editing settings.py
, I highly recommend to create a file called .env
at the root of this repository which will be load automatically and, most importantly, ignored by git.
# ./env
SLACK_TOKEN=paste_your_slack_token_here
SLACK_SIGNING_SECRET=paste_your_slack_signing_secret_here
I've added a few extra to this project to improve the developer experience. They will be installed with pip.
- venv Python's virtual environnement tool to isolate project and dependencies
- Pylint A static code analyzer to enforce best practices and python standards
- autopep8 A formatter for PEP8 Style Guide for Python Code
- pytest Unit test framework that improves on Python's unittest library
- python-dotenv Reads from
.env
and sets them as environnement variables - isort Sort your imports, so you don't have to.
- Github Actions Automatically run tests on every push
.vscode/settings.json
to integrate all of this with VSCode
I've also added the depencencies and config required for their integration with Django and VSCode.
You can start the test suite simply by typing pytest
in a terminal or you can run them directly in VSCode
This is a Django app that uses Django Forms
and Django's generic FormView
to send a message in Slack.
# forms.py
from django import forms
from django.conf import settings
from slack_sdk import WebClient
class SlackButtonForm(forms.Form):
channel = forms.CharField()
text = forms.CharField()
def send_slack_message(self):
client = WebClient(token=settings.SLACK_TOKEN)
client.chat_postMessage(channel=self.cleaned_data['channel'], text=self.cleaned_data['text'])
# views.py
from django.contrib import messages
from django.urls import reverse_lazy
from django.views.generic import FormView
from slack_sdk.errors import SlackApiError
from slack_button.forms import SlackButtonForm
class SlackButtonView(FormView):
template_name = "slack_button/slack_button.html"
form_class = SlackButtonForm
success_url = reverse_lazy("slack-button")
def form_valid(self, form):
try:
form.send_slack_message()
messages.success(self.request, "Message sent successfully")
except SlackApiError as e:
messages.error(self.request, e.response["error"])
return super().form_valid(form)
This Django app creates a model so you need to perform the migrations :
python manage.py migrate
Signals are attach to post_save
and post_delete
to send a notfication in Slack.
# signals.py
from django.conf import settings
from django.db.models.signals import post_delete, post_save
from django.dispatch import receiver
from slack_sdk import WebClient
from slack_signals.models import Todo
slack_channel = "general"
@receiver(post_save, sender=Todo)
def todo_notify_save(instance, created, **_kwargs):
action = "Created" if created else "Updated"
text = f"Todo {action}: {instance}"
client = WebClient(token=settings.SLACK_TOKEN)
client.chat_postMessage(channel=slack_channel, text=text)
@receiver(post_delete, sender=Todo)
def todo_notify_delete(instance, **_kwargs):
text = f"Todo Deleted: {instance}"
client = WebClient(token=settings.SLACK_TOKEN)
client.chat_postMessage(channel=slack_channel, text=text)
This app uses a plain function view to receive events from Slack API. This is where we'll need the Slack Signing Secret. It will verify that the request really comes from Slack.
But first we need to setup a Slash Command.
Slack will need a URL to send information to. If you're running the app locally, your laptop is probably not configured to be reachable from the internet. For this, I use popular reverse proxy called ngrok.
When your app is running locally (by default on port 8000), you can simply open another terminal and type [ngrok http 8000] and it will start a reverse proxy. For example, it will give you something like this
Session Status online
Account __@__.com (Plan: Free)
Version 2.3.40
Region United States (us)
Web Interface http://127.0.0.1:4040
Forwarding http://0d33-24-48-109-62.ngrok.io -> http://localhost:8000
Forwarding https://0d33-24-48-109-62.ngrok.io -> http://localhost:8000
If you click on the https url (ex: https://0d33-24-48-109-62.ngrok.io) you'll be able to access your local application from the internet.
For the Slash Command Request URL, use this URL but append the path to our webhook (/slack-webhook/
) which gives somethings like
https://xxxx-xx-xx-xxx-xx.ngrok.io/slack-webhook/
The final code looks like :
# views.py
from django.conf import settings
from django.http import HttpResponseForbidden, JsonResponse
from django.views.decorators.http import require_POST
from django.views.decorators.csrf import csrf_exempt
from slack_sdk.signature import SignatureVerifier
@require_POST
@csrf_exempt
def webhook_view(request):
verifier = SignatureVerifier(signing_secret=settings.SLACK_SIGNING_SECRET)
if not verifier.is_valid_request(request.body.decode("utf-8"), request.headers):
return HttpResponseForbidden()
return JsonResponse({"text": "Hello from Django!"})