UNPKG

@spectrumsense/spectrum-chat-dev

Version:

Embeddable AI Widget - Add trusted, evidence-based answers directly to your website. Simple installation, enterprise-grade security.

916 lines (670 loc) 20.9 kB
# Spectrum Chat API Reference **Version:** 1.0 **Last Updated:** October 6, 2025 --- ## Table of Contents 1. [Widget Configuration](#widget-configuration) 2. [Custom Element API](#custom-element-api) 3. [Global Mode API](#global-mode-api) 4. [Security Functions](#security-functions) 5. [Event System](#event-system) 6. [Storage Keys](#storage-keys) 7. [Error Types](#error-types) 8. [TypeScript Definitions](#typescript-definitions) --- ## Widget Configuration ### Configuration Options All configuration options work in both custom element (as attributes) and global mode (as properties). #### Required Options | Option | Type | Description | Example | |--------|------|-------------|---------| | `api-url` / `apiUrl` | `string` | API endpoint URL | `https://api.example.com/api/v1/conversations` | | `site-key` / `siteKey` | `string` | Public site key for origin validation | `pub_customer_a1b2c3d4` | #### Security Options | Option | Type | Default | Description | |--------|------|---------|-------------| | `use-jwt` / `useJWT` | `boolean` | `false` | Enable JWT session tokens (Phase 1) | | `tenant-id` / `tenantId` | `string` | Optional | Legacy tenant ID (backward compatibility) | #### Feature Options | Option | Type | Default | Description | |--------|------|---------|-------------| | `citations` / `enableCitations` | `boolean` | `true` | Include source citations in responses | | `title` | `string` | `'AI Assistant'` | Widget header title | | `intro-text` / `introText` | `string` | Default message | Welcome message displayed on first open | | `show-intro` / `showIntro` | `boolean` | `true` | Show intro message on first open | #### Styling Options | Option | Type | Default | Description | |--------|------|---------|-------------| | `primary-color` / `primaryColor` | `string` | `hsl(220 15% 25%)` | Primary theme color (header, buttons) | | `user-color` / `userColor` | `string` | `hsl(220 15% 45%)` | User message bubble color | | `ai-color` / `aiColor` | `string` | `hsl(220 15% 25%)` | AI message bubble color | | `fab-icon` / `fabIcon` | `string` | `'✦'` | Floating action button icon (emoji or text) | | `fab-color` / `fabColor` | `string` | `hsl(220 15% 25%)` | FAB background color | | `position` | `string` | `'bottom-right'` | Widget position (`bottom-right`, `bottom-left`, `top-right`, `top-left`) | | `width` | `string` | `'320px'` | Widget panel width | | `height` | `string` | `'350px'` | Widget panel height | | `panel-border-radius` / `panelBorderRadius` | `string` | `'1rem'` | Border radius of widget panel | | `panel-shadow` / `panelShadow` | `string` | Default shadow | Box shadow for widget panel | #### Advanced Options | Option | Type | Default | Description | |--------|------|---------|-------------| | `debug` | `boolean` | `false` | Enable debug console logging | | `max-messages` / `maxMessages` | `number` | `100` | Maximum messages in browser storage | | `browser-storage` / `browserStorage` | `boolean` | `false` | Use DeepChat's browser storage | | `custom-styles` / `customStyles` | `string` | `'{}'` | JSON string of custom DeepChat styles | | `enable-response-interceptor` / `enableResponseInterceptor` | `boolean` | `true` | Enable response processing (citations, etc.) | --- ## Custom Element API ### Basic Usage ```html <spectrum-chat api-url="https://api.example.com/api/v1/conversations" site-key="pub_customer_a1b2c3d4" title="Help Center"> </spectrum-chat> ``` ### Methods #### `open()` Opens the chat widget panel. ```javascript const widget = document.querySelector('spectrum-chat'); widget.open(); ``` #### `close()` Closes the chat widget panel. ```javascript const widget = document.querySelector('spectrum-chat'); widget.close(); ``` #### `isChatOpen()` Returns whether the chat panel is currently open. **Returns:** `boolean` ```javascript const widget = document.querySelector('spectrum-chat'); console.log(widget.isChatOpen()); // true or false ``` #### `updateConfig(newConfig)` Updates widget configuration dynamically. **Parameters:** - `newConfig` (object): New configuration values ```javascript const widget = document.querySelector('spectrum-chat'); widget.updateConfig({ title: 'Customer Support', primaryColor: '#2563eb' }); ``` #### `refreshStyles()` Refreshes message bubble styles (useful after color changes). ```javascript const widget = document.querySelector('spectrum-chat'); widget.refreshStyles(); ``` #### `hideIntro()` Manually hides the intro message. ```javascript const widget = document.querySelector('spectrum-chat'); widget.hideIntro(); ``` ### Events #### `spectrum-chat-opened` Fired when the chat panel is opened. ```javascript const widget = document.querySelector('spectrum-chat'); widget.addEventListener('spectrum-chat-opened', (event) => { console.log('Chat opened!'); }); ``` #### `spectrum-chat-closed` Fired when the chat panel is closed. ```javascript const widget = document.querySelector('spectrum-chat'); widget.addEventListener('spectrum-chat-closed', (event) => { console.log('Chat closed!'); }); ``` --- ## Global Mode API ### Basic Usage ```javascript window.SpectrumChatConfig = { apiUrl: 'https://api.example.com/api/v1/conversations', siteKey: 'pub_customer_a1b2c3d4', useJWT: true, title: 'Help Center' }; ``` ### `SpectrumChatGlobal` Object The global API is available at `window.SpectrumChatGlobal`. ### Configuration Methods #### `getConfig()` Gets current widget configuration. **Returns:** `object` - Current configuration ```javascript const config = SpectrumChatGlobal.getConfig(); console.log(config); ``` #### `updateConfig(newConfig)` Updates widget configuration and reinitializes if needed. **Parameters:** - `newConfig` (object): New configuration values ```javascript SpectrumChatGlobal.updateConfig({ title: 'Customer Support', primaryColor: '#2563eb', useJWT: true }); ``` ### Widget Control Methods #### `open()` Opens the chat widget panel. ```javascript SpectrumChatGlobal.open(); ``` #### `close()` Closes the chat widget panel. ```javascript SpectrumChatGlobal.close(); ``` #### `isOpen()` Returns whether the chat panel is currently open. **Returns:** `boolean` ```javascript console.log(SpectrumChatGlobal.isOpen()); // true or false ``` #### `getWidget()` Gets the DOM element of the widget. **Returns:** `HTMLElement | null` ```javascript const widgetElement = SpectrumChatGlobal.getWidget(); console.log(widgetElement); ``` ### Session Management Methods #### `getConversationId()` Gets the current conversation ID. **Returns:** `string | null` ```javascript const conversationId = SpectrumChatGlobal.getConversationId(); console.log('Conversation ID:', conversationId); // "c_abc123..." ``` #### `getSessionId()` Gets the current JWT session ID (Phase 1 only). **Returns:** `string | null` ```javascript const sessionId = SpectrumChatGlobal.getSessionId(); console.log('Session ID:', sessionId); // "550e8400-e29b..." ``` #### `getTokenData()` Gets the complete JWT token data (Phase 1 only). **Returns:** `object | null` ```javascript const tokenData = SpectrumChatGlobal.getTokenData(); console.log(tokenData); // { // token: "eyJhbGciOiJI...", // session_id: "550e8400-e29b...", // expires_at: "2025-10-06T13:00:00Z" // } ``` #### `isTokenValid()` Checks if the current JWT token is valid (Phase 1 only). **Returns:** `boolean` ```javascript const isValid = SpectrumChatGlobal.isTokenValid(); console.log('Token valid:', isValid); // true or false ``` #### `initializeSession()` Manually initializes or refreshes the JWT session (Phase 1 only). **Returns:** `Promise<object | null>` ```javascript try { const tokenData = await SpectrumChatGlobal.initializeSession(); console.log('Session initialized:', tokenData); } catch (error) { console.error('Failed to initialize session:', error); } ``` #### `clearSession()` Clears the current session (conversation ID, JWT token, and messages). ```javascript SpectrumChatGlobal.clearSession(); console.log('Session cleared'); ``` ### Lifecycle Methods #### `reinitialize()` Reinitializes the entire widget (removes and recreates). ```javascript SpectrumChatGlobal.reinitialize(); ``` --- ## Security Functions These functions are used internally but can be accessed for advanced use cases. ### `hashPageUrl()` Generates SHA256 hash of current page URL. **Returns:** `Promise<string>` ```javascript const hash = await hashPageUrl(); console.log('Page URL hash:', hash); ``` ### `generateNonce()` Generates a UUID v4 nonce for request tracking. **Returns:** `string` ```javascript const nonce = generateNonce(); console.log('Nonce:', nonce); // "550e8400-e29b-41d4-a716-446655440000" ``` ### `isTokenValid(tokenData)` Checks if a JWT token is valid (not expired, with 5-minute buffer). **Parameters:** - `tokenData` (object): Token data with `expires_at` property **Returns:** `boolean` ```javascript const tokenData = { token: "...", session_id: "...", expires_at: "2025-10-06T13:00:00Z" }; const isValid = isTokenValid(tokenData); console.log('Token valid:', isValid); ``` ### `createSession(config)` Creates a new JWT session (Phase 1). **Parameters:** - `config` (object): Configuration with `apiUrl` and `siteKey` **Returns:** `Promise<object>` ```javascript try { const tokenData = await createSession({ apiUrl: 'https://api.example.com/api/v1/conversations', siteKey: 'pub_customer_a1b2c3d4', debug: true }); console.log('Session created:', tokenData); } catch (error) { console.error('Failed to create session:', error); } ``` ### `handleApiError(error)` Translates technical API errors to user-friendly messages. **Parameters:** - `error` (object): Error object or response **Returns:** `object` - Formatted error with `text` and `error` properties ```javascript try { // ... API call } catch (error) { const userError = handleApiError(error); console.log('User message:', userError.text); console.log('Error code:', userError.error); } ``` --- ## Event System ### Custom Element Events Events dispatched by the `<spectrum-chat>` custom element: #### `spectrum-chat-opened` Dispatched when the chat panel opens. ```javascript document.querySelector('spectrum-chat').addEventListener('spectrum-chat-opened', () => { console.log('Chat opened'); // Track analytics // Update UI }); ``` #### `spectrum-chat-closed` Dispatched when the chat panel closes. ```javascript document.querySelector('spectrum-chat').addEventListener('spectrum-chat-closed', () => { console.log('Chat closed'); // Track analytics // Update UI }); ``` ### Global Mode Events Events dispatched on `document` in global mode: #### `spectrum-chat-opened` ```javascript document.addEventListener('spectrum-chat-opened', (event) => { console.log('Chat opened:', event.detail); // event.detail = { isOpen: true } }); ``` #### `spectrum-chat-closed` ```javascript document.addEventListener('spectrum-chat-closed', (event) => { console.log('Chat closed:', event.detail); // event.detail = { isOpen: false } }); ``` ### DeepChat Events The underlying DeepChat component also fires events: #### `message` Fired when user sends a message. ```javascript const widget = document.querySelector('spectrum-chat'); const deepChat = widget.shadowRoot.querySelector('deep-chat'); deepChat.addEventListener('message', (event) => { console.log('User message:', event.detail); }); ``` #### `response` Fired when AI responds. ```javascript deepChat.addEventListener('response', (event) => { console.log('AI response:', event.detail); }); ``` --- ## Storage Keys The widget uses `sessionStorage` (default) or `localStorage` for persistence. ### Storage Keys | Key | Type | Description | |-----|------|-------------| | `spectrum-chat-conversation-id` | `string` | Current conversation ID | | `spectrum-chat-token` | `string` (JSON) | JWT token data (Phase 1 only) | | `spectrum-chat-messages` | `string` (JSON) | Message history (global mode only) | ### Token Data Structure ```javascript { "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "session_id": "550e8400-e29b-41d4-a716-446655440000", "expires_at": "2025-10-06T13:00:00Z" } ``` ### Message Data Structure ```javascript [ { "text": "Hello, how can I help?", "role": "assistant", "timestamp": 1696000000000 }, { "text": "I need help with returns", "role": "user", "timestamp": 1696000005000 } ] ``` ### Accessing Storage ```javascript // Get conversation ID const conversationId = sessionStorage.getItem('spectrum-chat-conversation-id'); // Get token data const tokenDataStr = sessionStorage.getItem('spectrum-chat-token'); const tokenData = tokenDataStr ? JSON.parse(tokenDataStr) : null; // Get messages const messagesStr = sessionStorage.getItem('spectrum-chat-messages'); const messages = messagesStr ? JSON.parse(messagesStr) : []; // Clear storage sessionStorage.removeItem('spectrum-chat-conversation-id'); sessionStorage.removeItem('spectrum-chat-token'); sessionStorage.removeItem('spectrum-chat-messages'); ``` --- ## Error Types ### Error Response Structure ```typescript { text: string; // User-friendly error message role: string; // Always "assistant" error: string; // Error code/type sources?: null; // Always null for errors } ``` ### Error Codes | Error Code | HTTP Status | Description | User Message | |------------|-------------|-------------|--------------| | `network_error` | N/A | Network/connection failure | "Unable to connect to chat service..." | | `origin_not_allowed` | 403 | Domain not in allowed list | "This domain is not authorized..." | | `https_required` | 403 | HTTP used in production | "This chat service requires HTTPS..." | | `origin_mismatch` | 403 | Origin doesn't match conversation | "Session security error..." | | `forbidden` | 403 | Generic forbidden error | "Access denied. Contact support." | | `conversation_expired` | 404 | Conversation not in cache | "Conversation expired. Starting new..." | | `invalid_site_key` | 404 | Site key invalid/disabled | "Chat service is unavailable." | | `token_expired` | 401 | JWT token expired | "Session expired. Please try again." | | `moderation_flagged` | 200 | Content flagged | Custom message from API | | `server_error` | 500+ | Server error | "An error occurred. Try again later." | | `unknown_error` | Any | Unexpected error | "An unexpected error occurred..." | ### Error Handling Example ```javascript // Custom element const widget = document.querySelector('spectrum-chat'); const deepChat = widget.shadowRoot.querySelector('deep-chat'); deepChat.addEventListener('response', (event) => { const response = event.detail; if (response.error) { console.error('Error type:', response.error); console.log('User message:', response.text); // Handle specific errors switch (response.error) { case 'origin_not_allowed': // Contact admin to add domain break; case 'token_expired': // Token will auto-refresh and retry break; case 'conversation_expired': // New conversation will start automatically break; } } }); ``` --- ## TypeScript Definitions ### Configuration Types ```typescript interface SpectrumChatConfig { // Required apiUrl: string; siteKey: string; // Security useJWT?: boolean; tenantId?: string; // Features enableCitations?: boolean; title?: string; introText?: string; showIntro?: boolean; // Styling primaryColor?: string; userColor?: string; aiColor?: string; fabIcon?: string; fabColor?: string; position?: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left'; width?: string; height?: string; panelBorderRadius?: string; panelShadow?: string; // Advanced debug?: boolean; maxMessages?: number; browserStorage?: boolean; customStyles?: string; enableResponseInterceptor?: boolean; } ``` ### Token Data Types ```typescript interface TokenData { token: string; session_id: string; expires_at: string; // ISO 8601 timestamp } ``` ### Response Types ```typescript interface ConversationResponse { text: string; role: 'assistant' | 'user'; conversation_id?: string; sources?: Source[] | null; error?: string | null; } interface Source { index: number; title: string; url: string; } ``` ### Error Response Types ```typescript interface ErrorResponse { text: string; // User-friendly message error: string; // Error code } type ErrorCode = | 'network_error' | 'origin_not_allowed' | 'https_required' | 'origin_mismatch' | 'forbidden' | 'conversation_expired' | 'invalid_site_key' | 'token_expired' | 'moderation_flagged' | 'server_error' | 'unknown_error'; ``` ### Global API Types ```typescript interface SpectrumChatGlobal { // Configuration getConfig(): SpectrumChatConfig; updateConfig(config: Partial<SpectrumChatConfig>): void; // Widget control open(): void; close(): void; isOpen(): boolean; getWidget(): HTMLElement | null; // Session management getConversationId(): string | null; getSessionId(): string | null; getTokenData(): TokenData | null; isTokenValid(): boolean; initializeSession(): Promise<TokenData | null>; clearSession(): void; // Lifecycle reinitialize(): void; } ``` ### Custom Element Types ```typescript interface SpectrumChatElement extends HTMLElement { // Methods open(): void; close(): void; isChatOpen(): boolean; updateConfig(config: Partial<SpectrumChatConfig>): void; refreshStyles(): void; hideIntro(): void; // Properties shadowRoot: ShadowRoot; } ``` --- ## Usage Examples ### Example 1: Basic Integration ```html <spectrum-chat api-url="https://api.example.com/api/v1/conversations" site-key="pub_customer_a1b2c3d4" title="Help Center"> </spectrum-chat> ``` ### Example 2: With JWT and Custom Styling ```html <script> window.SpectrumChatConfig = { apiUrl: 'https://api.example.com/api/v1/conversations', siteKey: 'pub_customer_a1b2c3d4', useJWT: true, title: 'Customer Support', primaryColor: '#2563eb', userColor: '#3b82f6', aiColor: '#2563eb', fabIcon: '💬', enableCitations: true }; </script> <script src="https://unpkg.com/@spectrumsense/spectrum-chat@latest/dist/spectrum-chat.js"></script> ``` ### Example 3: Programmatic Control ```javascript // Wait for widget to load document.addEventListener('DOMContentLoaded', () => { const chat = SpectrumChatGlobal; // Check status console.log('Token valid:', chat.isTokenValid()); console.log('Conversation ID:', chat.getConversationId()); // Open on button click document.getElementById('help-btn').addEventListener('click', () => { chat.open(); }); // Clear on logout document.getElementById('logout-btn').addEventListener('click', () => { chat.clearSession(); }); // Monitor state document.addEventListener('spectrum-chat-opened', () => { console.log('Chat opened'); // Track analytics }); }); ``` ### Example 4: Error Handling ```javascript const widget = document.querySelector('spectrum-chat'); const deepChat = widget.shadowRoot.querySelector('deep-chat'); deepChat.addEventListener('response', (event) => { const response = event.detail; if (response.error) { console.error('Error:', response.error); // Custom error handling if (response.error === 'origin_not_allowed') { alert('Please contact support to enable chat on this domain.'); } } else { console.log('Response:', response.text); // Display citations if available if (response.sources && response.sources.length > 0) { console.log('Sources:', response.sources); } } }); ``` --- ## Browser Compatibility ### Required Features - ✅ Web Crypto API (for SHA256 hashing) - ✅ sessionStorage / localStorage - ✅ Fetch API - ✅ ES6+ JavaScript (arrow functions, const/let, async/await) - ✅ Custom Elements v1 - ✅ Shadow DOM ### Supported Browsers - ✅ Chrome 88+ - ✅ Firefox 85+ - ✅ Safari 14+ - ✅ Edge 88+ - ✅ Opera 74+ ### Polyfills For older browsers, you may need polyfills: ```html <!-- Custom Elements polyfill --> <script src="https://unpkg.com/@webcomponents/custom-elements@1.5.0/custom-elements.min.js"></script> <!-- Fetch polyfill --> <script src="https://unpkg.com/whatwg-fetch@3.6.2/dist/fetch.umd.js"></script> ``` --- ## Support For questions or issues: - 📚 Documentation: [SECURITY_IMPLEMENTATION.md](./SECURITY_IMPLEMENTATION.md) - 📚 Migration: [MIGRATION_GUIDE.md](./MIGRATION_GUIDE.md) - 🔧 Debug: Enable `debug="true"` in widget - 📧 Support: support@spectrumsense.com --- **Last Updated:** October 6, 2025 **Version:** 1.0.0