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
namestring❌✅Channel name/title
ownerIdstring❌✅ID of the user who owns this channel
createdAtdatetime✅✅Creation timestamp
idstring✅✅Unique identifier (UUID)
updatedAtdatetime✅✅Last 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
approvedboolean❌❌Whether the subscription is approved
channelIdstring❌✅ID of the channel being subscribed to
permissionsarray❌❌Array of permission strings (e.g., ["read", "write"])
subscribedAtdatetime❌❌Timestamp when subscription was created
subscribedIdstring❌❌ID of the user subscribing
createdAtdatetime✅✅Creation timestamp
idstring✅✅Unique identifier (UUID)
updatedAtdatetime✅✅Last modification timestamp

Message Entity​

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

Field Details:

FieldTypeAuto-GeneratedRequiredDescription
channelIdstring❌✅ID of the channel where message is sent
contentstring❌✅Message content/text
senderIdstring❌✅ID of the user sending the message
titlestring❌❌Optional message title
createdAtdatetime✅✅Creation timestamp
idstring✅✅Unique identifier (UUID)
updatedAtdatetime✅✅Last 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
namestring✅Channel name/title
ownerIdstring✅ID 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
namestring❌Filter by channel name
ownerIdstring❌Filter by owner ID
pagenumber❌Page number for pagination
limitnumber❌Number 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
namestring❌New channel name/title
ownerIdstring❌New 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
channelIdstring✅ID of the channel to subscribe to
approvedboolean❌Whether the subscription is approved
permissionsarray❌Array of permission strings
subscribedAtstring❌Timestamp when subscription was created
subscribedIdstring❌ID 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
approvedboolean❌Filter by approval status
channelIdstring❌Filter by channel ID
subscribedIdstring❌Filter by subscriber ID
subscribedAtstring❌Filter by subscription date
pagenumber❌Page number for pagination
limitnumber❌Number 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
channelIdstring✅ID of the channel where message is sent
contentstring✅Message content/text
senderIdstring✅ID of the user sending the message
titlestring❌Optional 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
channelIdstring✅ID of the channel to get messages from
contentstring❌Filter by message content
senderIdstring❌Filter by sender ID
titlestring❌Filter by message title
pagenumber❌Page number for pagination
limitnumber❌Number 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
contentstring❌Updated message content
titlestring❌Updated 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'"
]
}
}