Skip to main content

Conversation Integration

Namespace: /v1/conversation and /v1/conversation/live

Purpose: Internal team messaging and conversation management


Socket Events

Client → Server Events

EventDescriptionAuthenticationScope Required
joinJoin conversation namespace and set status activeRequiredconversation
disconnectUser disconnected (automatic)N/AN/A
active_statusUpdate user presence statusRequiredconversation
add_conversationCreate new conversationRequiredconversation
list_conversationGet conversation list with filtersRequiredconversation
conversation_filterFilter conversations by criteriaRequiredconversation
get_conversation_by_idFetch specific conversationRequiredconversation
list_messageGet messages for conversationRequiredconversation
list_message_by_idGet messages centered on message IDRequiredconversation
channelGet channel counters and conversation listRequiredconversation
typingBroadcast typing indicatorRequiredconversation
readMark messages as readRequiredconversation
snoozeSnooze conversationRequiredconversation
archiveArchive conversationRequiredconversation
openOpen/close conversationRequiredconversation
show_on_topPin conversation to topRequiredconversation
add_participantAdd users to conversationRequiredconversation
messageSend new messageRequiredconversation
edit_conversationUpdate conversation metadataRequiredconversation

Server → Client Events

EventDescriptionData Structure
add_conversationNew conversation created{ _id, title, image, users, channel_id, is_open, unread_count, ... }
active_statusUser presence changed{ userID, conversation_active_status }
list_conversationConversation list response{ conversation: [], messageList: {}, paging: {} }
conversation_filterFiltered conversation listSame as list_conversation
get_conversation_by_idSingle conversation data{ success, data: { conversation } }
update_conversationConversation updated{ success, data: { conversation } }
list_messageMessage list response{ conversation: {}, messages: [], paging: {} }
channelChannel counters{ data: { counters }, conversation_list: {} }
typingUser typing indicator{ userID, conversation_id, channel_id, is_typing }
messageNew message received{ UUID, data, attachments, sent_by, is_sender, ... }
openConversation opened/closed{ conversationId, is_open, channel_id }
archiveConversation archived{ archive: true, conversationId, channel_id }
snoozeConversation snoozed{ snooze, snooze_till, conversationId, channel_id }
show_on_topConversation pinned{ show_on_top, conversationId, channel_id }
remove_userUser removed from conversation{ conversation_id }

Database Models

  • Conversation - Team conversations
  • ConversationMessage - Messages in conversations
  • ConversationChannel - Channel definitions (e.g., "Client Chat", "Internal")
  • User - User data and socket IDs

Event Details

join

Purpose: Register user connection and set active status

Request:

socket.emit('join', {}, callback);

Response:

{ success: true, message: 'SUCCESS' }

Side Effects:

  • Updates user's conversation_socket_ids array
  • Sets conversation_active_status to active
  • Broadcasts active_status event to all users in shared conversations

add_conversation

Purpose: Create new team conversation

Request:

socket.emit(
'add_conversation',
{
users: ['user_id_1', 'user_id_2'], // Array of participant IDs
title: 'Project Discussion', // Optional
channel_id: 'channel_id', // Required
origin: 'web', // Optional
},
callback,
);

Response:

{
success: true,
message: 'SUCCESS',
data: {
_id: '64abc...',
title: 'Project Discussion',
users: [...],
channel_id: 'channel_id',
unread_count: 0,
is_open: true,
...
}
}

Validation:

  • At least 2 participants required
  • Cannot create conversation with yourself only
  • All users must exist in database
  • Duplicate conversations are prevented (same participants + channel)

message

Purpose: Send new message in conversation

Request:

socket.emit(
'message',
{
conversation_id: '64abc...',
channel_id: 'channel_id',
UUID: 'unique-uuid-v4',
data: 'Hello team!',
attachments: [
{
type: 'image',
url: 'https://...',
name: 'screenshot.png',
},
],
mentions: ['user_id_1'], // Optional @mentions
},
callback,
);

Response:

{
success: true,
message: 'SUCCESS',
data: {
UUID: 'unique-uuid-v4',
conversation_id: '64abc...',
data: 'Hello team!',
sent_by: { _id, name, email, image },
is_sender: true,
createdAt: '2025-10-13T10:30:00.000Z',
...
}
}

Side Effects:

  • Increments unread_count for all participants except sender
  • Updates last_activity in conversation
  • Emits message event to all active participant sockets
  • Sends FCM push notification to offline users
  • Un-snoozes conversation if snoozed

typing

Purpose: Broadcast typing indicator to conversation participants

Request:

socket.emit(
'typing',
{
conversation_id: '64abc...',
channel_id: 'channel_id',
is_typing: true,
},
callback,
);

Response:

{ success: true, message: 'SUCCESS' }

Broadcast:

All active participants receive:

{
userID: 'sender_id',
conversation_id: '64abc...',
channel_id: 'channel_id',
is_typing: true
}

Note: Typically sent when user starts typing, and again with is_typing: false when stops.


read

Purpose: Mark all messages as read in conversation

Request:

socket.emit(
'read',
{
conversation_id: '64abc...',
channel_id: 'channel_id',
},
callback,
);

Response:

{ success: true, message: 'SUCCESS' }

Side Effects:

  • Sets unread_count[userID] to 0
  • Adds userID to read_by array in all messages
  • No broadcast to other users (personal action)

snooze

Purpose: Temporarily hide conversation

Request:

socket.emit(
'snooze',
{
conversation_id: '64abc...',
channel_id: 'channel_id',
time: 60, // Minutes (0 = indefinite)
},
callback,
);

Response:

{
success: true,
message: 'SUCCESS',
data: { snooze: true }
}

Broadcast (to sender only):

{
snooze: true,
snooze_till: '2025-10-13T11:30:00.000Z',
conversationId: '64abc...',
channel_id: 'channel_id'
}

Behavior:

  • time: 0 → Snooze indefinitely
  • time: 60 → Snooze for 60 minutes
  • Snoozed conversations hidden from "OPEN" filter
  • Shown in "SNOOZE" filter
  • Auto-unsnooze when time expires

list_conversation

Purpose: Get paginated conversation list with optional filters

Request:

socket.emit(
'list_conversation',
{
channel_id: 'channel_id',
filter: 'OPEN', // 'OPEN', 'CLOSE', 'SNOOZE', 'UNREAD', 'PRIORITY'
sort: 'NEWEST', // 'NEWEST', 'OLDEST'
limit: 20,
next: '2025-10-13T10:00:00.000Z', // For pagination
},
callback,
);

Response:

{
conversation: [
{
_id: '64abc...',
title: 'Project Discussion',
image: ['https://...'],
users: [...],
unread_count: 3,
is_open: true,
show_on_top: false,
snooze: false,
last_activity: {...},
is_admin: true,
...
}
],
messageList: {
// First conversation's messages (if !next)
conversation: {...},
messages: [...],
paging: { limit: 20, sort: 'DESC', next: '...' }
},
paging: {
limit: 20,
next: '2025-10-13T09:00:00.000Z'
}
}

Filters:

  • OPEN: Active, not snoozed
  • CLOSE: Closed conversations
  • SNOOZE: Snoozed conversations
  • UNREAD: Has unread messages
  • PRIORITY: Pinned (show_on_top)

channel

Purpose: Get all channel counters and optional conversation list

Request:

socket.emit(
'channel',
{
channel_id: 'channel_id', // Optional: also fetch conversations
filter: 'OPEN',
sort: 'NEWEST',
},
callback,
);

Response:

{
data: {
counters: {
'channel_id_1': {
_id: 'channel_id_1',
name: 'Client Chat',
open: 15,
unread: 3,
closed: 50,
priority: 2,
snoozed: 1
},
'prospect': { ... },
'you': { ... }, // All channels aggregated
'mentions': { ... } // Where user is @mentioned
}
},
conversation_list: { ... } // If channel_id provided
}

Client Example

import io from 'socket.io-client';

const socket = io('http://localhost:4000/v1/conversation', {
transports: ['websocket'],
query: { token: 'your_jwt_token' },
});

// Join
socket.emit('join', {}, response => {
console.log('Joined:', response);
});

// Listen for messages
socket.on('message', data => {
console.log('New message:', data);
// Update UI with new message
});

// Listen for typing
socket.on('typing', data => {
console.log(`${data.userID} is typing...`);
});

// Send message
socket.emit(
'message',
{
conversation_id: '64abc...',
channel_id: 'channel_id',
UUID: 'uuid-v4',
data: 'Hello!',
attachments: [],
},
response => {
console.log('Message sent:', response);
},
);

// Get conversations
socket.emit(
'list_conversation',
{
channel_id: 'channel_id',
filter: 'OPEN',
sort: 'NEWEST',
limit: 20,
},
response => {
console.log('Conversations:', response.conversation);
},
);
💬

Documentation Assistant

Ask me anything about the docs

Hi! I'm your documentation assistant. Ask me anything about the docs!

I can help you with:
- Code examples
- Configuration details
- Troubleshooting
- Best practices

Try asking: How do I configure the API?
09:31 AM