Real-Time Notifications (WebSocket)
A scalable, developer-ready WebSocket notification system for Express with optional email and queue-based delivery.
Overview
A powerful, real-time notification system using WebSocket (Socket.IO) for instant delivery across clients. Supports persistent storage (MongoDB), optional email notifications, and background queue processing with Bull. Ideal for modern apps needing instant alerts, multi-channel delivery, and scalability.
Installation
What This Does
Installs a fully functional WebSocket notification system with real-time delivery, persistence, and multi-channel support (socket, email, queue).
Files & Folders Created
| File / Path | Description |
|---|---|
| /src/config/websocket.js | Initializes the Socket.IO server and manages client connections. |
| /src/models/notification.js | MongoDB schema for storing notification data. |
| /src/config/email.js | Configures Nodemailer for optional email notifications. |
| /src/config/queue.js | Sets up Bull queue for background message processing. |
| /src/services/notificationService.js | Core service for creating and managing notifications. |
| /src/routes/notifications.js | REST routes for creating, listing, and marking notifications. |
| /server.js.example | Example server with integrated WebSocket and Express routing. |
Files to be modified
| File / Path | Description |
|---|---|
| server.js | Adds WebSocket initialization and notification API routes. |
| .env | Adds WebSocket, SMTP, and queue environment variables. |
Configuration
# WebSocket Notifications Configuration PORT=3001 ENABLE_EMAIL_NOTIFICATIONS=true NOTIFICATION_QUEUE_ENABLED=true SMTP_HOST=smtp.gmail.com SMTP_PORT=587 SMTP_USER=your-email@gmail.com SMTP_PASS=your-app-password SMTP_FROM=YourApp Notifications <your-email@gmail.com>
Frontend Integration
Integrate in your Next.js or React app to receive instant real-time notifications. Users join their own private WebSocket room to receive personalized alerts.
Send a new notification via WebSocket, email, or queue.
Fetch notifications for a user (supports unread filtering).
Mark a notification as read.
Example
1// app/notifications/NotificationClient.jsx (Next.js example)
2'use client';
3import { useEffect, useState } from 'react';
4import { io } from 'socket.io-client';
5
6export default function NotificationClient({ userId }) {
7 const [notifications, setNotifications] = useState([]);
8 const [connected, setConnected] = useState(false);
9
10 useEffect(() => {
11 const socket = io('http://localhost:3001', { transports: ['websocket'] });
12
13 socket.on('connect', () => {
14 setConnected(true);
15 socket.emit('join', userId);
16 console.log('🔗 Connected to WebSocket server');
17 });
18
19 socket.on('notification', (data) => {
20 setNotifications((prev) => [data, ...prev]);
21 });
22
23 socket.on('disconnect', () => {
24 setConnected(false);
25 console.log('❌ Disconnected from server');
26 });
27
28 return () => socket.disconnect();
29 }, [userId]);
30
31 return (
32 <div className="p-4 border border-white/10 rounded-lg bg-black/30">
33 <h3 className="text-lg font-semibold mb-2 text-white">
34 🔔 Notifications {connected ? '🟢' : '🔴'}
35 </h3>
36 {notifications.length === 0 ? (
37 <p className="text-sm text-muted-foreground">No notifications yet...</p>
38 ) : (
39 <ul className="space-y-2 max-h-[250px] overflow-y-auto [&::-webkit-scrollbar]:w-0 scrollbar-none">
40 {notifications.map((n) => (
41 <li
42 key={n._id}
43 className="text-sm text-foreground border border-white/10 rounded-md p-2"
44 >
45 <strong className="text-emerald-400">{n.title}</strong>
46 <p className="text-xs text-muted-foreground">{n.message}</p>
47 <span className="text-[10px] text-gray-500 block mt-1">
48 {n.type.toUpperCase()} • {n.priority.toUpperCase()}
49 </span>
50 </li>
51 ))}
52 </ul>
53 )}
54 </div>
55 );
56}Usage
1// Programmatic usage example
2const { createNotification } = require('./src/services/notificationService');
3
4await createNotification({
5 userId: '507f1f77bcf86cd799439011',
6 title: 'New message received',
7 message: 'You have a new message from Jane.',
8 type: 'info',
9 priority: 'normal',
10 channels: ['socket', 'email'],
11 metadata: { email: 'user@example.com' }
12});