Introduction
Welcome to the Commt Node.js SDK – the backbone of secure chat functionalities for your Node.js backend applications!
The Commt Node.js SDK is specifically designed for server-side applications, providing essential backend functionality for chat systems. Unlike frontend SDKs, this package focuses on secure message handling, room management, and seamless integration with your existing Node.js infrastructure.
What is Commt Node.js SDK?
The @commt/node-sdk is a TypeScript-first backend SDK that serves as the bridge between your Node.js application and the Commt chat platform. It provides essential server-side functionality including:
- Message Decryption: Handle encrypted messages sent from client applications
- Room Management: Create and manage chat rooms programmatically
- Secure Backend Integration: Seamlessly integrate with your existing authentication and database systems
- Webhook Support: Process real-time chat events in your backend
Key Benefits
- 🔐 Security First: Built-in AES encryption with end-to-end encryption support
- 🚀 Developer Friendly: Written in TypeScript with comprehensive type definitions
- ⚡ Lightweight: Minimal dependencies for optimal performance
- 🔧 Flexible: Easy integration with any Node.js framework (Express, Fastify, Koa, etc.)
- 📦 Production Ready: Battle-tested in production environments
Perfect For
- Backend Developers building chat APIs and webhooks
- CTOs and Tech Leads implementing secure communication systems
- Full-stack Teams requiring server-side chat functionality
- Enterprise Applications needing scalable chat infrastructure
This SDK works seamlessly with Commt's frontend SDKs (React Native and React) to provide a complete chat solution for your application ecosystem.
Installation
Getting started with the Commt Node.js SDK is straightforward. Choose your preferred package manager and follow the installation steps below.
Package Manager Installation
Using NPM
npm install @commt/node-sdkUsing Yarn
yarn add @commt/node-sdkUsing pnpm
pnpm add @commt/node-sdkVerification
After installation, you can verify the SDK is properly installed by checking the package version:
npm list @commt/node-sdkTypeScript Support
The Commt Node.js SDK is written in TypeScript and provides full type definitions out of the box. No additional @types packages are required.
Prerequisites
Before using the Commt Node.js SDK, ensure you have:
- Node.js: Version 14.0 or higher
- Active Commt Project: Get your API credentials from the Commt Dashboard (opens in a new tab)
- Project Configuration: Your
apiKey,projectId, andsecretkey ready
Next Steps
Once installed, you can proceed to the Configuration section to set up your Commt client and start integrating chat functionality into your Node.js application.
Package Information
- Package Name:
@commt/node-sdk - License: MIT
- Repository: GitHub (opens in a new tab)
- NPM: View on NPM (opens in a new tab)
Configuration
The Commt Node.js SDK uses a simple initialization pattern that allows you to configure the client once and access it globally throughout your application.
Basic Configuration
Initialize the Commt SDK in your main application file (e.g., index.js, app.js, or server.js):
import { Commt } from "@commt/node-sdk";
// Initialize Commt with your project credentials
Commt.init({
apiKey: "your-api-key",
projectId: "your-project-id",
secret: "your-secret-key", // Must be 16, 24, or 32 bytes
});
// Create a global instance for easy access
global.commt = Commt.with();Configuration Options
| Parameter | Type | Required | Description |
|---|---|---|---|
apiKey | string | ✅ | Your project API key from Commt Dashboard |
projectId | string | ✅ | Your unique project identifier |
secret | string | ✅ | Encryption secret key (16, 24, or 32 bytes) |
APIUrl | string | ❌ | Custom API endpoint (defaults to Commt's service) |
Getting Your Credentials
- Sign up for a Commt account at dashboard.commt.co (opens in a new tab)
- Create a new project or select an existing one
- Copy your credentials from the project settings:
- API Key
- Project ID
- Secret Key
Environment Variables (Recommended)
For production applications, store your credentials securely using environment variables:
import { Commt } from "@commt/node-sdk";
Commt.init({
apiKey: process.env.COMMT_API_KEY,
projectId: process.env.COMMT_PROJECT_ID,
secret: process.env.COMMT_SECRET_KEY,
});
global.commt = Commt.with();Create a .env file in your project root:
COMMT_API_KEY=your-api-key
COMMT_PROJECT_ID=your-project-id
COMMT_SECRET_KEY=your-secret-keyGlobal Access Pattern
Once initialized, you can access the Commt instance from anywhere in your application:
// In any route or controller file
app.post('/save-message', async (req, res) => {
// Access the global commt instance
const decryptedMessage = global.commt.decrypt(req.body);
// ... handle the message
});Custom API Endpoint
If you're using a self-hosted Commt instance, you can specify a custom API URL:
Commt.init({
apiKey: "your-api-key",
projectId: "your-project-id",
secret: "your-secret-key",
APIUrl: "https://your-custom-commt-instance.com"
});Secret Key Requirements
The secret key is used for AES encryption and must meet specific byte requirements:
- 16 bytes: AES-128 encryption
- 24 bytes: AES-192 encryption
- 32 bytes: AES-256 encryption (recommended)
Example of a 32-byte secret key:
"a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6"Initialization Best Practices
- Initialize Early: Call
Commt.init()before setting up your routes or middleware - Single Initialization: Only initialize once per application lifecycle
- Environment-Specific: Use different credentials for development, staging, and production
- Error Handling: Always handle initialization errors gracefully
try {
Commt.init({
apiKey: process.env.COMMT_API_KEY,
projectId: process.env.COMMT_PROJECT_ID,
secret: process.env.COMMT_SECRET_KEY,
});
global.commt = Commt.with();
console.log('Commt SDK initialized successfully');
} catch (error) {
console.error('Failed to initialize Commt SDK:', error);
process.exit(1);
}API Methods
The Commt Node.js SDK provides essential methods for handling chat functionality on the server side. Below are the core methods available in the SDK.
Core Methods Overview
| Method | Purpose | Returns |
|---|---|---|
init() | Initialize the Commt SDK | void |
with() | Get SDK instance | Commt |
decrypt() | Decrypt incoming messages | string |
createRoom() | Create a new chat room | string |
Static Methods
Commt.init(config)
Initializes the Commt SDK with your project configuration.
Parameters:
interface IInit {
apiKey: string; // Your project API key
projectId: string; // Your project ID
secret: string; // Encryption secret (16, 24, or 32 bytes)
APIUrl?: string; // Optional custom API endpoint
}Example:
import { Commt } from "@commt/node-sdk";
Commt.init({
apiKey: "your-api-key",
projectId: "your-project-id",
secret: "your-32-byte-secret-key-here",
});Commt.with()
Returns the initialized Commt instance for use throughout your application.
Returns: Commt - The configured Commt instance
Example:
const commt = Commt.with();
// Now you can use commt.decrypt(), commt.createRoom(), etc.Instance Methods
decrypt(props)
Decrypts encrypted messages received from client applications.
Parameters:
interface IAESDecrypt {
iv: string; // Initialization vector
cipher: string; // Encrypted message
}Returns: string - Decrypted message content (usually JSON)
Example:
app.post('/save-message', async (req, res) => {
const { message: cipher, iv } = req.body;
// Decrypt the message
const decryptedData = commt.decrypt({ cipher, iv });
const messageData = JSON.parse(decryptedData);
console.log(messageData);
// Output: { roomId: "123", message: { text: "Hello!", senderId: "user1", ... } }
});createRoom(participants)
Creates a new chat room and returns a unique room identifier.
Parameters:
participants: string[]- Array of participant chat authentication IDs
Returns: string - Generated chatRoomAuthId for the new room
Example:
app.post('/create-room', async (req, res) => {
const { participants } = req.body; // Array of chatAuthIds
// Create room in Commt system
const chatRoomAuthId = commt.createRoom(participants);
// Save to your database
await RoomModel.create({
roomId: generateRoomId(), // Your internal room ID
chatRoomAuthId, // Commt's room identifier
participants: participants,
createdAt: new Date()
});
res.json({ success: true, chatRoomAuthId });
});Method Usage Patterns
Message Processing Workflow
// 1. Receive encrypted message from client
app.post('/webhook/message', async (req, res) => {
try {
// 2. Decrypt the message
const { message: cipher, iv } = req.body;
const decryptedData = commt.decrypt({ cipher, iv });
const result = JSON.parse(decryptedData);
// 3. Extract message details
const { roomId, message } = result;
// 4. Save to your database
await MessageModel.create({
roomId,
type: message.type,
senderId: message.senderId,
text: message.text,
createdAt: message.createdAt,
});
// 5. Return success response
res.status(200).json({ success: true });
} catch (error) {
res.status(500).json({ error: error.message });
}
});Room Creation Workflow
app.post('/rooms', async (req, res) => {
try {
const { participants, roomName, roomType } = req.body;
// 1. Create room in Commt system
const chatRoomAuthId = commt.createRoom(participants.map(p => p.chatAuthId));
// 2. Store room in your database
const room = await RoomModel.create({
name: roomName,
type: roomType,
chatRoomAuthId,
participants: participants.map(p => p.id),
createdBy: req.user.id
});
res.json({ room, chatRoomAuthId });
} catch (error) {
res.status(500).json({ error: error.message });
}
});Error Handling
Always wrap SDK method calls in try-catch blocks for robust error handling:
try {
const decryptedMessage = commt.decrypt({ cipher, iv });
// Process message...
} catch (error) {
console.error('Decryption failed:', error);
res.status(400).json({ error: 'Invalid message format' });
}TypeScript Support
All methods include full TypeScript definitions for better development experience:
import { Commt, IDGenerator } from "@commt/node-sdk";
// TypeScript will provide autocompletion and type checking
const commt = Commt.with();
const roomId: string = commt.createRoom(["user1", "user2"]);Utilities
The Commt Node.js SDK includes helpful utility functions to enhance your development experience.
IDGenerator
A utility function for generating unique identifiers, commonly used for creating room IDs, message IDs, or other unique identifiers in your chat application.
Import
import { IDGenerator } from "@commt/node-sdk";Usage
// Generate a long ID (default)
const longId = IDGenerator({ longId: true });
// Example output: "a1b2c3-d4e5f6-g7h8i9j0k1l2m3n4o5p6"
// Generate a short ID
const shortId = IDGenerator({ longId: false });
// Example output: "a1b2c3d4e5"
// Generate with custom length (only for long IDs)
const customId = IDGenerator({ longId: true, idStrLen: 40 });
// Example output: "a1b2c3-d4e5f6-g7h8i9j0k1l2m3n4o5p6q7r8"Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
longId | boolean | true | Generate long or short format ID |
idStrLen | number | 32 | Length of the generated ID (long format only) |
Examples
Room ID Generation
import { IDGenerator } from "@commt/node-sdk";
app.post('/create-room', async (req, res) => {
// Generate unique room ID for your database
const roomId = IDGenerator({ longId: false });
const room = await RoomModel.create({
roomId,
name: req.body.roomName,
// ... other room data
});
res.json({ room });
});Message ID Generation
app.post('/save-message', async (req, res) => {
// Generate unique message ID
const messageId = IDGenerator({ longId: true, idStrLen: 24 });
const message = await MessageModel.create({
id: messageId,
text: req.body.text,
senderId: req.body.senderId,
// ... other message data
});
res.json({ message });
});User Session ID
app.post('/login', async (req, res) => {
// Generate session ID
const sessionId = IDGenerator({ longId: true });
await SessionModel.create({
id: sessionId,
userId: user.id,
expiresAt: new Date(Date.now() + 24 * 60 * 60 * 1000) // 24 hours
});
res.json({ sessionId, user });
});ID Format Specifications
Long Format
- Includes hyphens for readability
- Starts with a letter (base 36)
- Includes timestamp component
- Configurable length (minimum 32 characters)
- Example:
"k-m-g7h8i9j0k1l2m3n4o5p6q7r8s9"
Short Format
- No hyphens, compact format
- Fixed length based on algorithm
- Faster generation
- Example:
"k4m2n7p9"
Best Practices
- Use Short IDs for frequently generated identifiers (messages, events)
- Use Long IDs for important entities (rooms, users, sessions)
- Consistent Length for database indexing performance
- Store as Strings in your database for compatibility
// Good: Consistent ID strategy
const roomId = IDGenerator({ longId: true, idStrLen: 32 });
const messageId = IDGenerator({ longId: false });
// Database schema consideration
const roomSchema = {
id: { type: String, length: 32 }, // Long format
messageIds: [{ type: String, length: 10 }] // Short format
};Integration with Database Models
MongoDB Example
const RoomSchema = new mongoose.Schema({
_id: {
type: String,
default: () => IDGenerator({ longId: true, idStrLen: 24 })
},
chatRoomAuthId: String,
participants: [String],
createdAt: { type: Date, default: Date.now }
});PostgreSQL Example
CREATE TABLE rooms (
id VARCHAR(32) PRIMARY KEY DEFAULT generate_room_id(),
chat_room_auth_id VARCHAR(20),
participants TEXT[],
created_at TIMESTAMP DEFAULT NOW()
);// Custom function for PostgreSQL
export const generateRoomId = () => IDGenerator({ longId: true, idStrLen: 32 });Performance Considerations
- Short IDs: ~100,000 generations per second
- Long IDs: ~50,000 generations per second
- Memory Usage: Minimal (< 1KB per 1000 IDs)
- Uniqueness: Cryptographically secure randomness
The IDGenerator is optimized for high-throughput applications and provides sufficient entropy to avoid collisions in distributed systems.
Quick Start
Get up and running with the Commt Node.js SDK in just a few minutes. This guide will walk you through the essential steps to integrate chat functionality into your Node.js application.
Step 1: Installation
Install the Commt Node.js SDK using your preferred package manager:
npm install @commt/node-sdkStep 2: Get Your Credentials
- Visit the Commt Dashboard (opens in a new tab)
- Create a new project or select an existing one
- Copy your project credentials:
- API Key
- Project ID
- Secret Key (must be 16, 24, or 32 bytes)
Step 3: Initialize the SDK
Create your main application file and initialize Commt:
index.js
import express from 'express';
import { Commt } from '@commt/node-sdk';
const app = express();
// Initialize Commt SDK
Commt.init({
apiKey: "your-api-key",
projectId: "your-project-id",
secret: "your-32-byte-secret-key-here"
});
// Create global instance
global.commt = Commt.with();
app.use(express.json());
console.log('Commt SDK initialized successfully!');Step 4: Handle Incoming Messages
Create an endpoint to receive and decrypt messages from client applications to save into your own Database:
app.post('/webhook/message', async (req, res) => {
try {
// Extract encrypted data from request
const { message: cipher, iv } = req.body;
// Decrypt using Commt SDK
const decryptedData = global.commt.decrypt({ cipher, iv });
const messageData = JSON.parse(decryptedData);
console.log('Received message:', messageData);
// messageData contains: { roomId, message: { text, senderId, createdAt, type } }
// Save to your database
await saveMessageToDatabase(messageData);
res.status(200).json({ success: true });
} catch (error) {
console.error('Message processing failed:', error);
res.status(500).json({ error: 'Failed to process message' });
}
});Step 5: Create Chat Rooms
Add an endpoint to create new room:
app.post('/rooms', async (req, res) => {
try {
const { participants } = req.body;
// participants: ["chatAuthId1", "chatAuthId2", ...]
// Create room in Commt system
const chatRoomAuthId = global.commt.createRoom(participants);
// Save room to your database
const room = await createRoomInDatabase({
chatRoomAuthId,
participants,
createdAt: new Date()
});
res.json({
success: true,
roomId: room.id,
chatRoomAuthId
});
} catch (error) {
console.error('Room creation failed:', error);
res.status(500).json({ error: 'Failed to create room' });
}
});Step 6: Start Your Server
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`🚀 Chat server running on port ${PORT}`);
console.log(`📨 Webhook endpoint: http://localhost:${PORT}/webhook/message`);
console.log(`🏠 Room creation: http://localhost:${PORT}/rooms`);
});Complete Quick Start Example
Here's the full working example:
quick-start.js
import express from 'express';
import { Commt, IDGenerator } from '@commt/node-sdk';
const app = express();
app.use(express.json());
// Initialize Commt
Commt.init({
apiKey: "your-api-key",
projectId: "your-project-id",
secret: "your-32-byte-secret-key-here"
});
global.commt = Commt.with();
// In-memory storage for demo (use a real database in production)
const messages = [];
const rooms = [];
// Message webhook endpoint
app.post('/webhook/message', async (req, res) => {
try {
const { message: cipher, iv } = req.body;
const decryptedData = global.commt.decrypt({ cipher, iv });
const messageData = JSON.parse(decryptedData);
// Store message
messages.push({
id: IDGenerator({ longId: false }),
...messageData,
receivedAt: new Date()
});
console.log(`💬 New message in room ${messageData.roomId}: "${messageData.message.text}"`);
res.status(200).json({ success: true });
} catch (error) {
console.error('Error:', error);
res.status(500).json({ error: error.message });
}
});
// Create room endpoint
app.post('/rooms', (req, res) => {
try {
const { participants, name } = req.body;
const chatRoomAuthId = global.commt.createRoom(participants);
const room = {
id: IDGenerator({ longId: false }),
chatRoomAuthId,
name: name || 'New Room',
participants,
createdAt: new Date()
};
rooms.push(room);
console.log(`🏠 Created room: ${room.name} (${chatRoomAuthId})`);
res.json({ success: true, room });
} catch (error) {
res.status(500).json({ error: error.message });
}
});
// Get messages for a room
app.get('/rooms/:roomId/messages', (req, res) => {
const roomMessages = messages.filter(m => m.roomId === req.params.roomId);
res.json({ messages: roomMessages });
});
// Get all rooms
app.get('/rooms', (req, res) => {
res.json({ rooms });
});
// Health check
app.get('/health', (req, res) => {
res.json({
status: 'OK',
commt: 'initialized',
timestamp: new Date().toISOString()
});
});
const PORT = 3000;
app.listen(PORT, () => {
console.log(`
🚀 Commt Chat Server Started!
📡 Server: http://localhost:${PORT}
📨 Message Webhook: POST /webhook/message
🏠 Create Room: POST /rooms
📋 Health Check: GET /health
Ready to receive chat messages!
`);
});Testing Your Setup
1. Start the server:
node quick-start.js2. Test room creation:
curl -X POST http://localhost:3000/rooms \
-H "Content-Type: application/json" \
-d '{"participants": ["user1", "user2"], "name": "Test Room"}'3. Check health:
curl http://localhost:3000/healthNext Steps
- Database Integration: Replace in-memory storage with MongoDB, PostgreSQL, or your preferred database
- Authentication: Add user authentication and authorization
- Frontend Integration: Connect with Commt's React or React Native SDKs
- Production Setup: Add logging, monitoring, and error handling
- Advanced Features: Implement file uploads, typing indicators, and read receipts
Common Issues & Solutions
Issue: "Secret key must be 16, 24, or 32 bytes"
// ✅ Correct: 32-byte secret key
secret: "a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6"
// ❌ Wrong: Too short
secret: "mypassword"Issue: Decryption fails
- Verify your secret key matches the one used in client applications
- Ensure the cipher and iv are correctly extracted from request body
Issue: Room creation returns error
- Check that participants array contains valid chat authentication IDs
- Verify your API key has room creation permissions
You're now ready to build powerful chat applications with the Commt Node.js SDK!
Security
The Commt Node.js SDK is designed with security as a top priority. Follow these best practices to ensure your chat application remains secure and protected.
Credential Management
Environment Variables
Always store sensitive credentials in environment variables, never in your source code:
// ✅ Good: Using environment variables
Commt.init({
apiKey: process.env.COMMT_API_KEY,
projectId: process.env.COMMT_PROJECT_ID,
secret: process.env.COMMT_SECRET_KEY,
});
// ❌ Bad: Hardcoded credentials
Commt.init({
apiKey: "ak_123456789",
projectId: "proj_987654321",
secret: "my-secret-key",
});Secret Key Requirements
Your encryption secret key must meet specific security standards:
- Length: Exactly 16, 24, or 32 bytes
- Randomness: Use cryptographically secure random generation
- Uniqueness: Each environment should have a unique secret
- Rotation: Regularly rotate secrets in production
// Generate a secure 32-byte secret key
import crypto from 'crypto';
const generateSecretKey = () => {
return crypto.randomBytes(32).toString('hex').substring(0, 32);
};
// Example: "a7b9c2d4e6f8g1h3i5j7k9l2m4n6o8p0"Message Encryption
AES Encryption
Commt uses AES-CBC encryption for all message content:
- Algorithm: AES-CBC (Cipher Block Chaining)
- Key Sizes: 128, 192, or 256 bits
- IV (Initialization Vector): Unique per message
- Padding: PKCS#7
End-to-End Encryption
For maximum security, enable E2E encryption in your project settings:
// The SDK automatically handles E2E when enabled
const decryptedMessage = commt.decrypt({ cipher, iv });
// Message is automatically decrypted using your secret keyInput Validation
Always validate and sanitize input data before processing:
import Joi from 'joi';
const messageSchema = Joi.object({
message: Joi.string().required(),
iv: Joi.string().hex().length(32).required()
});
app.post('/webhook/message', async (req, res) => {
try {
// Validate input
const { error, value } = messageSchema.validate(req.body);
if (error) {
return res.status(400).json({ error: 'Invalid input format' });
}
// Process validated data
const decryptedData = commt.decrypt(value);
// ... continue processing
} catch (error) {
res.status(500).json({ error: 'Processing failed' });
}
});Error Handling
Secure Error Messages
Avoid exposing sensitive information in error messages:
app.post('/webhook/message', async (req, res) => {
try {
const decryptedData = commt.decrypt(req.body);
// ... process message
} catch (error) {
// ✅ Good: Generic error message to client
console.error('Decryption error:', error); // Log detailed error
res.status(400).json({ error: 'Invalid message format' });
// ❌ Bad: Exposing internal details
// res.status(500).json({ error: error.message });
}
});Production Checklist
Security Audit Checklist
- All credentials stored in environment variables
- Secret keys meet length requirements (32 bytes recommended)
- HTTPS enabled for all endpoints
- Rate limiting implemented
- Input validation on all endpoints
- Error handling doesn't expose sensitive data
- Security logging implemented
- CORS properly configured
- Database connections secured
- API authentication implemented
- Regular security updates scheduled
Following these security best practices will help ensure your Commt-powered chat application remains secure and trustworthy for your users.
Complete Example
This comprehensive example demonstrates how to build a complete chat backend API using the Commt Node.js SDK with Express.js.
Project Structure
chat-backend/
├── src/
│ ├── controllers/
│ │ ├── messageController.js
│ │ ├── roomController.js
│ │ └── userController.js
│ ├── models/
│ │ ├── Message.js
│ │ ├── Room.js
│ │ └── User.js
│ ├── routes/
│ │ ├── messages.js
│ │ ├── rooms.js
│ │ └── users.js
│ ├── middleware/
│ │ └── auth.js
│ └── app.js
├── .env
└── package.jsonApplication Setup
package.json
{
"name": "chat-backend",
"version": "1.0.0",
"type": "module",
"scripts": {
"start": "node src/app.js",
"dev": "nodemon src/app.js"
},
"dependencies": {
"@commt/node-sdk": "^latest",
"express": "^4.18.2",
"mongoose": "^7.5.0",
"cors": "^2.8.5",
"dotenv": "^16.3.1"
}
}Environment Configuration
.env
# Commt Configuration
COMMT_API_KEY=your-api-key-here
COMMT_PROJECT_ID=your-project-id-here
COMMT_SECRET_KEY=your-32-byte-secret-key-here
# Database
MONGODB_URI=mongodb://localhost:27017/chat-app
# Server
PORT=3000Main Application
src/app.js
import express from 'express';
import cors from 'cors';
import dotenv from 'dotenv';
import mongoose from 'mongoose';
import { Commt } from '@commt/node-sdk';
// Import routes
import messageRoutes from './routes/messages.js';
import roomRoutes from './routes/rooms.js';
import userRoutes from './routes/users.js';
dotenv.config();
const app = express();
const PORT = process.env.PORT || 3000;
// Initialize Commt SDK
try {
Commt.init({
apiKey: process.env.COMMT_API_KEY,
projectId: process.env.COMMT_PROJECT_ID,
secret: process.env.COMMT_SECRET_KEY,
});
global.commt = Commt.with();
console.log('✅ Commt SDK initialized successfully');
} catch (error) {
console.error('❌ Failed to initialize Commt SDK:', error);
process.exit(1);
}
// Middleware
app.use(cors());
app.use(express.json());
// Database connection
mongoose.connect(process.env.MONGODB_URI)
.then(() => console.log('✅ Connected to MongoDB'))
.catch(err => console.error('❌ MongoDB connection error:', err));
// Routes
app.use('/api/messages', messageRoutes);
app.use('/api/rooms', roomRoutes);
app.use('/api/users', userRoutes);
// Health check
app.get('/health', (req, res) => {
res.json({ status: 'OK', timestamp: new Date().toISOString() });
});
app.listen(PORT, () => {
console.log(`🚀 Server running on port ${PORT}`);
});Data Models
Message Model
src/models/Message.js
import mongoose from 'mongoose';
const messageSchema = new mongoose.Schema({
roomId: { type: String, required: true, index: true },
senderId: { type: String, required: true },
text: { type: String, required: true },
type: { type: String, default: 'text' },
createdAt: { type: Date, default: Date.now },
updatedAt: { type: Date, default: Date.now }
});
messageSchema.index({ roomId: 1, createdAt: -1 });
export default mongoose.model('Message', messageSchema);Room Model
src/models/Room.js
import mongoose from 'mongoose';
import { IDGenerator } from '@commt/node-sdk';
const roomSchema = new mongoose.Schema({
roomId: {
type: String,
default: () => IDGenerator({ longId: false }),
unique: true
},
chatRoomAuthId: { type: String, required: true, unique: true },
name: String,
participants: [{ type: String, required: true }],
createdBy: String,
isGroup: { type: Boolean, default: false },
avatar: String,
createdAt: { type: Date, default: Date.now }
});
export default mongoose.model('Room', roomSchema);User Model
src/models/User.js
import mongoose from 'mongoose';
const userSchema = new mongoose.Schema({
userId: { type: String, required: true, unique: true },
chatAuthId: { type: String, required: true, unique: true },
name: { type: String, required: true },
email: String,
avatar: String,
isOnline: { type: Boolean, default: false },
lastSeen: { type: Date, default: Date.now }
});
export default mongoose.model('User', userSchema);API Controllers
Message Controller
src/controllers/messageController.js
import Message from '../models/Message.js';
export const saveMessage = async (req, res) => {
try {
const { message: cipher, iv } = req.body;
// Decrypt message using Commt SDK
const decryptedData = global.commt.decrypt({ cipher, iv });
const result = JSON.parse(decryptedData);
const { roomId, message } = result;
// Save message to database
const newMessage = await Message.create({
roomId,
senderId: message.senderId,
text: message.text,
type: message.type || 'text',
createdAt: message.createdAt || new Date()
});
res.status(200).json({
success: true,
messageId: newMessage._id
});
} catch (error) {
console.error('Save message error:', error);
res.status(500).json({
error: 'Failed to save message',
details: error.message
});
}
};
export const getMessages = async (req, res) => {
try {
const { roomId } = req.params;
const { page = 1, limit = 50 } = req.query;
const messages = await Message.find({ roomId })
.sort({ createdAt: -1 })
.limit(limit * 1)
.skip((page - 1) * limit)
.exec();
res.json({
messages: messages.reverse(),
hasNext: messages.length === parseInt(limit)
});
} catch (error) {
res.status(500).json({ error: error.message });
}
};Room Controller
src/controllers/roomController.js
import Room from '../models/Room.js';
export const createRoom = async (req, res) => {
try {
const { participants, name, isGroup = false } = req.body;
// Create room in Commt system
const chatAuthIds = participants.map(p => p.chatAuthId);
const chatRoomAuthId = global.commt.createRoom(chatAuthIds);
// Save room to database
const room = await Room.create({
chatRoomAuthId,
name,
participants: participants.map(p => p.userId),
isGroup,
createdBy: req.user?.userId
});
res.status(201).json({
success: true,
room: {
roomId: room.roomId,
chatRoomAuthId: room.chatRoomAuthId,
name: room.name,
participants: room.participants,
isGroup: room.isGroup
}
});
} catch (error) {
console.error('Create room error:', error);
res.status(500).json({
error: 'Failed to create room',
details: error.message
});
}
};
export const getRooms = async (req, res) => {
try {
const { userId } = req.params;
const rooms = await Room.find({
participants: userId
}).sort({ createdAt: -1 });
res.json({ rooms });
} catch (error) {
res.status(500).json({ error: error.message });
}
};API Routes
Message Routes
src/routes/messages.js
import express from 'express';
import { saveMessage, getMessages } from '../controllers/messageController.js';
const router = express.Router();
// POST /api/messages/save - Save encrypted message from webhook
router.post('/save', saveMessage);
// GET /api/messages/:roomId - Get messages for a room
router.get('/:roomId', getMessages);
export default router;Room Routes
src/routes/rooms.js
import express from 'express';
import { createRoom, getRooms } from '../controllers/roomController.js';
const router = express.Router();
// POST /api/rooms - Create new room
router.post('/', createRoom);
// GET /api/rooms/:userId - Get user's rooms
router.get('/:userId', getRooms);
export default router;Usage Examples
Creating a Room
curl -X POST http://localhost:3000/api/rooms \
-H "Content-Type: application/json" \
-d '{
"participants": [
{"userId": "user1", "chatAuthId": "auth1"},
{"userId": "user2", "chatAuthId": "auth2"}
],
"name": "Project Discussion",
"isGroup": true
}'Webhook Endpoint for Messages
curl -X POST http://localhost:3000/api/messages/save \
-H "Content-Type: application/json" \
-d '{
"message": "encrypted-cipher-text",
"iv": "initialization-vector"
}'Retrieving Messages
curl http://localhost:3000/api/messages/room123?page=1&limit=20Production Considerations
- Error Logging: Implement comprehensive logging with Winston or similar
- Rate Limiting: Add rate limiting middleware for API protection
- Authentication: Implement JWT or session-based authentication
- Validation: Add input validation with Joi or express-validator
- Database Indexing: Optimize database queries with proper indexing
- Monitoring: Set up health checks and performance monitoring
This example provides a solid foundation for building production-ready chat applications with the Commt Node.js SDK.
Troubleshooting
This guide helps you resolve common issues when working with the Commt Node.js SDK. Find solutions to frequently encountered problems and learn how to debug effectively.
Common Issues
Installation Issues
Symptoms:
npm ERR! 404 Not Found - GET https://registry.npmjs.org/@commt/node-sdkSolutions:
- Verify the package name is correct:
@commt/node-sdk - Check your npm registry configuration:
npm config get registry - Try clearing npm cache:
npm cache clean --force
Issue: TypeScript compilation errors
Symptoms:
error TS2307: Cannot find module '@commt/node-sdk'Solutions:
- Install the package properly:
npm install @commt/node-sdk - Restart your TypeScript server
- Check your
tsconfig.jsonfor correct module resolution
Initialization Issues
Issue: "Secret key must be 16, 24 or 32 bytes"
Symptoms:
Error: Secret key must be 16, 24 or 32 bytesSolutions:
// ❌ Wrong: Incorrect byte length
secret: "mypassword" // Only 10 bytes
// ✅ Correct: 32-byte secret key
secret: "a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6" // Exactly 32 bytesGenerate a proper secret key:
import crypto from 'crypto';
// Generate 32-byte secret
const secret = crypto.randomBytes(32).toString('hex').substring(0, 32);
console.log('Generated secret:', secret);Issue: "API key is invalid"
Symptoms:
Error: API key is invalid or expiredSolutions:
- Verify your API key from the Commt Dashboard (opens in a new tab)
- Check if the API key has the correct permissions
- Ensure you're using the correct project ID
- Verify the API key format (should start with specific prefix)
Decryption Issues
Issue: Decryption fails with "Invalid cipher format"
Symptoms:
Error: Invalid cipher format or corrupted dataCommon Causes & Solutions:
-
Mismatched secret keys:
// Ensure the same secret is used in both client and server // Client (React/RN): secret: "your-32-byte-secret" // Server (Node.js): secret: "your-32-byte-secret" -
Incorrect IV format:
// ✅ Correct: IV should be hex string const { cipher, iv } = req.body; commt.decrypt({ cipher, iv }); // ❌ Wrong: IV in wrong format const iv = Buffer.from(req.body.iv).toString('hex'); -
Corrupted request data:
// Validate input before decryption if (!cipher || !iv || typeof cipher !== 'string' || typeof iv !== 'string') { throw new Error('Invalid request format'); }
Issue: "Cannot parse decrypted JSON"
Symptoms:
Error: Unexpected token in JSON at position 0Solutions:
try {
const decryptedData = commt.decrypt({ cipher, iv });
// Add validation before parsing
if (!decryptedData || typeof decryptedData !== 'string') {
throw new Error('Decryption returned invalid data');
}
const messageData = JSON.parse(decryptedData);
} catch (parseError) {
console.error('JSON parse error:', parseError);
console.log('Raw decrypted data:', decryptedData);
}Room Creation Issues
Issue: Room creation returns undefined
Symptoms:
const chatRoomAuthId = commt.createRoom(participants);
console.log(chatRoomAuthId); // undefinedSolutions:
-
Check participants format:
// ✅ Correct: Array of chat auth IDs const participants = ["chatAuth1", "chatAuth2"]; // ❌ Wrong: Objects or other formats const participants = [ { id: "user1", chatAuthId: "chatAuth1" } ]; -
Verify initialization:
// Ensure SDK is properly initialized if (!global.commt) { throw new Error('Commt SDK not initialized'); } -
Check API connectivity:
// Add error handling for network issues try { const chatRoomAuthId = commt.createRoom(participants); if (!chatRoomAuthId) { throw new Error('Room creation failed - no ID returned'); } } catch (error) { console.error('Room creation error:', error); }
Network and API Issues
Issue: 401 Unauthorized errors
Symptoms:
Error: Request failed with status code 401Solutions:
-
Verify API credentials:
console.log('API Key:', process.env.COMMT_API_KEY?.substring(0, 10) + '...'); console.log('Project ID:', process.env.COMMT_PROJECT_ID); -
Check key permissions in dashboard
-
Regenerate API key if compromised
Getting Help
Check Documentation
- Review the API Methods section
- Read the Configuration guide
- Study the Complete Example
Contact Support
- Email: [email protected]
- Create Support Ticket on Commt Dashboard (opens in a new tab)
- Include error logs and configuration details
- Provide steps to reproduce the issue
Community Resources
- GitHub Issues: commt/commt-nodejs (opens in a new tab)
- Check existing issues for similar problems
- Create detailed bug reports with code examples
Before Reporting Issues
Include this information:
- Environment: Node.js version, OS, package version
- Configuration: Sanitized config (hide credentials)
- Error logs: Complete error messages and stack traces
- Reproduction steps: Minimal code that reproduces the issue
- Expected vs actual behavior: Clear description of the problem
This troubleshooting guide should help you resolve most common issues with the Commt Node.js SDK.