aimojster/chatbot.js

162 lines
6.4 KiB
JavaScript

/*
DEDICATED JAVASCRIPT FOR AIMOJSTER.SI CHATBOT WIDGET
Last Updated: 16. September 2025 (v8.0 - Final Production Version)
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.
*/
document.addEventListener('DOMContentLoaded', function() {
// --- DOM ELEMENTI ---
const chatWidgetButton = document.getElementById('chat-widget-button');
const chatContainer = document.getElementById('chat-widget-container');
const closeChatBtn = document.getElementById('close-chat-btn');
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';
// 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.");
return;
}
// ====================================================================== //
// === UPRAVLJANJE S SEJO (SESSION ID MANAGEMENT) === //
// ====================================================================== //
/**
* 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);
if (!sessionId) {
// crypto.randomUUID() je moderen, varen in standarden način za generiranje UUID-jev.
sessionId = crypto.randomUUID();
sessionStorage.setItem(SESSION_KEY, 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"
};
try {
const response = await fetch(N8N_WEBHOOK_URL, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(payload)
});
if (!response.ok) {
throw new Error(`Server returned status: ${response.status}`);
}
const data = await response.json();
const botReply = data.output;
if (botReply) {
addBotMessageToUI(botReply);
} 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.");
}
}
// ====================================================================== //
// === UPRAVLJANJE Z UI IN DOGODKI === //
// ====================================================================== //
// --- 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;
chatMessagesContainer.appendChild(messageElement);
chatMessagesContainer.scrollTop = chatMessagesContainer.scrollHeight;
}
function showTypingIndicator() {
if (chatMessagesContainer.querySelector('.typing-indicator')) return;
const indicator = document.createElement('div');
indicator.classList.add('chat-message', 'bot-message', 'typing-indicator');
indicator.innerHTML = '<span>.</span><span>.</span><span>.</span>';
chatMessagesContainer.appendChild(indicator);
chatMessagesContainer.scrollTop = chatMessagesContainer.scrollHeight;
}
function hideTypingIndicator() {
const indicator = chatMessagesContainer.querySelector('.typing-indicator');
if (indicator) indicator.remove();
}
const addUserMessageToUI = (message) => addMessageToUI(message, 'user');
const addBotMessageToUI = (message) => {
hideTypingIndicator();
addMessageToUI(message, 'bot');
};
// --- Glavni Event Listener za oddajo sporočila ---
chatInputForm.addEventListener('submit', function(event) {
event.preventDefault();
const userMessage = chatInputField.value.trim();
if (userMessage) {
addUserMessageToUI(userMessage);
sendMessageToBot(userMessage);
chatInputField.value = '';
}
});
// --- Event Listenerji za odpiranje in zapiranje okna ---
chatWidgetButton.addEventListener('click', openChatWidget);
closeChatBtn.addEventListener('click', closeChatWidget);
console.log("Chatbot v8.0 (Final Production) initialized successfully.");
});