Skip to main content
Version: 0.4.2 (Previous)

💬 Chat Service

Testing Status

The Chat Service provides a comprehensive solution for managing real-time communication features including channels, subscriptions, and messaging capabilities. This unified service combines channel management and subscription handling into a single, cohesive API.


🚀 Quickstart

import express from 'express';
import { MongoClient } from 'mongodb';

import { middlewares, services } from '@nodeblocks/backend-sdk';

const { nodeBlocksErrorMiddleware } = middlewares;
const { chatService } = services;

const client = new MongoClient('mongodb://localhost:27017').db('dev');

express()
.use(
chatService(
{
identity: client.collection('identity'),
chatChannels: client.collection('chatChannels'),
chatMessages: client.collection('chatMessages'),
subscriptions: client.collection('subscriptions'),
},
{
authSecrets: {
authEncSecret: 'your-encryption-secret',
authSignSecret: 'your-signing-secret',
},
user: {
typeIds: {
admin: '100',
guest: '000',
user: '001',
},
},
}
)
)
.use(nodeBlocksErrorMiddleware())
.listen(8089, () => console.log('Server running'));

📋 Endpoint Summary

Channel Operations

MethodPathDescription
POST/channelsCreate a new channel
GET/channelsList all channels
GET/channels/:channelIdGet a specific channel
PATCH/channels/:channelIdUpdate a channel
DELETE/channels/:channelIdDelete a channel

Subscription Operations

MethodPathDescription
POST/subscriptionsCreate a new subscription
GET/subscriptionsList all subscriptions
GET/subscriptions/:subscriptionIdGet a specific subscription
DELETE/subscriptions/:subscriptionIdDelete a subscription

Message Operations

MethodPathDescription
POST/messagesCreate a new message
GET/messages?channelId=:channelIdList messages in a channel
GET/messages/:messageIdGet a specific message
PATCH/messages/:messageIdUpdate a message
DELETE/messages/:messageIdDelete a message

🗄️ Entity Schemas

Channel Entity

{
"name": "string",
"ownerId": "string",
"createdAt": "string (datetime)",
"id": "string",
"updatedAt": "string (datetime)"
}

Field Details:

FieldTypeAuto-GeneratedRequiredDescription
namestringChannel name/title
ownerIdstringID of the user who owns this channel
createdAtdatetimeCreation timestamp
idstringUnique identifier (UUID)
updatedAtdatetimeLast modification timestamp

Subscription Entity

{
"approved": "boolean",
"channelId": "string",
"permissions": ["string"],
"subscribedAt": "string (datetime)",
"subscribedId": "string",
"createdAt": "string (datetime)",
"id": "string",
"updatedAt": "string (datetime)"
}

Field Details:

FieldTypeAuto-GeneratedRequiredDescription
approvedbooleanWhether the subscription is approved
channelIdstringID of the channel being subscribed to
permissionsarrayArray of permission strings (e.g., ["read", "write"])
subscribedAtdatetimeTimestamp when subscription was created
subscribedIdstringID of the user subscribing
createdAtdatetimeCreation timestamp
idstringUnique identifier (UUID)
updatedAtdatetimeLast modification timestamp

Message Entity

{
"channelId": "string",
"content": "string",
"senderId": "string",
"title": "string",
"createdAt": "string (datetime)",
"id": "string",
"updatedAt": "string (datetime)"
}

Field Details:

FieldTypeAuto-GeneratedRequiredDescription
channelIdstringID of the channel where message is sent
contentstringMessage content/text
senderIdstringID of the user sending the message
titlestringOptional message title
createdAtdatetimeCreation timestamp
idstringUnique identifier (UUID)
updatedAtdatetimeLast modification timestamp

📝 Note: Auto-generated fields are set by the service and should not be included in create/update requests. Schema enforces additionalProperties: false - only defined fields are allowed.


🔐 Authentication Headers

For protected endpoints, include the following headers:

