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

Maxim Bassin
11 min readNov 13, 2021

--

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

In the first part, we’ve set up our Slack app, the dev environment and managed to run our first node.js code from our computer 🥳.

In this part you will:

  1. Set up Git versioning control
  2. Open a GitHub project and sync your project to it
  3. Set up a worker on the Heroku server
  4. Link Heroku to be in sync with the GitHub account

Let’s review and understand the code we’ve used:

  • Line #2
const { WebClient, LogLevel } = require("@slack/web-api");

This line calls for the Node Slack SDK package, and assigns it to a parameter called WebClient. Which is a setup we have to do in order to use the Slack-related actions. LogLevel parameter is redundant and we’ll ignore it for now.

  • Then, on line #5 we’re creating an instance called client, which we will use to make Slack-related actions (posting a message in our case). We’ve added our token to the instance so it will have the authority to perform these actions
const client = new WebClient("YOUR-Bot-User-OAuth-Token");

which basically translates into:

Create a new constant instance called client, it should be a new instance of WebClient, initialized by the app token that allows it to perform actions.

  • On line #7 we’ve created an instance called channelId, that keeps the member ID
const channelId = "YOUR-MEMBER-ID";

The reason that we’ve used an instance, is so that we will type channelId every time that we’d need to use it, instead of explicitly writing the ID. Parametrizing all the information at the beginning of the code is a very good way to keep a flexible and readable code.

  • Then we have a block, starting at line #8 and finishing on line #21
(async () => {
//SOME CODE TO SEND A MESSAGE TO SLACK
})();

This is a format for an asynchronous function. It means that during the code execution, the code execution will not pause until the content of the async function will finish (as with non-async functions, where the code execution is paused until the function has finished its execution). Why do we need an asynchronous function to execute the message sending? Good question! It has to do with the code inside the function:

try {
//SOME CODE TO SEND A MESSAGE TO SLACK
}
catch (error) {
//SOME CODE TO DEAL WITH WHAT HAPPENS WHEN THE MESSAGEE WILL NOT BE SUCCESSFULLY DELIVERED
}

It has a try/catch block, which is a method to try and execute a command and being able to deal with the case where the command fails, without breaking out of the execution (if the command fails, we’d be able to handle it and continue the execution of the rest of our code). To implement the try/catch block, it has to live within an async function.

  • Let’s examine the command that actually sends the message to Slack, on lines #11–13
  const result = await client.chat.postMessage({
channel: channelId,
text: "Hello world from my computer"
});

It’s a bit counter-intuitive but what is written here is something among the lines of:

The result that I want, is the outcome of when I’ll finish waiting for chat.postMessage method of the client instance to complete. The chat.postMessage method executes using 2 configuration parameters: channel, which equals to our channelId (previously defined), and text, which equals to the message we’d like to send.

This block executes the chat.postMessage and puts the execution result (the Slack server response for our chat.PostMessage call) into the result.

  • Then on line #16
  console.log(result);

We’re displaying the response in our terminal. Basically saying: Set a log entry of the console to be the content of the result.

The content of the result is what we saw here:

  • Let’s review the catch part of the block
catch (error) {
console.error(error);
}

This basically translates into: If there is an error with the try block, set the content of the error into the error parameter, and then set a log entry of the console to be the content of the error.

Pretty simple, right? 😅

Now let’s set up versioning control and put our code in the cloud

But why 🤔?

Good question! During development, there are many interactions and sometimes parallel coding. In order not to lose ourselves, we should keep track of all our changes by managing versions of the changes. Having our code and versions on the cloud will allow us to sync it with a server to run our code, and also will allow us and other team members to contribute to our code from anywhere.

Let’s open a GitHub account to store our code and its versions

  • Go to https://github.com/
  • Sign up
  • In VSCode, click the version. control icon on the left toolbar and click Publish to GitHub
  • Click on the checkmark button to make the first commit
  • Add commit note and press the return key
  • Oh no, we had an error, let’s see what the issue
  • Let’s set up the user email and name for git commits
  • Open the terminal and put in the following info (replace the email and name placeholders with the data you used to set up the GitHub account)
git config --global user.email "you@example.com"

and then hit the return key.

Then add the user name and hit the return key

git config --global user.name "Your Name"
  • Let’s try to commit again, using the checkmark icon and adding the note

you should note that the list on the left side became empty — meaning that all our latest changes have a project version assigned to them.

  • You’ll notice on GitHub that now you have a new repository. Click it.
  • Copy the repository link
  • Now let’s Push our latest version to GitHub
  • We’ll get an error shown on the bottom right of the VSCode window. Let’s click “Add Remote” to resolve it.
  • Paste the URL you’ve copied from GitHub
  • Add a name to the remote source and hit the Return key
  • Let’s try to Push our code again
  • Now, when you’ll refresh your GitHub project, you’ll see our local files in the project.

Let’s review what just happened

We’ve hooked up the version control system (git) and then pushed our latest version to our master branch in GitHub.

So what are these Commit and Push actions?

We used Commit, to commit the files for versioning, and Push, to push the latest version to the remote repository on GitHub.

During our development, we will save & Commit our changes and then Push them to GitHub, for every new code version we’ll create.

OK, now we’ll set up a remote server (Heroku) to run our app

(9 steps)

  1. Go to Heroku and create a new account with all the defaults. Be sure to set the default programming language as Node.js

2. Create a new app in Heroku (give it a fun and recognizable name)

3. Connect your GitHub project to the app

4. In VSCode, let’s specify that start is the command that should execute the app.js file that contains our app. It’s just something that needs to be done in order for things to run as expected.

4.1 Go to Explorer, click the package.json file

4.2 Replace the “test” line under scripts with the following:

"start": "node app.js"

4.3 Save the modified package.json file

4.4 Create a new file in the project folder and call it Procfile (without extension). Add the following line to the file and save it (This is something that needs to be configured to make things run as expected on Heroku).

worker: npm start
“worker” will indicate to Heroku, that our app is a process that runs on the server, vs a “web” that specify a setup that listens to ports and fetches web pages, like a website

4.5 On the Heroku website, change the following configuration to be “worker” instead of “web”

5. Now let’s change the message we’d like to send using our app (don’t forget to save the file), commit the changes, push it to GitHub and see what happens. The pushed changes should put our code to the Heroku server and run it from there — eventually sending our message to our Slack from the Heroku server

***THIS IS SOMETHING THAT YOU WILL DO FOR EVERY CODE CHANGE AFTER YOU SAVE YOUR FILES***

If you didn’t see any updates, it’s probably because you didn’t save your changes

6. On Heroku, you can click to manually deploy the change to the server.

7. If all went well, you should see this message in Heroku and get a new slack message

8. Set Heroku to automatically deploy any changes happening on the GitHub repository. This way, every push to GitHub will be automatically deployed to Heroku and executed.

9. Let’s test again our end-to-end, by changing the message again, committing, and pushing the change.

Remeber to save the file

You did it! 🍾

You’ve successfully set up a server that runs your app. In addition, your local development is synced with a remote repository. So all your committed and pushed changes are automatically executed on the server.

This is pretty big — Good job!

Now what?

Our next steps will be:

  1. Install cron npm package
  2. Using Slack’s message building tool, customize the message format to be sent via API
  3. Set up an AWS account and create a new bucket to store images

Let’s go to part 3>>

--

--