In this guide, you’ll learn how to use Novu to send notifications directly to a Slack channel. But before coding anything up, we first need to go through a setup process. The corresponding docs for this guide are available on our docs.

The entire code of this app (frontend as well as backend) can be found here.

So let’s begin!

Create a Slack App

Creating a Slack app is fairly simple. Follow these steps to create your app:

  1. Go to Slack’s app dashboard and click on the ‘Create new App’ button, as shown in the image:

Create an app from Slack's app dashboard

  1. Choose ‘From Scratch’ from the following dialog:

Select 'From Scratch' in the following dialog

  1. Choose a name for your app and select the Slack workspace in which you want to send notifications:

Name your app and select the workspace

  1. Once you’re done, simply click the ‘Create App’ button:

Click on the 'Create App' button

  1. Once done, you’ll be greeted with the screen shown below. We’ll make a couple of changes here and it’ll be ready to go.

Slack greets you with this screen

  1. We’ll need Client Id from the Slack Developer’s Dashboard for configuring Slack Integration in the Novu Web Dashboard later, so keep it handy.

Get 'Client Id' from the Slack developer's dashboard

Create a workflow in the Novu Web Dashboard

  1. To create a workflow, head to the workflow section in the Novu Web Dashboard.
  2. Click on the ‘Add a workflow’ button and select ‘Blank workflow’ from the dropdown.

Create a workflow from the Novu Web Dashboard

  1. Once there, give your workflow a name and drag and drop the ‘chat’ option below the ‘workflow trigger’ step.

Drag and drop the 'chat' option

  1. You can also add variables in the Workflow Editor. For example, here I’ve added ‘chatMsg’ as a variable as I’ll be sending data using it.

Configure the step as per your liking

Whatever is placed inside double braces is a variable.
5. Make sure that you’ve turned on the Slack integration in the Integrations Store.

Make sure that Slack integration is set to active

  1. To turn the Slack integration on, you’ll need Client Id. You should have it already but if you don’t, you can obtain it from the Slack Developer’s Dashboard.

Get 'Client Id' from the Slack developer's dashboard

  1. Once you have it, you need to plug it into the respective field in the Slack Integration Settings on the Novu Web Dashboard.

Plug the 'Client Id' into the Slack Integration setting in Novu web dashboard

Create the backend

The backend for this app is quite simple. Simply install the Novu package:

npm install @novu/node

Now, create a route that you’ll hit when called from the front end. We’ll also need to add it to our Slack app (discussed below). For our demo app, this is the route I’ve created:

import express from "express";
import { chatController } from "../controller/chat.js";

const router = express.Router();"/sendChat", chatController);

export default router;

Now, we need a controller function to handle what is to be sent in the trigger’s function payload. Here’s the controller I wrote:

import { chat } from "../novu/novu.js"

export const chatController = async (req, res) => {
    const { chatMsg } = req.body;
    try {
        await chat(chatMsg);
        res.status(201).json({ message: "Message sent successfully" });
    } catch (error) {
        res.status(500).json({ message: error.message })
Notice how we’re expecting ‘chatMsg’ in our payload. This is why we added it as a variable in the workflow created earlier.

To make it modular, we’ll keep the trigger code in a separate function in a separate file, novu.js, in our case, which is as follows:

import { Novu, ChatProviderIdEnum } from '@novu/node';

export const chat = async (chatMsg) => {
    const novu = new Novu(process.env.YOUR_NOVU_API_KEY_HERE);
    await novu.subscribers.identify(process.env.SUB_ID, {
        firstName: 'newSubForSlackChat',

    await novu.trigger('slack', {
        to: {
            subscriberId: process.env.SUB_ID
        payload: {
            chatMsg: chatMsg

In this code snippet above, we’re first initializing a new instance of Novu, then using it to ‘identify’ or create a subscriber.

The ‘identify’ method tries to find a subscriber with the given info. If it can’t find any such subscriber, it creates a new subscriber with the supplied info.
After creating the subscriber, it runs the trigger code for the workflow we had created. You can find the trigger workflow by clicking on the ‘Get Snippet’ button on the workflow:

Click the 'Get Snippet' button to get trigger code

Paste this trigger code in your backend

Configure the Slack app

There are two ways to configure the Slack app. One is the Novu managed option and another the manually managed option. Since the Novu managed is fairly straightforward, I’ll demonstrate the manual method here. Follow along to set it up!

  1. Goto ‘Incoming Webhooks’ in your Slack app settings and turn it on.

Turn on 'Incoming Webhooks' in your Slack app

  1. Click on the ‘Add New Webhook to Workspace’:

Click the 'Add New Webhook to Workspace' button

  1. Now, go ahead and select the channel in which you want to send notifications and click ‘allow’.

Select the channel

  1. Then, copy the ‘webhookUrl’ from Slack.

Copy the webhookUrl from Slack

  1. Now, add the code below to the backend trigger functionality. Using this code, we are specifying what webhookUrl Novu will use to authenticate when using the Slack provider.
import {
} from '@novu/node';

const novu = new Novu("<NOVU_API_KEY>");

await novu.subscribers.setCredentials('subscriberId', ChatProviderIdEnum.Slack, {
  webhookUrl: "<WEBHOOK_URL>",

In our case, we’ll add it to the Novu.js file we created earlier so that the final file becomes :

import { Novu, ChatProviderIdEnum } from '@novu/node';

export const chat = async (chatMsg) => {
    const novu = new Novu(process.env.YOUR_NOVU_API_KEY_HERE);
    await novu.subscribers.identify(process.env.SUB_ID, {
        firstName: 'newSubForSlackChat',

    await novu.subscribers.setCredentials(process.env.SUB_ID, ChatProviderIdEnum.Slack, {
        webhookUrl: process.env.SLACK_WEBHOOK_URL,

    await novu.trigger('slack', {
        to: {
            subscriberId: process.env.SUB_ID
        payload: {
            chatMsg: chatMsg
  1. Finally, we’ll add the route we’d created earlier to the redirect URL section, as shown:

Add your endpoint to the redirect URL section on Slack

For demonstration purposes, I’ve added both the local as well as the deployed URL. You only need one depending on whether you’re running this locally or have a deployed version.
Now, our backend is all done, our Slack is all setup and all we need to do is hit the URL

Front end set up

For our demonstration purposes, the front end is pretty basic. All we have to do is have an input field to take the notification text in and send the payload. The front end code for this demo app is available on our Github repo. And here’s our app in all its glory!

Our app in action!

This is how we send Slack notifications using Novu!