Authorization: Bearer <access_token>
x-nb-fingerprint: <device_fingerprint>

⚠️ Important: The x-nb-fingerprint header is required for all authenticated requests if fingerprint was specified during authorization. Without it, requests will return 401 Unauthorized.


🔧 API Endpoints

📺 Channel Operations

1. Create Channel

Creates a new chat channel with the provided information.

Request:

  • Method: POST
  • Path: /channels
  • Headers:
    • Content-Type: application/json
    • Authorization: Bearer <token>
    • x-nb-fingerprint: <device-fingerprint>
  • Authorization: Bearer token required

Request Body:

FieldTypeRequiredDescription
namestringChannel name/title
ownerIdstringID of the user who owns this channel

Response Body:

FieldTypeDescription
namestringChannel name/title
ownerIdstringID of the user who owns this channel
createdAtstringCreation timestamp
idstringUnique channel identifier
updatedAtstringLast update timestamp

Example Request:

curl -X POST http://localhost:8089/channels \
-H "Content-Type: application/json" \
-d '{
"name": "Project Updates",
"ownerId": "user-456"
}'

Success Response:

HTTP/1.1 201 Created
Content-Type: application/json

{
"name": "Project Updates",
"ownerId": "user-456",
"createdAt": "2025-06-24T08:33:40.146Z",
"id": "af62eac3-06aa-481a-8c44-a029e96de2ed",
"updatedAt": "2025-06-24T08:33:40.146Z"
}

Validation Error Examples:

Missing Required Field:

{
"error": {
"message": "must have ownerId when creating a new channel"
}
}

Schema Validation Error:

{
"error": {
"message": "Validation Error",
"data": [
"request body must have required property 'ownerId'"
]
}
}

Additional Properties Error:

{
"error": {
"message": "Validation Error",
"data": [
"request body must NOT have additional properties"
]
}
}
{
"error": {
"message": "Validation Error",
"data": [
"request body must NOT have additional properties",
"request body must NOT have additional properties"
]
}
}

2. List Channels

Retrieves all channels with optional filtering and pagination.

Request:

  • Method: GET
  • Path: /channels
  • Headers:
    • Authorization: Bearer <token>
    • x-nb-fingerprint: <device-fingerprint>
  • Authorization: Bearer token required

Query Parameters:

ParameterTypeRequiredDescription
namestringFilter by channel name
ownerIdstringFilter by owner ID
pagenumberPage number for pagination
limitnumberNumber of items per page

Response Body:

FieldTypeDescription
namestringChannel name/title
ownerIdstringID of the user who owns this channel
createdAtstringCreation timestamp
idstringUnique channel identifier
updatedAtstringLast update timestamp

Example Request:

curl http://localhost:8089/channels

Success Response:

HTTP/1.1 200 OK
Content-Type: application/json

[
{
"name": "Project Updates",
"ownerId": "user-456",
"createdAt": "2025-06-24T08:33:40.146Z",
"id": "af62eac3-06aa-481a-8c44-a029e96de2ed",
"updatedAt": "2025-06-24T08:33:40.146Z"
}
]

3. Get Channel

Retrieves a specific channel by ID.

Request:

  • Method: GET
  • Path: /channels/:id
  • Headers:
    • Authorization: Bearer <token>
    • x-nb-fingerprint: <device-fingerprint>
  • Authorization: Bearer token required

Example Request:

curl http://localhost:8089/channels/af62eac3-06aa-481a-8c44-a029e96de2ed

4. Update Channel

Updates an existing channel's properties.

Request:

  • Method: PATCH
  • Path: /channels/:id
  • Headers:
    • Content-Type: application/json
    • Authorization: Bearer <token>
    • x-nb-fingerprint: <device-fingerprint>
  • Authorization: Bearer token required

Request Body:

FieldTypeRequiredDescription
namestringNew channel name/title
ownerIdstringNew owner ID

Response Body:

FieldTypeDescription
namestringUpdated channel name/title
ownerIdstringUpdated owner ID
createdAtstringCreation timestamp
idstringUnique channel identifier
updatedAtstringLast update timestamp

Example Request:

curl -X PATCH http://localhost:8089/channels/af62eac3-06aa-481a-8c44-a029e96de2ed \
-H "Content-Type: application/json" \
-d '{
"name": "Updated Project Updates"
}'

5. Delete Channel

Removes a channel and all associated data.

Request:

  • Method: DELETE
  • Path: /channels/:id
  • Headers:
    • Authorization: Bearer <token>
    • x-nb-fingerprint: <device-fingerprint>
  • Authorization: Bearer token required

Response Body:

FieldTypeDescription
No response body-Delete endpoint returns no response body on success

Example Request:

curl -X DELETE http://localhost:8089/channels/af62eac3-06aa-481a-8c44-a029e96de2ed

Success Response:

  • Status: 204 No Content
  • Body: (empty)

Not Found Error Example:

{
"error": {
"message": "Channel not found"
}
}

📋 Subscription Operations

6. Create Subscription

Creates a new subscription to a channel.

Request:

  • Method: POST
  • Path: /subscriptions
  • Headers:
    • Content-Type: application/json
    • Authorization: Bearer <token>
    • x-nb-fingerprint: <device-fingerprint>
  • Authorization: Bearer token required

Request Body:

FieldTypeRequiredDescription
channelIdstringID of the channel to subscribe to
approvedbooleanWhether the subscription is approved
permissionsarrayArray of permission strings
subscribedAtstringTimestamp when subscription was created
subscribedIdstringID of the user subscribing

Response Body:

FieldTypeDescription
channelIdstringID of the channel being subscribed to
subscribedIdstringID of the user subscribing
approvedbooleanWhether the subscription is approved
permissionsarrayArray of permission strings
subscribedAtstringTimestamp when subscription was created
createdAtstringCreation timestamp
idstringUnique subscription identifier
updatedAtstringLast update timestamp

Example Request:

curl -X POST http://localhost:8089/subscriptions \
-H "Content-Type: application/json" \
-d '{
"channelId": "af62eac3-06aa-481a-8c44-a029e96de2ed",
"subscribedId": "user-456",
"approved": true,
"permissions": ["read", "write"]
}'

Success Response:

HTTP/1.1 201 Created
Content-Type: application/json

{
"channelId": "af62eac3-06aa-481a-8c44-a029e96de2ed",
"subscribedId": "user-456",
"approved": true,
"permissions": ["read", "write"],
"createdAt": "2025-06-27T02:16:07.916Z",
"id": "b17501d6-2576-4a18-86f5-3545da75e678",
"updatedAt": "2025-06-27T02:16:07.916Z"
}

Validation Error Example:

{
"error": {
"message": "Validation Error",
"data": [
"request body must have required property 'channelId'",
"request body must have required property 'subscribedId'",
]
}
}
{
"error": {
"message": "Validation Error",
"data": [
"request body must NOT have additional properties",
]
}
}

7. List Subscriptions

Retrieves all subscriptions with optional filtering and pagination.

Request:

  • Method: GET
  • Path: /subscriptions
  • Headers:
    • Authorization: Bearer <token>
    • x-nb-fingerprint: <device-fingerprint>
  • Authorization: Bearer token required

Query Parameters:

ParameterTypeRequiredDescription
approvedbooleanFilter by approval status
channelIdstringFilter by channel ID
subscribedIdstringFilter by subscriber ID
subscribedAtstringFilter by subscription date
pagenumberPage number for pagination
limitnumberNumber of items per page

Response Body:

FieldTypeDescription
channelIdstringID of the channel being subscribed to
subscribedIdstringID of the user subscribing
approvedbooleanWhether the subscription is approved
permissionsarrayArray of permission strings
subscribedAtstringTimestamp when subscription was created
createdAtstringCreation timestamp
idstringUnique subscription identifier
updatedAtstringLast update timestamp

