UNPKG

@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
# 🎯 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. [![NPM Version](https://img.shields.io/npm/v/@voxket-ai/voxket-live)](https://www.npmjs.com/package/@voxket-ai/voxket-live) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![TypeScript](https://img.shields.io/badge/%3C%2F%3E-TypeScript-%230074c1.svg)](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 ![Alt text](https://example.com/image.png) ``` **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