Skip to content

Real-time chat backend with private rooms and a CLI client.

Notifications You must be signed in to change notification settings

Amitrajit007/Chat-Backend

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

35 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Chat Backend

A WebSocket-driven chat backend using Socket.IO, Express, TypeScript, MongoDB, and Redis.
Designed to handle real-time direct messaging with persistent storage, rate limiting, content moderation, and cached message history.


πŸ“‹ Table of Contents


Features

  • Real-time Messaging: Instant bidirectional communication using Socket.IO
  • Direct Messaging (DM): Private one-on-one chat rooms
  • Message Persistence: All messages stored in MongoDB for chat history
  • Online Presence: Track and broadcast online users
  • Rate Limiting: Prevent spam with automatic message throttling (3 messages/minute)
  • Content Moderation: Automatic filtering of inappropriate content
  • Message History API: Retrieve past messages via REST endpoint
  • Redis-backed Caching: Reduce repeated MongoDB reads for chat history queries
  • Typing Indicators: Real-time visual feedback when a user is composing a message
  • Read Receipts: Track and update the delivery and read status of messages
  • TypeScript: Full type safety across client, server, and shared types
  • CLI Client: Command-line interface for testing and demonstration

Architecture

System Overview

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Client A       │──┐
β”‚  (Socket.IO)    β”‚  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
                     β”œβ”€β”€β–Ί β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚    β”‚  Backend Server  │──────│  MongoDB    β”‚
β”‚  Client B       │───    β”‚  (Express +      β”‚      β”‚  (Messages) β”‚
β”‚  (Socket.IO)    β”‚  β”‚    β”‚   Socket.IO)     β”‚      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                     β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  Client C       β”‚β”€β”€β”˜
β”‚  (Socket.IO)    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Message Flow

Client A
  └─ emit("dm-message", text)
       β”‚
       β–Ό
    Backend
       β”œβ”€ Validate & Rate Limit
       β”œβ”€ Save to MongoDB
       └─ io.to(room).emit("dm-message", message)
            β”‚
            β–Ό
         Client A + Client B
            └─ on("dm-message") β†’ Display message

Tech Stack

Server

  • Node.js with TypeScript
  • Express - HTTP server and REST API
  • Socket.IO - WebSocket communication
  • Redis - query caching
  • MongoDB with Mongoose(ORM) - Message persistence
  • dotenv - Environment configuration
  • CORS - Cross-origin resource sharing

Client

  • Socket.IO Client - WebSocket client library
  • TypeScript - Type-safe client code
  • Node.js readline - CLI interface

Shared

  • TypeScript - Shared type definitions between client and server

Project Structure

.
β”œβ”€β”€ README.md
β”œβ”€β”€ client
β”‚Β Β  β”œβ”€β”€ cli.ts
β”‚Β Β  β”œβ”€β”€ package-lock.json
β”‚Β Β  β”œβ”€β”€ package.json
β”‚Β Β  β”œβ”€β”€ test.ts
β”‚Β Β  β”œβ”€β”€ tsconfig.json
β”‚Β Β  └── utils
β”œβ”€β”€ packages
β”‚Β Β  β”œβ”€β”€ package-lock.json
β”‚Β Β  └── shared
β”‚Β Β      β”œβ”€β”€ dist
β”‚Β Β      β”‚Β Β  β”œβ”€β”€ index.d.ts
β”‚Β Β      β”‚Β Β  └── types
β”‚Β Β      β”‚Β Β      β”œβ”€β”€ historyMessage.d.ts
β”‚Β Β      β”‚Β Β      └── socket.d.ts
β”‚Β Β      β”œβ”€β”€ package.json
β”‚Β Β      β”œβ”€β”€ src
β”‚Β Β      β”‚Β Β  β”œβ”€β”€ index.ts
β”‚Β Β      β”‚Β Β  └── types
β”‚Β Β      β”‚Β Β      β”œβ”€β”€ historyMessage.ts
β”‚Β Β      β”‚Β Β      └── socket.ts
β”‚Β Β      └── tsconfig.json
└── server
    β”œβ”€β”€ package-lock.json
    β”œβ”€β”€ package.json
    β”œβ”€β”€ src
    β”‚Β Β  β”œβ”€β”€ config
    β”‚Β Β  β”‚Β Β  └── dbConnection.ts
    β”‚Β Β  β”œβ”€β”€ controller
    β”‚Β Β  β”‚Β Β  └── msgHistory.controller.ts
    β”‚Β Β  β”œβ”€β”€ index.ts
    β”‚Β Β  β”œβ”€β”€ model
    β”‚Β Β  β”‚Β Β  └── chat.ts
    β”‚Β Β  β”œβ”€β”€ routes
    β”‚Β Β  β”‚Β Β  └── messageHistory.route.ts
    β”‚Β Β  β”œβ”€β”€ service
    β”‚Β Β  β”‚Β Β  └── messageHistory.service.ts
    β”‚Β Β  β”œβ”€β”€ sockets
    β”‚Β Β  β”‚Β Β  β”œβ”€β”€ deliveryMsg.ts
    β”‚Β Β  β”‚Β Β  β”œβ”€β”€ disconnect.ts
    β”‚Β Β  β”‚Β Β  β”œβ”€β”€ dmMessages.ts
    β”‚Β Β  β”‚Β Β  β”œβ”€β”€ index.ts
    β”‚Β Β  β”‚Β Β  β”œβ”€β”€ presence.state.ts
    β”‚Β Β  β”‚Β Β  β”œβ”€β”€ readMsg.ts
    β”‚Β Β  β”‚Β Β  β”œβ”€β”€ setUsername.ts
    β”‚Β Β  β”‚Β Β  β”œβ”€β”€ startDm.ts
    β”‚Β Β  β”‚Β Β  └── typeIndicator.ts
    β”‚Β Β  β”œβ”€β”€ tsconfig.json
    β”‚Β Β  └── utils
    β”‚Β Β      β”œβ”€β”€ roomId.ts
    β”‚Β Β      └── time.ts
    └── test
        β”œβ”€β”€ client-test-1.ts
        β”œβ”€β”€ client-test-2.ts
        β”œβ”€β”€ client-test-3.ts
        └── client-test-4.ts

