Message Handling
Understanding how messages flow through the Intercom component, from sending to receiving streaming responses.
Message Flow Overview
The Intercom component handles two types of message operations:
Sending Messages - User sends messages to deva
Receiving Messages - Deva responds with streaming messages
Sending Messages
User Input
Messages are sent through the input field at the bottom of the chat interface.
Flow:
User types message in input field
User presses Enter or clicks send button
Message is sent to API
Message appears immediately in chat (optimistic update)
Server confirms and returns message ID
Message streaming begins for deva response
Message Structure
User messages contain:
text: Message content
thread_id: Conversation thread identifier
persona_id: User's persona ID
created_at: Timestamp
Receiving Messages
Real-Time Streaming
Deva responses stream in real-time using Server-Sent Events (SSE):
Stream Phases:
Incoming Indicator
Shows typing indicator (three bouncing dots)
Indicates deva is preparing response
Content Streaming
Text streams word-by-word
Updates in real-time as content arrives
Shows partial message with accumulated content
Stream Complete
Final message object received
Streaming stops
Complete message displays in chat
Stream Events
The SDK uses fetchEventSource to handle SSE streams:
Event Types:
content- Partial content chunksresponse_message- Complete message objectcompletion- Stream completed successfully
Message States
Optimistic Updates
When user sends a message:
// Message appears immediately
mutate(userMessage);
// Then confirmed by server
// If error, message is rolled backBenefits:
Instant feedback
Better user experience
Handles network delays gracefully
Loading States
User Message:
Shown immediately (optimistic)
Loading indicator if network slow
Deva Response:
Initial: Typing indicator (three dots)
Streaming: Partial text with blinking cursor
Complete: Full message displayed
Message History
Pagination
Messages load in batches:
Initial load: 10 most recent messages
Load more: Scroll up to load older messages
Batch size: 10 messages per page
Implementation:
const {
messages,
hasNext,
fetchNext
} = useDevaMessages({ threadId });Scroll Behavior
Auto-scroll:
Scrolls to bottom when new message arrives
Scrolls to bottom when user sends message
Maintains position when loading older messages
Manual scroll:
User can scroll up to view history
Triggers pagination when reaching top
Preserves scroll position during pagination
Streaming Implementation
How Streaming Works
// 1. User sends message
const message = await sendMessage(text);
// 2. SDK starts listening for deva response stream
const streamUrl = `${url}/api/sdk/chat/${threadId}/messages/${messageId}/query/stream`;
// 3. Stream opens
fetchEventSource(streamUrl, {
onopen: () => {
// Connection established
},
onmessage: (event) => {
if (event.type === "content") {
// Accumulate content chunks
accumulatedContent += event.data;
updateMessage(accumulatedContent);
}
if (event.type === "response_message") {
// Final message received
setCompleteMessage(event.data);
}
},
onerror: (error) => {
// Handle stream errors
},
onclose: () => {
// Stream completed
}
});Stream States
Active Stream:
Shows typing indicator
Updates text in real-time
Prevents new messages until complete
Complete Stream:
Shows final message
Enables new message sending
Adds message to history
Error Stream:
Shows error indicator
Allows retry
Maintains previous messages
Learn more about the Streaming Implementation.
Error Handling
Network Errors
When network fails:
Shows error message
Maintains optimistic message
Allows retry
Stream Errors
When stream fails:
Shows "Problem" error indicator
Displays error message
Stream is aborted
Chat remains functional
Message Send Errors
When sending fails:
Message not added to history
Error displayed
User can retry
Learn more about the Error Handling.
Message Types
User Messages
Properties:
text: Message contentpersona_id: User's personaauthor_type: "USER"created_at: Timestamp
Display:
Right-aligned
User avatar
User's display name
Deva Messages
Properties:
text: Response content (streamed)persona_id: Deva's personaauthor_type: "BOT"created_at: Timestamp
Display:
Left-aligned
Deva avatar
Deva's display name
Learn more about the Message Types.
Thread Management
Thread Creation
Threads are created automatically:
// First message to a deva creates thread
const thread = await createDMThread(devaUsername);
// Subsequent messages use existing threadThread Persistence
Threads persist across sessions
Message history maintained
Thread ID stored in component state
Learn more about the Thread Types.
Best Practices
Message Sending:
Trim whitespace before sending
Validate non-empty messages
Show loading state during send
Handle errors gracefully
Receiving Messages:
Auto-scroll to new messages
Maintain scroll position during pagination
Show clear loading indicators
Handle stream interruptions
Performance:
Use optimistic updates for instant feedback
Paginate message history
Abort streams when component unmounts
Clean up event listeners
Advanced Features
Infinite Scroll
Messages load automatically when scrolling up:
Implementation:
Intersection Observer watches top of message area
When user scrolls near top, triggers
fetchNext()Loads 10 more messages
Maintains scroll position
Repeats until no more messages
Stream Interruption
Streams can be interrupted:
User closes chat (stream aborted)
Component unmounts (cleanup)
Network disconnects (error handling)
New message sent (current stream completes first)
During streaming, partial message:
{
id: string;
text: string; // Accumulated content so far
// Other fields populated when complete
}Related Documentation
Components Overview - Other components
Message Types - Message type definitions
Response Types - Response type definitions
Streaming - Streaming implementation
Error Handling - Error handling
Core Concepts:
Authentication Flow - Auth requirements
Architecture Overview - How SDK works
Last updated