Crash course on backend programming for Product Managers//Building a Slack app from scratch — Part 5

Maxim Bassin
13 min readNov 13, 2021

--

This is the 5th part of the series, where we build an awesome app, all by ourselves.

In this part you will:

  1. Create a new server app on Heroku that will serve as a website
  2. Set the server application to respond to GET messages
  3. Create a simple HTML page with an “Add to Slack” button
  4. Built an Oauth2 authentication process: Get from Slack a temporary authorization code and exchange it for an access token

Off we go!

The idea here is that we’d need to have a website that would contain an “Add to Slack” button. By clicking that button, any user will be able to install our app to their domain. When the user will click the button, they will be prompted with Slack’s authorization popup, once confirmed, the authorization process will provide us with the Slack info of the user and their workspace, together with a token that we’d be able to use to send them messages from our app. Remember, currently, we only have 1 user using our app (our own Slack), and we use the hardcoded token and the channel ID

Our goal here is to store that data in the database and retrieve it dynamically, just as with messages.

Setting up the environment for a new website

To create a website, we’ll use Heroku

(7 steps)

  1. Go to Heroku, and create a new app

2. Got to VSCode and open a new window

3. Create a new folder for our website project and navigate to it from VSCode

You should see the folder name here

4. Now we should create a placeholder file named server.js. This file will be used as the behind-the-scenes coordinator to handle website requests.

And save it as is, under the name of “server.js”

5. Let’s connect our folder to a new private GitHub repository

Now we have our new repository on GitHub for our website.

6. Let’s connect the GitHub repository to a new app in Heroku, so whatever code we’ll push to the repository, will be synced to Heroku — our server.

7. And finally, we’ll allow automatic deployment, so any change pushed to GitHub will be automatically deployed to Heroku

Creating a simple website

The setup

(4 steps)

  1. Initiate npm in your working folder, by opening the terminal in the VSCode and typing npm init (and click enter). npm is a package manager for the JavaScript programming language and it will help us download the package for Slack and MongoDB interaction.

2. Click the return key a few times to have the default settings

3. Install the Slack npm package by typing the following and clicking enter:

npm install @slack/web-api

4. Install MongoDB npm package with this line:

npm install mongodb

The landing page

We’ll create a simple website that will contain the word “hello world”

(8 steps)

  1. Create a new file by double-clicking the empty space in the tabs header

2. Add the following code to the file

<!DOCTYPE html>
<head>
</head>
<body>
<h1>hello world</h1>
</body>

3. Save the file as “index.html”

Note: This is a very basic setup of a webpage, where the first line is the document type declaration, the <head></head> part is a placeholder for page configurations (<NAME> is the opening tag, and the </NAME> is a closing tag of any element on a page), and <body></body> is the section containing the content of our site. In our case, we have only one element, which is <h1></h1> which is a text Header1 type of element, having “hello world” as content.

4. Run the file locally to see how it looks

Simple indeed

Click to stop the run

5. Now we’d like to present this page to whoever will visit our Heroku website. Your default name is YOURHEROKUAPPNAME.heroku.com

And now that we visit it, it doesn't present any content

So we need to instruct the server.js file to prevent index.html page to whoever visits our website. When users navigate to a website, they perform a GET request from that URL. server.js is the logic responsible for the website, so we’d need to specify what the site should do when it gets a GET request.

In order to do so, we’d need our app to listen and respond to requests. We should install another npm package to help us with that. Run the following command in the terminal (don’t forget to hit the return button)

npm install express

6. Now we’ll create a service using the express package to listen to requests and handle the responses. Add the following code to the server.js file (note the explanation comments for each line

const express = require('express');//add the service to our file to use it's functions
const app = express();//create a constant named app that will utilize express service
const PORT = process.env.PORT; //get the active port our heroku app is runnin on. This is also the port we'll listen toapp.listen(PORT, function() {});//our app is set to listen to the port
app.get('/', (req, res) => {
res.sendFile(__dirname + '/index.html')
})//when our app will get a get request for our app base url, without any file specified, it will respond with the index.html file that resides in the root of our website

7. Save the server.js and index.html files, add, commit and push them to git

8. Check the app website on Heroku, you should get the index.html content

Let’s recap so far:

  • We’ve set app a web service (server.js)
  • Using the express npm package, the service listens to a server port
  • For when the client gets to the homepage, our service serves the client with the index.html page

That’s some serious stuff there! Way to go🎉

Add the “Add to Slack” button to our website

(7 steps)

1. Go to api.slack.com , choose your app and go to Basic information>Manage distribution menu and click the “Distribute App” button

2. Under Add OAuth Redirect URLs click the Set Up Redirect URLs button

3. Under Redirect URLs, click the Add New Redirect URL

4. Copy the Herokus website address and paste it here

And then add slack at the end of the URL and click Add

5. Save the URL

6. Now go to Manage Distribution and copy the code for the “Add to Slack” button

7. Paste the copied code right below the h1 closing tag in the index.html file

Make the “Add to Slack” button work

When a user will click on your “Add to Slack” button and agree to the terms in the popup, Slack will send a GET request to the Redirect URL that we’ve set up earlier (https://slackappwebsiteformedium.herokuapp.com/slack). This request will contain a temporary authorization code. We’d need to extract that code, and send a request to slack with our credentials and temporary authorization code to receive an access token to send messages to the user that just installed our app.

(9 steps)

  1. Install Axios npm package that will help us send the temporary authorization token and our credentials to slack

Run this in the terminal

npm install axios

And create a constant named axios to use the Axios services by adding this line to the beginning of the code

const axios = require('axios');

2. Create a new parameter called params. It will include the temporary authorization code and our credentials that we’ll send to Slack once a user will install the app. Add this at the beginning of the server.js file

const params = new URLSearchParams(); // a const named param is initialized as a URL parameter type object

3. Set our code to listen to GET requests to the Redirect URL that we’ve set up earlier (https://slackappwebsiteformedium.herokuapp.com/slack)

Install this npm package to help us parse (process) different types of information, by typing the following code to the terminal:

npm install body-parser

And then add this code, so we will be able to parse different types of information formats

const bodyParser = require('body-parser')
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());

then add the listener for ‘/slack’ path, by adding the below

app.get('/slack',(req,res) => {})

4. Extract the temporary authorization code from the request, and add it under the code parameter in the params object we’ve created, by adding the following code inside the listener we’ve just created. Note the code comments.

if(req.query.code){ //check if the request query contains a parameter named code
params.append('code', req.query.code)//add to the params object a parameter named code, that has the value of the code recieved in the request query
}

5. For the message we need to send to Slack in order to get the access token, we’d need to add our client ID and client secret. We’ll do the following:

  • Get them from Slack
  • Store them as environment parameters in Heroku (note the key names, we’ll use them later)
  • Append them to the params object. Add this to the listener:
params.append('client_id', process.env.client_id)//appending to the params object as client_id the client_id variable stored on the server 
params.append('client_secret', process.env.client_secret)//appending to the params object as client_secret the client_secret variable stored on the server

6. Now that we have our data to get the access token from Slack, we need to send a post request to Slack. Add this to our main function to send the params object to slack and then to print out the data section of the result in the server log, to see what we’ll get from Slack:

axios.post('https://slack.com/api/oauth.v2.access', params, {headers: {'Content-Type': 'application/x-www-form-urlencoded'}}).then(async (result) => {//after the prevous operation will finish, use the results output of that operation and execute this functionconsole.log(result.data)//prints out the data section of the result into the server logs});

We are sending Slack our credentials along with the temporary authorization code we got (all in the params object, encoded by the setting in the config object that we’ve configured early on), the response to this call contains the authorization token to that specific user who installed our app with some basic user info.

7. Then finally we’ll redirect the user back to the index page for after when the user confirmed our app on Slack’s page, by adding this line right after the closing parentheses of the if statement, so that the user will always be taken to our landing page, regardless of authorization.

res.sendFile(__dirname + '/index.html')

8. Save, commit, and push

9. Open the server log, then run our page (by clicking “Open app”) and install the slack app again. After which, we’ll look at the server logs to see how Slack’s response looks like after our app is installed

The 2 most important pieces of information that we’ll use are the authed_user.id (to specify the channel for sending a message) and the access_token (the token to use to send the message to that user)

let’s review what we’ve accomplished like a boss:

  • Created a server application that responds to GET messages
  • Created a website that has an “Add to Slack” button
  • Built an Oauth2 authentication process where we get from Slack a temporary authorization code and exchange it for an access token

In the next (and final) part you will:

  1. Create a new collection in Mongo DB to store user credentials
  2. Using the website app, upon every app installation, store the user credentials in Mongo DB
  3. Using the worker app and the for loop, set the app to go over all the user info and send them a message once a week

Let’s go to part 6>>

--

--