Example Request:

curl http://localhost:8089/subscriptions

8. Get Subscription

Retrieves a specific subscription by ID.

Request:

  • Method: GET
  • Path: /subscriptions/:id
  • Headers:
    • Authorization: Bearer <token>
    • x-nb-fingerprint: <device-fingerprint>
  • Authorization: Bearer token required

Example Request:

curl http://localhost:8089/subscriptions/b17501d6-2576-4a18-86f5-3545da75e678

9. Delete Subscription

Removes a subscription (unsubscribe from channel).

Request:

  • Method: DELETE
  • Path: /subscriptions/:id
  • Headers:
    • Authorization: Bearer <token>
    • x-nb-fingerprint: <device-fingerprint>
  • Authorization: Bearer token required

Response Body:

FieldTypeDescription
No response body-Delete endpoint returns no response body on success

Example Request:

curl -X DELETE http://localhost:8089/subscriptions/b17501d6-2576-4a18-86f5-3545da75e678

Success Response:

  • Status: 204 No Content
  • Body: (empty)

Not Found Error Example:

{
"error": {
"message": "Subscription not found"
}
}

💬 Message Operations

10. Create Message

Sends a new message to a channel.

Request:

  • Method: POST
  • Path: /messages
  • Headers:
    • Content-Type: application/json
    • Authorization: Bearer <token>
    • x-nb-fingerprint: <device-fingerprint>
  • Authorization: Bearer token required

Request Body:

FieldTypeRequiredDescription
channelIdstringID of the channel where message is sent
contentstringMessage content/text
senderIdstringID of the user sending the message
titlestringOptional message title

Response Body:

FieldTypeDescription
channelIdstringID of the channel where message is sent
contentstringMessage content/text
senderIdstringID of the user sending the message
titlestringOptional message title
createdAtstringCreation timestamp
idstringUnique message identifier
updatedAtstringLast update timestamp

Example Request:

curl -X POST http://localhost:8089/messages \
-H "Content-Type: application/json" \
-d '{"channelId": "test-channel-123", "content": "Hello world!", "senderId": "user-456"}'

Success Response:

{
"channelId": "test-channel-123",
"content": "Hello world!",
"senderId": "user-456",
"createdAt": "2025-07-01T03:22:06.178Z",
"id": "2b43d66c-9cab-434b-9cb7-18de8d3ec9c9",
"updatedAt": "2025-07-01T03:22:06.178Z"
}

Validation Error Example:

{
"error": {
"message": "Validation Error",
"data": [
"request body must have required property 'senderId'",
"request body must have required property 'channelId'"
]
}
}

11. List Messages

Retrieves messages in a specific channel.

Request:

  • Method: GET
  • Path: /messages?channelId=:channelId
  • Headers:
    • Authorization: Bearer <token>
    • x-nb-fingerprint: <device-fingerprint>
  • Authorization: Bearer token required

Query Parameters:

ParameterTypeRequiredDescription
channelIdstringID of the channel to get messages from
contentstringFilter by message content
senderIdstringFilter by sender ID
titlestringFilter by message title
pagenumberPage number for pagination
limitnumberNumber of items per page

Response Body:

FieldTypeDescription
channelIdstringID of the channel where message is sent
contentstringMessage content/text
senderIdstringID of the user sending the message
titlestringOptional message title
createdAtstringCreation timestamp
idstringUnique message identifier
updatedAtstringLast update timestamp

Example Request:

curl "http://localhost:8089/messages?channelId=test-channel-123"

Success Response:

[
{
"channelId": "test-channel-123",
"content": "Updated message content",
"senderId": "user-456",
"createdAt": "2025-07-01T03:22:06.178Z",
"id": "2b43d66c-9cab-434b-9cb7-18de8d3ec9c9",
"updatedAt": "2025-07-01T03:22:34.413Z"
}
]

Validation Error Example:

{
"error": {
"message": "Validation Error",
"data": [
"query parameter 'channelId' is required"
]
}
}

