diff --git a/chatbot.js b/chatbot.js index ee34f3f..db4bba7 100644 --- a/chatbot.js +++ b/chatbot.js @@ -1,134 +1,193 @@ /* DEDICATED JAVASCRIPT FOR AIMOJSTER.SI CHATBOT WIDGET - Last Updated: 16. September 2025 (v8.0 - Final Production Version) + Last Updated: 16. September 2025 (v15.0 - Relaunch with Demo Center) Author: Gemini AI for AIMojster.si - This is the final, clean production version of the chatbot script. - It reliably creates, stores (per session), and sends a unique session ID with every user message, - ensuring that the n8n workflow functions correctly. + This script powers the interactive demo center on the redesigned website. + It includes logic to launch specific demo bots directly from the main page content, + ensuring a seamless and engaging user experience. */ document.addEventListener('DOMContentLoaded', function() { - // --- DOM ELEMENTI --- + //====================================================================== + // 1. KONFIGURACIJA IN IZBIRA DOM ELEMENTOV + //====================================================================== + const chatWidgetButton = document.getElementById('chat-widget-button'); const chatContainer = document.getElementById('chat-widget-container'); const closeChatBtn = document.getElementById('close-chat-btn'); + const chatHeaderTitle = document.getElementById('chat-header-title'); const chatMessagesContainer = document.getElementById('chat-messages'); const chatInputForm = document.getElementById('chat-input-form'); const chatInputField = document.getElementById('chat-input'); - - // --- KONFIGURACIJA --- - const N8N_WEBHOOK_URL = 'https://n8n.spletnimojster.si/webhook/joze/chat'; + const chatResetBtn = document.getElementById('chat-reset-btn'); + const demoLaunchButtons = document.querySelectorAll('.launch-demo-btn'); // NOVO: Gumbi v demo centru - // Preverimo, ali obstajajo vsi potrebni HTML elementi za delovanje. - if (!chatWidgetButton || !chatContainer || !chatInputForm) { - console.error("Chatbot HTML elements could not be found. The script will not initialize."); + if (!chatWidgetButton || !chatContainer || !chatInputForm || !chatHeaderTitle || !chatResetBtn) { + console.error("Critical chatbot HTML elements are missing. The script will not initialize."); return; } - // ====================================================================== // - // === UPRAVLJANJE S SEJO (SESSION ID MANAGEMENT) === // - // ====================================================================== // + const bots = { + main: { + name: "AI Mojster Asistent", + url: 'https://n8n.spletnimojster.si/webhook/013f5fb3-52bd-44bb-bc0a-41027d9916af/chat', + greeting: "Pozdravljeni! Sem AI asistent podjetja AIMojster. 🤖 Tukaj sem, da vam v živo pokažem, kaj zmorejo naši pametni boti. Izberite enega od spodnjih primerov in ga preizkusite!" + }, + rag: { + name: "Demo: Pekarna Novak", + url: 'https://n8n.spletnimojster.si/webhook/joze/chat', + greeting: "Dober dan in dobrodošli v Pekarni Novak! 🥐 Diši po sveže pečenem, kajne? Sem vaš virtualni pomočnik in poznam celotno našo ponudbo. Vprašajte me, kaj imamo danes dobrega, ali preverite alergene za kateri koli izdelek." + }, + calendar: { + name: "Demo: Potovalni Svetovalec", + url: 'https://n8n.spletnimojster.si/webhook/d0b3a15a-8d1c-437c-8523-00e108af14a4/chat', + greeting: "Pozdravljeni v agenciji Sončni Pobegi! ☀️ Pripravljeni na sanjsko potovanje? Povejte mi svoje želje – iščete sprostitev na plaži, aktivne počitnice v gorah ali raziskovanje mest? Skupaj bova našla popolno destinacijo za vas!" + }, + sales: { + name: "Demo: Fitnes Svetovalec", + url: 'https://n8n.spletnimojster.si/webhook/63f6f29f-54a2-4a6c-bf5e-0767a590a2a8/chat', + greeting: "Živjo, bodoči član! 💪 Sem vaš osebni AI svetovalec v fitnes centru FitLife. Tukaj sem, da vam pomagam najti popoln paket članstva. Pripravljeni, da začneva vašo fitnes pot?" + } + }; + + let activeBotKey = 'main'; + + // ====================================================================== + // 2. UPRAVLJANJE STANJA IN Vmesnika (UI) + // ====================================================================== + + function startConversation() { + chatContainer.classList.remove('hidden'); + activeBotKey = 'main'; + updateChatHeader(); + chatMessagesContainer.innerHTML = ''; + + showTypingIndicator(); + setTimeout(() => { + hideTypingIndicator(); + addMessageToUI(bots.main.greeting, 'bot'); + showBotSelectionButtons(); + }, 1200); + + chatResetBtn.classList.remove('visible'); + chatInputForm.classList.remove('hidden'); + chatInputField.focus(); + } + + function switchBot(botKey) { + if (!bots[botKey]) { + console.error(`Bot with key "${botKey}" does not exist.`); + return; + } + activeBotKey = botKey; + updateChatHeader(); + chatMessagesContainer.innerHTML = ''; + + showTypingIndicator(); + setTimeout(() => { + hideTypingIndicator(); + addMessageToUI(bots[activeBotKey].greeting, 'bot'); + }, 1200); + + chatResetBtn.classList.add('visible'); + chatInputForm.classList.remove('hidden'); + chatInputField.focus(); + } + + function updateChatHeader() { + chatHeaderTitle.textContent = bots[activeBotKey].name; + } + + function showBotSelectionButtons() { + const container = document.createElement('div'); + container.className = 'bot-selection-container'; + const buttonsToShow = [ + { key: 'rag', text: 'Preizkusi Bota za Pekarno' }, + { key: 'calendar', text: 'Preizkusi Potovalnega Agenta' }, + { key: 'sales', text: 'Preizkusi Fitnes Svetovalca' } + ]; + buttonsToShow.forEach(btnInfo => { + const button = document.createElement('button'); + button.className = 'bot-selection-btn'; + button.textContent = btnInfo.text; + button.addEventListener('click', () => switchBot(btnInfo.key)); + container.appendChild(button); + }); + chatMessagesContainer.appendChild(container); + } + + // ====================================================================== + // 3. UPRAVLJANJE S SEJO IN KOMUNIKACIJA Z N8N + // ====================================================================== - /** - * Zanesljivo pridobi ali ustvari unikaten Session ID za trenutni pogovor. - * Uporablja `sessionStorage`, kar pomeni, da ID obstane med osveževanjem strani, - * a se ponastavi, ko uporabnik zapre zavihek brskalnika. - * @returns {string} The unique session ID for the current chat session. - */ function getSessionId() { - const SESSION_KEY = 'aimojster_chatbot_session_id'; // Uporabimo unikatno ime ključa - let sessionId = sessionStorage.getItem(SESSION_KEY); - + let sessionId = sessionStorage.getItem('aimojster_multibot_session_id'); if (!sessionId) { - // crypto.randomUUID() je moderen, varen in standarden način za generiranje UUID-jev. sessionId = crypto.randomUUID(); - sessionStorage.setItem(SESSION_KEY, sessionId); + sessionStorage.setItem('aimojster_multibot_session_id', sessionId); } return sessionId; } - // ====================================================================== // - // === KOMUNIKACIJA Z N8N === // - // ====================================================================== // - - /** - * Sestavi in pošlje uporabnikovo sporočilo skupaj s session ID-jem na n8n webhook. - * @param {string} userMessage - Sporočilo, ki ga je vnesel uporabnik. - */ async function sendMessageToBot(userMessage) { showTypingIndicator(); - - // Pridobimo ali ustvarimo session ID za to sejo. - const currentSessionId = getSessionId(); - - // Sestavimo pravilen objekt (payload), ki ga n8n pričakuje. - const payload = { - sessionId: currentSessionId, - chatInput: userMessage, - action: "sendMessage" - }; + const currentBot = bots[activeBotKey]; + const webhookUrl = currentBot.url; + const sessionId = getSessionId(); + const payload = { sessionId, chatInput: userMessage, action: "sendMessage" }; try { - const response = await fetch(N8N_WEBHOOK_URL, { + const response = await fetch(webhookUrl, { method: 'POST', - headers: { - 'Content-Type': 'application/json' - }, + headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload) }); - - if (!response.ok) { - throw new Error(`Server returned status: ${response.status}`); - } - + if (!response.ok) throw new Error(`Server returned status: ${response.status}`); const data = await response.json(); const botReply = data.output; - + + hideTypingIndicator(); if (botReply) { - addBotMessageToUI(botReply); + addMessageToUI(botReply, 'bot'); } else { - // To se zgodi, če n8n vrne prazen odgovor ali napačno strukturo. - console.error("Response from bot was empty or in a malformed structure.", data); throw new Error("Malformed response from server."); } - } catch (error) { - console.error('Error communicating with the chatbot API:', error); - addBotMessageToUI("Oprostite, prišlo je do tehnične napake. Poskusite znova kasneje."); + console.error(`Error communicating with bot "${activeBotKey}":`, error); + hideTypingIndicator(); + addMessageToUI("Oprostite, prišlo je do tehnične napake. Poskusite znova kasneje.", 'bot'); } } - // ====================================================================== // - // === UPRAVLJANJE Z UI IN DOGODKI === // - // ====================================================================== // + // ====================================================================== + // 4. UI POMOČNIKI IN EVENT LISTENERS + // ====================================================================== - // --- Pomožne UI funkcije --- - function openChatWidget() { - chatContainer.classList.remove('hidden'); - chatInputField.focus(); - } - - function closeChatWidget() { - chatContainer.classList.add('hidden'); - } - function addMessageToUI(text, sender) { const messageElement = document.createElement('div'); messageElement.classList.add('chat-message', `${sender}-message`); - messageElement.textContent = text; + if (sender === 'bot') { + if (typeof marked !== 'undefined') { + messageElement.innerHTML = marked.parse(text); + } else { + messageElement.textContent = text; + } + } else { + messageElement.textContent = text; + } chatMessagesContainer.appendChild(messageElement); - chatMessagesContainer.scrollTop = chatMessagesContainer.scrollHeight; + scrollToBottom(); } function showTypingIndicator() { if (chatMessagesContainer.querySelector('.typing-indicator')) return; const indicator = document.createElement('div'); indicator.classList.add('chat-message', 'bot-message', 'typing-indicator'); - indicator.innerHTML = '...'; + indicator.innerHTML = ''; chatMessagesContainer.appendChild(indicator); - chatMessagesContainer.scrollTop = chatMessagesContainer.scrollHeight; + scrollToBottom(); } function hideTypingIndicator() { @@ -136,27 +195,45 @@ document.addEventListener('DOMContentLoaded', function() { if (indicator) indicator.remove(); } - const addUserMessageToUI = (message) => addMessageToUI(message, 'user'); - const addBotMessageToUI = (message) => { - hideTypingIndicator(); - addMessageToUI(message, 'bot'); - }; + function scrollToBottom() { + chatMessagesContainer.scrollTop = chatMessagesContainer.scrollHeight; + } - // --- Glavni Event Listener za oddajo sporočila --- chatInputForm.addEventListener('submit', function(event) { event.preventDefault(); const userMessage = chatInputField.value.trim(); - if (userMessage) { - addUserMessageToUI(userMessage); + const selectionContainer = chatMessagesContainer.querySelector('.bot-selection-container'); + if (selectionContainer) { + selectionContainer.remove(); + } + addMessageToUI(userMessage, 'user'); sendMessageToBot(userMessage); chatInputField.value = ''; } }); - // --- Event Listenerji za odpiranje in zapiranje okna --- - chatWidgetButton.addEventListener('click', openChatWidget); - closeChatBtn.addEventListener('click', closeChatWidget); + // --- Glavni Event Listenerji --- - console.log("Chatbot v8.0 (Final Production) initialized successfully."); + // 1. Klik na plavajoči gumb (odpre glavnega bota) + chatWidgetButton.addEventListener('click', startConversation); + + // 2. Klik na gumb za zapiranje + closeChatBtn.addEventListener('click', () => chatContainer.classList.add('hidden')); + + // 3. Klik na gumb za vrnitev v glavni meni + chatResetBtn.addEventListener('click', startConversation); + + // 4. NOVO: Klik na gumbe v "Demo Centru" na strani + demoLaunchButtons.forEach(button => { + button.addEventListener('click', function() { + const botKey = this.dataset.botKey; // Preberemo ključ bota (npr. 'rag') + if (botKey) { + chatContainer.classList.remove('hidden'); // Najprej odpremo okno + switchBot(botKey); // Nato zaženemo izbranega bota + } + }); + }); + + console.log("Multi-Bot Demo Center (v15.0 - Relaunch) initialized successfully."); }); \ No newline at end of file diff --git a/index.html b/index.html index f3bc894..fff55ab 100644 --- a/index.html +++ b/index.html @@ -7,7 +7,7 @@