Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.blackbox.dasha.ai/llms.txt

Use this file to discover all available pages before exploring further.

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:
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:
{
  "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:
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

FieldTypeRequiredDescription
type"incomingChatMessage"YesMessage type identifier
contentstringYesText message content
timestampstring (ISO 8601)YesMessage timestamp
channelIdstring | nullNoOptional channel identifier

Step 3: Receive messages

Handle incoming messages from the server:
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

FieldTypeDescription
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)
{
  "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:
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();
{
  "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