Skip to main content
Ansa uses WebSocket connections (via Socket.IO) to provide real-time features like typing indicators, agent presence, and instant message delivery.

Features

FeatureDescription
Typing IndicatorsShow when users or agents are typing
Agent PresenceSee when human agents join conversations
Message DeliveryInstant message updates without polling
ReconnectionAutomatic reconnect with message replay

How It Works

The widget automatically establishes a WebSocket connection when opened. The connection handles:
  1. Bi-directional typing indicators between users and dashboard agents
  2. Real-time message delivery for human agent responses
  3. Presence updates when agents join or leave conversations
  4. Automatic reconnection with message history replay

Events

Client → Server

EventPayloadDescription
join-conversation{ conversationId }Subscribe to conversation updates
typing-start{ conversationId }User started typing
typing-stop{ conversationId }User stopped typing

Server → Client

EventPayloadDescription
typing{ conversationId, isTyping, userId }Typing indicator update
agent-joined{ conversationId, agentName }Human agent joined
message-replayMessage[]Messages since disconnect

Rate Limiting

To prevent abuse, WebSocket events are rate-limited:
Event TypeLimit
Messages10 per minute
Typing3 per second
Overall50 events per minute
When rate limits are exceeded, a rate-limit-exceeded event is sent:
{
  "type": "rate-limit-exceeded",
  "retryAfter": 5000
}

Custom Integration

If you’re building a custom chat interface, you can connect directly to the WebSocket:
import { io } from "socket.io-client";

const socket = io("wss://api.ansa.so", {
  path: "/socket",
  auth: {
    token: "your-api-key",
    conversationId: "conv_xxx"
  }
});

// Join a conversation
socket.emit("join-conversation", { conversationId: "conv_xxx" });

// Listen for typing indicators
socket.on("typing", ({ isTyping, userId }) => {
  if (isTyping) {
    showTypingIndicator(userId);
  } else {
    hideTypingIndicator(userId);
  }
});

// Send typing status
let typingTimeout;
input.addEventListener("input", () => {
  socket.emit("typing-start", { conversationId });
  clearTimeout(typingTimeout);
  typingTimeout = setTimeout(() => {
    socket.emit("typing-stop", { conversationId });
  }, 2000);
});

// Handle agent joining
socket.on("agent-joined", ({ agentName }) => {
  showSystemMessage(`${agentName} joined the conversation`);
});

// Handle reconnection
socket.on("message-replay", (messages) => {
  messages.forEach(appendMessage);
});

Connection States

StateDescription
connectingInitial connection attempt
connectedWebSocket active
disconnectedConnection lost, will retry
reconnectingAttempting to reconnect
failedMax retries exceeded
The widget handles connection management automatically, including:
  • Exponential backoff for reconnection attempts
  • Message queuing during disconnection
  • Automatic replay of missed messages

Dashboard Integration

Human agents in the dashboard see:
  • User typing indicators — When customers are typing
  • Connection status — Whether the user is online
  • Read receipts — When messages are delivered

Next Steps

Widget API

Control widget programmatically

Webhooks

Server-side event notifications