
Security News
Feross on the 10 Minutes or Less Podcast: Nobody Reads the Code
Socket CEO Feross Aboukhadijeh joins 10 Minutes or Less, a podcast by Ali Rohde, to discuss the recent surge in open source supply chain attacks.
@optave/client-sdk
Advanced tools
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.
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:
EventEmitter to handle asynchronous events.To install the Optave Client SDK, use npm or yarn:
npm install @optave/client-sdk
or
yarn add @optave/client-sdk
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:
Benefits:
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.
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.
The SDK provides four optimized builds, each tailored for specific deployment environments and security requirements:
| Build | Module Format | Allows clientSecret | AJV Validation | CSP Safe | Intended Environments | Size (Uncompressed) | Size (Gzipped) |
|---|---|---|---|---|---|---|---|
| Browser ESM | ES Module | ❌ No | ❌ External Only | ✅ Yes | Modern browsers, Vite, Webpack 5+, bundled apps | ~47KB | ~14KB |
| Browser UMD | UMD | ❌ No | ❌ External Only | ✅ Yes | Salesforce Lightning, CDN, legacy browsers, CSP environments | ~54KB | ~15KB |
| Server ESM | ES Module | ✅ Yes | ✅ Full AJV | ❌ No | Node.js servers, microservices, backend APIs | ~164KB | ~25KB |
| Server UMD | UMD | ✅ Yes | ❌ External Only | ✅ Yes | Node.js CommonJS, legacy servers, mixed Node.js environments | ~49KB | ~14KB |
🔒 Security & CSP Compliance
tokenProvider📦 Bundle Size Impact
🚀 Performance Characteristics
⚙️ Validation Strategy
Default Import (Recommended):
import OptaveJavaScriptSDK from '@optave/client-sdk';
// Automatically selects:
// - browser.mjs in browser environments
// - server.mjs in Node.js environments
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');
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>
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
});
ws package)unsafe-eval permissions. This enables compatibility with environments like Salesforce Lightning, enterprise applications, and other CSP-restricted platforms.The SDK implements a comprehensive build governance system ensuring quality and compatibility across all environments:
# 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:
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
Unified Build Environment:
FULL=1 environment variable for non-minified debugging buildsgenerate-source-maps.js)Quality Assurance:
Size Optimization Tips:
Choose the build that best matches your environment and bundler capabilities.
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.
// 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,
});
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:
// 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
// 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
// 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
// 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.
The SDK works seamlessly with popular frontend build tools. Each has its own convention for exposing environment variables to client-side code:
| Build Tool | Environment Variable Prefix | Example |
|---|---|---|
| Vite | VITE_ | import.meta.env.VITE_OPTAVE__WEBSOCKET_URL |
| Create React App | REACT_APP_ | process.env.REACT_APP_OPTAVE__WEBSOCKET_URL |
| Next.js | NEXT_PUBLIC_ | process.env.NEXT_PUBLIC_OPTAVE__WEBSOCKET_URL |
| Nuxt | NUXT_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.
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.
Salesforce-compatible builds (Browser ESM and both UMD builds) automatically:
eval() or new Function()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'
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:
globalThis.Optave is undefined.For enterprise applications with strict security policies:
If your setup requires authentication, the SDK provides an authenticate method to obtain an access token using client credentials.
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.
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:
Robust Error Handling: Enhanced error messages with detailed context and troubleshooting guidance, making debugging authentication issues significantly easier.
The Optave SDK implements several security measures by default to protect your applications and users:
⚠️ 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();
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
});
For backend implementations, implement these security practices:
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();
});
The SDK automatically detects and protects against unsafe environments:
All these environments will reject client secrets and require tokenProvider implementation.
// ✅ 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
After obtaining (or otherwise retrieving) a token, open the WebSocket connection:
async function connectWebSocket() {
const token = await optaveClient.authenticate();
optaveClient.openConnection(token);
}
The WebSocket implementation has been significantly enhanced for better reliability and performance:
Enhanced Connection Management:
UMD Build Enhancements:
clientSecret authentication with 100% test success ratesMemory Management:
Salesforce Lightning Integration:
The SDK emits several events to handle various states and messages. You can listen to these events to manage your application's behavior accordingly.
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.');
});
The SDK provides several methods to send different types of messages through the WebSocket connection. Each method corresponds to a specific action type.
customerInteraction).interaction instead.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);
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.
sessionId, channel details (browser, deviceInfo, deviceType, etc.), and interface information.requestId, context, connections, attributes, scope (with structured conversations and interactions), and settings.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.
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:
headers object in the params you pass to send() or the convenience method (e.g. interaction({ headers: { timestamp: '...' }, ... })).timestamp prevents accidental fabrication—if you omit it, it is simply absent (not auto-filled).Correlation & Tracing:
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.Below are examples demonstrating how to initialize the SDK, establish a connection, handle events, and send messages.
// 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
// 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();
OptaveJavaScriptSDK(options)Creates a new instance of the OptaveJavaScriptSDK.
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.
openConnection(bearerToken)Establishes a WebSocket connection using the provided bearer token.
bearerToken (string): The authentication token.closeConnection()Closes the active WebSocket connection.
send(requestType, action, params)Sends a message through the WebSocket connection.
requestType (string): The type of the request.action (string): The specific action to perform.params (Object): The parameters for the request.These methods are shortcuts for sending specific types of messages.
adjust message.elevate message.interaction message.reception message.interaction.summarize message.translate message.recommend message.insights message.Since OptaveJavaScriptSDK extends EventEmitter, you can use all standard EventEmitter methods such as on, once, emit, etc.
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);
});
The SDK includes robust error handling to ensure that issues are communicated effectively.
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);
});
websocketUrl or authenticationUrl are missing.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
}
FAQs
Optave client SDK (browser + Node)
We found that @optave/client-sdk demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

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.

Security News
Socket CEO Feross Aboukhadijeh joins 10 Minutes or Less, a podcast by Ali Rohde, to discuss the recent surge in open source supply chain attacks.

Research
/Security News
Campaign of 108 extensions harvests identities, steals sessions, and adds backdoors to browsers, all tied to the same C2 infrastructure.

Security News
OpenAI rotated macOS signing certificates after a malicious Axios package reached its CI pipeline in a broader software supply chain attack.