class EveAI { constructor(config) { // Required parameters this.tenantId = config.tenantId; // Chat configuration this.language = config.language || 'en'; this.languages = config.languages?.split(',') || ['en']; this.specialistId = config.specialistId; // Server Configuration this.socketUrl = config.socketUrl || 'https://chat.askeveai.com'; this.authUrl = config.authUrl || 'https://api.askeveai.com'; this.proxyUrl = config.proxyUrl; // URL for auth proxy (WP or standalone) this.wpRestNamespace = 'eveai/v1'; // This should match the PHP constant this.wpRestUrl = `${config.wpBaseUrl || '/wp-json'}/${this.wpRestNamespace}`; // Initialize token management this.tokenManager = new EveAITokenManager({ proxyUrl: this.proxyUrl, onTokenChange: this.handleTokenChange.bind(this), onError: this.handleAuthError.bind(this) }); this.chatWidget = null; } async initialize(containerId) { try { if (!containerId) { throw new Error('Container ID is required'); } console.log('Starting initialization with settings:', { tenantId: this.tenantId, wpRestUrl: this.wpRestUrl }); // Get the WordPress nonce const wpNonce = window.eveaiWP?.nonce; if (!wpNonce) { throw new Error('WordPress nonce not found'); } // Use WordPress REST API endpoint instead of direct API call const response = await fetch(`${this.wpRestUrl}/token`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-WP-Nonce': wpNonce, }, credentials: 'same-origin', // Important for WP cookie handling body: JSON.stringify({ tenant_id: this.tenantId }) }); console.log('Token request response status:', response.status); if (!response.ok) { const errorText = await response.text(); console.error('Auth error response:', errorText); throw new Error('Authentication failed'); } const { access_token, expires_in } = await response.json(); console.log('Token received:', access_token); console.log('Token Expiry:', expires_in); // Store token and expiry this.sessionToken = access_token; this.tokenExpiry = Date.now() + (expires_in * 1000); // Initialize token refresh timer this.setupTokenRefresh(expires_in); return this.initializeChat(containerId, access_token); } catch (error) { console.error('Full initialization error:', error); throw error; } } setupTokenRefresh(expiresIn) { // Set up refresh 5 minutes before expiry const refreshTime = (expiresIn - 300) * 1000; // Convert to milliseconds setTimeout(() => this.refreshToken(), refreshTime); } async refreshToken() { try { const response = await fetch(`${this.wpRestUrl}/refresh`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${this.sessionToken}` } }); if (response.ok) { const { access_token, expires_in } = await response.json(); this.sessionToken = access_token; this.tokenExpiry = Date.now() + (expires_in * 1000); // Update token in chat widget if (this.chatWidget) { this.chatWidget.setAttribute('session-token', access_token); } // Setup next refresh this.setupTokenRefresh(expires_in); } else { console.error('Token refresh failed'); } } catch (error) { console.error('Token refresh error:', error); } } async initializeChat(containerId) { const container = document.getElementById(containerId); if (!container) { throw new Error('Container not found'); } // Create chat widget with all necessary attributes const chatWidget = document.createElement('eveai-chat-widget'); // Set all required attributes const attributes = { 'tenant-id': this.tenantId, 'session-token': this.sessionToken, 'language': this.language, 'languages': this.languages.join(','), 'specialist-id': this.specialistId, 'server-url': this.socketUrl }; console.log('Setting widget attributes:', attributes); Object.entries(attributes).forEach(([attr, value]) => { if (value === null || value === undefined) { console.warn(`Warning: ${attr} is ${value}`); } chatWidget.setAttribute(attr, value); }); container.appendChild(chatWidget); this.chatWidget = chatWidget; return chatWidget; } handleTokenChange(newToken) { if (this.chatWidget) { this.chatWidget.setAttribute('session-token', newToken); } } handleAuthError(error) { if (this.chatWidget) { this.chatWidget.handleAuthError(error); } } } // Make available globally // window.EveAI = EveAI;