Prospect Integration
Namespace: /v1/conversation (shares with Conversation)
Purpose: Prospect communication tracking and management
Socket Events
Client → Server Events
| Event | Description | Authentication | Scope Required |
|---|---|---|---|
prospect_add_conversation | Create prospect conversation | Required | conversation |
prospect_list_conversation | List prospect conversations | Required | conversation |
prospect_list_message | Get prospect messages | Required | conversation |
prospect_list_message_by_id | Get messages by message ID | Required | conversation |
prospect_add_participant | Add participant to prospect chat | Required | conversation |
prospect_open | Open/close prospect conversation | Required | conversation |
prospect_snooze | Snooze prospect conversation | Required | conversation |
prospect_show_on_top | Pin prospect conversation | Required | conversation |
prospect_read | Mark prospect messages as read | Required | conversation |
prospect_archive | Archive prospect conversation | Required | conversation |
prospect_get_conversation_by_id | Get prospect conversation | Required | conversation |
prospect_add_note | Add note to prospect | Required | conversation |
prospect_edit_conversation | Edit prospect conversation | Required | conversation |
Server → Client Events
| Event | Description | Data Structure |
|---|---|---|
prospect_add_conversation | Prospect conversation created | { _id, title, image, contact_id, users, ... } |
prospect_message | New prospect message | { UUID, data, type, sent_by, conversation_id, ... } |
Database Models
- ConversationProspect - Prospect conversations
- Communication - Prospect messages (incoming/outgoing)
- Contact - Prospect contact data
Event Details
prospect_add_conversation
Purpose: Create conversation with prospect/contact
Request:
socket.emit(
'prospect_add_conversation',
{
contact_id: '64contact...', // Required
channel_id: 'channel_id', // Required
users: ['user_id_1'], // Optional: team members
title: 'Prospect Discussion', // Optional
},
callback,
);
Response:
{
success: true,
message: 'SUCCESS'
}
Broadcast (to all participants):
{
_id: '64prospect...',
title: 'John Doe',
image: ['https://contact-image.png'],
contact_id: {
_id: '64contact...',
name: 'John Doe',
email: 'john@example.com',
...
},
users: [...],
unread_count: 0,
is_open: true,
...
}
Behavior:
- If conversation exists for contact, reopen and add new users
- If new, create ConversationProspect record
- Contact must exist in database
- Title/image auto-generated from contact if not provided
prospect_add_note
Purpose: Add internal note to prospect conversation (not visible to contact)
Request:
socket.emit(
'prospect_add_note',
{
conversation_id: '64prospect...',
channel_id: 'channel_id',
UUID: 'unique-uuid',
data: 'Internal note: Follow up next week',
mentions: ['user_id_1'], // Optional @mentions
attachments: [],
},
callback,
);
Response:
{
success: true,
message: 'SUCCESS',
data: {
UUID: 'unique-uuid',
conversation_id: '64prospect...',
data: 'Internal note: Follow up next week',
is_note: true,
mentions: [...],
sent_by: {...},
is_sender: true,
...
}
}
Broadcast:
- Emitted only to mentioned users and sender
- Increments
unread_countfor mentioned users - NOT sent to contact (internal only)
prospect_list_message
Purpose: Get paginated message list for prospect conversation
Request:
socket.emit(
'prospect_list_message',
{
conversation_id: '64prospect...',
channel_id: 'channel_id',
limit: 20,
sort: 'DESC', // or 'ASC'
next: '2025-10-13T10:00:00.000Z', // For pagination
},
callback,
);
Response:
{
conversation: {
_id: '64prospect...',
title: 'John Doe',
contact_id: {...},
users: [...],
unread_count: 0,
...
},
messages: [
{
_id: '64msg...',
type: 'OUTGOING', // or 'INCOMING'
data: 'Message text',
sent_by: {...}, // User or Contact
is_sender: false,
is_note: false,
conversation_id: '64prospect...',
createdAt: '2025-10-13T10:30:00.000Z',
...
}
],
paging: {
limit: 20,
sort: 'DESC',
next: '2025-10-13T09:00:00.000Z'
}
}
Message Types:
- INCOMING: Message from contact to team
- OUTGOING: Message from team to contact
- NOTE: Internal note (only visible to mentioned users + sender)
prospect_list_conversation
Purpose: Get list of prospect conversations with filters
Request:
socket.emit(
'prospect_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',
},
callback,
);
Response:
{
conversation: [
{
_id: '64prospect...',
title: 'John Doe',
image: ['https://...'],
contact_id: {...},
users: [...],
unread_count: 2,
is_open: true,
show_on_top: false,
last_activity: {...},
is_admin: true,
...
}
],
messageList: {
// First conversation's messages
conversation: {...},
messages: [...],
paging: {...}
},
paging: {
limit: 20,
next: '2025-10-13T09:00:00.000Z'
}
}
Data Flow
Incoming Prospect Message Flow
1. External service (Twilio SMS, Email) receives message
↓
2. External API creates Communication record
type: 'INCOMING'
sent_by: contact_id (Contact)
↓
3. External API calls REST endpoint:
GET /conversations/prospect/emit/message/:messageID
↓
4. General Socket retrieves Communication
↓
5. Populates sent_by with Contact data
↓
6. Finds all ConversationProspect where contact_id matches
↓
7. Increments unread_count for all users
↓
8. Emits 'prospect_message' to all user sockets
↓
9. Sends FCM push notifications to offline users
Outgoing Prospect Message Flow
1. User sends message via Internal API
POST /v1/conversations/prospect/:id/message
↓
2. Internal API creates Communication record
type: 'OUTGOING'
sent_by: user_id (User)
↓
3. Internal API sends via Twilio/SendGrid
↓
4. Internal API calls REST endpoint:
GET /conversations/prospect/emit/message/:messageID
↓
5. General Socket broadcasts to all users
Client Example
import io from 'socket.io-client';
const socket = io('http://localhost:4000/v1/conversation', {
transports: ['websocket'],
query: { token: 'your_jwt_token' },
});
// Create prospect conversation
socket.emit(
'prospect_add_conversation',
{
contact_id: '64contact...',
channel_id: 'channel_id',
users: ['user_id_1'],
},
response => {
console.log('Prospect conversation created:', response);
},
);
// Listen for prospect messages
socket.on('prospect_message', data => {
console.log('New prospect message:', data);
// data.type: 'INCOMING' or 'OUTGOING'
// data.sent_by: Contact or User object
});
// Add internal note
socket.emit(
'prospect_add_note',
{
conversation_id: '64prospect...',
channel_id: 'channel_id',
UUID: 'uuid-v4',
data: 'Called prospect, will follow up Monday',
mentions: ['user_id_2'],
},
response => {
console.log('Note added:', response);
},
);
// List prospect conversations
socket.emit(
'prospect_list_conversation',
{
channel_id: 'channel_id',
filter: 'OPEN',
limit: 20,
},
response => {
console.log('Prospect conversations:', response.conversation);
},
);
Differences from Team Conversation
| Feature | Team Conversation | Prospect Conversation |
|---|---|---|
| Participants | Only Users | Users + 1 Contact |
| Message Model | ConversationMessage | Communication |
| Message Types | Single type | INCOMING, OUTGOING, NOTE |
| Notes | Not supported | Internal notes (is_note: true) |
| External Link | None | Twilio, Email integration |
| Broadcast | All participants | Notes only to mentioned users |