Skip to content

Commit 51edf84

Browse files
authored
Update the Django example (#348)
1 parent 51daa12 commit 51edf84

File tree

24 files changed

+441
-241
lines changed

24 files changed

+441
-241
lines changed

examples/django/README.md

Lines changed: 78 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,85 @@
1-
Follow the instructions [here](https://slack.dev/bolt-python/concepts#authenticating-oauth) for configuring OAuth flow supported Slack apps. This example works with the default env variables such as `SLACK_CLIENT_ID`, `SLACK_CLIENT_SECRET`, `SLACK_SCOPES`, `SLACK_SIGNING_SECRET`, and so forth.
1+
## Bolt for Python - Django integration example
22

3+
This example demonstrates how you can use Bolt for Python in your Django application. The project consists of two apps.
4+
5+
### `simple_app` - Single-workspace App Example
6+
7+
If you want to run a simple app like the one you've tried in the [Getting Started Guide](https://slack.dev/bolt-python/tutorial/getting-started), this is the right one for you. By default, this Django project runs this application. If you want to switch to OAuth flow supported one, modify `myslackapp/urls.py`.
8+
9+
To run this app, all you need to do are:
10+
11+
* Create a new Slack app configuration at https://api.slack.com/apps?new_app=1
12+
* Go to "OAuth & Permissions"
13+
* Add `app_mentions:read`, `chat:write` in Scopes > Bot Token Scopes
14+
* Go to "Install App"
15+
* Click "Install to Workspace"
16+
* Complete the installation flow
17+
* Copy the "Bot User OAuth Token" value, which starts with `xoxb-`
18+
19+
You can start your Django application this way:
20+
21+
```bash
22+
python -m venv .venv
23+
source .venv/bin/activate
24+
pip install -U pip
25+
pip install -r requirements.txt
26+
27+
export SLACK_SIGNING_SECRET=(You can find this value at Settings > Basic Information > App Credentials > Signing Secret)
28+
export SLACK_BOT_TOKEN=(You can find this value at Settings > Install App > Bot User OAuth Token)
29+
30+
python manage.py migrate
31+
python manage.py runserver 0.0.0.0:3000
332
```
33+
34+
As you did at [Getting Started Guide](https://slack.dev/bolt-python/tutorial/getting-started), configure ngrok or something similar to serve a public endpoint. Lastly,
35+
36+
* Go back to the Slack app configuration page
37+
* Go to "Event Subscriptions"
38+
* Turn the feature on
39+
* Set the "Request URL" to `https://{your public domain}/slack/events`
40+
* Go to the Slack workspace you've installed this app
41+
* Invite the app's bot user to a channel
42+
* Mention the bot user in the channel
43+
* You'll see a reply from your app's bot user!
44+
45+
### `oauth_app` - Multiple-workspace App Example (OAuth flow supported)
46+
47+
By default, this Django project runs this application. If you want to switch to OAuth flow supported one, modify `myslackapp/urls.py`.
48+
49+
This example uses SQLite. If you are looking for an example using MySQL, check the `mysql-docker-compose.yml` and the comment in `myslackapp/settings.py`.
50+
51+
52+
To run this app, all you need to do are:
53+
54+
* Create a new Slack app configuration at https://api.slack.com/apps?new_app=1
55+
* Go to "OAuth & Permissions"
56+
* Add `app_mentions:read`, `chat:write` in Scopes > Bot Token Scopes
57+
* Follow the instructions [here](https://slack.dev/bolt-python/concepts#authenticating-oauth) for configuring OAuth flow supported Slack apps
58+
59+
You can start your Django application this way:
60+
61+
```bash
62+
python -m venv .venv
63+
source .venv/bin/activate
64+
pip install -U pip
465
pip install -r requirements.txt
5-
export SLACK_CLIENT_ID=
6-
export SLACK_CLIENT_SECRET=
7-
export SLACK_SCOPES=commands,chat:write
8-
export SLACK_SIGNING_SECRET=
66+
67+
export SLACK_SIGNING_SECRET=(You can find this value at Settings > Basic Information > App Credentials > Signing Secret)
68+
export SLACK_CLIENT_ID=(You can find this value at Settings > Basic Information > App Credentials > Client ID)
69+
export SLACK_CLIENT_SECRET=(You can find this value at Settings > Basic Information > App Credentials > Client Secret)
70+
export SLACK_SCOPES=app_mentions:read,chat:write
971

1072
python manage.py migrate
1173
python manage.py runserver 0.0.0.0:3000
1274
```
75+
76+
As you did at [Getting Started Guide](https://slack.dev/bolt-python/tutorial/getting-started), configure ngrok or something similar to serve a public endpoint. Lastly,
77+
78+
* Go back to the Slack app configuration page
79+
* Go to "Event Subscriptions"
80+
* Turn the feature on
81+
* Set the "Request URL" to `https://{your public domain}/slack/events`
82+
* Visit `https://{your public domain}/slack/install` and complete the installation flow
83+
* Invite the app's bot user to a channel
84+
* Mention the bot user in the channel
85+
* You'll see a reply from your app's bot user!

examples/django/manage.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55

66

77
def main():
8-
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "slackapp.settings")
8+
"""Run administrative tasks."""
9+
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myslackapp.settings")
910
try:
1011
from django.core.management import execute_from_command_line
1112
except ImportError as exc:

examples/django/myslackapp/asgi.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
"""
2+
ASGI config for myslackapp project.
3+
4+
It exposes the ASGI callable as a module-level variable named ``application``.
5+
6+
For more information on this file, see
7+
https://docs.djangoproject.com/en/3.2/howto/deployment/asgi/
8+
"""
9+
10+
import os
11+
12+
from django.core.asgi import get_asgi_application
13+
14+
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myslackapp.settings")
15+
16+
application = get_asgi_application()
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,35 @@
11
"""
2-
Django settings for slackapp project.
2+
Django settings for myslackapp project.
33
4-
Generated by 'django-admin startproject' using Django 3.0.8.
4+
Generated by 'django-admin startproject' using Django 3.2.3.
55
66
For more information on this file, see
7-
https://docs.djangoproject.com/en/3.0/topics/settings/
7+
https://docs.djangoproject.com/en/3.2/topics/settings/
88
99
For the full list of settings and their values, see
10-
https://docs.djangoproject.com/en/3.0/ref/settings/
10+
https://docs.djangoproject.com/en/3.2/ref/settings/
1111
"""
12-
1312
import os
13+
from pathlib import Path
1414

15-
LOGGING = {
16-
"version": 1,
17-
"disable_existing_loggers": False,
18-
"handlers": {
19-
"console": {
20-
"class": "logging.StreamHandler",
21-
},
22-
},
23-
"root": {
24-
"handlers": ["console"],
25-
"level": "DEBUG",
26-
},
27-
"loggers": {
28-
"django": {
29-
"handlers": ["console"],
30-
"level": os.getenv("DJANGO_LOG_LEVEL", "INFO"),
31-
"propagate": False,
32-
},
33-
"django.db": {
34-
"level": "DEBUG",
35-
},
36-
"slack_bolt": {
37-
"handlers": ["console"],
38-
"level": "DEBUG",
39-
"propagate": False,
40-
},
41-
},
42-
}
15+
# Build paths inside the project like this: BASE_DIR / 'subdir'.
16+
BASE_DIR = Path(__file__).resolve().parent.parent
4317

44-
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
45-
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
4618

4719
# Quick-start development settings - unsuitable for production
48-
# See https://docs.djangoproject.com/en/3.0/howto/deployment/checklist/
20+
# See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/
4921

50-
# SECURITY WARNING: keep the secret key used in production secret!
5122
# TODO: CHANGE THIS IF YOU REUSE THIS APP
52-
SECRET_KEY = (
53-
"This is just a example. You should not expose your secret key in real apps"
54-
)
23+
SECRET_KEY = "This is just a example. You should not expose your secret key in real apps"
5524

5625
# SECURITY WARNING: don't run with debug turned on in production!
5726
DEBUG = True
5827

28+
5929
# ALLOWED_HOSTS = []
6030
ALLOWED_HOSTS = ["*"]
6131

32+
6233
# Application definition
6334

6435
INSTALLED_APPS = [
@@ -68,7 +39,8 @@
6839
"django.contrib.sessions",
6940
"django.contrib.messages",
7041
"django.contrib.staticfiles",
71-
"slackapp.apps.SlackAppConfig",
42+
"simple_app.apps.SimpleAppConfig",
43+
"oauth_app.apps.OauthAppConfig",
7244
]
7345

7446
MIDDLEWARE = [
@@ -81,7 +53,7 @@
8153
"django.middleware.clickjacking.XFrameOptionsMiddleware",
8254
]
8355

84-
ROOT_URLCONF = "slackapp.urls"
56+
ROOT_URLCONF = "myslackapp.urls"
8557

8658
TEMPLATES = [
8759
{
@@ -99,35 +71,44 @@
9971
},
10072
]
10173

102-
WSGI_APPLICATION = "slackapp.wsgi.application"
74+
WSGI_APPLICATION = "myslackapp.wsgi.application"
75+
10376

10477
# Database
105-
# https://docs.djangoproject.com/en/3.0/ref/settings/#databases
78+
# https://docs.djangoproject.com/en/3.2/ref/settings/#databases
10679

10780
DATABASES = {
108-
# python manage.py migrate
109-
# python manage.py runserver 0.0.0.0:3000
81+
# You can initialize your local database by the following steps:
82+
#
83+
# python manage.py migrate
84+
# python manage.py runserver 0.0.0.0:3000
85+
#
86+
"default": {
87+
"ENGINE": "django.db.backends.sqlite3",
88+
"NAME": BASE_DIR / "db.sqlite3",
89+
}
90+
# If you want to use MySQL quickly, the following steps work for you
91+
#
92+
# docker-compose -f mysql-docker-compose.yml up --build
93+
# pip install mysqlclient
94+
# python manage.py migrate
95+
# python manage.py runserver 0.0.0.0:3000
96+
#
97+
# And then, enable the following setting instead:
98+
#
11099
# "default": {
111-
# "ENGINE": "django.db.backends.sqlite3",
112-
# "NAME": os.path.join(BASE_DIR, "db.sqlite3"),
100+
# "ENGINE": "django.db.backends.mysql",
101+
# "NAME": "slackapp",
102+
# "USER": "app",
103+
# "PASSWORD": "password",
104+
# "HOST": "127.0.0.1",
105+
# "PORT": 33306,
113106
# },
114-
115-
# docker-compose -f mysql-docker-compose.yml up --build
116-
# pip install mysqlclient
117-
# python manage.py migrate
118-
# python manage.py runserver 0.0.0.0:3000
119-
"default": {
120-
"ENGINE": "django.db.backends.mysql",
121-
"NAME": "slackapp",
122-
"USER": "app",
123-
"PASSWORD": "password",
124-
"HOST": "127.0.0.1",
125-
"PORT": 33306,
126-
},
127107
}
128108

109+
129110
# Password validation
130-
# https://docs.djangoproject.com/en/3.0/ref/settings/#auth-password-validators
111+
# https://docs.djangoproject.com/en/3.2/ref/settings/#auth-password-validators
131112

132113
AUTH_PASSWORD_VALIDATORS = [
133114
{
@@ -144,8 +125,9 @@
144125
},
145126
]
146127

128+
147129
# Internationalization
148-
# https://docs.djangoproject.com/en/3.0/topics/i18n/
130+
# https://docs.djangoproject.com/en/3.2/topics/i18n/
149131

150132
LANGUAGE_CODE = "en-us"
151133

@@ -157,7 +139,43 @@
157139

158140
USE_TZ = True
159141

142+
160143
# Static files (CSS, JavaScript, Images)
161-
# https://docs.djangoproject.com/en/3.0/howto/static-files/
144+
# https://docs.djangoproject.com/en/3.2/howto/static-files/
162145

163146
STATIC_URL = "/static/"
147+
148+
# Default primary key field type
149+
# https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field
150+
151+
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
152+
153+
154+
LOGGING = {
155+
"version": 1,
156+
"disable_existing_loggers": False,
157+
"handlers": {
158+
"console": {
159+
"class": "logging.StreamHandler",
160+
},
161+
},
162+
"root": {
163+
"handlers": ["console"],
164+
"level": "DEBUG",
165+
},
166+
"loggers": {
167+
"django": {
168+
"handlers": ["console"],
169+
"level": os.getenv("DJANGO_LOG_LEVEL", "INFO"),
170+
"propagate": False,
171+
},
172+
"django.db": {
173+
"level": "DEBUG",
174+
},
175+
"slack_bolt": {
176+
"handlers": ["console"],
177+
"level": "DEBUG",
178+
"propagate": False,
179+
},
180+
},
181+
}

examples/django/myslackapp/urls.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
"""myslackapp URL Configuration
2+
3+
The `urlpatterns` list routes URLs to views. For more information please see:
4+
https://docs.djangoproject.com/en/3.2/topics/http/urls/
5+
Examples:
6+
Function views
7+
1. Add an import: from my_app import views
8+
2. Add a URL to urlpatterns: path('', views.home, name='home')
9+
Class-based views
10+
1. Add an import: from other_app.views import Home
11+
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
12+
Including another URLconf
13+
1. Import the include() function: from django.urls import include, path
14+
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
15+
"""
16+
from django.contrib import admin
17+
from django.urls import path
18+
19+
is_simple_app = True
20+
21+
if is_simple_app:
22+
# A simple app that works only for a single Slack workspace
23+
# (prerequisites)
24+
# export SLACK_BOT_TOKEN=
25+
# export SLACK_SIGNING_SECRET=
26+
from simple_app.urls import slack_events_handler
27+
28+
urlpatterns = [path("slack/events", slack_events_handler)]
29+
else:
30+
# OAuth flow supported app
31+
# (prerequisites)
32+
# export SLACK_CLIENT_ID=
33+
# export SLACK_CLIENT_SECRET=
34+
# export SLACK_SIGNING_SECRET=
35+
# export SLACK_SCOPES=app_mentions:read
36+
from oauth_app.urls import slack_events_handler, slack_oauth_handler
37+
38+
urlpatterns = [
39+
path("slack/events", slack_events_handler, name="handle"),
40+
path("slack/install", slack_oauth_handler, name="install"),
41+
path("slack/oauth_redirect", slack_oauth_handler, name="oauth_redirect"),
42+
]
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
"""
2-
WSGI config for slackapp project.
2+
WSGI config for myslackapp project.
33
44
It exposes the WSGI callable as a module-level variable named ``application``.
55
66
For more information on this file, see
7-
https://docs.djangoproject.com/en/3.0/howto/deployment/wsgi/
7+
https://docs.djangoproject.com/en/3.2/howto/deployment/wsgi/
88
"""
99

1010
import os
1111

1212
from django.core.wsgi import get_wsgi_application
1313

14-
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "slackapp.settings")
14+
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myslackapp.settings")
1515

1616
application = get_wsgi_application()
File renamed without changes.

0 commit comments

Comments
 (0)