// Universal AI Chatbot Script const chatbotToggle = document.getElementById('chatbot-toggle'); const chatbotWindow = document.getElementById('chatbot-window'); const chatbotSend = document.getElementById('chatbot-send'); const chatbotInput = document.getElementById('chatbot-input'); const chatbotMessages = document.getElementById('chatbot-messages'); const API_ENDPOINT = 'chatbot-answer.php'; // Update as needed let isLoading = false; let chatInitialized = false; let chatSessionId = null; // Unique ID for the chat session // Initialize chat session ID on page load document.addEventListener('DOMContentLoaded', () => { // Generate or retrieve chat_session_id chatSessionId = getCookie('chat_session_id') || generateChatSessionId(); setCookie('chat_session_id', chatSessionId, 1); // Store for 1 day setTimeout(() => { if (!chatInitialized) { appendMessage('Bot', 'Hello! How may I assist you today?', 'bot'); chatInitialized = true; } }, 1000); }); // Function to generate a unique chat session ID function generateChatSessionId() { return 'chat_' + Math.random().toString(36).substr(2, 9) + '_' + Date.now(); } // Cookie handling functions function setCookie(name, value, days = 1) { const expires = new Date(Date.now() + days * 864e5).toUTCString(); document.cookie = name + '=' + encodeURIComponent(value) + '; expires=' + expires + '; path=/'; } function getCookie(name) { return document.cookie.split('; ').reduce((r, v) => { const parts = v.split('='); return parts[0] === name ? decodeURIComponent(parts[1]) : r; }, ''); } chatbotToggle.onclick = () => { chatbotWindow.style.display = chatbotWindow.style.display === 'block' ? 'none' : 'block'; }; chatbotSend.onclick = sendMessage; chatbotInput.addEventListener('keydown', function(e) { if (e.key === 'Enter') sendMessage(); }); let previousUserMessage = ''; let answerdata = ''; function sendMessage() { const msg = chatbotInput.value.trim(); if (!msg) return; appendMessage('You', msg, 'user'); chatbotInput.value = ''; // Detect slot navigation and set cookie if (/next slot/i.test(msg)) { let page = parseInt(getCookie('slot_page') || '0', 10); setCookie('slot_page', page + 1); } else if (/(book|schedule|want|arrange|need|require|organize|plan|set|line up|organize).*demo/i.test(msg)) { setCookie('slot_page', 0); } appendMessage('Bot', 'Writing...', 'bot'); addMessageToTranscript('user', msg); resetInactivityTimer(); // Prepare request data const requestData = { question: msg, lastUserMsg: previousUserMessage, slot_page: getCookie('slot_page'), slot_data: getCookie('slot_data'), chat_session_id: chatSessionId, // Include chat session ID client_id: 'MjY=', booking_session_id: getCookie('booking_session_id') || '' // Include booking session ID if available }; // Handle slot number selection if (/^\d{1,4}$/.test(msg.trim())) { try { console.log('=== Slot Selection Debug ==='); const lastResponse = JSON.parse(localStorage.getItem('last_slot_response') || '{}'); if (lastResponse && lastResponse.slots && Array.isArray(lastResponse.slots)) { console.log('Sending slots to server:', lastResponse.slots); requestData.slot_number = parseInt(msg.trim(), 10); requestData.displayedSlots = JSON.stringify(lastResponse.slots); if (lastResponse.selected_date) { requestData.selected_date = lastResponse.selected_date; } if (lastResponse.slot_page !== undefined) { requestData.slot_page = lastResponse.slot_page; } console.log('Slot data prepared for sending:', { slot_number: requestData.slot_number, slots: lastResponse.slots.length, selected_date: requestData.selected_date, slot_page: requestData.slot_page, chat_session_id: requestData.chat_session_id, booking_session_id: requestData.booking_session_id, client_id: 'MjY=' }); } else { console.warn('No valid slots found in last response'); } } catch (e) { console.error('Error handling slot selection:', e); } } fetch(API_ENDPOINT, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(requestData) }) .then(res => res.json()) .then(data => { chatbotMessages.removeChild(chatbotMessages.lastChild); appendMessage('Bot', data.answer ? data.answer : 'No answer found.', 'bot'); addMessageToTranscript('Bot', data.answer ? data.answer : 'No answer found.'); answerdata += '+' + data.answer; // Store booking_session_id if provided if (data.booking_session_id) { setCookie('booking_session_id', data.booking_session_id, 1); } if (data.slot_data) { setCookie('slot_data', data.slot_data); } // Store slot response if (data.slots && Array.isArray(data.slots)) { console.log('=== Storing Slots Data ==='); const responseData = { slots: data.slots, timestamp: new Date().toISOString() }; if (data.selected_date !== undefined) { responseData.selected_date = data.selected_date; } if (data.slot_page !== undefined) { responseData.slot_page = data.slot_page; } try { localStorage.setItem('last_slot_response', JSON.stringify(responseData)); console.log('Stored slot data in localStorage:', { slots: responseData.slots.length, selected_date: responseData.selected_date, slot_page: responseData.slot_page }); } catch (e) { console.error('Error storing slot data:', e); } } }) .catch(() => { chatbotMessages.removeChild(chatbotMessages.lastChild); appendMessage('Bot', 'Sorry, there was an error getting the answer.', 'bot'); addMessageToTranscript('Bot', 'Sorry, there was an error getting the answer.'); }); previousUserMessage += '+' + msg; if (/(bye|goodbye|thank you|thanks|see you)/i.test(msg)) { endChat(); } resetInactivityTimer(); } // --- Chat Transcript and End Chat Logic --- let chatTranscript = []; let inactivityTimer = null; const INACTIVITY_LIMIT = 10 * 60 * 1000; // 10 minutes function addMessageToTranscript(sender, message) { chatTranscript.push({ sender, message }); } function resetInactivityTimer() { if (inactivityTimer) clearTimeout(inactivityTimer); inactivityTimer = setTimeout(() => { console.log("Inactivity timeout"); endChat(); }, INACTIVITY_LIMIT); } function endChat() { if (chatTranscript.length === 0) return; const payload = JSON.stringify({ action: 'end_chat', transcript: chatTranscript, chat_session_id: chatSessionId, // Include chat session ID client_id: 'MjY=', booking_session_id: getCookie('booking_session_id') || '' // Include booking session ID }); if (navigator.sendBeacon) { const blob = new Blob([payload], { type: 'application/json' }); navigator.sendBeacon(API_ENDPOINT, blob); } else { fetch(API_ENDPOINT, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: payload });// Universal AI Chatbot Script const chatbotToggle = document.getElementById('chatbot-toggle'); const chatbotWindow = document.getElementById('chatbot-window'); const chatbotSend = document.getElementById('chatbot-send'); const chatbotInput = document.getElementById('chatbot-input'); const chatbotMessages = document.getElementById('chatbot-messages'); const API_ENDPOINT = 'chatbot-answer-new.php'; // Update as needed let isLoading = false; let chatInitialized = false; let chatSessionId = null; // Unique ID for the chat session // Initialize chat session ID on page load document.addEventListener('DOMContentLoaded', () => { // Generate or retrieve chat_session_id chatSessionId = getCookie('chat_session_id') || generateChatSessionId(); setCookie('chat_session_id', chatSessionId, 1); // Store for 1 day setTimeout(() => { if (!chatInitialized) { appendMessage('Bot', 'Hello! How may I assist you today?', 'bot'); chatInitialized = true; } }, 1000); }); // Function to generate a unique chat session ID function generateChatSessionId() { return 'chat_' + Math.random().toString(36).substr(2, 9) + '_' + Date.now(); } // Cookie handling functions function setCookie(name, value, days = 1) { const expires = new Date(Date.now() + days * 864e5).toUTCString(); document.cookie = name + '=' + encodeURIComponent(value) + '; expires=' + expires + '; path=/'; } function getCookie(name) { return document.cookie.split('; ').reduce((r, v) => { const parts = v.split('='); return parts[0] === name ? decodeURIComponent(parts[1]) : r; }, ''); } chatbotToggle.onclick = () => { chatbotWindow.style.display = chatbotWindow.style.display === 'block' ? 'none' : 'block'; }; chatbotSend.onclick = sendMessage; chatbotInput.addEventListener('keydown', function(e) { if (e.key === 'Enter') sendMessage(); }); let previousUserMessage = ''; let answerdata = ''; function sendMessage() { const msg = chatbotInput.value.trim(); if (!msg) return; appendMessage('You', msg, 'user'); chatbotInput.value = ''; // Detect slot navigation and set cookie if (/next slot/i.test(msg)) { let page = parseInt(getCookie('slot_page') || '0', 10); setCookie('slot_page', page + 1); } else if (/(book|schedule|want|arrange|need|require|organize|plan|set|line up|organize).*demo/i.test(msg)) { setCookie('slot_page', 0); } appendMessage('Bot', 'Writing...', 'bot'); addMessageToTranscript('user', msg); resetInactivityTimer(); // Prepare request data const requestData = { question: msg, lastUserMsg: previousUserMessage, slot_page: getCookie('slot_page'), slot_data: getCookie('slot_data'), chat_session_id: chatSessionId, // Include chat session ID client_id: 'MjY=', booking_session_id: getCookie('booking_session_id') || '' // Include booking session ID if available }; // Handle slot number selection if (/^\d{1,4}$/.test(msg.trim())) { try { console.log('=== Slot Selection Debug ==='); const lastResponse = JSON.parse(localStorage.getItem('last_slot_response') || '{}'); if (lastResponse && lastResponse.slots && Array.isArray(lastResponse.slots)) { console.log('Sending slots to server:', lastResponse.slots); requestData.slot_number = parseInt(msg.trim(), 10); requestData.displayedSlots = JSON.stringify(lastResponse.slots); if (lastResponse.selected_date) { requestData.selected_date = lastResponse.selected_date; } if (lastResponse.slot_page !== undefined) { requestData.slot_page = lastResponse.slot_page; } console.log('Slot data prepared for sending:', { slot_number: requestData.slot_number, slots: lastResponse.slots.length, selected_date: requestData.selected_date, slot_page: requestData.slot_page, chat_session_id: requestData.chat_session_id, booking_session_id: requestData.booking_session_id, client_id: 'MjY=' }); } else { console.warn('No valid slots found in last response'); } } catch (e) { console.error('Error handling slot selection:', e); } } fetch(API_ENDPOINT, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(requestData) }) .then(res => res.json()) .then(data => { chatbotMessages.removeChild(chatbotMessages.lastChild); appendMessage('Bot', data.answer ? data.answer : 'No answer found.', 'bot'); addMessageToTranscript('Bot', data.answer ? data.answer : 'No answer found.'); answerdata += '+' + data.answer; // Store booking_session_id if provided if (data.booking_session_id) { setCookie('booking_session_id', data.booking_session_id, 1); } if (data.slot_data) { setCookie('slot_data', data.slot_data); } // Store slot response if (data.slots && Array.isArray(data.slots)) { console.log('=== Storing Slots Data ==='); const responseData = { slots: data.slots, timestamp: new Date().toISOString() }; if (data.selected_date !== undefined) { responseData.selected_date = data.selected_date; } if (data.slot_page !== undefined) { responseData.slot_page = data.slot_page; } try { localStorage.setItem('last_slot_response', JSON.stringify(responseData)); console.log('Stored slot data in localStorage:', { slots: responseData.slots.length, selected_date: responseData.selected_date, slot_page: responseData.slot_page }); } catch (e) { console.error('Error storing slot data:', e); } } }) .catch(() => { chatbotMessages.removeChild(chatbotMessages.lastChild); appendMessage('Bot', 'Sorry, there was an error getting the answer.', 'bot'); addMessageToTranscript('Bot', 'Sorry, there was an error getting the answer.'); }); previousUserMessage += '+' + msg; if (/(bye|goodbye|thank you|thanks|see you)/i.test(msg)) { endChat(); } resetInactivityTimer(); } // --- Chat Transcript and End Chat Logic --- let chatTranscript = []; let inactivityTimer = null; const INACTIVITY_LIMIT = 10 * 60 * 1000; // 10 minutes function addMessageToTranscript(sender, message) { chatTranscript.push({ sender, message }); } function resetInactivityTimer() { if (inactivityTimer) clearTimeout(inactivityTimer); inactivityTimer = setTimeout(() => { console.log("Inactivity timeout"); endChat(); }, INACTIVITY_LIMIT); } function endChat() { if (chatTranscript.length === 0) return; const payload = JSON.stringify({ action: 'end_chat', transcript: chatTranscript, chat_session_id: chatSessionId, // Include chat session ID client_id: 'MjY=', booking_session_id: getCookie('booking_session_id') || '' // Include booking session ID }); if (navigator.sendBeacon) { const blob = new Blob([payload], { type: 'application/json' }); navigator.sendBeacon(API_ENDPOINT, blob); } else { fetch(API_ENDPOINT, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: payload }); } chatTranscript = []; if (inactivityTimer) clearTimeout(inactivityTimer); // Clear booking_session_id but keep chat_session_id for potential new chats setCookie('booking_session_id', '', -1); } window.addEventListener('beforeunload', function() { endChat(); }); function linkify(text) { return text.replace(/(https?:\/\/[^\s]+)/g, '$1'); } function appendMessage(sender, text, type) { const msgDiv = document.createElement('div'); msgDiv.className = 'chatbot-msg' + (type === 'user' ? ' user' : ''); msgDiv.innerHTML = '' + sender + ': ' + ((type === 'bot') ? linkify(text) : text); chatbotMessages.appendChild(msgDiv); chatbotMessages.scrollTop = chatbotMessages.scrollHeight; } } chatTranscript = []; if (inactivityTimer) clearTimeout(inactivityTimer); // Clear booking_session_id but keep chat_session_id for potential new chats setCookie('booking_session_id', '', -1); } window.addEventListener('beforeunload', function() { endChat(); }); function linkify(text) { return text.replace(/(https?:\/\/[^\s]+)/g, '$1'); } function appendMessage(sender, text, type) { const msgDiv = document.createElement('div'); msgDiv.className = 'chatbot-msg' + (type === 'user' ? ' user' : ''); msgDiv.innerHTML = '' + sender + ': ' + ((type === 'bot') ? linkify(text) : text); chatbotMessages.appendChild(msgDiv); chatbotMessages.scrollTop = chatbotMessages.scrollHeight; }