12. Get Message by ID

Retrieves a specific message by ID.

Request:

  • Method: GET
  • Path: /messages/:id
  • Headers:
    • Authorization: Bearer <token>
    • x-nb-fingerprint: <device-fingerprint>
  • Authorization: Bearer token required

Example Request:

curl http://localhost:8089/messages/2b43d66c-9cab-434b-9cb7-18de8d3ec9c9

Success Response:

{
"channelId": "test-channel-123",
"content": "Updated message content",
"senderId": "user-456",
"createdAt": "2025-07-01T03:22:06.178Z",
"id": "2b43d66c-9cab-434b-9cb7-18de8d3ec9c9",
"updatedAt": "2025-07-01T03:22:34.413Z"
}

Not Found Error Example:

{
"error": {
"message": "Message not found"
}
}

13. Update Message

Updates an existing message's content.

Request:

  • Method: PATCH
  • Path: /messages/:id
  • Headers:
    • Content-Type: application/json
    • Authorization: Bearer <token>
    • x-nb-fingerprint: <device-fingerprint>
  • Authorization: Bearer token required

Request Body:

FieldTypeRequiredDescription
contentstringUpdated message content
titlestringUpdated message title

Response Body:

FieldTypeDescription
channelIdstringID of the channel where message is sent
contentstringUpdated message content
senderIdstringID of the user sending the message
titlestringUpdated message title
createdAtstringCreation timestamp
idstringUnique message identifier
updatedAtstringLast update timestamp

Example Request:

curl -X PATCH http://localhost:8089/messages/2b43d66c-9cab-434b-9cb7-18de8d3ec9c9 \
-H "Content-Type: application/json" \
-d '{"content": "Updated message content"}'

Success Response:

{
"channelId": "test-channel-123",
"content": "Updated message content",
"senderId": "user-456",
"createdAt": "2025-07-01T03:22:06.178Z",
"id": "2b43d66c-9cab-434b-9cb7-18de8d3ec9c9",
"updatedAt": "2025-07-01T03:22:34.413Z"
}

Not Found Error Example:

{
"error": {
"message": "Chat message not found"
}
}

14. Delete Message

Removes a message from a channel.

Request:

  • Method: DELETE
  • Path: /messages/:id
  • Headers:
    • Authorization: Bearer <token>
    • x-nb-fingerprint: <device-fingerprint>
  • Authorization: Bearer token required

Response Body:

FieldTypeDescription
No response body-Delete endpoint returns no response body on success

Example Request:

curl -X DELETE http://localhost:8089/messages/81950444-5223-47c8-8a8c-0604c2955f15

Success Response:

  • Status: 204 No Content
  • Body: (empty)

Not Found Error Example:

{
"error": {
"message": "Chat message not found"
}
}

⚙️ Configuration Options

Service Configuration

interface ChatServiceConfiguration {
authSecrets: {
authEncSecret: string; // JWT encryption secret
authSignSecret: string; // JWT signing secret
};
user?: {
typeIds?: {
admin: string; // Admin user type identifier
guest: string; // Guest user type identifier
user: string; // Regular user type identifier
};
};
}

Configuration Details

The chat service configuration is organized into logical groups for security and user type management.

🔐 Security Settings

authSecrets - JWT token security secrets

  • Type: { authEncSecret: string; authSignSecret: string }
  • Description: Secret keys for JWT encryption and signing (used for token validation)
  • Required: Yes (for production)
  • Child Properties:
    • authEncSecret: Secret key for JWT payload encryption
    • authSignSecret: Secret key for JWT signature verification

👥 User Type Settings

