// 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: 'MzY=',
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: 'MzY='
});
} 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: 'MzY=',
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: 'MzY=',
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: 'MzY='
});
} 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: 'MzY=',
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;
}