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 first 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:
- Part 2 – Bolt
- Part 3 – Integrating with Salesforce
- Part 4 – Local Development and Debugging
- Part 5 – What’s Coming Next
The use case
When we started to think about this project, several use cases came to mind. We wanted to create a sample app that used Slack and Salesforce, and we wanted to showcase how to scaffold the app, how to implement the authentication with Salesforce, and different options for communicating in both directions — from Slack to Salesforce and from Salesforce to Slack. After giving it some thought, we decided to create a travel approvals app.
Travel approvals reside in a Salesforce custom object.
The user experience
Employees can create travel requests from Slack using a global shortcut command.
From the app home, users can see a list of the travel requests that they’ve submitted for approval.
Managers can also see pending requests to review on the home page. Within Slack, they can approve or reject them. Or, if they want to see more details, they can click a button to view the record in Salesforce.
On the other hand, Salesforce sends notifications in different cases, such as when a travel request submitted by the user has been approved or rejected, and when a new travel request needs the user’s attention. Managers can approve or reject new travel requests from the message.
To see the app in action, watch this demo.
The architecture
When we create a Slack app, we really need to do two things. First of all, we need to define the app at api.slack.com in a Slack workspace that can later be distributed in various ways. This is done through a UI, either manually or by copying a manifest.yml file, and no code is needed at this point.
Secondly, Slack provides a series of APIs (Events API, Web API, and more) that you can use to interact with the installed app. To interact with these APIs, you normally build an app using code in your language of choice. You could use these APIs directly in your app, but luckily Slack provides a library to make your life easier: the Bolt framework. Bolt provides a web server to run your app, it sets up authentication with the Slack app, and it gives you simplified interfaces to work with all Slack APIs and features. The Bolt framework is available for Python, JavaScript, and Java.
Note: You may run across references to the Python, Node, and Java SDKs. However, Slack now recommends using the Bolt framework as it includes the functionality in those packages and more.
To build Ready to Fly, we decided to build a Node.js app. This app acts as a middleware layer through which all the communication streams go. We hosted the app on Heroku, as the deployment process is straightforward and we could run our demo app on free dynos. The Node.js app uses the JavaScript version of Bolt (Bolt.js) to communicate with Slack. With Bolt, all the authentication work is managed for you, which is a great advantage.
Conversely, the Node.js app uses JSforce to callout to Salesforce, via a connected app. For Ready to Fly, we decided to use the OAuth 2.0 Web Server Flow for Web App Integration flow (sometimes known as “user-to-user flow”). This flow allows Slack users to authorize as a concrete user in Salesforce, so the app can access Salesforce data in the user’s context. This is exactly what we wanted to do, as travel requests need to be created, approved, or rejected on behalf of the authorized user. We’ll explore in depth how we implemented the flow in another blog post in this series (spoiler: we used Salesforce Slack Starter Kit!).
To call out from Salesforce to the Slack app, we decided to use a Bolt.js feature called custom HTTP routes. This creates a standard express router to receive requests from the outside. We could have used Webhooks to create messages in the Slack app directly, but that didn’t work for our use case because we needed to execute some logic in response to the Salesforce callout.
You can watch this short video to get familiar with the Slack app system architecture.
The repository structure
The Ready to Fly app code is organized in a single Git repository for simplicity. Both the Node.js app code and the Salesforce app code are included in the repo.
To deploy the app, follow the README instructions. You’ll have to run a deploy script and also perform some manual steps. You’ll need a Slack workspace to which you’ll install the app, a Heroku account, and a Salesforce org (one that is a developer hub). The deploy script will:
- Create a scratch org and deploy the Salesforce app code, including the code needed for authentication, together with some sample data
- Deploy the Node.js app code to Heroku, setting up all the needed auth tokens and configuration variables in secure environment variables
Next steps
We’ve built this app from scratch. However, Salesforce is working on the Apex SDK for Slack, a new collection of developer tools that will let you use your Salesforce development skills to create Slack apps in Salesforce levering your existing Apex skills. The SDK is currently in Pilot for our ISV partners. We’ll talk more about the SDK later in the blog series.
That’s all for this first blog post in our series. Don’t forget to check the Ready to Fly code and get the app running in your own Salesforce org and Slack workspace! Remember — there is a related video series and another short video that will help you get familiar with the Slack app system architecture.
We’ll continue digging into more implementation details in future posts. In the next one, we’ll dive into the Node.js app structure and how it uses Bolt.js to communicate with Slack. So, stay tuned!
About the author
Alba Rivas works as a Principal Developer Advocate at Salesforce. She focuses on Lightning Web Components and Lightning adoption strategy. You can follow her on Twitter @AlbaSFDC.