user.typeIds - User type identifier configuration

  • Type: { admin?: string; guest?: string; user?: string }
  • Description: Custom user type identifiers for role-based access control
  • Default: undefined (uses default type validation)
  • Child Properties:
    • admin: Admin user type identifier
      • Type: string
      • Description: Custom identifier for admin users
      • Use Case: Role-based access control for administrative operations
      • Example: "admin", "administrator", "superuser"
    • guest: Guest user type identifier
      • Type: string
      • Description: Custom identifier for guest users
      • Use Case: Limited access for unauthenticated or temporary users
      • Example: "guest", "visitor", "anonymous"
    • user: Regular user type identifier
      • Type: string
      • Description: Custom identifier for regular users
      • Use Case: Standard user access permissions
      • Example: "user", "member", "customer"

Example Configuration

const chatConfig = {
authSecrets: {
authEncSecret: process.env.AUTH_ENC_SECRET || 'your-enc-secret',
authSignSecret: process.env.AUTH_SIGN_SECRET || 'your-sign-secret'
},
user: {
typeIds: {
admin: 'administrator',
guest: 'visitor',
user: 'member'
}
}
};

🚨 Error Handling

All chat service errors return JSON format with appropriate HTTP status codes:

Common Error Codes

StatusError MessageDescription
400Validation ErrorInvalid request body format or missing required fields
400must have ownerId when creating a new channelMissing ownerId field in request body
400request body must have required property 'name'Missing name field in request body
400request body must have required property 'ownerId'Missing ownerId field in request body
400request body must have required property 'channelId'Missing channelId field in request body
400request body must have required property 'subscribedId'Missing subscribedId field in request body
400request body must have required property 'content'Missing content field in request body
400request body must have required property 'senderId'Missing senderId field in request body
400request body must NOT have additional propertiesRequest contains unsupported fields
400query parameter 'channelId' is requiredMissing required query parameter
400Failed to create channelDatabase insert operation failed to return an inserted ID
400Failed to update channelUpdate operation doesn't modify any data (no changes detected)
400Failed to delete channelDatabase deletion operation failed
400Failed to create subscriptionDatabase insert operation failed to return an inserted ID
400Failed to delete subscriptionDatabase deletion operation failed
400Failed to create messageDatabase insert operation failed to return an inserted ID
400Failed to update messageUpdate operation doesn't modify any data (no changes detected)
400Failed to delete messageDatabase deletion operation failed
401token could not be verifiedMissing or invalid authorization token
401Authentication failedMissing or invalid authentication token
401Token fails security checkToken security validation failed
403User is not authorized to access this resourceUser lacks required permissions (admin access)
404Channel not foundChannel doesn't exist for the requested operation
404Subscription not foundSubscription doesn't exist for the requested operation
404Message not foundMessage doesn't exist for the requested operation
404Chat message not foundChat message doesn't exist for the requested operation
500Failed to create channelDatabase connection issues or unexpected failures during creation
500Failed to get channelDatabase connection issues or unexpected failures during retrieval
500Failed to find channelsDatabase connection issues, invalid filter syntax, or unexpected failures during listing
500Failed to update channelDatabase connection issues or unexpected failures during update
500Failed to delete channelDatabase connection issues or unexpected failures during deletion
500Failed to create subscriptionDatabase connection issues or unexpected failures during creation
500Failed to get subscriptionDatabase connection issues or unexpected failures during retrieval
500Failed to find subscriptionsDatabase connection issues, invalid filter syntax, or unexpected failures during listing
500Failed to delete subscriptionDatabase connection issues or unexpected failures during deletion
500Failed to create messageDatabase connection issues or unexpected failures during creation
500Failed to get messageDatabase connection issues or unexpected failures during retrieval
500Failed to find messagesDatabase connection issues, invalid filter syntax, or unexpected failures during listing
500Failed to update messageDatabase connection issues or unexpected failures during update
500Failed to delete messageDatabase connection issues or unexpected failures during deletion

Error Response Format

{
"error": {
"message": "Error message description",
"data": ["Additional error details"]
}
}

Validation Errors include additional details:

{
"error": {
"message": "Validation Error",
"data": [
"request body must have required property 'name'",
"request body must have required property 'ownerId'"
]
}
}