Building Substack-like Application with Notification Service - Real-time lists updation and Broadcasts

Sanjeev Kumar
February 10, 2024
TABLE OF CONTENTS

Keeping your audience engaged and up-to-date is crucial for the success of any online publication or newsletter service. One effective way to do this is by implementing a real-time notification system that allows you to broadcast updates and messages to your subscribers instantly. In this tutorial, we will walk you through the process of building a notification system from scratch for a Substack-type newsletter application. We will cover everything from setting up the necessary infrastructure to integrating real-time updates using web sockets. By the end of this guide, you will have a fully functional notification system that will help you keep your readers informed and coming back for more.

Technology Stack

  • Frontend - React.js, Bootstrap
  • Backend - Node.js
  • For Notifications -SuprSend NodeSDK

File structure:

Application Features

  1. Users have the ability to both subscribe and unsubscribe to any newsletters that are available.
  2. Notifications can be broadcasted to all users who have subscribed to a specific newsletter.
  3. A user has the option to subscribe to any number of newsletters they desire.

Basic Application UI:

A screenshot of a newsletterDescription automatically generated

 

A screenshot of a computerDescription automatically generated

Frontend Code:

You can create your own UI, or checkout the frontend code for the developed Substack type application on Github: SuprSend-NotificationAPI/Suprsend-Newsletter: Suprsend Newsletter

Backend Code and Integration

Setting up Index.js

  
      require("dotenv").config();
      const express = require("express");
      const port = 4000;
      const app = express();
      const cors = require('cors');

      app.use(cors());
      app.use(express.json());

      const { Event } = require("@suprsend/node-sdk");
      const { Suprsend, SubscriberListBroadcast } = require("@suprsend/node-sdk");
      const supr_client = new Suprsend(process.env.WKEY, process.env.WSECRET);                               
        
    

Creating Lists on SuprSend using Lists API - https://docs.suprsend.com/docs/node-lists

  
       const data1 = supr_client.subscriber_lists.create({
            list_id: "TrendyBytes",
            list_name: "TrendyBytes",
            list_description: "Stay in the know about the latest trends, tech, and more with our bite-sized newsletter."
        });

        const data2 = supr_client.subscriber_lists.create({
            list_id: "WellnessWave",
            list_name: "WellnessWave",
            list_description: "A weekly wellness boost delivered to your inbox, packed with tips for a healthier you."
        });

        const data3 = supr_client.subscriber_lists.create({
            list_id: "EcoEcho",
            list_name: "EcoEcho",
            list_description: "Get your eco-friendly fix with news and tips on sustainable living and environmental updates."
        });

        const data4 = supr_client.subscriber_lists.create({
            list_id: "CultureSnap",
            list_name: "CultureSnap",
            list_description: "Explore global cultures through quick snapshots of traditions, stories, and art from around the world."
        });

        const data5 = supr_client.subscriber_lists.create({
            list_id: "BizBrief",
            list_name: "BizBrief",
            list_description: "Your quick business update stay informed about markets, money, and more in a nutshell."
        });

        const data0 = supr_client.subscriber_lists.create({
            list_id: "notasubscriber",
            list_name: "notasubscriber",
            list_description: "user is not subscribed to any of the list"
        });                      
        
    

Building Routes

Subscribing to the newsletter and hence that list

  
       /********************** Subscribe to a list **************************************/
        app.post("/subscribe/:listname", async (req, res) => {
            const { usermail } = req.body;
            const distinct_id = usermail; 
            const user = supr_client.user.get_instance(distinct_id);
            user.add_email(usermail);
            const response = user.save();
            response.then((res) => console.log("response", res));

            const data1 = supr_client.subscriber_lists.remove("notasubscriber", [distinct_id]);
            data1.then((res) => console.log(res)).catch((err) => console.log(err));

            const event_name = "NEWSSUBSCRIBED";
            let properties = {
                "name": req.params.listname
            };
            const event = new Event(distinct_id, event_name, properties);
            const response2 = await supr_client.track_event(event);
            console.log('response', response2);

            const data = supr_client.subscriber_lists.add(req.params.listname, [distinct_id]);

            data.then((res) => console.log(res)).catch((err) => console.log(err));
            res.json("Added a user");
        });                     
        
    

Unsubscribing through the list

  
			/************************* Unsubscribe to a list **************************************/


        app.post("/unsubscribe/:listname",async(req,res)=>{
            const distinct_id = req.body.usermail;
            const data = supr_client.subscriber_lists.remove(req.params.listname, [
               distinct_id
            ]);
            data.then((res) => console.log(res)).catch((err) => console.log(err));
            res.json("unsubscribed a user");
        })                    
        
    

Broadcasting message to the entire list using SuprSend broadcast API - https://docs.suprsend.com/docs/node-broadcast

  
			/************************* send notification to a list **************************************/


        app.post("/sendnotification/:listname",async(req,res)=>{
            const broadcast_body = {
                list_id: req.params.listname,
                template:  req.params.listname.toLowerCase(),
                notification_category: "transactional",
                channels: ["email"],
                data:{

                }
            }  
            const inst = new SubscriberListBroadcast(broadcast_body);
            const data = supr_client.subscriber_lists.broadcast(inst);
            data.then((res) => console.log(res)).catch((err) => console.log(err));
            res.json("notification sent");
        })


        /************************* listening of port **************************************/


        app.listen(port,()=>{
            console.log("server started on port 4000");
        })                
        
    

Sample Email upon Subscription to any Newsletter from the UI

A screenshot of a computerDescription automatically generated

Written by:
Sanjeev Kumar
Engineering, SuprSend
Implement a powerful stack for your notifications
By clicking “Accept All Cookies”, you agree to the storing of cookies on your device to enhance site navigation, analyze site usage, and assist in our marketing efforts. View our Privacy Policy for more information.