Home

Post Messages to Slack with Node.js

Build a simple Slack app that sends one-way messages to a channel using a Node script.

Slack apps appear to be complex when getting started using their documentation. And many apps are complex. They are built to be distributed among multiple Slack teams, and they typically listen for input from users and adjust responses based on that input. They are apps, after all.

But they don't have to be. Sometimes you may just want to send a message to Slack based on some other event. You don't need to listen for input from users, but only want to send one-way messages.

This process is actually quite simple and only involves three basic steps:

  1. Registering the app
  2. Understanding how blocks work
  3. Writing the script

Let's do it!

Registering a Slack Application

Let's create and configure a new Slack application.

Create Slack App

Begin by going to api.slack.com/apps and clicking Create New App.

Choose From Scratch, then give it a name and choose the workspace where you want to install it.

Enable Incoming Webhooks

In the basic information section, go into Incoming Webhooks.

Slide the toggle to enable the feature. After doing this, you will see a button near the bottom called Add New Webhook To Workspace. Click this and choose a channel where you'll install the app.

note

This doesn't mean it's the only channel the bot can post to. You can change this later, but have to pick something now.

After doing this, you'll see that the webhook integration has been added to the channel in your Slack team.

Add Permissions

Navigate to OAuth & Permissions (under Features in the side navigation) and scroll down to the Scopes section.

Enable the following scopes as Bot Token Scopes:

  • chat:write
  • chat:write.public
  • incoming-webhook (should already be enabled)
warning

If the channel you want to post to is a private channel, go back to Slack and invite the app user into the channel.

You will likely see a notification at this point, asking you to reinstall the application into the workspace after adding these scopes. Follow the steps it provides.

Display Information

Finally, if you want to adjust how the app appears when posting messages, you can adjust the display information near the bottom of the Basic Information page under Settings.

Note that we'll have to come back here for some security credentials when we start writing code. But for now, let's move on to learn about blocks.

Understanding Slack Blocks

Slack messages are typically made up of blocks. These are structured JSON objects that tell Slack how to render the message. It gives you a lot of flexibility in how you present your message.

Block Kit Builder

This is likely the thing you'll spend the most time adjusting so that your messages are formatted exactly as you'd like. Fortunately, there is a block kit builder that you can use to get more familiar with blocks.

Example Blocks

Here's an example of blocks you might use to notify Slack that you just published a post.

{
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": ":fire: New post published to the site: <https://www.seancdavis.com/|*Working with Slack API*>"
}
},
{
"type": "divider"
},
{
"type": "context",
"elements": [
{
"type": "image",
"image_url": "https://avatars.githubusercontent.com/u/5245089?v=4",
"alt_text": "Sean C Davis"
},
{
"type": "mrkdwn",
"text": "Author: <https://www.seancdavis.com/|*Sean C Davis*>"
}
]
}
]
}

Block Structure

There are a few things that tripped me up as I was learning about blocks:

  • A markdown block is of type mrkdwn (not markdown).
  • Markdown structure is not standard markdown. Slack has its own flavor. The block kit builder will show you some examples.
  • You should not use action blocks. Actions are for interactive apps and you're not enabling any interactivity in the app we're building here.

Here are the block kit docs, which are a nice reference while you're structuring your content.

Writing the Script

The code is so surprisingly simple that I don't even need to show you an example project. It just takes a few steps.

If you don't have a project already, begin with a new blank Node.js project.

Install Dependencies

The only dependency we'll use here is Slacks's SDK, called @slack/bolt.

npm install @slack/bolt

If you also don't have a way to store and load environment variables, you can take advantage of dotenv.

npm install dotenv

Save Environment Variables

We're going to retrieve and store three environment variables:

SLACK_SIGNING_SECRET: Find this in the App Credentials section in the Basic Information page. Copy the Signing Secret.

SLACK_BOT_TOKEN: This is under OAuth & Permissions. There should be a single token that you can copy. (See below for a screenshot.)

SLACK_CHANNEL: The name of the channel that you are going to send the message to. I use an environment variable so that I can easily swap this out between development and production.

Once you have these values, paste them in the appropriate place in your project.

.env

SLACK_SIGNING_SECRET="..."
SLACK_BOT_TOKEN="..."
SLACK_CHANNEL="..."

Write the Script

Then we can write the script. And it's super simple!

index.mjs

import Slack from "@slack/bolt";

const app = new Slack.App({
signingSecret: process.env.SLACK_SIGNING_SECRET,
token: process.env.SLACK_BOT_TOKEN,
});

const blocks =
/* Add blocks payload here ... */

await app.client.chat.postMessage({
token: process.env.SLACK_BOT_TOKEN,
channel: process.env.SLACK_CHANNEL,
text: "...",
blocks,
});

Be sure to set the blocks constant to the payload you've built with the block kit builder (or use my example).

And replace the text property in postMessage with an appropriate text representation of your message. This is for usages where Slack does not render block content.

note

Notice here that I'm using .mjs as the file extension. This is so I could have access to top-level await. You can also set "type": "module" in your package.json.

Now run the script and see the results!


I hope this serves as a solid foundation for you to build something great (or fun, or both)!

Feel free to create an issue if you have a question or trouble with this code.

Let's Connect

Keep Reading

How I Begin New JavaScript Projects

These are the first steps I take when I start a new JavaScript project.

May 26, 2021

Adding S3 Credentials for Node.js AWS SDK

My go-to method for gaining access to AWS using the Node.js tooling.

Aug 20, 2021

WTF is Node.js?

An brief introduction to Node.js, along with links to dig in further with a tutorial or course.

Jun 29, 2020