Getting Started

Prerequisites

  • Node.js (v16 or higher)
  • MongoDB (local or MongoDB Atlas)
  • npm or yarn

Installation

  1. Clone the repository

    git clone https://github.com/Amitrajit007/Chat-Backend.git
    cd Chat-backend
  2. Install server dependencies

    cd server
    npm install
  3. Install client dependencies

    cd ../client
    npm install
  4. Install shared package dependencies

    cd ../packages/shared
    npm install
    npm run build  # Compile TypeScript types

Configuration

Create a .env file in the server/ directory:

PORT=5000
Atlas_URI=mongodb://localhost:27017/chat-app
# Or use MongoDB Atlas:
# Atlas_URI=mongodb+srv://username:password@cluster.mongodb.net/chat-app

Running the Application

  1. Start the server

    cd server
    npm run dev

    Server will run on http://localhost:5000

  2. Start client instances (in separate terminals)

    # Terminal 1 - User "alice" chatting with "bob"
    cd client
    npx ts-node cli.ts alice bob
    
    # Terminal 2 - User "bob" chatting with "alice"
    npx ts-node cli.ts bob alice

πŸ”Œ Socket Events

Client β†’ Server

Event Payload Description
set-username string Set the username for the connected socket
start-dm string Start a DM session with target user
dm-message string Send a message in the current DM room

Server β†’ Client

Event Payload Description
online-users string[] Broadcast list of currently online users
dm-message ChatMessage Receive a message in the DM room
dm-error string | ChatMessage Error notification (rate limit, moderation, etc.)

ChatMessage Type

type ChatMessage = {
  roomId: string; // Sorted usernames (e.g., "alice,bob")
    id: string; //   Message ID
    from: string; // Sender username
    text: string; // Message content
    to: string; // Recipient username
    time: string; // Formatted timestamp
}

REST API Endpoints

Get Message History

Retrieve past messages between two users.

Endpoint: GET /lastmessages

Query Parameters:

  • from (string, required) - First username
  • to (string, required) - Second username
  • limit (number, optional) - Number of messages to retrieve (default: 10 and max: 25)

Example Request:

curl "http://localhost:5000/lastmessages?from=alex&to=john&limit=3"

Example Response:

[
  {
    "_id": "45ec5a84-4d0f-4dc4-ae88-f8fe03fe7941",
    "roomId": "alex,john",
    "id": "45ec5a84-4d0f-4dc4-ae88-f8fe03fe7941",
    "from": "alex",
    "text": "i love peace",
    "to": "john",
    "time": "4/1/2026, 10:07:27 pm",
    "__v": 0
  },
  {
    "_id": "2cac0dd7-ff7e-4541-94bc-9d2a6659bb16",
    "roomId": "alex,john",
    "id": "2cac0dd7-ff7e-4541-94bc-9d2a6659bb16",
    "from": "john",
    "text": "Hello alex",
    "to": "alex",
    "time": "5/1/2026, 1:09:34 am",
    "__v": 0
  },
  {
    "_id": "70a45670-9f03-4e1c-b29f-651964ed53d6",
    "roomId": "alex,john",
    "id": "70a45670-9f03-4e1c-b29f-651964ed53d6",
    "from": "alex",
    "text": "hii",
    "to": "john",
    "time": "5/1/2026, 1:09:54 am",
    "__v": 0
  }
]

Health Check

Endpoint: GET /health

Response: OK

Server Status

Endpoint: GET /

Response:

{
  "msg": "Active @ 5000"
}

Database Schema

Message Collection

{
  roomId: String,   // Sorted usernames (e.g., "alice,bob")
  id: String,       // Message ID
  from: String,     // Sender username
  text: String,     // Message content
  to: String,       // Recipient username
  time: String,     // Formatted timestamp
}

Indexes:

  • { roomId: 1, createdAt: -1 } - Optimized for message history queries

Usage Examples

Example Console Output

Server Console:

Listening at 5000
MongoDB connected successfully
Online :  [ 'alex' ]
alex is connected in romm : dm:alexjohn
Online :  [ 'alex', 'john' ]
john is connected in romm : dm:alexjohn
Client disconnect with id:  LkSQBjXklUABPJPaAAAD
Online :  [ 'alex' ]
Client disconnect with id:  S1JIjaZJXQerzz4PAAAJ
No one is Online

John's Console:

Chatting with alex
Type messages and press Enter...

online: [ 'alex', 'You' ]
online: [ 'You' ]
online: [ 'You', 'alex' ]
alex : hii John    5/1/2026, 3:26:01 am
alex : How are you  ?    5/1/2026, 3:26:12 am
> Im fine, thanks 
You : Im fine, thanks    5/1/2026, 3:26:38 am
[READ] b9a30bdc-aadc-46b5-ab46-60cb500a8889
[DELIVERED] b9a30bdc-aadc-46b5-ab46-60cb500a8889
alex : Cool πŸ‘    5/1/2026, 3:27:01 am

Caught Ctrl+C
Closing connection...
Disconnected

Alex's Console:

Chatting with john
Type messages and press Enter...

online: [ 'john', 'You' ]
> hii John
You : hii John    5/1/2026, 3:26:01 am
[DELIVERED] b2a328e8-0034-4635-a3ee-c79db5016afd
[READ] b2a328e8-0034-4635-a3ee-c79db5016afd
> How are you  ?
You : How are you  ?    5/1/2026, 3:26:12 am
[DELIVERED] 5d54095b-2864-4e5c-837f-533900a64912
[READ] 5d54095b-2864-4e5c-837f-533900a64912J
John : Im fine, thanks    5/1/2026, 3:26:38 am
> Cool πŸ‘
You : Cool πŸ‘    5/1/2026, 3:27:01 am
[DELIVERED] e587c3a8-2041-46e3-8676-b37df243faf8
[READ] e587c3a8-2041-46e3-8676-b37df243faf8
online: [ 'You' ]

Caught Ctrl+C
Closing connection...
Disconnected

Testing

Run Client 1 Test:

npm run client-test-1

Run Client 2 Test:

npm run client-test-2

Rate Limiting & Moderation

Rate Limiting

  • Limit: 5 messages per minute per user
  • Penalty: 5-second mute on exceeding limit
  • Error Message: "Too many messages. Muted for 5s."

Content Moderation

Messages containing the following keywords are automatically rejected:

  • "war"
  • "gun" These are just examples, you can add more keywords to the server\src\sockets\dmMessages.ts file.

Rejected Message Response:

Error: Message is not accepted

Implementation Details

Rate limiting is implemented per socket connection:

socket.data.rate = {
  count: 0,           // Messages sent in current window
  lastReset: Date.now(), // Window start time
  mutedUntil: 0       // Timestamp when mute expires
}

Notes

  • socket.id is a temporary identifier assigned per connection, used for debugging and logging
  • Room IDs are generated by sorting usernames alphabetically to ensure consistency (e.g., "alice,bob" regardless of who initiates)
  • Timestamps are formatted in local time: "DD/MM/YYYY, HH:MM:SS am/pm"
  • All messages are persisted to MongoDB for chat history

About

Real-time chat backend with private rooms and a CLI client.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors