Skip to content

Commit 6b576cf

Browse files
author
Rodney Urquhart
committed
Finishing step 3 in the tutorial
1 parent 2789f9c commit 6b576cf

File tree

5 files changed

+228
-30
lines changed

5 files changed

+228
-30
lines changed
Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,47 @@
11
# 01 - Create a Slack app
22

3-
## Create a new Slack App on [api.slack.com](https://api.slack.com/apps)
3+
## Slack Apps
4+
> 💡 Build useful apps, internal tools, simplified workflows, or brillant bots for just your team or Slack's millions of users.
45
5-
In your browser, on [api.slack.com/apps](https://api.slack.com/apps) you'll find a green button labeled [Create New App](https://api.slack.com/apps/new) on the top right of the page.
6-
<img width="1049" alt="Create New App" src="https://user-images.githubusercontent.com/3329665/56550880-ae1b2080-653b-11e9-8e83-94bcdb8380d3.png">
7-
8-
Once you click that you'll see a modal apppear.
9-
1. Type in your app name
10-
2. Select the team you'd like to build your app on.
6+
- To get started, create a new Slack App on [api.slack.com](https://api.slack.com/apps?new_app=1).
7+
1. Type in your app name
8+
2. Select the team you'd like to build your app on.
119
<img width="570" alt="Create-A-Slack-App" src="https://user-images.githubusercontent.com/3329665/56550657-13224680-653b-11e9-8f91-15c17e6977b7.png">
1210

13-
## Add A Bot User
11+
### Add A Bot User
12+
13+
Let's get ourselves a shiny new **Bot User** so our app can communicate on Slack.
1414

15-
Let's get ourselves a shiny new **Bot User** so our app can communicate on Slack. On the left side navigation of your app's settings page you'll find the **Bot Users** tab where you can create a new bot user for your app.
15+
- On the left side navigation of your app's settings page you'll find the **Bot Users** tab where you can create a new bot user for your app.
1616

1717
<img width="191" alt="app_settings_nav_bot_user" src="https://user-images.githubusercontent.com/3329665/56551168-76f93f00-653c-11e9-9fd8-1a3e434773fe.png">
1818

19-
Next tap "Add a Bot User".
19+
- Next click "Add a Bot User".
2020

2121
<img width="631" alt="Add a Bot User" src="https://user-images.githubusercontent.com/3329665/56551307-dfe0b700-653c-11e9-94ad-e1d34fdbd6f5.png">
2222

23-
Give your bot user a name (e.g. "pythonboardingbot"), tap "Add Bot User", and "Save Changes".
23+
- Give your bot user a name (e.g. "pythonboardingbot"), click "Add Bot User", and "Save Changes".
2424

2525
<img width="613" alt="Bot User" src="https://user-images.githubusercontent.com/3329665/56551468-52ea2d80-653d-11e9-85d7-e383bd1b3537.png">
2626

27-
You should briefly see a success banner.
27+
🎉 You should briefly see a success banner.
2828

2929
<img width="1050" alt="Success banner" src="https://user-images.githubusercontent.com/3329665/56551675-d60b8380-653d-11e9-983a-5dd53cb55a97.png">
3030

31-
## Install the app in your workspace
32-
Under "Settings" on the lefthand side, click "Install App" and then "Install App to Workspace".
31+
### Install the app in your workspace
32+
- Under "Settings" on the lefthand side, click "Install App" and then "Install App to Workspace".
3333
<img width="961" alt="Install App" src="https://user-images.githubusercontent.com/3329665/56844936-c2c62400-686d-11e9-8417-f79d92b7ae27.png">
3434

3535
Next you'll need to authorize the app for the Bot User permissions.
36+
- Click the "Authorize" button.
37+
3638
<img width="527" alt="Authorize the app" src="https://user-images.githubusercontent.com/3329665/56844940-e6896a00-686d-11e9-922c-045031c418b9.png">
3739

38-
Finally copy and save your token. You'll need this to communicate with Slack's Platform.
40+
🏁 Finally copy and save your token. You'll need this to communicate with Slack's Platform.
3941
<img width="786" alt="Copy the Bot token" src="https://user-images.githubusercontent.com/3329665/56845230-ec357e80-6872-11e9-83d4-5f953aee20b5.png">
4042

4143
---
4244

4345
**Next section: [02 - Building a message](02-building-a-message.md).**
4446

45-
**Back to the [Table of contents](https://github.com/slackapi/python-slackclient/tutorial#table-of-contents).**
47+
**Back to the [Table of contents](/tutorial/#table-of-contents).**

tutorial/02-building-a-message.md

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
# Building a message
2-
> ⬛️[Design with Block Kit Builder](https://api.slack.com/tools/block-kit-builder)
3-
>Shuffle and stack blocks to quickly prototype app messages on Slack. When you're ready, we'll provide the message payload so all you have to do is copy and paste it into your app's code.
2+
The code for this step is also available [here](/tutorial/PythOnBoardingBot/onboarding_tutorial.py).
43

5-
In order to create a message in Slack that looks like this:
6-
<img width="787" alt="Onboarding Message" src="https://user-images.githubusercontent.com/3329665/56854465-b84a6f80-68eb-11e9-9625-f45ac2d2fe18.png">
4+
> 💡 **[Block Kit](https://api.slack.com/block-kit)** is a new UI framework that offers you more control and flexibility when building messages for Slack. Comprised of "blocks," stackable bits of message UI, you can customize the order and appearance of information delivered by your app in Slack. Using the **[Block Kit Builder](https://api.slack.com/tools/block-kit-builder)** you can shuffle and stack blocks to quickly prototype app messages on Slack. When you're ready, we'll provide the message payload so all you have to do is copy and paste it into your app's code.
5+
6+
We're going to be using Block Kit to build our onboarding tutorial messages.
77

8+
With Block Kit, we can create a message in Slack that looks like this:
9+
<img width="787" alt="Onboarding Message" src="https://user-images.githubusercontent.com/3329665/56854465-b84a6f80-68eb-11e9-9625-f45ac2d2fe18.png">
810

9-
We have to send a json payload that looks like this:
11+
By sending the following json payload:
1012
```Python
1113
{
1214
"channel": "D0123456",
@@ -58,7 +60,9 @@ We have to send a json payload that looks like this:
5860
}
5961
```
6062

61-
To make this simpler, more pleasant and more productive we'll create a file `onboarding_tutorial.py` with a `OnboardingTutorial` class that's responsible for building it. We'll also store the state of which tasks were completed so that it's easy to update existing messages.
63+
To make this simpler, more pleasant and more productive we'll create a class that's responsible for building it. We'll also store the state of which tasks were completed so that it's easy to update existing messages.
64+
- Create a file called `onboarding_tutorial.py`
65+
- 🏁Add the following code into it:
6266
```Python
6367
class OnboardingTutorial:
6468
"""Constructs the onboarding message and stores the state of which tasks were completed."""
@@ -144,4 +148,4 @@ class OnboardingTutorial:
144148

145149
**Previous section: [01 - Creating the Slack app](/tutorial/01-creating-the-slack-app.md).**
146150

147-
**Back to the [Table of contents](https://github.com/slackapi/python-slackclient/tutorial#table-of-contents).**
151+
**Back to the [Table of contents](/tutorial/#table-of-contents).**
Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
# Responding to Slack events
2+
The code for this step is also available [here](/tutorial/PythOnBoardingBot).
3+
4+
## Install the dependencies
5+
> 💡 **[“Requirements files”](https://pip.pypa.io/en/stable/user_guide/#id12)** are files containing a list of items to be installed using pip install. Details on the format of the files are here: [Requirements File Format](https://pip.pypa.io/en/stable/reference/pip_install/#requirements-file-format).
6+
7+
- In the root directory create a "requirements.txt" file.
8+
- Add the following contents to that file and save the file.
9+
```
10+
slackclient>=2.0.0
11+
certifi
12+
```
13+
> 💡 Certifi is a carefully curated collection of Root Certificates for validating the trustworthiness of SSL certificates while verifying the identity of TLS hosts. It has been extracted from the Requests project.
14+
15+
- Next you can install those dependencies by running the following command from your terminal:
16+
```
17+
$ pip3 install -r requirements.txt
18+
-> Successfully installed slackclient-2.0.0
19+
```
20+
21+
## Creating the app
22+
23+
- Create an `app.py` file to run the app.
24+
25+
The first thing we'll need to do is import the code our app needs to run.
26+
- In `app.py` add the following code:
27+
```Python
28+
import os
29+
import logging
30+
import slack
31+
import ssl as ssl_lib
32+
import certifi
33+
from onboarding_tutorial import OnboardingTutorial
34+
```
35+
36+
Next we'll need our app to store some data. For simplicity we'll store our app data in-memory with the following data structure: `{"channel": {"user_id": OnboardingTutorial}}`.
37+
- Add the the following line to `app.py`.
38+
```Python
39+
onboarding_tutorials_sent = {}
40+
```
41+
42+
Let's add a function that's responsible for creating and sending the onboarding welcome message to new users. We'll also save the time stamp of the message when it's posted so we can update this message in the future.
43+
- Add the following lines of code to `app.py`.
44+
```Python
45+
def start_onboarding(web_client: slack.WebClient, user_id: str, channel: str):
46+
# Create a new onboarding tutorial.
47+
onboarding_tutorial = OnboardingTutorial(channel)
48+
49+
# Get the onboarding message payload
50+
message = onboarding_tutorial.get_message_payload()
51+
52+
# Post the onboarding message in Slack
53+
response = web_client.chat_postMessage(**message)
54+
55+
# Capture the timestamp of the message we've just posted so
56+
# we can use it to update the message after a user
57+
# has completed an onboarding task.
58+
onboarding_tutorial.timestamp = response["ts"]
59+
60+
# Store the message sent in onboarding_tutorials_sent
61+
if channel not in onboarding_tutorials_sent:
62+
onboarding_tutorials_sent[channel] = {}
63+
onboarding_tutorials_sent[channel][user_id] = onboarding_tutorial
64+
```
65+
*Note:* We're using the `WebClient` to send messages into Slack.
66+
> 💡 **[WebClient](/slack/web/client.py)** A WebClient allows apps to communicate with the Slack Platform's Web API. This client handles constructing and sending HTTP requests to Slack as well as parsing any responses received into a `SlackResponse` dictionary-like object.
67+
68+
### Responding to events in Slack
69+
When events occurr in Slack there are two primary ways to be notified about them. We can send you an HTTP Request through our Events API (preferred) or you can stream events through a websocket connection with our RTM API. The RTM API is only recommended if you're behind a firewall and cannot receive incoming web requests from Slack.
70+
71+
In this tutorial we'll be using the RTM API via the `RTMClient`. If you're interested in using the Events API take a look at the [SlackEventAdapter](https://github.com/slackapi/python-slack-events-api). We'll be adding support for the Events API into this library soon (See [#403](https://github.com/slackapi/python-slackclient/issues/403)).
72+
73+
> 💡 **[RTMClient](/slack/rtm/client.py)** An RTMClient allows apps to communicate with the Slack Platform's RTM API. The event-driven architecture of this client allows you to simply link callbacks to their corresponding events. When an event occurs this client executes your callback while passing along any information it receives.
74+
75+
Back to our application, it's time to link our onboarding functionality to Slack events.
76+
- Add the following lines of code to `app.py`.
77+
```Python
78+
# ================ Team Join Event =============== #
79+
# When the user first joins a team, the type of the event will be 'team_join'.
80+
# Here we'll link the onboarding_message callback to the 'team_join' event.
81+
@slack.RTMClient.run_on(event="team_join")
82+
def onboarding_message(**payload):
83+
"""Create and send an onboarding welcome message to new users. Save the
84+
time stamp of this message so we can update this message in the future.
85+
"""
86+
# Get the id of the Slack user associated with the incoming event
87+
user_id = payload["data"]["user"]["id"]
88+
# Get WebClient so you can communicate back to Slack.
89+
web_client = payload["web_client"]
90+
91+
# Open a DM with the new user.
92+
response = web_client.im_open(user_id)
93+
channel = response["channel"]["id"]
94+
95+
# Post the onboarding message.
96+
start_onboarding(web_client, user_id, channel)
97+
98+
99+
# ============= Reaction Added Events ============= #
100+
# When a users adds an emoji reaction to the onboarding message,
101+
# the type of the event will be 'reaction_added'.
102+
# Here we'll link the update_emoji callback to the 'reaction_added' event.
103+
@slack.RTMClient.run_on(event="reaction_added")
104+
def update_emoji(**payload):
105+
"""Update onboarding welcome message after recieving a "reaction_added"
106+
event from Slack. Update timestamp for welcome message as well.
107+
"""
108+
data = payload["data"]
109+
web_client = payload["web_client"]
110+
channel_id = data["item"]["channel"]
111+
user_id = data["user"]
112+
113+
# Get the original tutorial sent.
114+
onboarding_tutorial = onboarding_tutorials_sent[channel_id][user_id]
115+
116+
# Mark the reaction task as completed.
117+
onboarding_tutorial.reaction_task_completed = True
118+
119+
# Get the new message payload
120+
message = onboarding_tutorial.get_message_payload()
121+
122+
# Post the updated message in Slack
123+
updated_message = web_client.chat_update(**message)
124+
125+
# Update the timestamp saved on the onboarding tutorial object
126+
onboarding_tutorial.timestamp = updated_message["ts"]
127+
128+
129+
# =============== Pin Added Events ================ #
130+
# When a users pins a message the type of the event will be 'pin_added'.
131+
# Here we'll link the update_pin callback to the 'reaction_added' event.
132+
@slack.RTMClient.run_on(event="pin_added")
133+
def update_pin(**payload):
134+
"""Update onboarding welcome message after recieving a "pin_added"
135+
event from Slack. Update timestamp for welcome message as well.
136+
"""
137+
data = payload["data"]
138+
web_client = payload["web_client"]
139+
channel_id = data["channel_id"]
140+
user_id = data["user"]
141+
142+
# Get the original tutorial sent.
143+
onboarding_tutorial = onboarding_tutorials_sent[channel_id][user_id]
144+
145+
# Mark the pin task as completed.
146+
onboarding_tutorial.pin_task_completed = True
147+
148+
# Get the new message payload
149+
message = onboarding_tutorial.get_message_payload()
150+
151+
# Post the updated message in Slack
152+
updated_message = web_client.chat_update(**message)
153+
154+
# Update the timestamp saved on the onboarding tutorial object
155+
onboarding_tutorial.timestamp = updated_message["ts"]
156+
157+
158+
# ============== Message Events ============= #
159+
# When a user sends a DM, the event type will be 'message'.
160+
# Here we'll link the update_share callback to the 'message' event.
161+
@slack.RTMClient.run_on(event="message")
162+
def message(**payload):
163+
"""Display the onboarding welcome message after receiving a message
164+
that contains "start".
165+
"""
166+
data = payload["data"]
167+
web_client = payload["web_client"]
168+
channel_id = data.get("channel")
169+
user_id = data.get("user")
170+
text = data.get("text")
171+
172+
if text and text.lower() == "start":
173+
return start_onboarding(web_client, user_id, channel_id)
174+
```
175+
176+
Finally, we need to make our app runnable.
177+
- 🏁 Add the following lines of code to the end of `app.py`.
178+
```Python
179+
if __name__ == "__main__":
180+
slack_token = os.environ["SLACK_BOT_TOKEN"]
181+
rtm_client = slack.RTMClient(slack_token)
182+
rtm_client.start()
183+
```
184+
185+
---
186+
187+
**Next section: [04 - Running the app](/tutorial/04-running-the-app.md).**
188+
189+
**Previous section: [02 - Building a message](/tutorial/01-building-a-message.md).**
190+
191+
**Back to the [Table of contents](/tutorial/#table-of-contents).**

tutorial/PythOnBoardingBot/app.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import certifi
66
from onboarding_tutorial import OnboardingTutorial
77

8-
# For simplicity we'll store our app data with the following data structure.
8+
# For simplicity we'll store our app data in-memory with the following data structure.
99
# onboarding_tutorials_sent = {"channel": {"user_id": OnboardingTutorial}}
1010
onboarding_tutorials_sent = {}
1111

@@ -39,11 +39,12 @@ def onboarding_message(**payload):
3939
"""Create and send an onboarding welcome message to new users. Save the
4040
time stamp of this message so we can update this message in the future.
4141
"""
42-
# Get the id of the Slack user associated with the incoming event
43-
user_id = payload["data"]["user"]["id"]
4442
# Get WebClient so you can communicate back to Slack.
4543
web_client = payload["web_client"]
4644

45+
# Get the id of the Slack user associated with the incoming event
46+
user_id = payload["data"]["user"]["id"]
47+
4748
# Open a DM with the new user.
4849
response = web_client.im_open(user_id)
4950
channel = response["channel"]["id"]
@@ -58,7 +59,7 @@ def onboarding_message(**payload):
5859
# Here we'll link the update_emoji callback to the 'reaction_added' event.
5960
@slack.RTMClient.run_on(event="reaction_added")
6061
def update_emoji(**payload):
61-
"""Update onboarding welcome message after recieving a "reaction_added"
62+
"""Update the onboarding welcome message after recieving a "reaction_added"
6263
event from Slack. Update timestamp for welcome message as well.
6364
"""
6465
data = payload["data"]
@@ -87,7 +88,7 @@ def update_emoji(**payload):
8788
# Here we'll link the update_pin callback to the 'reaction_added' event.
8889
@slack.RTMClient.run_on(event="pin_added")
8990
def update_pin(**payload):
90-
"""Update onboarding welcome message after recieving a "pin_added"
91+
"""Update the onboarding welcome message after recieving a "pin_added"
9192
event from Slack. Update timestamp for welcome message as well.
9293
"""
9394
data = payload["data"]
@@ -113,7 +114,7 @@ def update_pin(**payload):
113114

114115
# ============== Message Events ============= #
115116
# When a user sends a DM, the event type will be 'message'.
116-
# Here we'll link the update_share callback to the 'message' event.
117+
# Here we'll link the message callback to the 'message' event.
117118
@slack.RTMClient.run_on(event="message")
118119
def message(**payload):
119120
"""Display the onboarding welcome message after receiving a message

tutorial/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ Open up your new project folder "PythOnBoardingBot" in your text editor.
4646
## Table of contents
4747
- [01 - Creating the Slack app](/tutorial/01-creating-the-slack-app.md)
4848
- [02 - Building a message](/tutorial/02-building-a-message.md)
49-
- [03 - Responding to Slack events](/tutorial/03-running-the-app.md)
49+
- [03 - Responding to Slack events](/tutorial/03-responding-to-slack-events.md)
5050
- [04 - Running the app](/tutorial/04-running-the-app.md)
5151

5252
## Coming up next

0 commit comments

Comments
 (0)