Build a text chat interface with WebSockets. Establish connections, send messages, receive agent responses, and handle conversation lifecycle.
What you’ll learn: Connection setup, message exchange, response handling, and conversation cleanup.
Testing requires a valid API key. Generate a web integration token from your agent’s Web Integrations settings in the Dasha BlackBox dashboard before starting.
Prerequisites
Before you start, ensure you have:
A Dasha BlackBox agent with chat enabled
A web integration token (from Dashboard → Agent → Web Integrations)
The AllowWebChat feature enabled on your web integration
Text chat follows this message sequence:
Step 1: Establish connection
Connect to the WebSocket endpoint and send the initialize message:
Example: WebSocket connection for chat
const token = 'YOUR_WEB_INTEGRATION_TOKEN' ;
const ws = new WebSocket (
`wss://blackbox.dasha.ai/api/v1/ws/webCall?token=${ token }`
);
ws. onopen = () => {
// Send initialize message to start chat session
ws. send ( JSON . stringify ({
type: 'initialize' ,
timestamp: new Date (). toISOString (),
request: {
callType: 'chat' ,
additionalData: {
// Custom data passed to agent prompts
userId: 'user-123' ,
context: 'support'
}
}
}));
};
The server responds with a connection event when the agent session is ready:
Example: Connection event response
{
"type" : "event" ,
"name" : "connection" ,
"timestamp" : "2025-01-20T10:00:01Z" ,
"data" : {
"recordId" : "call-abc123"
}
}
Step 2: Send messages
Use the incomingChatMessage type to send text messages:
Example: Send chat message
function sendMessage ( text ) {
if (ws.readyState !== WebSocket. OPEN ) {
console. error ( 'WebSocket not connected' );
return ;
}
ws. send ( JSON . stringify ({
type: 'incomingChatMessage' ,
content: text,
timestamp: new Date (). toISOString ()
}));
}
// Usage
sendMessage ( 'Hello, I need help with my order' );
IncomingChatMessage schema
Field Type Required Description type"incomingChatMessage"Yes Message type identifier contentstringYes Text message content timestampstring (ISO 8601)Yes Message timestamp channelIdstring | nullNo Optional channel identifier
Step 3: Receive messages
Handle incoming messages from the server:
Example: Handle incoming messages
ws. onmessage = ( event ) => {
const message = JSON . parse (event.data);
switch (message.type) {
case 'event' :
handleEvent (message);
break ;
case 'text' :
handleTextMessage (message);
break ;
case 'toolCall' :
handleToolCall (message);
break ;
case 'toolCallResult' :
handleToolResult (message);
break ;
case 'conversationResult' :
handleConversationResult (message);
break ;
case 'error' :
handleError (message);
break ;
}
};
function handleEvent ( message ) {
switch (message.name) {
case 'connection' :
console. log ( 'Agent session ready' );
break ;
case 'opened' :
console. log ( 'Conversation opened' );
break ;
case 'closed' :
console. log ( 'Conversation closed' );
break ;
}
}
function handleTextMessage ( message ) {
const { source , text } = message.content;
if (source === 'assistant' ) {
// Agent response
displayAgentMessage (text);
} else if (source === 'user' ) {
// Echo of user message (for transcript)
console. log ( 'Message confirmed:' , text);
}
}
function handleError ( message ) {
console. error ( 'Error:' , message.data.message);
showErrorToUser (message.data.message);
}
TextHistoryMessage schema
Field Type Description type"text"Message type identifier timestampstring (ISO 8601)Message timestamp content.source"assistant" | "user"Message sender content.textstring | nullMessage text content content.namestring | nullOptional sender name content.type"potential" | "confident" | "final"Recognition confidence (user messages) content.segmentIdstringSegment identifier (user messages)
TextHistoryMessage example
{
"type" : "text" ,
"timestamp" : "2025-01-20T10:00:05Z" ,
"content" : {
"source" : "assistant" ,
"text" : "Hello! I'd be happy to help you with your order. Could you provide your order number?" ,
"name" : null
}
}
Step 4: End conversation
Send a terminate message and wait for the conversation result:
Example: End conversation gracefully
function endConversation () {
return new Promise (( resolve , reject ) => {
let conversationResult = null ;
const timeout = setTimeout (() => {
reject ( new Error ( 'Timeout waiting for conversation result' ));
}, 5000 );
const originalHandler = ws.onmessage;
ws. onmessage = ( event ) => {
const message = JSON . parse (event.data);
if (message.type === 'conversationResult' ) {
conversationResult = message.result;
clearTimeout (timeout);
ws.onmessage = originalHandler;
resolve (conversationResult);
} else {
originalHandler (event);
}
};
ws. send ( JSON . stringify ({
type: 'terminate' ,
timestamp: new Date (). toISOString ()
}));
});
}
// Usage
const result = await endConversation ();
console. log ( 'Conversation summary:' , result);
ws. close ();
ConversationResultHistoryMessage example
{
"type" : "conversationResult" ,
"timestamp" : "2025-01-20T10:05:00Z" ,
"result" : {
"status" : "completed" ,
"duration" : 300 ,
"metadata" : {
"callId" : "call-abc123" ,
"agentId" : "agent-xyz"
}
}
}
Next steps
Message Reference Complete schema documentation for all WebSocket messages
Voice Call Implementation Add WebRTC voice calls to your integration
Tool Execution Handle agent tool calls via WebSocket
Error Handling Handle connection errors and edge cases