tag. * Or use the Divi Theme Options → Integration panel. * * Configuration: * - WEBHOOK_URL: n8n webhook endpoint * - brand colors are hardcoded for KIWI EV */(function() { 'use strict';// ============ CONFIGURATION ============ const CONFIG = { webhookUrl: 'https://n8n.srv1272413.hstgr.cloud/webhook/14df1758-7932-4d2d-8926-2a2298c0fc4a/chat', companyName: 'KIWI EV Support', subtitle: 'Your AI-powered KIWI EV assistant is here to help.', primaryColor: '#00a651', primaryDark: '#007b3d', secondaryColor: '#f0f0f0', textColor: '#333333', headerTextColor: '#ffffff', botBubbleColor: '#f0f0f0', userBubbleColor: '#00a651', welcomeMessage: '👋 Welcome to KIWI EV! Ask me anything about our electric vehicles, partnerships, or how we can help you bring affordable EV solutions to your market.', placeholderText: 'Ask about KIWI EV products, partnerships, or support...', sessionStorageKey: 'kiwi_ev_chat_session', historyStorageKey: 'kiwi_ev_chat_history', storagePrefix: 'kiwi_ev_', };// ============ STATE ============ let isOpen = false; let sessionId = loadSessionId(); let messages = loadHistory(); let isSending = false;// ============ SESSION MANAGEMENT ============ function generateSessionId() { return 'kiwi_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9); }function loadSessionId() { try { let sid = localStorage.getItem(CONFIG.sessionStorageKey); if (!sid) { sid = generateSessionId(); localStorage.setItem(CONFIG.sessionStorageKey, sid); } return sid; } catch(e) { return generateSessionId(); } }function loadHistory() { try { let data = localStorage.getItem(CONFIG.historyStorageKey); return data ? JSON.parse(data) : []; } catch(e) { return []; } }function saveHistory() { try { localStorage.setItem(CONFIG.historyStorageKey, JSON.stringify(messages.slice(-50))); } catch(e) { // localStorage full or unavailable — silently ignore } }// ============ UI CONSTRUCTION ============ function createWidget() { // Check if already exists if (document.getElementById('kiwi-ev-chat-widget')) return;// Create root container const root = document.createElement('div'); root.id = 'kiwi-ev-chat-widget'; root.innerHTML = `
`;document.body.appendChild(root); bindEvents(); restoreHistory();// Auto-resize textarea const input = document.getElementById('kiwiInput'); input.addEventListener('input', function() { this.style.height = 'auto'; this.style.height = Math.min(this.scrollHeight, 100) + 'px'; }); }// ============ EVENT BINDING ============ function bindEvents() { document.getElementById('kiwiChatButton').addEventListener('click', toggleChat); document.getElementById('kiwiSendBtn').addEventListener('click', sendMessage); document.getElementById('kiwiInput').addEventListener('keydown', function(e) { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); sendMessage(); } }); }// ============ CHAT TOGGLE ============ function toggleChat() { isOpen = !isOpen; const panel = document.getElementById('kiwiChatPanel'); const button = document.getElementById('kiwiChatButton'); panel.classList.toggle('open', isOpen); button.classList.toggle('open', isOpen); if (isOpen) { setTimeout(() => { document.getElementById('kiwiInput').focus(); scrollToBottom(); }, 100); } }// ============ MESSAGE DISPLAY ============ function addMessage(text, role) { const container = document.getElementById('kiwiMessages'); const typingEl = document.getElementById('kiwiTyping'); const msgDiv = document.createElement('div'); msgDiv.className = 'kiwi-message ' + role; const bubble = document.createElement('div'); bubble.className = 'kiwi-bubble'; bubble.textContent = text; msgDiv.appendChild(bubble); const time = document.createElement('div'); time.className = 'kiwi-message-time'; time.textContent = new Date().toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }); msgDiv.appendChild(time); container.insertBefore(msgDiv, typingEl); scrollToBottom();messages.push({ role: role, text: text, time: new Date().toISOString() }); saveHistory(); }function showTyping() { document.getElementById('kiwiTyping').classList.add('active'); scrollToBottom(); }function hideTyping() { document.getElementById('kiwiTyping').classList.remove('active'); }function scrollToBottom() { const container = document.getElementById('kiwiMessages'); setTimeout(() => { container.scrollTop = container.scrollHeight; }, 50); }function restoreHistory() { // Show previous messages from this session (excluding welcome) const welcomeEl = document.querySelector('.kiwi-message.bot:first-child .kiwi-bubble'); if (welcomeEl && welcomeEl.textContent === CONFIG.welcomeMessage) { // Keep welcome, load rest for (const msg of messages) { if (msg.text !== CONFIG.welcomeMessage) { addMessage(msg.text, msg.role); } } } }// ============ SEND MESSAGE ============ function sendMessage() { if (isSending) return; const input = document.getElementById('kiwiInput'); const text = input.value.trim(); if (!text) return;input.value = ''; input.style.height = 'auto';addMessage(text, 'user'); isSending = true; document.getElementById('kiwiSendBtn').disabled = true; showTyping();// Call n8n webhook fetch(CONFIG.webhookUrl, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ action: 'sendMessage', sessionId: sessionId, chatInput: text, }) }) .then(response => { if (!response.ok) throw new Error('HTTP ' + response.status); return response.json(); }) .then(data => { hideTyping(); const reply = data.output || data.response || data.text || JSON.stringify(data); addMessage(reply, 'bot'); }) .catch(err => { hideTyping(); addMessage('Sorry, I\'m having trouble connecting right now. Please try again later.', 'bot'); console.error('Chat widget error:', err); }) .finally(() => { isSending = false; document.getElementById('kiwiSendBtn').disabled = false; }); }// ============ INIT ============ if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', createWidget); } else { createWidget(); }})();