This is the second blog in a five-part series.

Building a Slack app that integrates with Salesforce involves some challenges, such as knowing the right integration capability to use on each case, picking the right authorization flow, and implementing it securely. This is the second blog post of a series in which we cover the whole process of creating a Slack app that integrates with Salesforce from scratch. Learn along with us while we build Ready to Fly, our new sample app for submitting and approving travel requests in Salesforce without leaving Slack.

Note: some parts of this app have been live coded by my colleagues Mohith Shrivastava (@msrivastav13) and Kevin Poorman (@codefriar) in their codeLive video series: Building with Slack.

Check out the rest of the blogs in this series here:

The Bolt framework

Let’s continue our series by talking about the Bolt framework, which provides a web server to run your app on, sets up authentication with the Slack app, and gives you simplified interfaces to work with Slack APIs and features. The Bolt framework is available for Python, JavaScript, and Java. Per our familiarity with Lightning Web Components (LWC), we decided to use the JavaScript version and build a Node.js app for Ready to Fly.
Focus areas of this blog post are highlighted in red

How Slack apps work

If you’re familiar with web development, you’ll know that elements on a web page can react to events like “click” or “hover.” In a similar way, events occur when users perform actions in the Slack UI. For example, Slack fires events when messages are posted to a channel and when an app home is opened.

In JavaScript, you react to events by defining listeners, and it’s the same in Bolt.js. You can define listeners for events, actions, shortcuts, views, messages, and options — really different types of events. You generally write some logic in the listener, do a callout to an external system if needed, and then send changes to Slack that need to be reflected in your app’s UI.

Slack UIs are defined in JSON with a framework called Block Kit. You send a list of blocks over to a Slack API, and Slack generates the layout for you in a consistent manner. This minimizes the amount of work you have to do to create a layout, and it guarantees that all Slack apps have a consistent UX foundation. Bear in mind, Block Kit is the only way to define UIs; injecting HTML is not allowed.

Remember the app home of our Ready to Fly app?
Ready to Fly app home

Let’s explore the steps that are needed to render the user’s travel requests:

  1. The user opens the app home. The Events API publishes the app_home_opened event to your event subscription URL. You’ll need to set up this URL in the Slack app definition (more about this later).
  2. If the user is authorized with Salesforce, the Node.js app requests the user’s travel requests from Salesforce, using JSforce, a JavaScript library for use with the Salesforce APIs. You’ll need to create a connected app in Salesforce to handle authentication.
  3. Salesforce responds by sending the user’s travel requests.
  4. The Node.js app generates the UI with Block Kit, and publishes it to the app home.

A flow that shows travel requests when a user visits the app home

Let’s see another example. In Ready to Fly, an approver can see a travel request and then either approve or reject it.

Buttons that allow approvers to interact with travel requests

Let’s see how this flow works:

  1. The user clicks the “Approve” or “Reject“ buttons. Slack notifies the Node.js app that the button has been pressed, sending a block_actions payload to your interactivity URL. This is another URL that you’ll need to set up in the Slack app definition.
  2. If the user is authorized with Salesforce, the Node.js app sends the travel request status update to Salesforce, using JSforce.
  3. The Node.js app generates a modal UI with Block Kit and posts it to Slack. Slack prompts the modal to the user.