@voxket-ai/voxket-live
Version:
A React widget for embedding Voxket-powered audio/video/chat experiences.
1,969 lines (1,603 loc) • 57.3 kB
Markdown
# 🎯 Voxket Web SDK (`@voxket-ai/voxket-live`)
**The Complete AI Agent Integration Solution** - Seamlessly embed voice, video, and chat experiences powered by Voxket AI agents into any web application.
[](https://www.npmjs.com/package/@voxket-ai/voxket-live)
[](https://opensource.org/licenses/MIT)
[](https://www.typescriptlang.org/)
## 🌟 Key Features
### 🔥 **Multi-Modal AI Interactions**
- **🎤 Voice Conversations** - Real-time voice chat with AI agents
- **💬 Text Chat** - Instant messaging with typing indicators and message history
- **📹 Video Calls** - Face-to-face conversations with video support
- **📺 Screen Sharing** - Share your screen with AI agents for enhanced support
### 🎨 **Flexible Display Options**
- **🪟 Widget Mode** - Embedded widget for seamless integration
- **🚀 Popup Mode** - Floating chat bubble with customizable positioning
- **🖥️ Fullscreen Mode** - Immersive full-screen experience
- **📱 Responsive Design** - Works perfectly on desktop and mobile
### 🎭 **Rich Theming System**
- **🌙 Dark Theme** - Modern dark interface
- **☀️ Light Theme** - Clean light interface
- **💎 Vox Theme** - Custom branded Voxket theme
- **🎨 Custom Themes** - Create your own themes with full CSS control
### ⚡ **Powerful Integration Options**
#### 🔧 **1. Simple Widget Integration** (React)
Perfect for React applications with minimal setup.
#### 🚀 **2. Client SDK Integration** (Any Framework)
Use the powerful VoxketClient for programmatic control with vanilla JavaScript, Vue, Angular, or any framework.
#### 📊 **3. Advanced React Integration**
Full React ecosystem with providers, hooks, and compound components.
### 🛠️ **Advanced Features**
#### 🎪 **Interactive Components (RPC System)**
- **🎯 Agent-Triggered UI** - Agents can display custom React components
- **📝 Forms & Surveys** - Collect user input through interactive forms
- **📊 Data Visualization** - Show charts, tables, and rich content
- **🎮 Custom Interactions** - Build any interactive experience
#### 📈 **Session Analytics & Logging**
- **📊 Real-time Metrics** - Monitor session quality and performance
- **🔍 Event Logging** - Track all user interactions and system events
- **💾 Data Export** - Export session data for analysis
- **⏱️ Session Timers** - Track session duration and activity
#### 🔌 **Event System**
- **📡 Connection Events** - Track connection status and quality
- **👥 Participant Events** - Monitor who joins and leaves
- **🎵 Media Events** - Handle track publishing/unpublishing
- **💬 Message Events** - Real-time message and transcription events
- **🤖 Agent Events** - Monitor agent state (thinking, speaking, idle)
#### 🎛️ **Media Controls**
- **🎤 Microphone Control** - Mute/unmute with visual feedback
- **📷 Camera Control** - Enable/disable video with device selection
- **📺 Screen Share** - Start/stop screen sharing
- **🎧 Audio Devices** - Select input/output devices
- **📹 Video Devices** - Choose camera sources
### 💼 **Business-Ready Features**
- **🔐 Enterprise Security** - HIPAA-compliant options available
- **🌐 Multi-Language Support** - Internationalization ready
- **📱 Cross-Platform** - Works on all modern browsers and devices
- **⚡ High Performance** - Built on LiveKit for optimal real-time performance
- **🛡️ Error Handling** - Robust error recovery and user feedback
- **🔄 Auto-Reconnection** - Automatic connection recovery
## 🚀 Quick Start
### 📦 Installation
```bash
npm install @voxket-ai/voxket-live
```
or
```bash
yarn add @voxket-ai/voxket-live
```
That's it! All dependencies including LiveKit are bundled automatically. React and React DOM are peer dependencies (your project should already have them).
### 🎨 **IMPORTANT: Import the CSS Styles**
**The SDK includes pre-compiled CSS with all necessary styles. You MUST import the CSS file for the widget to display correctly:**
```tsx
// In your main App.tsx or entry file
import '@voxket-ai/voxket-live/style.css';
```
Or in vanilla JavaScript/HTML:
```html
<link rel="stylesheet" href="node_modules/@voxket-ai/voxket-live/dist/index.css">
```
**Note:** The SDK does NOT require Tailwind CSS in your project - all styles are pre-compiled and bundled. The CSS import includes everything needed.
### 🎨 **Popup Icon Customization**
The popup trigger button comes with a default Voxket logo. You can customize it in two ways:
#### **Option 1: Use a Custom Logo URL**
Pass your own logo URL to the `popupTriggerLogoUrl` prop:
```tsx
<VoxketWidget
// ... other props
popupTriggerLogoUrl="https://example.com/my-custom-logo.png"
/>
```
#### **Option 2: Default Voxket Logo**
If you don't pass `popupTriggerLogoUrl`, the SDK automatically uses the bundled Voxket logo - no additional setup required!
### �🎯 **Option 1: Simple Widget (React)**
Perfect for React apps - drop in the widget component:
```tsx
import React from 'react';
import VoxketWidget from '@voxket-ai/voxket-live';
function App() {
return (
<div>
<h1>My App</h1>
<VoxketWidget
agentId="your-agent-id"
baseUrl="https://your.voxket.api"
appId="your-app-id"
appSecret="your-app-secret"
participantName="User"
modalities={['voice', 'chat']} // Choose: voice, chat, video, screen_share
theme="vox" // Options: dark, light, vox
displayType="widget" // Options: widget, popup, fullscreen
width="400px"
height="600px"
/>
</div>
);
}
```
### 🔧 **Option 2: Client SDK (Any Framework)**
Use with vanilla JavaScript, Vue, Angular, or any framework:
```javascript
import { VoxketClient } from '@voxket-ai/voxket-live';
// Create client
const client = new VoxketClient({
appId: "your-app-id",
appSecret: "your-app-secret",
baseUrl: "https://your.voxket.api",
agentId: "your-agent-id",
participantName: "User"
});
// Connect and render UI
await client.connect();
client.renderUI({
target: '#voxket-container', // CSS selector or HTMLElement
modality: ['voice', 'chat'],
theme: 'dark',
displayType: 'widget',
autoStart: true
});
```
### 🏗️ **Option 3: Advanced React Integration**
Full React ecosystem with providers and hooks:
```tsx
import { VoxketProvider, useVoxket } from '@voxket-ai/voxket-live';
function App() {
return (
<VoxketProvider config={{
appId: "your-app-id",
appSecret: "your-app-secret",
baseUrl: "https://your.voxket.api"
}}>
<MyComponent />
</VoxketProvider>
);
}
function MyComponent() {
const { client, connect, session } = useVoxket();
const handleStartChat = async () => {
await connect();
const session = await client.startSession("agent-id", {
modalities: ['chat'],
participantName: "User"
});
};
return (
<div>
<button onClick={handleStartChat}>Start Chat</button>
{session && <p>Session active: {session.id}</p>}
</div>
);
}
```
## 🎛️ **Display Types**
### 🪟 **Widget Mode**
Embedded widget that fits naturally into your application:
```tsx
<VoxketWidget
displayType="widget"
width="400px"
height="600px"
// ... other props
/>
```
### 🚀 **Popup Mode**
Floating chat bubble that can be positioned anywhere:
```tsx
<VoxketWidget
displayType="popup"
popupPosition="bottom-right" // top-left, top-right, bottom-left, bottom-right
popupTriggerText="Need Help?"
onPopupToggle={(isOpen) => console.log('Popup:', isOpen)}
// ... other props
/>
```
### 🖥️ **Fullscreen Mode**
Immersive full-screen experience:
```tsx
<VoxketWidget
displayType="fullscreen"
onDisplayTypeChange={(type) => console.log('Display changed to:', type)}
// ... other props
/>
```
## 🎨 **Themes & Customization**
### 🎭 **Built-in Themes**
```tsx
// Dark theme
<VoxketWidget theme="dark" />
// Light theme
<VoxketWidget theme="light" />
// Voxket branded theme
<VoxketWidget theme="vox" />
```
### 🎨 **Custom Styling**
```tsx
<VoxketWidget
className="my-custom-widget"
width="500px"
height="700px"
// Custom CSS classes and dimensions
/>
```
## 💬 **Session Events & Analytics**
### 📊 **Basic Session Tracking**
```tsx
<VoxketWidget
onSessionStart={(sessionId) => {
console.log('Session started:', sessionId);
analytics.track('voxket_session_started', { sessionId });
}}
onSessionEnd={(metrics) => {
console.log('Session ended:', metrics);
analytics.track('voxket_session_ended', {
duration: metrics.duration,
messageCount: metrics.messageCount
});
}}
enableSessionLogging={true}
/>
```
### 🔍 **Advanced Session Monitoring**
```tsx
import { SessionLog, SessionMetrics } from '@voxket-ai/voxket-live';
function MyApp() {
const [logs, setLogs] = useState<SessionLog[]>([]);
const [metrics, setMetrics] = useState<SessionMetrics | null>(null);
return (
<VoxketWidget
onSessionLogsUpdate={(logs) => {
setLogs(logs);
// Send to your analytics service
analytics.track('session_events', { eventCount: logs.length });
}}
onSessionMetricsUpdate={(metrics) => {
setMetrics(metrics);
// Update your dashboard
updateDashboard(metrics);
}}
// ... other props
/>
);
}
```
## 🎪 **Interactive Components (RPC System)**
### 📝 **Agent-Triggered UI Components**
Agents can trigger custom React components during conversations:
```typescript
import { VoxketClient } from '@voxket-ai/voxket-live';
const client = new VoxketClient(config);
// Register a custom form component
await client.registerFrontendRPC(
'customer_survey', // Method name the agent calls
SurveyComponent, // Your React component
'modal' // Presentation mode: embedded, modal, fullscreen
);
// Your custom component
function SurveyComponent({ handler, data }) {
const [rating, setRating] = useState(0);
const handleSubmit = () => {
handler.didSuccess({
survey_response: rating,
feedback: "Great service!"
});
};
return (
<div>
<h3>Rate your experience</h3>
<StarRating value={rating} onChange={setRating} />
<button onClick={handleSubmit}>Submit</button>
<button onClick={handler.dismissView}>Skip</button>
</div>
);
}
```
### 🎯 **Interactive UI Examples**
- **📋 Forms & Surveys** - Collect user feedback
- **📊 Data Visualization** - Show charts and graphs
- **🛒 Product Catalogs** - Display interactive product lists
- **📅 Appointment Scheduling** - Calendar integrations
- **💳 Payment Flows** - Secure payment processing
- **🎮 Custom Games** - Interactive experiences
## 📡 **Event System**
### 🔌 **Connection Events**
```javascript
client.on('connection.connected', () => {
console.log('✅ Connected to Voxket');
});
client.on('connection.disconnected', (reason) => {
console.log('❌ Disconnected:', reason);
});
client.on('connection.error', (error) => {
console.error('🚨 Connection error:', error);
});
```
## 🔔 **Custom Event System**
### 📡 **Register Event Emitters**
Register custom event emitters to listen for LiveKit text stream topics:
```typescript
import { VoxketClient } from '@voxket-ai/voxket-live';
const client = new VoxketClient(config);
// Register an event emitter for custom events
client.registerEventEmitter('custom_event_topic', (data) => {
console.log('Custom event received:', data);
// Handle your custom business logic
handleCustomEvent(data);
});
// Register multiple event emitters
client.registerEventEmitter('user_action', (actionData) => {
console.log('User action:', actionData);
analytics.track('user_action', actionData);
});
client.registerEventEmitter('system_notification', (notification) => {
showNotification(notification);
});
```
### 🎯 **Event Listener Registration**
Register event listeners for any SDK events with automatic cleanup:
```typescript
// Register event listeners with automatic unsubscribe
const unsubscribe = client.registerEventListener('chat.message.received', (message) => {
console.log('New message:', message);
updateUI(message);
});
// Manual cleanup when needed
unsubscribe();
// Register multiple listeners
client.registerEventListener('connection.connected', () => {
console.log('Connected to Voxket!');
updateConnectionStatus('connected');
});
client.registerEventListener('agent.thinking', () => {
showTypingIndicator();
});
```
### 🏢 **Business Integration Examples**
#### **Real-time Notifications**
```typescript
// Listen for agent-triggered notifications
client.registerEventEmitter('agent_notification', (data) => {
// Show toast notification
showToast({
title: data.title,
message: data.message,
type: data.type
});
});
// Listen for system updates
client.registerEventEmitter('system_update', (updateInfo) => {
if (updateInfo.type === 'maintenance') {
showMaintenanceWarning(updateInfo.schedule);
}
});
```
#### **Custom Analytics Integration**
```typescript
// Track custom business events
client.registerEventEmitter('business_event', (eventData) => {
// Send to your analytics platform
analytics.track(eventData.event_name, {
...eventData.properties,
timestamp: new Date().toISOString(),
session_id: client.getCurrentSession()?.id
});
});
// Example: Track user interactions
client.registerEventEmitter('user_interaction', (interaction) => {
mixpanel.track('Voxket User Interaction', {
interaction_type: interaction.type,
interaction_data: interaction.data,
user_id: getCurrentUserId()
});
});
```
#### **Workflow Automation**
```typescript
// Trigger business workflows
client.registerEventEmitter('workflow_trigger', (workflowData) => {
switch (workflowData.workflow_type) {
case 'lead_qualification':
triggerLeadQualificationWorkflow(workflowData.lead_data);
break;
case 'support_escalation':
escalateToHumanAgent(workflowData.ticket_data);
break;
case 'appointment_booking':
processAppointmentRequest(workflowData.appointment_data);
break;
}
});
```
### 💬 **Chat & Messaging Events**
```javascript
client.on('chat.message.received', (message) => {
console.log('💬 New message:', message);
displayMessage(message);
});
client.on('chat.message.sent', (message) => {
console.log('📤 Message sent:', message);
logOutgoingMessage(message);
});
client.on('transcription.received', (transcription) => {
console.log('🎤 Voice transcription:', transcription);
displayTranscription(transcription);
});
```
---
## 📝 **Rich Content & Markdown Support**
The Voxket SDK automatically detects and renders rich content in chat messages, including **GitHub Flavored Markdown (GFM)** with full support for tables, links, code blocks, and more.
### ✨ **Supported Markdown Features**
#### 📋 **Tables with Embedded Links**
Agent messages can include formatted tables with clickable links embedded within table cells:
```markdown
| CRA Partner | Registration Link | Description |
|-------------|-------------------|-------------|
| **CAMS** | [Click here to register](https://app.camsnps.in/register) | Computer Age Management Services |
| **KFintech** | [Register now](https://kfintech.com/register) | Widely used platform |
```
**Renders as:**
| CRA Partner | Registration Link | Description |
|-------------|-------------------|-------------|
| **CAMS** | [Click here to register](https://app.camsnps.in/register) | Computer Age Management Services |
| **KFintech** | [Register now](https://kfintech.com/register) | Widely used platform |
#### 🔗 **Links**
```markdown
Check out [Voxket AI](https://voxket.ai) for more information!
Visit https://voxket.ai (auto-linked)
```
**Features:**
- ✅ Embedded links in text: `[text](url)`
- ✅ Auto-detection of bare URLs
- ✅ External link icon indicator
- ✅ Opens in new tab with `target="_blank"`
- ✅ Proper security with `rel="noopener noreferrer"`
#### 📋 **Lists**
```markdown
**Unordered Lists:**
- Item one
- Item two
- Nested item
- Another nested item
**Ordered Lists:**
1. First step
2. Second step
3. Third step
```
#### 💻 **Code Blocks**
````markdown
Inline code: `const greeting = "Hello"`
```javascript
// Syntax-highlighted code block
function greet(name) {
return `Hello, ${name}!`;
}
```
````
**Features:**
- ✅ Syntax highlighting for 180+ languages
- ✅ Inline code with backticks
- ✅ Multi-line code blocks with language specification
- ✅ Theme-aware styling (dark/light modes)
#### 📐 **Headings & Formatting**
```markdown
# Heading 1
## Heading 2
### Heading 3
**Bold text**
*Italic text*
~~Strikethrough~~
> Blockquote for important information
```
#### 🖼️ **Images**
```markdown

```
**Features:**
- ✅ Automatic lazy loading
- ✅ Responsive sizing
- ✅ Rounded corners with shadow
---
### 🎨 **Theming for Rich Content**
All markdown elements automatically adapt to your chosen theme:
```tsx
<VoxketWidget
theme="dark" // Markdown content uses dark theme styling
// ... other props
/>
```
**Theme Support:**
- 🌙 **Dark Mode:** Light text on dark backgrounds, blue links
- ☀️ **Light Mode:** Dark text on light backgrounds, darker blue links
- 💎 **Custom Themes:** Markdown inherits your custom theme colors
---
### 🤖 **Agent-Side Markdown**
For AI agents to send markdown content, simply return markdown-formatted text in the agent's response:
**Example Agent Response:**
```json
{
"type": "text",
"content": "Here's the information you requested:\n\n| Feature | Status |\n|---------|--------|\n| Voice | ✅ Available |\n| Chat | ✅ Available |\n\nFor more details, visit [our docs](https://docs.voxket.ai)."
}
```
The SDK will **automatically detect** markdown patterns and render them appropriately!
---
### 🔍 **Automatic Detection**
The SDK intelligently detects markdown content using multiple strategies:
- ✅ Explicit metadata: `{ metadata: { format: 'markdown' } }`
- ✅ Pattern matching: Headers, lists, tables, code blocks, links
- ✅ Structure analysis: README-like content, multiple sections
- ✅ Fallback: Plain text with auto-linked URLs
**No configuration needed** - it just works!
---
### 🤖 **Agent State Events**
```javascript
client.on('agent.thinking', () => {
showTypingIndicator();
});
client.on('agent.speaking', () => {
showSpeakingIndicator();
});
client.on('agent.connected', () => {
console.log('🤖 Agent joined the conversation');
});
```
### 🎵 **Media Events**
```javascript
client.on('track.muted', ({ source, enabled }) => {
console.log(`🔇 ${source} muted:`, !enabled);
});
client.on('track.unmuted', ({ source, enabled }) => {
console.log(`🔊 ${source} unmuted:`, enabled);
});
```
## 🎛️ **Media Controls**
### 🎤 **Microphone Control**
```javascript
// Toggle microphone
await client.toggleMicrophone();
// Explicit control
await client.setMicrophoneEnabled(true); // Unmute
await client.setMicrophoneEnabled(false); // Mute
// Check current state
const isMuted = !client.isMicrophoneEnabled;
```
### 📷 **Camera Control**
```javascript
// Toggle camera
await client.toggleCamera();
// Explicit control
await client.enableCamera();
await client.disableCamera();
// Check current state
const isCameraOn = client.isCameraEnabled;
```
### 📺 **Screen Sharing**
```javascript
// Start screen share
await client.startScreenShare();
// Stop screen share
await client.stopScreenShare();
// Check if screen sharing is active
const isSharing = client.isScreenShareEnabled;
```
### 🎧 **Device Management**
```javascript
// Get available devices
const audioDevices = await client.getAudioInputDevices();
const videoDevices = await client.getVideoInputDevices();
// Switch devices
await client.setAudioInputDevice(deviceId);
await client.setVideoInputDevice(deviceId);
```
## 💼 **Business Integration Examples**
### 🛒 **E-commerce Customer Support**
```javascript
const supportClient = new VoxketClient({
appId: "ecommerce-app",
appSecret: "your-secret",
baseUrl: "https://api.voxket.com",
agentId: "customer-support",
onMessageReceived: (message) => {
// Log customer interactions
analytics.track('customer_support_message', {
content: message.content,
timestamp: message.timestamp
});
}
});
// Add to product pages
document.getElementById('help-button').onclick = async () => {
await supportClient.connect();
supportClient.renderUI({
target: '#support-widget',
modality: ['chat'],
theme: 'light',
displayType: 'popup',
popupPosition: 'bottom-right'
});
};
```
### 🏥 **Healthcare Patient Portal**
```javascript
const healthcareClient = new VoxketClient({
appId: "healthcare-portal",
appSecret: "hipaa-compliant-secret",
baseUrl: "https://secure.voxket.com",
agentId: "patient-support",
participantName: getCurrentPatient().name,
onSessionStart: (sessionId) => {
// HIPAA-compliant logging
auditLogger.log({
event: 'patient_session_started',
sessionId,
patientId: getCurrentPatient().id,
timestamp: new Date()
});
}
});
// Secure patient communications
await healthcareClient.connect();
healthcareClient.renderUI({
target: '#patient-support',
modality: ['chat'], // Text-only for security
theme: 'light'
});
```
### 💰 **Financial Services**
```javascript
const financeClient = new VoxketClient({
appId: "banking-app",
appSecret: "secure-secret",
baseUrl: "https://secure-api.voxket.com",
agentId: "financial-advisor",
onSessionStart: (sessionId) => {
// Compliance logging
complianceLogger.record({
type: 'customer_interaction_start',
sessionId,
customerId: getCurrentCustomer().id
});
}
});
// Financial consultation widget
await financeClient.connect();
financeClient.renderUI({
target: '#advisor-chat',
modality: ['voice', 'video'],
theme: 'dark',
displayType: 'fullscreen'
});
```
## 🛠️ **Advanced Usage**
### 🔄 **Session Management**
```javascript
// Start a session with specific configuration
const session = await client.startSession("agent-id", {
participantName: "John Doe",
modalities: ['voice', 'chat'],
metadata: {
customerType: "premium",
department: "support"
}
});
// Get current session
const currentSession = client.getCurrentSession();
// End session manually
await client.endSession();
```
### 📊 **Custom Analytics Integration**
```javascript
client.on('session.created', (session) => {
analytics.track('voxket_session_created', {
sessionId: session.id,
agentId: session.agentId,
modalities: session.activeModalities
});
});
client.on('chat.message.received', (message) => {
analytics.track('voxket_message_received', {
messageType: message.sender.type,
contentLength: message.content.length,
sessionId: client.getCurrentSession()?.id
});
});
```
### 🔌 **Multiple Widget Instances**
```javascript
// Support chat
const supportClient = new VoxketClient(supportConfig);
supportClient.renderUI({
target: '#support-widget',
modality: ['chat']
});
// Sales call
const salesClient = new VoxketClient(salesConfig);
salesClient.renderUI({
target: '#sales-widget',
modality: ['voice', 'video']
});
```
## 🎯 **HTML/Vanilla JavaScript Integration**
Use the SDK without any framework:
```html
<!DOCTYPE html>
<html>
<head>
<title>Voxket Integration</title>
<script src="https://unpkg.com/@voxket-ai/voxket-live@latest/dist/index.js"></script>
</head>
<body>
<div id="voxket-container"></div>
<script>
const { VoxketClient } = window.VoxketLive;
const client = new VoxketClient({
appId: 'your-app-id',
appSecret: 'your-secret',
baseUrl: 'https://api.voxket.com',
agentId: 'support-agent'
});
client.connect().then(() => {
client.renderUI({
target: '#voxket-container',
modality: ['chat'],
theme: 'light'
});
});
</script>
</body>
</html>
```
## 🔧 **VoxketClient API Reference**
### 🏗️ **Constructor Options**
```typescript
interface VoxketClientConfig {
// Required
appId: string; // Your Voxket App ID
appSecret: string; // Your Voxket App Secret
baseUrl: string; // Voxket API base URL
// Optional
agentId?: string; // Default agent ID
participantName?: string; // Default participant name
modalities?: SessionModality[]; // Default modalities
debug?: boolean; // Enable debug logging
// Event Callbacks
onConnected?: () => void;
onDisconnected?: (reason?: string) => void;
onError?: (error: Error) => void;
onMessageReceived?: (message: ChatMessage) => void;
onTranscriptionReceived?: (transcription: TranscriptionSegment) => void;
onSessionStateChanged?: (state: SessionState) => void;
}
```
### 📞 **Connection Methods**
```typescript
// Connect to Voxket services
await client.connect(agentId?, participantName?, modalities?);
// Disconnect and cleanup
await client.disconnect();
// Check connection status
const isConnected = client.connected;
const state = client.getConnectionState();
```
### 🎬 **Session Management**
```typescript
// Start a new session
const session = await client.startSession(agentId, {
participantName: "User",
modalities: ['voice', 'chat'],
metadata: { customData: "value" }
});
// Get current session
const current = client.getCurrentSession();
// End current session
await client.endSession();
```
### 🎨 **UI Rendering**
```typescript
// Render UI widget
client.renderUI({
target: '#container', // CSS selector or HTMLElement
modality: ['voice', 'chat'], // Supported modalities
theme: 'dark', // Theme selection
component: 'widget', // Component type
displayType: 'popup', // Display mode
autoStart: true, // Auto-start session
width: '400px', // Custom width
height: '600px', // Custom height
onDisplayTypeChange: (type) => console.log(type)
});
// Remove UI
client.removeUI('#container');
client.removeAllUI();
```
### 💬 **Messaging**
```typescript
// Send text message
await client.sendMessage("Hello agent!");
// Send with metadata
await client.sendChatMessage("Hello", { priority: "high" });
// Send file attachments (images only)
await client.sendAttachment(imageFile);
await client.sendAttachments([file1, file2]);
```
### 🎵 **Media Control Methods**
```typescript
// Microphone control
await client.toggleMicrophone();
await client.setMicrophoneEnabled(true);
const isMuted = !client.isMicrophoneEnabled;
// Camera control
await client.enableCamera();
await client.disableCamera();
await client.toggleCamera();
const isCameraOn = client.isCameraEnabled;
// Screen sharing
await client.startScreenShare();
await client.stopScreenShare();
const isSharing = client.isScreenShareEnabled;
// Device management
const audioDevices = await client.getAudioInputDevices();
const videoDevices = await client.getVideoInputDevices();
await client.setAudioInputDevice(deviceId);
await client.setVideoInputDevice(deviceId);
```
### � **Event System Methods**
```typescript
// Register custom event emitter
client.registerEventEmitter(
topic: string,
handler: (data: string) => void
): void
// Register event listener with cleanup
client.registerEventListener<K extends keyof VoxketEvents>(
eventName: K,
callback: (data: any) => void
): () => void
// Example usage
const unsubscribe = client.registerEventListener('chat.message.received', (msg) => {
console.log('Message:', msg);
});
// Cleanup
unsubscribe();
```
### �👥 **Participant Management**
```typescript
// Get participants
const localParticipant = client.getLocalParticipant();
const remoteParticipants = client.getRemoteParticipants();
const allParticipants = client.getParticipants();
// Check permissions
const permissions = client.getPublishPermissions();
const canPublish = client.canPublishSource('microphone');
// Get media tracks
const micTrack = client.getMicrophoneTrack();
const cameraTrack = client.getCameraTrack();
const screenTrack = client.getScreenShareTrack();
```
## 🎪 **Interactive Components Deep Dive**
### 📝 **Creating Custom Interactive Components**
```typescript
import React, { useState } from 'react';
import { VoxketInteractiveViewProps } from '@voxket-ai/voxket-live';
function SurveyForm({ handler, data }: VoxketInteractiveViewProps) {
const [rating, setRating] = useState(0);
const [feedback, setFeedback] = useState('');
const handleSubmit = () => {
handler?.didSuccess({
survey_rating: rating,
customer_feedback: feedback,
submitted_at: new Date().toISOString()
});
};
const handleSkip = () => {
handler?.dismissView(); // Sends decline response to agent
};
return (
<div className="p-6 bg-white rounded-lg shadow-lg">
<h3 className="text-lg font-semibold mb-4">
{data?.title || 'Rate Your Experience'}
</h3>
<div className="mb-4">
<label className="block text-sm font-medium mb-2">
How would you rate our service?
</label>
<div className="flex gap-2">
{[1,2,3,4,5].map(num => (
<button
key={num}
onClick={() => setRating(num)}
className={`w-10 h-10 rounded ${
rating >= num ? 'bg-blue-500 text-white' : 'bg-gray-200'
}`}
>
{num}
</button>
))}
</div>
</div>
<div className="mb-4">
<label className="block text-sm font-medium mb-2">
Additional feedback (optional):
</label>
<textarea
value={feedback}
onChange={(e) => setFeedback(e.target.value)}
className="w-full p-2 border rounded"
rows={3}
/>
</div>
<div className="flex gap-2 justify-end">
<button
onClick={handleSkip}
className="px-4 py-2 text-gray-600 hover:bg-gray-100 rounded"
>
Skip
</button>
<button
onClick={handleSubmit}
disabled={rating === 0}
className="px-4 py-2 bg-blue-500 text-white rounded disabled:opacity-50"
>
Submit
</button>
</div>
</div>
);
}
// Register the component
await client.registerFrontendRPC(
'customer_satisfaction_survey',
SurveyForm,
'modal' // Can be 'embedded', 'modal', or 'fullscreen'
);
```
### 🛒 **E-commerce Product Showcase**
```typescript
function ProductCatalog({ handler, data }: VoxketInteractiveViewProps) {
const [selectedProduct, setSelectedProduct] = useState(null);
const products = data?.products || [];
const handleSelectProduct = (product: any) => {
handler?.didSuccess({
selected_product: product,
action: 'add_to_cart'
});
};
return (
<div className="p-4">
<h3 className="text-xl font-bold mb-4">Recommended Products</h3>
<div className="grid grid-cols-2 gap-4">
{products.map((product: any) => (
<div key={product.id} className="border rounded-lg p-4">
<img
src={product.image}
alt={product.name}
className="w-full h-32 object-cover rounded mb-2"
/>
<h4 className="font-semibold">{product.name}</h4>
<p className="text-gray-600">${product.price}</p>
<button
onClick={() => handleSelectProduct(product)}
className="mt-2 w-full bg-blue-500 text-white py-2 rounded"
>
Add to Cart
</button>
</div>
))}
</div>
</div>
);
}
```
### 📅 **Appointment Scheduler**
```typescript
function AppointmentBooker({ handler, data }: VoxketInteractiveViewProps) {
const [selectedSlot, setSelectedSlot] = useState('');
const [contactInfo, setContactInfo] = useState({ name: '', email: '' });
const availableSlots = data?.available_slots || [];
const handleBooking = () => {
handler?.didSuccess({
appointment: {
slot: selectedSlot,
contact: contactInfo,
type: data?.appointment_type,
booked_at: new Date().toISOString()
}
});
};
return (
<div className="p-6 bg-white rounded-lg">
<h3 className="text-lg font-semibold mb-4">Book Appointment</h3>
<div className="mb-4">
<label className="block text-sm font-medium mb-2">
Available Time Slots:
</label>
<div className="grid grid-cols-2 gap-2">
{availableSlots.map((slot: string) => (
<button
key={slot}
onClick={() => setSelectedSlot(slot)}
className={`p-2 rounded border ${
selectedSlot === slot
? 'bg-blue-500 text-white'
: 'bg-gray-50 hover:bg-gray-100'
}`}
>
{slot}
</button>
))}
</div>
</div>
<div className="mb-4">
<input
type="text"
placeholder="Your Name"
value={contactInfo.name}
onChange={(e) => setContactInfo({...contactInfo, name: e.target.value})}
className="w-full p-2 border rounded mb-2"
/>
<input
type="email"
placeholder="Email Address"
value={contactInfo.email}
onChange={(e) => setContactInfo({...contactInfo, email: e.target.value})}
className="w-full p-2 border rounded"
/>
</div>
<button
onClick={handleBooking}
disabled={!selectedSlot || !contactInfo.name || !contactInfo.email}
className="w-full bg-green-500 text-white py-2 rounded disabled:opacity-50"
>
Book Appointment
</button>
</div>
);
}
```
## 📊 **Session Analytics & Metrics**
### 📈 **Session Metrics Interface**
```typescript
interface SessionMetrics {
sessionId: string;
startTime: Date;
endTime?: Date;
duration?: number; // Duration in milliseconds
totalMessages: number; // Total messages exchanged
connectionIssues: number; // Network issues count
participantCount: number; // Number of participants
events: SessionLog[]; // All session events
}
interface SessionLog {
timestamp: Date;
event: string; // Event type
data?: any; // Event data
sessionId?: string; // Associated session
participantId?: string; // Participant who triggered event
}
```
### 📊 **Analytics Integration Examples**
```typescript
// Google Analytics 4
client.on('session.created', (session) => {
gtag('event', 'voxket_session_start', {
session_id: session.id,
agent_id: session.agentId,
modalities: session.activeModalities.join(',')
});
});
// Mixpanel
client.on('chat.message.received', (message) => {
mixpanel.track('Voxket Message Received', {
session_id: client.getCurrentSession()?.id,
message_type: message.sender.type,
message_length: message.content.length,
timestamp: message.timestamp
});
});
// Custom Analytics
const analyticsTracker = {
trackSession: (event: string, data: any) => {
fetch('/api/analytics', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ event, data, timestamp: new Date() })
});
}
};
client.on('session.ended', (session, metrics) => {
analyticsTracker.trackSession('session_completed', {
duration: metrics.duration,
message_count: metrics.totalMessages,
quality_score: calculateQualityScore(metrics)
});
});
```
## 🛠️ **Enterprise Features**
### 🔐 **Security & Compliance**
```typescript
// HIPAA-compliant configuration
const healthcareClient = new VoxketClient({
appId: "healthcare-app",
appSecret: "hipaa-compliant-secret",
baseUrl: "https://secure-api.voxket.com",
agentId: "patient-support",
// Disable session logging for compliance
enableSessionLogging: false,
onSessionStart: (sessionId) => {
// HIPAA audit logging
complianceLogger.logPatientInteraction({
sessionId,
patientId: getCurrentPatient().id,
timestamp: new Date(),
actionType: 'SESSION_START'
});
}
});
// Only use secure text-based modalities
await healthcareClient.connect();
healthcareClient.renderUI({
modality: ['chat'], // Text only for security
theme: 'light',
enableSessionLogging: false
});
```
### 🏢 **Multi-tenant Architecture**
```typescript
class TenantManager {
private clients: Map<string, VoxketClient> = new Map();
async createTenantClient(tenantId: string, config: any) {
const client = new VoxketClient({
appId: config.appId,
appSecret: config.appSecret,
baseUrl: config.baseUrl,
agentId: `${tenantId}-agent`,
onMessageReceived: (message) => {
// Tenant-specific message handling
this.handleTenantMessage(tenantId, message);
}
});
this.clients.set(tenantId, client);
return client;
}
getTenantClient(tenantId: string) {
return this.clients.get(tenantId);
}
private handleTenantMessage(tenantId: string, message: any) {
// Tenant-specific analytics, logging, etc.
console.log(`Tenant ${tenantId} received message:`, message);
}
}
// Usage
const tenantManager = new TenantManager();
const client = await tenantManager.createTenantClient('acme-corp', {
appId: 'acme-app-id',
appSecret: 'acme-secret',
baseUrl: 'https://acme.voxket.com'
});
```
### 🔄 **Advanced Session Management**
```typescript
// Session persistence across page reloads
class SessionManager {
private static SESSION_KEY = 'voxket_session';
static saveSession(session: VoxketSession) {
localStorage.setItem(this.SESSION_KEY, JSON.stringify({
id: session.id,
agentId: session.agentId,
startedAt: session.startedAt,
metadata: session.metadata
}));
}
static restoreSession(): VoxketSession | null {
const saved = localStorage.getItem(this.SESSION_KEY);
if (saved) {
try {
return JSON.parse(saved);
} catch {
return null;
}
}
return null;
}
static clearSession() {
localStorage.removeItem(this.SESSION_KEY);
}
}
// Restore previous session on page load
const client = new VoxketClient(config);
const previousSession = SessionManager.restoreSession();
if (previousSession) {
// Attempt to reconnect to existing session
try {
await client.connect();
// Check if session is still valid and restore UI state
} catch (error) {
SessionManager.clearSession();
// Start fresh session
}
}
```
## 🔧 **Troubleshooting**
### ❌ **Common Issues**
#### **1. Widget Not Displaying**
```typescript
// Check console for errors and verify configuration
const client = new VoxketClient({
appId: "your-app-id", // ✅ Make sure this is correct
appSecret: "your-app-secret", // ✅ Make sure this is correct
baseUrl: "https://api.voxket.com", // ✅ Check URL is correct
debug: true // ✅ Enable debug logging
});
```
#### **2. Connection Failures**
```typescript
client.on('connection.error', (error) => {
console.error('Connection failed:', error);
// Common fixes:
// - Verify appId and appSecret are correct
// - Check baseUrl is accessible
// - Ensure network connectivity
// - Check for CORS issues in browser console
});
client.on('connection.disconnected', (reason) => {
console.log('Disconnected reason:', reason);
// Auto-reconnect logic
setTimeout(() => {
client.connect().catch(console.error);
}, 5000);
});
```
#### **3. Microphone/Camera Permission Issues**
```typescript
// Handle permission errors gracefully
client.on('connection.error', (error) => {
if (error.code === 'PERMISSION_DENIED') {
showUserMessage('Please allow microphone/camera access to continue');
}
});
// Request permissions explicitly
navigator.mediaDevices.getUserMedia({
audio: true,
video: true
}).then(() => {
console.log('Permissions granted');
}).catch((error) => {
console.error('Permission denied:', error);
});
```
#### **4. React Strict Mode Issues**
```typescript
// For React 18 Strict Mode, wrap your app properly
function App() {
const [client, setClient] = useState<VoxketClient | null>(null);
useEffect(() => {
// Only create client once
if (!client) {
const newClient = new VoxketClient(config);
setClient(newClient);
}
return () => {
// Cleanup on unmount
client?.disconnect();
};
}, []);
if (!client) return <div>Loading...</div>;
return <VoxketWidget voxketClient={client} {...props} />;
}
```
### 🐛 **Debug Mode**
```typescript
// Enable comprehensive debugging
const client = new VoxketClient({
// ... config
debug: true
});
// Monitor all events
client.onAny((eventName, ...args) => {
console.log(`🔍 Event: ${eventName}`, args);
});
// Check connection state
console.log('Connection state:', client.getConnectionState());
console.log('Current session:', client.getCurrentSession());
console.log('Is connected:', client.connected);
```
### 🛠️ **Performance Optimization**
```typescript
// Optimize for production
const client = new VoxketClient({
// ... config
debug: false, // Disable debug logs
});
// Lazy load the widget
const LazyVoxketWidget = lazy(() => import('@voxket-ai/voxket-live'));
function App() {
return (
<Suspense fallback={<div>Loading chat...</div>}>
<LazyVoxketWidget {...props} />
</Suspense>
);
}
// Preload on user interaction
const preloadChat = () => {
import('@voxket-ai/voxket-live').then(() => {
console.log('Voxket SDK preloaded');
});
};
// Call preloadChat() on hover or focus events
```
## 🎯 **Best Practices**
### 🏗️ **Application Architecture**
#### **1. Client Instance Management**
```typescript
// ✅ Good: Single client instance
class VoxketManager {
private static instance: VoxketClient | null = null;
static getInstance(config: VoxketClientConfig): VoxketClient {
if (!this.instance) {
this.instance = new VoxketClient(config);
}
return this.instance;
}
static cleanup() {
if (this.instance) {
this.instance.disconnect();
this.instance = null;
}
}
}
// ❌ Bad: Multiple client instances
function BadComponent() {
const [client] = useState(() => new VoxketClient(config)); // Creates new client each render
}
```
#### **2. Error Handling**
```typescript
// ✅ Comprehensive error handling
async function initializeVoxket() {
try {
await client.connect();
client.renderUI({ target: '#voxket-widget' });
} catch (error) {
if (error.code === 'AUTHENTICATION_FAILED') {
showError('Invalid credentials');
} else if (error.code === 'NETWORK_ERROR') {
showError('Connection failed - please try again');
} else {
showError('Something went wrong');
}
// Log for debugging
console.error('Voxket initialization failed:', error);
}
}
```
#### **3. Event Cleanup**
```typescript
// ✅ Always cleanup event listeners
useEffect(() => {
const handleMessage = (message: ChatMessage) => {
// Handle message
};
client.on('chat.message.received', handleMessage);
return () => {
client.off('chat.message.received', handleMessage);
};
}, [client]);
```
### 📱 **User Experience**
#### **1. Loading States**
```typescript
function ChatWidget() {
const [isConnecting, setIsConnecting] = useState(false);
const [connectionError, setConnectionError] = useState('');
const initChat = async () => {
setIsConnecting(true);
setConnectionError('');
try {
await client.connect();
client.renderUI({ target: '#chat' });
} catch (error) {
setConnectionError('Failed to connect. Please try again.');
} finally {
setIsConnecting(false);
}
};
return (
<div>
{isConnecting && <div>Connecting to support...</div>}
{connectionError && <div className="error">{connectionError}</div>}
<button onClick={initChat} disabled={isConnecting}>
Start Chat
</button>
<div id="chat"></div>
</div>
);
}
```
#### **2. Progressive Enhancement**
```typescript
// Start with basic features, enhance based on capabilities
const client = new VoxketClient(config);
// Check agent capabilities
const agentInfo = client.getCurrentAgentInfo();
const supportedModalities = agentInfo?.modality_supported || ['chat'];
// Render appropriate UI
client.renderUI({
modality: supportedModalities.includes('voice')
? ['voice', 'chat']
: ['chat'],
theme: userPreferences.theme || 'vox'
});
```
#### **3. Accessibility**
```typescript
// Ensure keyboard navigation and screen reader support
<VoxketWidget
className="voxket-accessible"
// Widget automatically includes ARIA labels and keyboard support
{...props}
/>
/* CSS for better accessibility */
.voxket-accessible {
/* Ensure focus indicators are visible */
--focus-ring-color: #3b82f6;
}
.voxket-accessible *:focus {
outline: 2px solid var(--focus-ring-color);
outline-offset: 2px;
}
```
### 🔒 **Security**
#### **1. Credential Management**
```typescript
// ✅ Use environment variables
const client = new VoxketClient({
appId: process.env.VOXKET_APP_ID,
appSecret: process.env.VOXKET_APP_SECRET,
baseUrl: process.env.VOXKET_BASE_URL
});
// ✅ For browser apps, use backend proxy
async function getVoxketCredentials() {
const response = await fetch('/api/voxket-auth', {
headers: {
'Authorization': `Bearer ${userToken}`
}
});
return response.json();
}
```
#### **2. Content Security Policy**
```html
<!-- Add CSP headers for security -->
<meta http-equiv="Content-Security-Policy"
content="connect-src 'self' wss://*.voxket.com https://*.voxket.com;">
```
## 🌐 **Framework Integration Examples**
### ⚛️ **React with TypeScript**
```typescript
import React, { useCallback, useEffect, useState } from 'react';
import VoxketWidget, {
VoxketWidgetProps,
VoxketClient,
SessionMetrics
} from '@voxket-ai/voxket-live';
interface Props {
agentId: string;
userId: string;
userRole: 'customer' | 'admin';
}
export function CustomerSupport({ agentId, userId, userRole }: Props) {
const [sessionMetrics, setSessionMetrics] = useState<SessionMetrics | null>(null);
const [isActive, setIsActive] = useState(false);
const handleSessionStart = useCallback((sessionId: string) => {
setIsActive(true);
console.log('Support session started:', sessionId);
}, []);
const handleSessionEnd = useCallback((metrics: SessionMetrics) => {
setSessionMetrics(metrics);
setIsActive(false);
console.log('Session ended:', metrics);
}, []);
const widgetProps: VoxketWidgetProps = {
agentId,
baseUrl: process.env.NEXT_PUBLIC_VOXKET_BASE_URL!,
appId: process.env.NEXT_PUBLIC_VOXKET_APP_ID!,
appSecret: process.env.NEXT_PUBLIC_VOXKET_APP_SECRET!,
participantName: `User-${userId}`,
theme: 'vox',
modalities: ['chat', 'voice'],
displayType: 'popup',
popupPosition: 'bottom-right',
onSessionStart: handleSessionStart,
onSessionEnd: handleSessionEnd
};
return (
<div className="customer-support">
{isActive && (
<div className="status-indicator">
🟢 Support session active
</div>
)}
<VoxketWidget {...widgetProps} />
{sessionMetrics && (
<div className="session-summary">
<h4>Session Summary</h4>
<p>Duration: {Math.round(sessionMetrics.duration! / 1000)}s</p>
<p>Messages: {sessionMetrics.totalMessages}</p>
</div>
)}
</div>
);
}
```
### 🖖 **Vue 3 Composition API**
```typescript
<template>
<div class="vue-voxket">
<button @click="initializeChat" :disabled="isLoading">
Start Support Chat
</button>
<div ref="voxketContainer" class="voxket-container"></div>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue';
import { VoxketClient } from '@voxket-ai/voxket-live';
const voxketContainer = ref<HTMLElement>();
const isLoading = ref(false);
let client: VoxketClient | null = null;
const initializeChat = async () => {
if (!client || !voxketContainer.value) return;
isLoading.value = true;
try {
await client.connect();
client.renderUI({
target: voxketContainer.value,
modality: ['chat'],
theme: 'light',
autoStart: true
});
} catch (error) {
console.error('Failed to initialize chat:', error);
} finally {
isLoading.value = false;
}
};
onMounted(() => {
client = new VoxketClient({
appId: import.meta.env.VITE_VOXKET_APP_ID,
appSecret: import.meta.env.VITE_VOXKET_APP_SECRET,
baseUrl: import.meta.env.VITE_VOXKET_BASE_URL,
agentId: 'vue-support-agent'
});
});
onUnmounted(() => {
if (client) {
client.removeAllUI();
client.disconnect();
}
});
</script>
```
### 🅰️ **Angular Component**
```typescript
// voxket.service.ts
import { Injectable } from '@angular/core';
import { VoxketClient } from '@voxket-ai/voxket-live';
@Injectable({ providedIn: 'root' })
export class VoxketService {
private client: VoxketClient;
constructor() {
this.client = new VoxketClient({
appId: environment.voxketAppId,
appSecret: environment.voxketAppSecret,
baseUrl: environment.voxketBaseUrl
});
}
async startChat(containerId: string, agentId: string) {
await this.client.connect();
this.client.renderUI({
target: `#${containerId}`,
agentId,
modality: ['chat'],
theme: 'dark'
});
}
dis