Skip to content

Conversation

haleychaas
Copy link
Contributor

Summary

In an effort to move workshops off slack.dev and over to their appropriate repos, I've added this python tutorial (currently lives here).

Preview here: https://docs-slack-d-docs-haley-1wpghj.herokuapp.com/tools/bolt-python/tutorial/order-confirmation/

Testing

Category

  • slack_bolt.App and/or its core components
  • slack_bolt.async_app.AsyncApp and/or its core components
  • Adapters in slack_bolt.adapter
  • Document pages under /docs
  • Others

Requirements

Please read the Contributing guidelines and Code of Conduct before creating this issue or pull request. By submitting, you are agreeing to those rules.

  • I've read and understood the Contributing Guidelines and have done my best effort to follow them.
  • I've read and agree to the Code of Conduct.
  • I've run ./scripts/install_all_and_run_tests.sh after making the changes.

@zimeg zimeg changed the title Docs: Order confirmation tutorial docs: order confirmation tutorial Oct 2, 2025
@zimeg zimeg added docs Improvements or additions to documentation semver:patch labels Oct 2, 2025
Copy link

codecov bot commented Oct 2, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 91.03%. Comparing base (5f6196f) to head (af2066b).
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #1381   +/-   ##
=======================================
  Coverage   91.03%   91.03%           
=======================================
  Files         222      222           
  Lines        7514     7514           
=======================================
  Hits         6840     6840           
  Misses        674      674           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link
Member

@zimeg zimeg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@haleychaas LGTM! Bringing tutorials toward the package makes so much sense to me and I'm hoping we can extend this to test the code samples alongside this at a future point perhaps 🔮 ✨

Comment on lines 5 to 15
<Columns>
<Column>
Use the Bolt for Python starter template to create a simple order confirmation app that links to a system of record—like Salesforce—in this tutorial.

The scenario: you work for a large e-commerce company that employs many delivery workers. Those delivery workers don’t have access to a laptop when they’re on the go, but they do have access to Slack on their mobile devices. This tutorial teaches you how to create a simple Slack app that is geared towards these workers. Delivery drivers will enter order numbers on their mobile, along with some additional information about the order. That information is then sent to a channel in Slack and to a system of record. In this tutorial, Salesforce is our system of record..

</Column>
<Column>
![Image of delivery tracker app](/img/bolt-python/delivery-tracker-main.png)
</Column>
</Columns>
Copy link
Contributor

@lukegalbraithrussell lukegalbraithrussell Oct 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i see what you're going for here - matching how it was on the other website by it being side-by-side. But I think it makes more sense for us to just completely reformat this to match how the rest of our tutorials work. Perhaps with the image all the way at the bottom (although being at the top is fine too)

Comment on lines 7 to 9
Use the Bolt for Python starter template to create a simple order confirmation app that links to a system of record—like Salesforce—in this tutorial.

The scenario: you work for a large e-commerce company that employs many delivery workers. Those delivery workers don’t have access to a laptop when they’re on the go, but they do have access to Slack on their mobile devices. This tutorial teaches you how to create a simple Slack app that is geared towards these workers. Delivery drivers will enter order numbers on their mobile, along with some additional information about the order. That information is then sent to a channel in Slack and to a system of record. In this tutorial, Salesforce is our system of record..
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Use the Bolt for Python starter template to create a simple order confirmation app that links to a system of record—like Salesforce—in this tutorial.
The scenario: you work for a large e-commerce company that employs many delivery workers. Those delivery workers don’t have access to a laptop when they’re on the go, but they do have access to Slack on their mobile devices. This tutorial teaches you how to create a simple Slack app that is geared towards these workers. Delivery drivers will enter order numbers on their mobile, along with some additional information about the order. That information is then sent to a channel in Slack and to a system of record. In this tutorial, Salesforce is our system of record..
In this tutorial, you'll use the Bolt for Python framework to create an order confirmation app that links to a system of record—like Salesforce.
The Slack app will:
* allow users to enter order numbers from within Slack, along with some additional order information,
* post that information to a Slack channel, and
* send the information to the system of record.
End users will be able to enter information across devices, as many will likely be using a mobile device.

what about something like this

</Column>
</Columns>

You’ll also learn how to use the Bolt for Python starter app template and modify it to fit your needs. Note that this app is meant to be used for educational purposes and has not been tested rigorously enough to be used in production
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
You’ll also learn how to use the Bolt for Python starter app template and modify it to fit your needs. Note that this app is meant to be used for educational purposes and has not been tested rigorously enough to be used in production
Along the way, you'll learn how to use the Bolt for Python starter app template as a jumping off point for your own custom apps. Let's begin!
:::warning[Consider the following]
This tutorial was created for educational purposes within a Slack workshop. As a result, it's not been tested quite as rigorously as our sample apps. Proceed carefully if you'd like to use a similar app in production


### Installing the Slack CLI

If you don't already have it, install the Slack CLI from your terminal. Navigate to the installation guide ([for Mac and Linux](/tools/slack-cli/guides/installing-the-slack-cli-for-mac-and-linux) or [for Windows](/tools/slack-cli/guides/installing-the-slack-cli-for-windows)) and follow the steps.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
If you don't already have it, install the Slack CLI from your terminal. Navigate to the installation guide ([for Mac and Linux](/tools/slack-cli/guides/installing-the-slack-cli-for-mac-and-linux) or [for Windows](/tools/slack-cli/guides/installing-the-slack-cli-for-windows)) and follow the steps.
If you don't already have the Slack CLI, install it from your terminal by first navigating to the installation guide ([for Mac and Linux](/tools/slack-cli/guides/installing-the-slack-cli-for-mac-and-linux) or [for Windows](/tools/slack-cli/guides/installing-the-slack-cli-for-windows)) and following the steps.

or a colon tbh. or maybe none. but the swapping "it" and the "slack cli" part is mroe something im more confident about


### Cloning the starter app

Once installed, use the command `slack create` in your terminal and find the `bolt-python-starter-template`. Alternatively, you can clone the [Bolt for Python template](https://github.com/slack-samples/bolt-python-starter-template) using git.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i'd add details on what "finding the template" is. navigating to it and selecting it or whatever it is


Once installed, use the command `slack create` in your terminal and find the `bolt-python-starter-template`. Alternatively, you can clone the [Bolt for Python template](https://github.com/slack-samples/bolt-python-starter-template) using git.

You can remove the portions from the template that are not used within this tutorial to make things a bit cleaner for yourself. To do this, open your project and delete the commands, events, and shortcuts folders from the `/listeners` folder. You can also do the same to the corresponding folders within the `/listeners/tests` folder as well. Finally, remove the imports of these files from the `/listeners/__init__.py` file.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"open your project" is a big vague. Can we explicilty tell them to navigate to the created folder, and open it up in an IDE?


Once installed, use the command `slack create` in your terminal and find the `bolt-python-starter-template`. Alternatively, you can clone the [Bolt for Python template](https://github.com/slack-samples/bolt-python-starter-template) using git.

You can remove the portions from the template that are not used within this tutorial to make things a bit cleaner for yourself. To do this, open your project and delete the commands, events, and shortcuts folders from the `/listeners` folder. You can also do the same to the corresponding folders within the `/listeners/tests` folder as well. Finally, remove the imports of these files from the `/listeners/__init__.py` file.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
You can remove the portions from the template that are not used within this tutorial to make things a bit cleaner for yourself. To do this, open your project and delete the commands, events, and shortcuts folders from the `/listeners` folder. You can also do the same to the corresponding folders within the `/listeners/tests` folder as well. Finally, remove the imports of these files from the `/listeners/__init__.py` file.
You can remove the portions from the template that are not used within this tutorial to make things a bit cleaner for yourself. To do this, open your project and delete the `commands`, `events`, and `shortcuts` folders from the `/listeners` folder. You can also do the same to the corresponding folders within the `/listeners/tests` folder as well. Finally, remove the imports of these files from the `/listeners/__init__.py` file.


## Creating your app

We’ll use the contents of the `manifest.json` file below, which can also be found [here](https://github.com/wongjas/delivery-confirmation-app/blob/main/manifest.json). This file describes the metadata associated with your app, like its name and permissions that it requests.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want them accessing this personal repo? I'd lean not to, especially if we're just copying the entire manifest below

Comment on lines 44 to 50
"display_information": {
"name": "Name your app here!"
},
"features": {
"bot_user": {
"display_name": "Name your app here!",
"always_online": false
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there a reason we don't have a name for this? maybe "Delivery Tracker App" since that matches the pic

}
```

Customize your app with a name of your own instead of the default in the `display_name` and `name` fields.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i'd remove this and update the name. this is a specific tutorial not a general guide

Comment on lines 81 to 85
Once your app has been created, scroll down to **App-Level Tokens** on the **Basic Information** page and create a token that requests the [`connections:write`](/reference/scopes/connections.write) scope. This token will allow you to use [Socket Mode](/apis/events-api/using-socket-mode), which is a secure way to develop on Slack through the use of WebSockets. Save the value of your app token and store it in a safe place (we’ll use it in the next step).

### Install app

Install your app by navigating to **Install App** in the left sidebar. When you press **Allow**, this means you’re agreeing to install your app with the permissions that it’s requesting. Copy the bot token that you receive as well and store this in a safe place as well for subsequent steps.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i'd add some clarity at the beginning of these that we are still in app settings. lots of times people will jump to different sections of a tutorial when something goes wrong and its disorienting without that context


## Starting your app's server

Within a terminal of your choice, set the two tokens from the previous step as environment variables using the commands below. Make sure not to mix these two up, `SLACK_APP_TOKEN` will start with “xapp-“ and `SLACK_BOT_TOKEN` will start with “xoxb-“.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is only true for macos/linux. For windows there's... powershell and then like something else. for powershell it'd be lke

$env:SLACK_APP_TOKEN = "<YOUR-APP-TOKEN-HERE>"


```bash
# Setup your python virtual environment
python3 -m venv .venv
Copy link
Contributor

@lukegalbraithrussell lukegalbraithrussell Oct 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is a nit more than anything but it's a dumb macos thing that it defaults to python3 (because python is reserved for python2. most linux and windows users will just have it as python

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🐍 thought: I understand too a default installation might reference python2 but IMHO preferring "python" itself as a catchall might be good.

🗣️ ramble: Right now python<=3.9 are EOL with recommendations against using version 2 at all IIRC. Also I have heard rumor that some developers use alternative python alias altogether including "pypy" but these should still be aliased...


## Coding the app

There will be four major steps needed to get from the template to the finish line:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"there's only 16 miles left!" tracy says to us

Suggested change
There will be four major steps needed to get from the template to the finish line:
We'll make four changes to the app:

Comment on lines 116 to 119
1. Update the “hi” message to something more interesting and interactive
2. Handle when the wrong delivery ID button is pressed
3. Handle when the correct delivery IDs are sent and bring up a modal for more information
4. Send the information to all of the places needed when the form is submitted (including third-party locations)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

v nuanced thought that doesn't matter really. should these be unordered? They are indeed ordered that way reading the tutorial straight down, but they aren't really dependent on each other as ordered lists imply

3. Handle when the correct delivery IDs are sent and bring up a modal for more information
4. Send the information to all of the places needed when the form is submitted (including third-party locations)

All of these steps require you to use [Block Kit Builder](https://app.slack.com/block-kit-builder), a tool that helps you create messages, modals and other surfaces within Slack. Open [Block Kit Builder](https://app.slack.com/block-kit-builder), take a look and play around! We’ll create some views next.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean, they don't have to use block kit builder, right? Some people make blocks (me) straight from the reference docs


### Updating the "hi" message

The first thing we want to do is change the “hi, how are you?” message from our app into something more useful. Here’s something that you can use to start off with, but you can make it your own within Block Kit Builder. Once you have something you like, copy the blocks by clicking the **Copy Payload** button in the top right.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh im getting the context. this is prob a low-code workshop so we told them they have to use bkb. i'd change the references to block kit in general, add the links to the proper reference page (like section for here) and then a little callout saying they can use bkb

The first thing we want to do is change the “hi, how are you?” message from our app into something more useful. Here’s something that you can use to start off with, but you can make it your own within Block Kit Builder. Once you have something you like, copy the blocks by clicking the **Copy Payload** button in the top right.

Take the function below and place your blocks within the blocks dictionary `[]`. Update the payload:
* Remove the initial blocks key and convert any boolean true values to `True` to fit with Python conventions.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i've never thought about having to convert block kit to python convention this would be so annoyinggggg

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🐍 thought: true

try:
delivery_id = context["matches"][0]
say(
blocks=[] # insert your blocks here
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the wording of this section implies it's sorta "do whatever you want but here's an example" i think maybei t makes more sense to just pick that block kit example and put it in this code snippet. people don't need choices

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📚 issue: A specific example might be needed to send actions to the action listeners in following steps?

👾 suggestion: For now requesting changes for this example but am open to working through this in iteration soon!


```python

from .sample_message import delivery_message_callback ## import the function to this file
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
from .sample_message import delivery_message_callback ## import the function to this file
from .sample_message import delivery_message_callback # import the function to this file

app.message(re.compile("(hi|hello|hey)"))(sample_message_callback) # This can be deleted!
# This regex will capture any number letters followed by dash
# and then any number of digits, our "confirmation number" e.g. ASDF-1234
app.message(re.compile(r"[A-Za-z]+-\d+"))(delivery_message_callback) ## add this line!
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would call out this regex specifically - we're not filtering for a v specific type of order confirmation that someone copying and pasting quickly might be confused about when they don't realize that


Take the function below and place your blocks within the blocks dictionary `[]`. Update the payload:
* Remove the initial blocks key and convert any boolean true values to `True` to fit with Python conventions.
* If you see variables within `{}` brackets, this is part of an f-string, which allows you to insert variables within strings in a clean manner. Place the `f` character before these strings like this:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is fine to stay but arguably not needed - any python dev is going to know what an f string is. but i guess this also catches first time devs, who would prob pick python as a starting poitn hmmmm

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh circling back to this forgot that they'll want to pythonify variables, so this is maybe useful to keep

logger.error(e)
```

Next, you’ll need to make some connections so that this function is called when a message is sent in the channel where your app is. Head to `messages/__init__.py` and add the line below to the register function. Don’t forget to add the import to the callback function as well!
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

confused about these "connections"

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Next, you’ll need to make some connections so that this function is called when a message is sent in the channel where your app is. Head to `messages/__init__.py` and add the line below to the register function. Don’t forget to add the import to the callback function as well!
Next, you’ll need to register this listener to respond when a message is sent in the channel with your app. Head to `messages/__init__.py` and add the line below to the register function. Don’t forget to add the import to the callback function as well!

⚡ suggestion: A few common terms I find elsewhere calls this "registering" a "listener" but these terms aren't defined too well I think?


Notice that if you try to click on either of the buttons within your message, nothing will happen. This is because we have yet to create a function to handle the button click. Let’s start with the `Not correct` button first.

1. Head to Block Kit Builder once again. We want to build a message that lets the user know that the wrong order ID has been submitted. Here's [something to get you started](https://app.slack.com/block-kit-builder/#%7B%22blocks%22:%5B%7B%22type%22:%22section%22,%22text%22:%7B%22type%22:%22mrkdwn%22,%22text%22:%22Delivery%20*%7Bdelivery_id%7D*%20was%20incorrect%20%E2%9D%8C%22%7D%7D%5D%7D).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd put the block kit snippet directly here, and then link out to the BKB. like how we do it in our reference odcs with "view this in bkb" buttons

Comment on lines 201 to 211
```python

from slack_bolt import App
from .sample_action import sample_action_callback # This can be deleted
from .sample_action import deny_delivery_callback

def register(app: App):
app.action("sample_action_id")(sample_action_callback) # This can be deleted
app.action("deny_delivery")(deny_delivery_callback) # Add this line

```
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

im 50/50 on this but with the "copy" button on these snippets i almost woudl rather us just delete the lines to be deleted instead of commenting them


```

Test out your code by sending in a confirmation number into your channel and clicking the `Not correct` button. If the message is updated, then you’re good to go onto the next step.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Test out your code by sending in a confirmation number into your channel and clicking the `Not correct` button. If the message is updated, then you’re good to go onto the next step.
Test out your app by sending in a confirmation number into your channel and clicking the `Not correct` button. If the message is updated, then you’re good to go onto the next step.

I have this weird thing where "code" sounds weird


The next step is to handle the `Confirm` button. In this case, we’re going to pull up a modal instead of just a message.

1. Using the following [modal](https://app.slack.com/block-kit-builder/#%7B%22type%22:%22modal%22,%22callback_id%22:%22approve_delivery_view%22,%22title%22:%7B%22type%22:%22plain_text%22,%22text%22:%22Approve%20Delivery%22%7D,%22private_metadata%22:%22%7Bdelivery_id%7D%22,%22blocks%22:%5B%7B%22type%22:%22section%22,%22text%22:%7B%22type%22:%22mrkdwn%22,%22text%22:%22Approving%20delivery%20*%7Bdelivery_id%7D*%22%7D%7D,%7B%22type%22:%22input%22,%22block_id%22:%22notes%22,%22label%22:%7B%22type%22:%22plain_text%22,%22text%22:%22Additional%20delivery%20notes%22%7D,%22element%22:%7B%22type%22:%22plain_text_input%22,%22action_id%22:%22notes_input%22,%22multiline%22:true,%22placeholder%22:%7B%22type%22:%22plain_text%22,%22text%22:%22Add%20notes...%22%7D%7D,%22optional%22:true%7D,%7B%22type%22:%22input%22,%22block_id%22:%22location%22,%22label%22:%7B%22type%22:%22plain_text%22,%22text%22:%22Delivery%20Location%22%7D,%22element%22:%7B%22type%22:%22plain_text_input%22,%22action_id%22:%22location_input%22,%22placeholder%22:%7B%22type%22:%22plain_text%22,%22text%22:%22Enter%20the%20location%20details...%22%7D%7D,%22optional%22:true%7D,%7B%22type%22:%22input%22,%22block_id%22:%22channel%22,%22label%22:%7B%22type%22:%22plain_text%22,%22text%22:%22Notification%20Channel%22%7D,%22element%22:%7B%22type%22:%22channels_select%22,%22action_id%22:%22channel_select%22,%22placeholder%22:%7B%22type%22:%22plain_text%22,%22text%22:%22Select%20channel%20for%20notifications%22%7D%7D,%22optional%22:false%7D%5D,%22submit%22:%7B%22type%22:%22plain_text%22,%22text%22:%22Approve%22%7D%7D) as a base, create a modal that captures the kind of information that you need.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i'd elaborate this in the same way discussed above


1. Using the following [modal](https://app.slack.com/block-kit-builder/#%7B%22type%22:%22modal%22,%22callback_id%22:%22approve_delivery_view%22,%22title%22:%7B%22type%22:%22plain_text%22,%22text%22:%22Approve%20Delivery%22%7D,%22private_metadata%22:%22%7Bdelivery_id%7D%22,%22blocks%22:%5B%7B%22type%22:%22section%22,%22text%22:%7B%22type%22:%22mrkdwn%22,%22text%22:%22Approving%20delivery%20*%7Bdelivery_id%7D*%22%7D%7D,%7B%22type%22:%22input%22,%22block_id%22:%22notes%22,%22label%22:%7B%22type%22:%22plain_text%22,%22text%22:%22Additional%20delivery%20notes%22%7D,%22element%22:%7B%22type%22:%22plain_text_input%22,%22action_id%22:%22notes_input%22,%22multiline%22:true,%22placeholder%22:%7B%22type%22:%22plain_text%22,%22text%22:%22Add%20notes...%22%7D%7D,%22optional%22:true%7D,%7B%22type%22:%22input%22,%22block_id%22:%22location%22,%22label%22:%7B%22type%22:%22plain_text%22,%22text%22:%22Delivery%20Location%22%7D,%22element%22:%7B%22type%22:%22plain_text_input%22,%22action_id%22:%22location_input%22,%22placeholder%22:%7B%22type%22:%22plain_text%22,%22text%22:%22Enter%20the%20location%20details...%22%7D%7D,%22optional%22:true%7D,%7B%22type%22:%22input%22,%22block_id%22:%22channel%22,%22label%22:%7B%22type%22:%22plain_text%22,%22text%22:%22Notification%20Channel%22%7D,%22element%22:%7B%22type%22:%22channels_select%22,%22action_id%22:%22channel_select%22,%22placeholder%22:%7B%22type%22:%22plain_text%22,%22text%22:%22Select%20channel%20for%20notifications%22%7D%7D,%22optional%22:false%7D%5D,%22submit%22:%7B%22type%22:%22plain_text%22,%22text%22:%22Approve%22%7D%7D) as a base, create a modal that captures the kind of information that you need.

2. Within the `actions/sample_action.pyfile`, add the following function, replacing the view with the one you created above. Again, any strings with variables will be updated to f-strings and also any booleans will need to be capitalized.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
2. Within the `actions/sample_action.pyfile`, add the following function, replacing the view with the one you created above. Again, any strings with variables will be updated to f-strings and also any booleans will need to be capitalized.
2. Within the `actions/sample_action.py` file, add the following function, replacing the view with the one you created above. Again, any strings with variables will be updated to f-strings and also any booleans will need to be capitalized.


Lastly, we’ll handle the submission of the form, which will trigger two things. We want to send the information into the specified channel, which will let the user know that the form was successful, as well as send the information into our system of record, Salesforce.

1. Here’s a [simple example](https://app.slack.com/block-kit-builder/?1#%7B%22blocks%22:%5B%7B%22type%22:%22section%22,%22text%22:%7B%22type%22:%22mrkdwn%22,%22text%22:%22%E2%9C%85%20Delivery%20*%7Bdelivery_id%7D*%20approved:%22%7D%7D,%7B%22type%22:%22section%22,%22text%22:%7B%22type%22:%22mrkdwn%22,%22text%22:%22*Delivery%20Notes:*%5Cn%7Bnotes%20or%20'None'%7D%22%7D%7D,%7B%22type%22:%22section%22,%22text%22:%7B%22type%22:%22mrkdwn%22,%22text%22:%22*Delivery%20Location:*%5Cn%7Bloc%20or%20'None'%7D%22%7D%7D%5D%7D) of a message that you can use to present the information in channel. Modify it however you like and then place it within the code below in the `/views/sample_views.py` file.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same thing as above


```

3. Let’s also send the information to Salesforce. There are [several ways](https://github.com/simple-salesforce/simple-salesforce?tab=readme-ov-file#examples) for you to access Salesforce through its API, but in this workshop, we’ve utilized `username`, `password` and `token`. If you need help with getting your API token for Salesforce, take a look at [this article](https://help.salesforce.com/s/articleView?id=xcloud.user_security_token.htm&type=5). You’ll need to add these values as environment variables like we did earlier with our Slack tokens. You can use the following commands:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
3. Let’s also send the information to Salesforce. There are [several ways](https://github.com/simple-salesforce/simple-salesforce?tab=readme-ov-file#examples) for you to access Salesforce through its API, but in this workshop, we’ve utilized `username`, `password` and `token`. If you need help with getting your API token for Salesforce, take a look at [this article](https://help.salesforce.com/s/articleView?id=xcloud.user_security_token.htm&type=5). You’ll need to add these values as environment variables like we did earlier with our Slack tokens. You can use the following commands:
3. Let’s also send the information to Salesforce. There are [several ways](https://github.com/simple-salesforce/simple-salesforce?tab=readme-ov-file#examples) for you to access Salesforce through its API, but in this example, we’ve utilized `username`, `password` and `token` variables. If you need help with getting your API token for Salesforce, take a look at [this article](https://help.salesforce.com/s/articleView?id=xcloud.user_security_token.htm&type=5). You’ll need to add these values as environment variables like we did earlier with our Slack tokens. You can use the following commands:


```

4. We’re going to use assume that order information is stored in the Order object and that the confirmation IDs map to the 8-digit Order numbers within Salesforce. Given that assumption, all we need to do is make a query to find the correct object, add the inputted information, and we’re done. Place this code before the last except within the `/views/sample_views.py` file.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
4. We’re going to use assume that order information is stored in the Order object and that the confirmation IDs map to the 8-digit Order numbers within Salesforce. Given that assumption, all we need to do is make a query to find the correct object, add the inputted information, and we’re done. Place this code before the last except within the `/views/sample_views.py` file.
4. We’re going to use assume that order information is stored in the Order object and that the confirmation IDs map to the 8-digit Order numbers within Salesforce. Given that assumption, we need to make a query to find the correct object, add the inputted information, and we’re done. Place this functionality before the last excerpt within the `/views/sample_views.py` file.

Copy link
Member

@zimeg zimeg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@haleychaas I'm finding these setup setups to be great! Leaving a few comments on section ideas but find right now the example might save confusion at a first read?

🧪 Please let me know if these comments make sense or of more test steps!


### Cloning the starter app

Once installed, use the command `slack create` in your terminal, select the `bolt-python-starter-template`, then choose your preferred language (this tutorial shows Python). Alternatively, you can clone the [Bolt for Python template](https://github.com/slack-samples/bolt-python-starter-template) using git.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Once installed, use the command `slack create` in your terminal, select the `bolt-python-starter-template`, then choose your preferred language (this tutorial shows Python). Alternatively, you can clone the [Bolt for Python template](https://github.com/slack-samples/bolt-python-starter-template) using git.
Once installed, use the command `slack create` in your terminal to get started with the Bolt for Python [starter template](https://github.com/slack-samples/bolt-python-starter-template). Alternatively, you can clone the starter template using Git:
```sh
$ slack create my-confirmation-app --template slack-samples/bolt-python-starter-template
$ cd my-confirmation-app
```

👁️‍🗨️ suggestion: I think we can be opinionated throughout this page on preferring python and also I suggest a command above for perhaps more fast starts?


Once installed, use the command `slack create` in your terminal, select the `bolt-python-starter-template`, then choose your preferred language (this tutorial shows Python). Alternatively, you can clone the [Bolt for Python template](https://github.com/slack-samples/bolt-python-starter-template) using git.

You can remove the portions from the template that are not used within this tutorial to make things a bit cleaner for yourself. To do this, open your project in VS Code (you can do this from the terminal with the `code .` command) and delete the `commands`, `events`, and `shortcuts` folders from the `/listeners` folder. You can also do the same to the corresponding folders within the `/listeners/tests` folder as well. Finally, remove the imports of these files from the `/listeners/__init__.py` file.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 question: Do you think starting from a blank template might make this more clear? IIRC we're needing still a blank template for python and I am adding this to soon follow up!


We’ll use the contents of the `manifest.json` file below. This file describes the metadata associated with your app, like its name and permissions that it requests.

Copy the contents of the file and [create a new app](https://api.slack.com/apps/new). Next, choose **From a manifest** and follow the prompts, pasting the manifest file contents you copied.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Copy the contents of the file and [create a new app](https://api.slack.com/apps/new). Next, choose **From a manifest** and follow the prompts, pasting the manifest file contents you copied.
These values are used to create an app one of two ways:
- **With the Slack CLI**: Save the contents of the file to your project's `manifest.json` file then skip ahead to [starting your app](#starting-your-app).
- **With app settings**: Copy the contents of the file and [create a new app](https://api.slack.com/apps/new). Next, choose **From a manifest** and follow the prompts, pasting the manifest file contents you copied.

📺 suggestion: Wanting to skip some sections following when using the CLI!


Still in the app settings, navigate to the **Install App** page in the left sidebar. Install your app. When you press **Allow**, this means you’re agreeing to install your app with the permissions that it’s requesting. Copy the bot token that you receive as well and store this in a safe place as well for subsequent steps.

## Starting your app's server
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
## Starting your app's server
### Saving credentials

📺 suggestion: These credentials are managed at runtime with the CLI - wanting to add another section on running the app that keeps this separate!

$env:SLACK_APP_TOKEN="YOUR-APP-TOKEN-HERE"
$env:SLACK_BOT_TOKEN="YOUR-BOT-TOKEN-HERE"
```

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
## Starting your app {#starting-your-app}

📦 suggestion: A section here might make linking for the CLI steps more clear I hope!

# Start your local server
python3 app.py
```

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
If you're not using the Slack CLI, a different `python` command can be used to start your app instead:
```sh
python3 app.py
```

📺 suggestion: Following the preferred commands above!

The first thing we want to do is change the “hi, how are you?” message from our app into something more useful. Here’s something that you can use to start off with, but you can make it your own within Block Kit Builder. Once you have something you like, copy the blocks by clicking the **Copy Payload** button in the top right.

Take the function below and place your blocks within the blocks dictionary `[]`. Update the payload:
* Remove the initial blocks key and convert any boolean true values to `True` to fit with Python conventions.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🐍 thought: true

logger.error(e)
```

Next, you’ll need to make some connections so that this function is called when a message is sent in the channel where your app is. Head to `messages/__init__.py` and add the line below to the register function. Don’t forget to add the import to the callback function as well!
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Next, you’ll need to make some connections so that this function is called when a message is sent in the channel where your app is. Head to `messages/__init__.py` and add the line below to the register function. Don’t forget to add the import to the callback function as well!
Next, you’ll need to register this listener to respond when a message is sent in the channel with your app. Head to `messages/__init__.py` and add the line below to the register function. Don’t forget to add the import to the callback function as well!

⚡ suggestion: A few common terms I find elsewhere calls this "registering" a "listener" but these terms aren't defined too well I think?

from .sample_message import delivery_message_callback # import the function to this file

def register(app: App):
app.message(re.compile("(hi|hello|hey)"))(sample_message_callback) # This can be deleted!
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
app.message(re.compile("(hi|hello|hey)"))(sample_message_callback) # This can be deleted!

🪓 suggestion: It might be the most clear to recommend overwriting the entire file with the example?

try:
delivery_id = context["matches"][0]
say(
blocks=[] # insert your blocks here
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📚 issue: A specific example might be needed to send actions to the action listeners in following steps?

👾 suggestion: For now requesting changes for this example but am open to working through this in iteration soon!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
docs Improvements or additions to documentation semver:patch
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants