New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details
Socket
Book a DemoSign in
Socket

@optave/client-sdk

Package Overview
Dependencies
Maintainers
1
Versions
19
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@optave/client-sdk

Optave client SDK (browser + Node)

latest
Source
npmnpm
Version
3.2.4
Version published
Maintainers
1
Created
Source

Optave Client SDK Documentation

Welcome to the Optave Client SDK documentation. This guide provides an overview of the SDK, instructions on how to set it up, and examples to help you integrate it seamlessly into your JavaScript projects.

Table of Contents

Introduction

The Optave Client SDK is a JavaScript library designed to facilitate seamless communication between your application and the Optave backend services via WebSockets and RESTful APIs. It provides a structured way to authenticate, manage sessions, handle user interactions, and send various types of messages with ease.

Key Features:

  • Event-Driven Architecture: Leveraging Node.js's EventEmitter to handle asynchronous events.
  • Authentication Support: Securely authenticate using client credentials.
  • WebSocket Management: Easily establish and manage WebSocket connections.
  • Structured Payloads: Automatically merges user-provided data with default payload structures.
  • Extensible Methods: Predefined methods for common actions like adjusting settings, elevating issues, summarizing interactions, and more.

Installation

To install the Optave Client SDK, use npm or yarn:

npm install @optave/client-sdk

or

yarn add @optave/client-sdk

Optional Performance Dependencies

For enhanced WebSocket performance in Node.js server environments, you can install the following optional native dependencies:

npm install --save-optional bufferutil utf-8-validate

These optional dependencies provide significant performance improvements:

  • bufferutil: Enables faster WebSocket frame masking and unmasking operations using native C++ implementations
  • utf-8-validate: Provides efficient UTF-8 validation for WebSocket messages as required by the RFC specification

Benefits:

  • Up to 2x faster WebSocket frame processing
  • Reduced CPU usage for high-throughput applications
  • Automatic fallback to JavaScript implementations if not available

Note: These dependencies are only beneficial in Node.js server environments and are not needed for browser applications. The SDK works perfectly without them - they simply provide performance optimizations when available.

Build System & Imports

The Optave Client SDK provides multiple build targets optimized for different environments. The package automatically selects the appropriate build based on your environment and import method.

Available Builds

The SDK provides four optimized builds, each tailored for specific deployment environments and security requirements:

BuildModule FormatAllows clientSecretAJV ValidationCSP SafeIntended EnvironmentsSize (Uncompressed)Size (Gzipped)
Browser ESMES Module❌ No❌ External Only✅ YesModern browsers, Vite, Webpack 5+, bundled apps~47KB~14KB
Browser UMDUMD❌ No❌ External Only✅ YesSalesforce Lightning, CDN, legacy browsers, CSP environments~54KB~15KB
Server ESMES Module✅ Yes✅ Full AJV❌ NoNode.js servers, microservices, backend APIs~164KB~25KB
Server UMDUMD✅ Yes❌ External Only✅ YesNode.js CommonJS, legacy servers, mixed Node.js environments~49KB~14KB

Build Selection Guide

🔒 Security & CSP Compliance

  • Browser builds are CSP-safe and exclude client secrets for security
  • Server builds allow client secrets and include full validation for backend use
  • All builds support token-based authentication via tokenProvider

📦 Bundle Size Impact

  • ESM builds are optimized for modern bundlers with tree-shaking
  • Browser ESM is smallest when bundled (external dependencies)
  • UMD builds are self-contained but larger (bundled dependencies)

🚀 Performance Characteristics

  • Browser ESM: Fastest loading, tree-shakeable, modern JavaScript
  • Browser UMD: Compatible with all environments, no bundler required
  • Server ESM: Optimized for Node.js with native WebSocket support
  • Server UMD: Maximum compatibility across Node.js versions

⚙️ Validation Strategy

  • Browser builds: Use lightweight, CSP-safe validation (no AJV)
  • Server ESM: Includes full AJV schema validation for data integrity
  • Server UMD: Uses CSP-safe validation (no AJV) for maximum compatibility
  • All builds validate required fields and basic payload structure

Automatic Build Selection

Default Import (Recommended):

import OptaveJavaScriptSDK from '@optave/client-sdk';
// Automatically selects:
// - browser.mjs in browser environments
// - server.mjs in Node.js environments

Explicit Build Selection

Browser Environments:

// ES Module (recommended for modern bundlers)
import OptaveJavaScriptSDK from '@optave/client-sdk/browser';
// or
import OptaveJavaScriptSDK from '@optave/client-sdk/browser-esm';

// UMD (for legacy browsers or CDN usage)
import OptaveJavaScriptSDK from '@optave/client-sdk/browser-umd';

Node.js Environments:

// ES Module (recommended for modern Node.js)
import OptaveJavaScriptSDK from '@optave/client-sdk/server';
// or
import OptaveJavaScriptSDK from '@optave/client-sdk/server-esm';

// UMD (works with CommonJS require() for mixed environments)
const OptaveJavaScriptSDK = require('@optave/client-sdk/server-umd');

CDN Usage (Browser Only)

ES Module CDN:

<script type="module">
  import OptaveJavaScriptSDK from 'https://unpkg.com/@optave/client-sdk/dist/browser.mjs';

  const sdk = new OptaveJavaScriptSDK({
    websocketUrl: 'wss://client-identifier.oco.optave.tech',
    // ... configuration
  });
</script>

UMD CDN (Global Variable):

<script src="https://unpkg.com/@optave/client-sdk/dist/browser.umd.js"></script>
<script>
  // OptaveJavaScriptSDK is now available globally
  const sdk = new OptaveJavaScriptSDK({
    websocketUrl: 'wss://client-identifier.oco.optave.tech',
    // ... configuration
  });
</script>

Framework-Specific Import Examples

Vite (Vue/React/Vanilla):

// Automatic selection (recommended)
import OptaveJavaScriptSDK from '@optave/client-sdk';

// Explicit browser build
import OptaveJavaScriptSDK from '@optave/client-sdk/browser';

Webpack (Create React App, Next.js):

// Automatic selection works with Webpack 5+
import OptaveJavaScriptSDK from '@optave/client-sdk';

// For older Webpack versions, use explicit imports
import OptaveJavaScriptSDK from '@optave/client-sdk/browser';

Node.js (Express, Fastify, etc.):

// ES Modules (package.json has "type": "module")
import OptaveJavaScriptSDK from '@optave/client-sdk';

// UMD (works with CommonJS require())
const OptaveJavaScriptSDK = require('@optave/client-sdk/server-umd');

TypeScript:

// Full TypeScript support included
import OptaveJavaScriptSDK from '@optave/client-sdk';

const sdk = new OptaveJavaScriptSDK({
  websocketUrl: process.env.OPTAVE__WEBSOCKET_URL!,
  // TypeScript will provide full intellisense and type checking
});

Build Optimization Notes

  • Browser builds exclude Node.js-specific dependencies (like ws package)
  • Server builds include WebSocket implementation and Node.js optimizations
  • ESM builds are smaller and faster to load
  • UMD builds have broader compatibility but are larger
  • All builds include full TypeScript definitions
  • CSP Compliance: Browser builds are optimized for strict Content Security Policy environments, excluding AJV and using platform-specific implementations that don't require unsafe-eval permissions. This enables compatibility with environments like Salesforce Lightning, enterprise applications, and other CSP-restricted platforms.

Build Governance & Quality Assurance

The SDK implements a comprehensive build governance system ensuring quality and compatibility across all environments:

Bundle Size Monitoring

# Check current bundle sizes against budget limits
npm run size

# Generate detailed size report with build comparison
npm run size:report

# Analyze bundle composition (interactive visualization)
npm run analyze

# Create baseline for size tracking and regression detection
npm run size:baseline

Current Size Budgets:

  • Browser UMD: 250KB limit (current: ~50KB) ✅
  • Server UMD: 180KB limit (current: ~55KB) ✅
  • Browser ESM: 80KB limit (current: ~47KB) ✅
  • Server ESM: 200KB limit (current: ~164KB) ✅

Multi-Build Testing Strategy

The SDK uses comprehensive multi-build testing to ensure reliability across all environments:

# Test all build variants with comprehensive validation
npm run test:all-builds

# Test specific build targets
npm run test:server          # Server ESM build (Node.js with full AJV)
npm run test:browser         # Browser ESM build (modern bundlers)
npm run test:umd-server      # Server UMD build (mixed environments)
npm run test:umd-browser     # Browser UMD build (legacy/CDN)
npm run test:umd-salesforce  # Salesforce Lightning compatibility

# Build quality validation
npm run test:build-matrix    # Matrix testing across all builds
npm run test:csp-compliance  # CSP compliance validation
npm run test:memory          # Memory usage and leak detection

Build System Features

Unified Build Environment:

  • Standardized FULL=1 environment variable for non-minified debugging builds
  • External source maps for CSP compliance (generate-source-maps.js)
  • Comprehensive build validation and artifact testing

Quality Assurance:

  • Build matrix testing ensures consistency across all variants
  • CSP compliance validation for enterprise environments
  • Memory leak detection and performance monitoring
  • Bundle size regression prevention with automated budgets

Size Optimization Tips:

  • Use Browser ESM for modern bundlers to minimize final bundle size
  • Browser UMD is self-contained but larger due to included polyfills
  • Server builds include AJV validation which adds ~40KB but provides robust data validation
  • All builds are optimized for their target environments and use cases

Choose the build that best matches your environment and bundler capabilities.

Configuration

Before using the SDK, you need to configure it with the necessary parameters. The primary configuration options include:

  • websocketUrl: The URL for the WebSocket connection.

  • authenticationUrl: (Optional) The URL for authentication, if you intend to use the authenticate method.

  • clientId: (Optional) Your client ID for authentication, if you intend to use the authenticate method.

  • clientSecret: (Optional) Your client secret for authentication, if you intend to use the authenticate method.

    ⚠️ SECURITY WARNING: Never set clientSecret in browser/mobile/Electron renderers. Client secrets must only be used in secure server-side environments to prevent exposure to end users.

Example Configuration

// Automatic build selection (recommended)
import OptaveJavaScriptSDK from '@optave/client-sdk';

// Or explicit server build for Node.js
// import OptaveJavaScriptSDK from '@optave/client-sdk/server';

// Or UMD for mixed environments (works with CommonJS require())
// const OptaveJavaScriptSDK = require('@optave/client-sdk/server-umd');

const optaveClient = new OptaveJavaScriptSDK({
    websocketUrl: process.env.OPTAVE__WEBSOCKET_URL,
    authenticationUrl: process.env.OPTAVE__AUTHENTICATION_URL,
    clientId: process.env.OPTAVE__CLIENT_ID,
    clientSecret: process.env.OPTAVE__CLIENT_SECRET,
});

Browser Environment Configuration

When using the SDK in browser applications, you'll need to configure it differently depending on your build tool. Here are examples for popular frontend frameworks:

Vite (Vue, React, Vanilla)

// Automatic selection (recommended)
import OptaveJavaScriptSDK from '@optave/client-sdk';

// Or explicit browser build
// import OptaveJavaScriptSDK from '@optave/client-sdk/browser';

const sdk = new OptaveJavaScriptSDK({
    websocketUrl: import.meta.env.VITE_OPTAVE__WEBSOCKET_URL,
    authTransport: 'subprotocol', // Default - recommended for security
    tokenProvider: async () => {
        const response = await fetch('/api/optave/ws-ticket', {
            method: 'POST',
            credentials: 'include' // Include cookies for authentication
        });
        if (!response.ok) throw new Error('Failed to obtain WebSocket token');
        const data = await response.json();
        return data.token;
    }
});

Environment variables (.env):

VITE_OPTAVE__WEBSOCKET_URL=wss://client-identifier.oco.optave.tech

Create React App

// Automatic selection (recommended)
import OptaveJavaScriptSDK from '@optave/client-sdk';

// Or explicit browser build for older Webpack versions
// import OptaveJavaScriptSDK from '@optave/client-sdk/browser';

const sdk = new OptaveJavaScriptSDK({
    websocketUrl: process.env.REACT_APP_OPTAVE__WEBSOCKET_URL,
    tokenProvider: async () => {
        const response = await fetch('/api/optave/ws-ticket', {
            method: 'POST',
            credentials: 'include'
        });
        if (!response.ok) throw new Error('Failed to obtain WebSocket token');
        const data = await response.json();
        return data.token;
    }
});

Environment variables (.env):

REACT_APP_OPTAVE__WEBSOCKET_URL=wss://client-identifier.oco.optave.tech

Next.js

// Automatic selection (recommended)
import OptaveJavaScriptSDK from '@optave/client-sdk';

// Or explicit browser build
// import OptaveJavaScriptSDK from '@optave/client-sdk/browser';

const sdk = new OptaveJavaScriptSDK({
    websocketUrl: process.env.NEXT_PUBLIC_OPTAVE__WEBSOCKET_URL,
    tokenProvider: async () => {
        const response = await fetch('/api/optave/ws-ticket', {
            method: 'POST',
            credentials: 'include'
        });
        if (!response.ok) throw new Error('Failed to obtain WebSocket token');
        const data = await response.json();
        return data.token;
    }
});

Environment variables (.env.local):

NEXT_PUBLIC_OPTAVE__WEBSOCKET_URL=wss://client-identifier.oco.optave.tech

Generic Browser (without build tools)

// For modern browsers supporting ES modules
import OptaveJavaScriptSDK from '@optave/client-sdk/browser';

// Or for legacy browser support
// Use the UMD CDN example shown in "Build System & Imports" section

const sdk = new OptaveJavaScriptSDK({
    websocketUrl: 'wss://client-identifier.oco.optave.tech', // Direct configuration
    tokenProvider: async () => {
        const response = await fetch('/api/optave/ws-ticket', {
            method: 'POST',
            credentials: 'include'
        });
        if (!response.ok) throw new Error('Failed to obtain WebSocket token');
        const data = await response.json();
        return data.token;
    }
});

⚠️ Important: Browser applications should never use clientSecret. Always use tokenProvider to obtain short-lived tokens from your secure backend.

Build Tool Integration

The SDK works seamlessly with popular frontend build tools. Each has its own convention for exposing environment variables to client-side code:

Build ToolEnvironment Variable PrefixExample
ViteVITE_import.meta.env.VITE_OPTAVE__WEBSOCKET_URL
Create React AppREACT_APP_process.env.REACT_APP_OPTAVE__WEBSOCKET_URL
Next.jsNEXT_PUBLIC_process.env.NEXT_PUBLIC_OPTAVE__WEBSOCKET_URL
NuxtNUXT_PUBLIC_process.env.NUXT_PUBLIC_OPTAVE__WEBSOCKET_URL

Security Note: Only variables with these prefixes are exposed to the browser. This prevents accidentally leaking server-side secrets to client-side code.

Content Security Policy (CSP) Compliance

The Optave Client SDK is designed to work in strict Content Security Policy environments without requiring unsafe-eval permissions. This makes it compatible with enterprise applications, Salesforce Lightning, and other security-conscious platforms.

CSP-Safe Implementation

Salesforce-compatible builds (Browser ESM and both UMD builds) automatically:

  • Exclude AJV and other libraries that require eval() or new Function()
  • Use platform-specific validation implementations that are CSP-compliant
  • Generate external source maps instead of inline eval-based modules
  • Avoid all runtime code generation

Compatible CSP Headers

The SDK works with strict CSP policies like:

Content-Security-Policy: default-src 'self'; script-src 'self'; object-src 'none'; style-src 'self' 'unsafe-inline'

Salesforce Lightning Compatibility

Specifically tested and optimized for Salesforce Lightning environments:

// Works in Lightning Web Components (LWC)
import OptaveJavaScriptSDK from '@optave/client-sdk/browser';

const sdk = new OptaveJavaScriptSDK({
    websocketUrl: 'wss://client-identifier.oco.optave.tech',
    tokenProvider: async () => {
        // Fetch from your Lightning backend
        const response = await fetch('/services/data/v58.0/optave/token', {
            method: 'POST',
            headers: { 'Authorization': `Bearer ${sessionId}` }
        });
        return (await response.json()).token;
    }
});

Important Considerations:

  • Race conditions: If app code runs before the script loads, globalThis.Optave is undefined.

Enterprise Environment Setup

For enterprise applications with strict security policies:

  • Use explicit browser builds to ensure CSP compatibility
  • Configure external token providers instead of client credentials
  • Test CSP headers during development to catch violations early

Authentication

If your setup requires authentication, the SDK provides an authenticate method to obtain an access token using client credentials.

Usage

async function authenticateClient() {
    try {
        const token = await optaveClient.authenticate();
        console.log('Authentication successful. Token:', token);
    } catch (error) {
        console.error('Authentication failed:', error);
    }
}

Note: Ensure that authenticationUrl, clientId, and clientSecret are correctly set in the configuration when using authenticate(). If you already have an externally obtained token you can skip authenticate() and call openConnection(token) directly.

Recent Authentication Enhancements

The SDK has been enhanced with several improvements for better reliability and security:

Automatic /token Suffix Handling: The SDK now automatically appends /token to authentication URLs for user-friendly configuration. You can provide either https://api.optave.com/auth or https://api.optave.com/auth/token - both work seamlessly.

Enhanced WebSocket Authentication:

  • Improved query parameter authentication with better error handling
  • Automatic detection of browser vs. server environments for secure credential handling
  • Enhanced timeout handling for WebSocket connections to prevent cascade failures

Robust Error Handling: Enhanced error messages with detailed context and troubleshooting guidance, making debugging authentication issues significantly easier.

Security Best Practices

The Optave SDK implements several security measures by default to protect your applications and users:

Client Secret Protection

⚠️ CRITICAL: Never include client secrets in client-side code. The SDK will automatically throw an error if a clientSecret is detected in browser, mobile, or Electron renderer environments.

// ❌ NEVER DO THIS - Will throw an error in client environments
const sdk = new OptaveJavaScriptSDK({
    clientSecret: 'secret_key_here', // This will cause an error!
    // ... other options
});

// ✅ SECURE APPROACH - Use tokenProvider instead
const sdk = new OptaveJavaScriptSDK({
    websocketUrl: import.meta.env.VITE_OPTAVE__WEBSOCKET_URL, // Vite example
    tokenProvider: async () => {
        // Fetch token from your secure backend endpoint
        const response = await fetch('/api/optave/ws-ticket', {
            method: 'POST',
            credentials: 'include' // Include cookies for authentication
        });
        if (!response.ok) throw new Error('Failed to obtain WebSocket token');
        const data = await response.json();
        return data.token;
    }
});

// ✅ COMPLETE BROWSER SETUP EXAMPLE (Vite)
const sdk = new OptaveJavaScriptSDK({
    websocketUrl: import.meta.env.VITE_OPTAVE__WEBSOCKET_URL,
    authTransport: 'subprotocol', // Default - uses Sec-WebSocket-Protocol header
    tokenProvider: async () => {
        const response = await fetch('/api/optave/ws-ticket', {
            method: 'POST',
            credentials: 'include',
            headers: {
                'Content-Type': 'application/json'
            }
        });
        if (!response.ok) throw new Error('Token request failed');
        const { token } = await response.json();
        return token; // Short-lived, one-time token
    }
});

// Event handlers
sdk.on('open', () => {
    console.log('WebSocket connection established');
    // Now you can send messages
});

sdk.on('error', (error) => {
    console.error('SDK error:', error);
});

// Open connection (automatically uses tokenProvider)
sdk.openConnection();

Authentication Transport Security

The SDK defaults to secure authentication transport using WebSocket subprotocols:

// ✅ DEFAULT (Recommended) - Token sent via Sec-WebSocket-Protocol header
const sdk = new OptaveJavaScriptSDK({
    authTransport: 'subprotocol', // This is the default
    // ... other options
});

// ⚠️ DISCOURAGED - Token sent in URL query parameters (will show warning)
const sdk = new OptaveJavaScriptSDK({
    authTransport: 'query', // Avoid this - tokens may leak in logs
    // ... other options
});

Server-Side Token Management

For backend implementations, implement these security practices:

  • Origin Validation: Always validate the Origin header on your token endpoint:
// Example Express.js token endpoint
app.post('/auth/oauth2/token', (req, res) => {
    const origin = req.headers.origin;
    const allowedOrigins = ['https://yourdomain.com', 'https://app.yourdomain.com'];

    if (!allowedOrigins.includes(origin)) {
        return res.status(403).json({ error: 'Invalid origin' });
    }

    // Generate short-lived, one-time token
    const token = generateShortLivedToken();
    res.json({ token });
});
  • Short-lived Tokens: Issue tokens with minimal lifetime (recommended: 5-15 minutes)

  • One-time Use: Consider implementing one-time tokens that are invalidated after first use

  • Secure Headers: Set appropriate security headers:

// Security headers example
app.use((req, res, next) => {
    res.setHeader('X-Content-Type-Options', 'nosniff');
    res.setHeader('X-Frame-Options', 'DENY');
    res.setHeader('X-XSS-Protection', '1; mode=block');
    next();
});

Environment Detection

The SDK automatically detects and protects against unsafe environments:

  • Browser environments (window object present)
  • Mobile environments (React Native, Expo)
  • Electron renderer processes

All these environments will reject client secrets and require tokenProvider implementation.

Connection Security

// ✅ SECURE - Let SDK handle token automatically
sdk.openConnection(); // Uses tokenProvider if no token provided

// ✅ SECURE - Pass token directly if you have one
sdk.openConnection('your-short-lived-token');

// The SDK will automatically:
// - Use secure WebSocket subprotocol authentication
// - Validate token presence when required
// - Handle authentication failures gracefully

Establishing a WebSocket Connection

After obtaining (or otherwise retrieving) a token, open the WebSocket connection:

async function connectWebSocket() {
    const token = await optaveClient.authenticate();
    optaveClient.openConnection(token);
}

Recent WebSocket Improvements

The WebSocket implementation has been significantly enhanced for better reliability and performance:

Enhanced Connection Management:

  • Improved WebSocket event listener handling with proper race condition prevention
  • Better async behavior with proper promise rejection handling
  • Enhanced timeout handling to prevent cascade test failures

UMD Build Enhancements:

  • Server UMD builds now support clientSecret authentication with 100% test success rates
  • Browser authentication detection has been simplified and made more reliable
  • Improved WebSocket integration for mixed browser/Node.js environments

Memory Management:

  • Comprehensive memory leak detection and prevention
  • Proper resource cleanup on connection close
  • Enhanced garbage collection patterns for long-running applications

Salesforce Lightning Integration:

  • Dedicated UMD builds optimized for Salesforce Lightning environments
  • GlobalThis access diagnostic tests for compatibility validation
  • CSP-compliant WebSocket implementations for enterprise security requirements

Event Handling

The SDK emits several events to handle various states and messages. You can listen to these events to manage your application's behavior accordingly.

Available Events

  • open: Emitted when the WebSocket connection is successfully opened.
  • message: Emitted when a message is received from the server.
  • error: Emitted when an error occurs.
  • close: Emitted when the WebSocket connection is closed.

Listening to Events

optaveClient.on('open', () => {
    console.log('WebSocket connection opened.');
});

optaveClient.on('message', (payload) => {
    const message = JSON.parse(payload);
    console.log('Received message:', message);
});

optaveClient.on('error', (error) => {
    console.error('An error occurred:', error);
});

optaveClient.on('close', () => {
    console.log('WebSocket connection closed.');
});

Sending Messages

The SDK provides several methods to send different types of messages through the WebSocket connection. Each method corresponds to a specific action type.

Available Methods

  • adjust(params): Sends an adjust message.
  • elevate(params): Sends an elevate message.
  • interaction(params): Sends an interaction message (successor to customerInteraction).
  • reception(params): Sends a reception message.
  • customerInteraction(params): (Deprecated) Legacy alias kept for backward compatibility. Use interaction instead.
  • summarize(params): Sends a summarize message.
  • translate(params): Sends a translate message.
  • recommend(params): Sends a recommend message.
  • insights(params): Sends an insights message.

Example: Sending a Interaction Message

const interactionParams = {
    session: {
        sessionId: "a1b2c3e6-e5f6-7890-1234-56789abcdef0",
        channel: {
            browser: "Safari 17.0",
            deviceInfo: "iOS/18.2, iPhone15,3",
            deviceType: "mobile",
            language: "en-US",
            location: "40.7128,-74.0060", // GPS coordinates
            medium: "chat", // options: "chat", "voice", "email"
            section: "support_page",
        },
        interface: {
            appVersion: "2.1.0",
            category: "crm",
            language: "en-US",
            name: "my_support_app",
            type: "custom_components",
        }
    },
    headers: {
        // Optional client event time; if omitted no timestamp header is sent
        timestamp: "2024-01-15T10:30:00.000Z"
    },
    request: {
        requestId: "a1b2c3d4-e5f6-7890-1234-56789ab2345",
        attributes: {
            variant: "A"
        },
        connections: {
            threadId: "9e8d7c6b-5a49-3827-1605-948372615abc" // REQUIRED
        },
        context: { // generated by optave
            organizationId: "f7e8d9c0-b1a2-3456-7890-123456789abc", // REQUIRED
        },
        scope: {
            conversations: [ // REQUIRED
                {
                    conversationId: "conv-789",
                    participants: [
                        {
                            participantId: "2c4f8a9b-1d3e-5f70-8293-456789012def", //sent by the client - optional
                            role: "user",
                            displayName: "John Doe"
                        },
                        {
                            participantId: "5b8c9d0e-2f4a-6b1c-9d8e-123456789xyz",
                            role: "operator",
                            displayName: "Sarah Smith"
                        }
                    ],
                    messages: [
                        {
                            timestamp: "2024-01-15T10:30:00.000Z",
                            participantId: "2c4f8a9b-1d3e-5f70-8293-456789012def",
                            content: "Hi, can you help me?"
                        },
                        {
                            timestamp: "2024-01-15T10:30:15.000Z",
                            participantId: "5b8c9d0e-2f4a-6b1c-9d8e-123456789xyz",
                            content: "Hello! I'd be happy to assist you today. What can I help you with?"
                        }
                    ]
                }
            ]
        },
        settings: {
            disableBrowsing: false,
            disableSearch: false,
            disableSources: false,
            disableStream: false,
            disableTools: false,
            maxResponseLength: 2000,
            overrideOutputLanguage: "en-US"
        }
    }
};

optaveClient.interaction(interactionParams);

Payload Structure

The SDK manages a default payload structure that encapsulates session information, user details, agent information, requests, and more. When sending a message, you provide a params object that is merged with the default payload to form the final payload sent over the WebSocket.

Default Payload Overview

  • session: Contains session tracking information including sessionId, channel details (browser, deviceInfo, deviceType, etc.), and interface information.
  • request: Details about the request including requestId, context, connections, attributes, scope (with structured conversations and interactions), and settings.

Merging Strategy

The SDK performs a selective deep merge where the user-provided params are merged "on top" of the default payload. Arrays in the payload are replaced entirely by the arrays provided in params.

Envelope Headers

Each outbound message is wrapped in an envelope with a headers object. The SDK auto-populates the following headers (fields marked optional are only present when supplied):

  • schemaRef – Format: optave.message.v<major> (derived from spec version major). Always present.
  • sdkVersion – The SDK package version from package.json.
  • action – The validated action string you invoked (e.g. customerinteraction).
  • correlationId – Taken in priority order from: user override (params.headers.correlationId), request.requestId, or auto-generated (uuid v7).
  • traceId – Auto-generated (uuid v7) unless overridden via params.headers.traceId.
  • idempotencyKey – Auto-generated (uuid v7) unless overridden via params.headers.idempotencyKey.
  • issuedAt – ISO timestamp when the envelope was built (always present).
  • timestamp – Optional client event time you provide (not generated automatically). Supply under params.headers.timestamp if you want to record the original occurrence time of the underlying event.
  • identifier – The request type (currently message).
  • networkLatencyMs – Included only if explicitly supplied as a number via params.headers.networkLatencyMs.
  • tenantId – Included only when tenantId option is set in the SDK constructor.

Header Override Rules:

  • Provide a top-level headers object in the params you pass to send() or the convenience method (e.g. interaction({ headers: { timestamp: '...' }, ... })).
  • Only the keys you supply are considered overrides; others are generated.
  • Supplying timestamp prevents accidental fabrication—if you omit it, it is simply absent (not auto-filled).

Correlation & Tracing:

  • Use a custom correlationId if you need to link multiple outbound requests to an external system ID.
  • traceId plus correlationId enable joining logs across services; normally you do not need to set them manually.
  • idempotencyKey can be overridden to ensure safe retries on the server side if that semantic is supported.

Example Usage

Below are examples demonstrating how to initialize the SDK, establish a connection, handle events, and send messages.

Browser Usage Example

// Automatic build selection (recommended)
import OptaveJavaScriptSDK from '@optave/client-sdk';

// Or explicit browser build
// import OptaveJavaScriptSDK from '@optave/client-sdk/browser';

const sdk = new OptaveJavaScriptSDK({
    websocketUrl: import.meta.env.VITE_OPTAVE__WEBSOCKET_URL,
    tokenProvider: async () => {
        const r = await fetch('/api/optave/ws-ticket', {
            method: 'POST',
            credentials: 'include'
        });
        if (!r.ok) throw new Error('ticket failed');
        const { token } = await r.json();
        return token;
    }
});

// Wait for 'open' before sending
sdk.on('open', () => {
    sdk.interaction({ /* your params */ });
});
sdk.on('error', (e) => console.error('SDK error', e));

sdk.openConnection(); // uses tokenProvider automatically

Node.js Server Example

// Automatic build selection (recommended)
import OptaveJavaScriptSDK from '@optave/client-sdk';

// Or explicit server build
// import OptaveJavaScriptSDK from '@optave/client-sdk/server';

// Or UMD for mixed environments (works with CommonJS require())
// const OptaveJavaScriptSDK = require('@optave/client-sdk/server-umd');

const optaveClient = new OptaveJavaScriptSDK({
    websocketUrl: process.env.OPTAVE__WEBSOCKET_URL,

    // These parameters are only required when using the authenticate() function.
    // In some cases, the authentication token can be obtained manually or through
    // another process, which makes the authenticate() call unnecessary. In this
    // case, only the openConnection function has to be called, passing the existing token value
    authenticationUrl: process.env.OPTAVE__AUTHENTICATION_URL,
    clientId: process.env.OPTAVE__CLIENT_ID,
    clientSecret: process.env.OPTAVE__CLIENT_SECRET,
});

async function run() {
    // Listen for messages from the WebSocket
    optaveClient.on('message', payload => {
        const message = JSON.parse(payload);
        const { actionType, state, action } = message;
    
        console.log(`Action: ${action} / State: ${state} / Action Type: ${actionType}`);
    });
    
    // Handle errors
    optaveClient.on('error', error => {
        if (typeof error === 'string') {
            console.error(error);
        } else {
            console.error('Error:', error);
        }
    });
    
    // After the connection is opened, send an interaction message
    optaveClient.once('open', () => {
        optaveClient.interaction({
            session: {
                sessionId: "a1b2c3e6-e5f6-7890-1234-56789abcdef0",
                channel: {
                    browser: "Safari 17.0",
                    deviceInfo: "iOS/18.2, iPhone15,3",
                    deviceType: "mobile",
                    language: "en-US",
                    location: "40.7128,-74.0060", // GPS coordinates
                    medium: "chat", // options: "chat", "voice", "email"
                    section: "support_page",
                },
                interface: {
                    appVersion: "2.1.0",
                    category: "crm",
                    language: "en-US",
                    name: "my_support_app",
                    type: "custom_components",
                }
            },
            request: {
                requestId: "a1b2c3d4-e5f6-7890-1234-56789ab2345",
                attributes: {
                    variant: "A"
                },
                connections: {
                    threadId: "9e8d7c6b-5a49-3827-1605-948372615abc" // REQUIRED
                },
                context: { // generated by optave
                    organizationId: "f7e8d9c0-b1a2-3456-7890-123456789abc", // REQUIRED
                },
                scope: {
                    conversations: [ // REQUIRED
                        {
                            conversationId: "conv-789",
                            participants: [
                                {
                                    participantId: "2c4f8a9b-1d3e-5f70-8293-456789012def", //sent by the client - optional
                                    role: "user",
                                    displayName: "John Doe"
                                },
                                {
                                    participantId: "5b8c9d0e-2f4a-6b1c-9d8e-123456789xyz",
                                    role: "operator",
                                    displayName: "Sarah Smith"
                                }
                            ],
                            messages: [
                                {
                                    timestamp: "2024-01-15T10:30:00.000Z",
                                    participantId: "2c4f8a9b-1d3e-5f70-8293-456789012def",
                                    content: "Hi, can you help me?"
                                },
                                {
                                    timestamp: "2024-01-15T10:30:15.000Z",
                                    participantId: "5b8c9d0e-2f4a-6b1c-9d8e-123456789xyz",
                                    content: "Hello! I'd be happy to assist you today. What can I help you with?"
                                }
                            ]
                        }
                    ],
                    interactions: [
                        {
                            content: "Support ticket T12345 has been created for user John Doe",
                            id: "1",
                            name: "ticket_created",
                            role: "System",
                            timestamp: "2024-01-15T10:29:45.000Z",
                        }
                    ]
                },
                settings: {
                    disableBrowsing: false,
                    disableSearch: false,
                    disableSources: false,
                    disableStream: false,
                    disableTools: false,
                    maxResponseLength: 2000,
                    overrideOutputLanguage: "en-US"
                }
            }
        });
    });

    // Authenticate and open the WebSocket connection
    try {
        const token = await optaveClient.authenticate();
        optaveClient.openConnection(token);
    } catch (error) {
        console.error('Failed to authenticate and connect:', error);
    }
}

run();

API Reference

OptaveJavaScriptSDK(options)

Creates a new instance of the OptaveJavaScriptSDK.

  • Parameters:
    • options (Object): Configuration options.
      • websocketUrl (string): The WebSocket URL.

      • authenticationUrl (string, optional): The authentication URL.

      • clientId (string, optional): The client ID for authentication.

      • clientSecret (string, optional): The client secret for authentication.

        ⚠️ SECURITY WARNING: Never set clientSecret in browser/mobile/Electron renderers. Client secrets must only be used in secure server-side environments.

authenticate()

Authenticates the client using the provided credentials and retrieves an access token.

  • Returns: (Promise) The access token.

openConnection(bearerToken)

Establishes a WebSocket connection using the provided bearer token.

  • Parameters:
    • bearerToken (string): The authentication token.

closeConnection()

Closes the active WebSocket connection.

send(requestType, action, params)

Sends a message through the WebSocket connection.

  • Parameters:
    • requestType (string): The type of the request.
    • action (string): The specific action to perform.
    • params (Object): The parameters for the request.

Predefined Methods

These methods are shortcuts for sending specific types of messages.

  • adjust(params): Sends an adjust message.
  • elevate(params): Sends an elevate message.
  • interaction(params): Sends an interaction message.
  • reception(params): Sends a reception message.
  • customerInteraction(params): (Deprecated) Legacy alias for interaction.
  • summarize(params): Sends a summarize message.
  • translate(params): Sends a translate message.
  • recommend(params): Sends a recommend message.
  • insights(params): Sends an insights message.

EventEmitter Methods

Since OptaveJavaScriptSDK extends EventEmitter, you can use all standard EventEmitter methods such as on, once, emit, etc.

Static Methods and Constants

The SDK provides several static methods and constants for accessing metadata and configuration:

import OptaveJavaScriptSDK from '@optave/client-sdk';

// Version information
const sdkVersion = OptaveJavaScriptSDK.getSdkVersion(); // e.g., "3.2.4" (SDK implementation version)
const specVersion = OptaveJavaScriptSDK.getSpecVersion(); // Returns: "1.0.0" (AsyncAPI protocol version - static)
const schemaRef = OptaveJavaScriptSDK.getSchemaRef(); // e.g., "optave.message.v3"

// Constants
const constants = OptaveJavaScriptSDK.CONSTANTS; // SDK configuration constants
const legacyEvents = OptaveJavaScriptSDK.LegacyEvents; // Legacy event names
const inboundEvents = OptaveJavaScriptSDK.InboundEvents; // New event names

// Usage example
sdk.on(OptaveJavaScriptSDK.LegacyEvents.MESSAGE, (data) => {
  console.log('Legacy message event:', data);
});

sdk.on(OptaveJavaScriptSDK.InboundEvents.SUPERPOWER_RESPONSE, (data) => {
  console.log('New superpower response:', data);
});

Error Handling

The SDK includes robust error handling to ensure that issues are communicated effectively.

Emitting Errors

Errors are emitted via the error event. You can listen to this event to handle errors gracefully.

optaveClient.on('error', (error) => {
    console.error('An error occurred:', error);
});

Common Error Scenarios

  • Missing Configuration: Errors will be emitted if required configuration options like websocketUrl or authenticationUrl are missing.
  • Authentication Failure: If authentication fails, an error with the corresponding message will be emitted.
  • WebSocket Issues: Errors related to WebSocket connections, such as connection failures or unexpected closures, will be emitted.

Error Object Structure

When an error is emitted, it follows the following structure:

{
    category: 'WEBSOCKET', // Error category (available types: AUTHENTICATION, ORCHESTRATOR, VALIDATION, WEBSOCKET)
    code: 'INVALID_WEBSOCKET_URL', // Error code that identifies which error just happened
    message: 'Empty or invalid Websocket URL', // Error message explaining the problem
    details: null // Error details which may or not bring additional information
    suggestions: [] // List of suggestions on how to fix the error
}

Keywords

sdk

FAQs

Package last updated on 30 Mar 2026

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts