// Chatbot script
const socket = io();
const loader = ``;
const errorMessage = 'My apologies, I\'m not avail at the moment, however, feel free to call our support team directly 0123456789.';
const urlPattern = /(\b(https?|ftp):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/gim;
const $document = document;
const $chatbot = $document.querySelector('.chatbot');
const $chatbotMessageWindow = $document.querySelector('.chatbot__message-window');
const $chatbotHeader = $document.querySelector('.chatbot__header');
const $chatbotMessages = $document.querySelector('.chatbot__messages');
const $chatbotInput = $document.querySelector('.chatbot__input');
const $chatbotSubmit = $document.querySelector('.chatbot__submit');
const $endChatContainer = document.getElementById('endChatContainer');
const $endChatButton = document.getElementById('endChatButton');
const botLoadingDelay = 1000;
const botReplyDelay = 2000;
let chatId = null; // Declare chatId as a global variable
document.addEventListener('keypress', event => {
if (event.which == 13) validateMessage();
}, false);
$chatbotHeader.addEventListener('click', async () => {
alert("User pressed button"); // Alert when the header is clicked
try {
// If socket is disconnected, reconnect it
if (!socket.connected) {
alert("Socket is disconnected. Attempting to connect...");
socket.connect();
} else {
alert("Socket is already connected.");
}
const response = await fetch('/start_chat', {
method: 'POST',
});
alert("Fetch request sent to /start_chat"); // Alert after sending fetch request
// Check the response status
if (!response.ok) {
alert("Failed to fetch chat data. Status: " + response.status);
const errorData = await response.json(); // Try to parse error response
alert("Error details: " + JSON.stringify(errorData)); // Show the error details
return; // Exit if the response is not ok
}
const data = await response.json();
console.log('Response Data:', data); // Log the response data for debugging
// Alert the server's response
alert("Response received from server: " + JSON.stringify(data));
if (data.chat_id) {
chatId = data.chat_id;
//alert('Room ID: ${chatId}`); // Alert with the chat ID
// Ensure socket.id is available after reconnection
if (!socket.id) {
alert("Socket ID is not available. Disconnecting the socket...");
socket.disconnect();
// Wait a moment before reconnecting
setTimeout(() => {
alert("Reconnecting the socket...");
// Reconnect the socket
socket.connect();
// Check if the new socket id is available
socket.on('connect', () => {
if (socket.id) {
//alert('Reconnected with new Socket ID: ${socket.id}`);
console.log('Reconnected with new socket ID:', socket.id);
// Now that we have a new socket ID, proceed with your logic
socket.emit('join_room', { chat_id: chatId });
$endChatContainer.style.display = 'block'; // Show the "End Chat" button container
toggle($chatbot, 'chatbot--closed'); // Open the chatbot only if chat_id is received
$chatbotInput.focus();
aiMessage(data.message || 'Chat started successfully! Chat ID: ' + chatId);
} else {
//alert('Socket connection failed. Please try again.');
}
});
}, 500); // Adjust the timeout as needed
return;
}
// If socket.id is already available, proceed as usual
//alert('Room ID: ${chatId}\nSocket ID: ${socket.id}`); // Alert the room and socket ID
socket.emit('join_room', { chat_id: chatId });
$endChatContainer.style.display = 'block'; // Show the "End Chat" button container
toggle($chatbot, 'chatbot--closed'); // Open the chatbot only if chat_id is received
$chatbotInput.focus();
// Display the message in the chatbot window
aiMessage(data.message || 'Chat started successfully! Chat ID: ' + chatId);
} else {
showCustomAlert('Chat support is not available at this time. Please click on Contact us to send us a message and we will get back to you shortly.');
//alert('Error fetching chat ID: No chat ID in response'); // Alert if no chat ID
console.error('Error fetching chat ID: No chat ID in response');
}
} catch (error) {
console.error('Error starting chat:', error);
//alert('An error occurred while starting the chat: ' + error.message);
showCustomAlert('An error occurred while starting the chat. Please try again later.');
}
});
// Event listener for chatbot submit
$chatbotSubmit.addEventListener('click', () => {
//alert('Chatbot submit button pressed'); // Alert when the submit button is clicked
validateMessage();
}, false);
const toggle = (element, klass) => {
const classes = element.className.match(/\S+/g) || [],
index = classes.indexOf(klass);
index >= 0 ? classes.splice(index, 1) : classes.push(klass);
element.className = classes.join(' ');
};
const userMessage = content => {
$chatbotMessages.innerHTML += `
${content}
`;
scrollToBottom(); // Scroll to the bottom after adding a new message
};
const aiMessage = (content, isLoading = false, delay = 0) => {
setTimeout(() => {
removeLoader();
$chatbotMessages.innerHTML += `
${content}
`;
scrollToBottom(); // Scroll to the bottom after adding a new message
}, delay);
};
const removeLoader = () => {
let loadingElem = document.getElementById('is-loading');
if (loadingElem) $chatbotMessages.removeChild(loadingElem);
};
const scrollToBottom = () => {
$chatbotMessageWindow.scrollTop = $chatbotMessageWindow.scrollHeight;
};
const escapeScript = unsafe => {
const safeString = unsafe.
replace(//g, ' ').
replace(/&/g, ' ').
replace(/"/g, ' ').
replace(/\\/, ' ').
replace(/\s+/g, ' ');
return safeString.trim();
};
const linkify = inputText => {
return inputText.replace(urlPattern, `$1`);
};
const validateMessage = () => {
const text = $chatbotInput.value;
const safeText = text ? escapeScript(text) : '';
if (safeText.length && safeText !== ' ') {
resetInputField();
userMessage(safeText);
if (chatId) {
socket.emit('chat_message', { message: safeText, room: chatId });
} else {
console.error('Chat ID not available for sending message');
}
}
};
const resetInputField = () => {
$chatbotInput.value = '';
};
const endChat = () => {
if (chatId) {
socket.emit('leave_room', { chat_id: chatId });
socket.disconnect(); // Directly disconnect the socket
chatId = null;
$endChatContainer.style.display = 'none'; // Hide the "End Chat" button container
aiMessage('Your chat session has ended. Please', false, botLoadingDelay);
resetChatbot(); // Reset the chatbot for a new chat
} else {
console.error('No active chat to end.');
}
};
const resetChatbot = () => {
// Reset the chatbot to its initial state
$chatbotMessages.innerHTML = ''; // Clear chat messages
toggle($chatbot, 'chatbot--closed'); // Collapse the chatbot
$chatbotInput.value = ''; // Clear input field
$endChatContainer.style.display = 'none'; // Hide the end chat button
};
$endChatButton.addEventListener('click', () => {
if (confirm('Are you sure you want to end the chat?')) {
endChat(); // Call the endChat function
}
});
socket.on('connect', () => {
console.log('Successfully connected to the server');
});
socket.on('disconnect', (reason) => {
console.log(`Disconnected from server. Reason: ${reason}`);
if (reason === 'io server disconnect') {
// The disconnection was initiated by the server, you might want to try to reconnect manually here
socket.connect();
}
});
socket.on('chat_message', (data) => {
////alert('Printing data message: ' + data.message);
console.log('Received agent message:', data.message);
aiMessage(data.message); // Replace this with your function to display the message
});
socket.on('user_joined', data => {
////alert('Printing data message: ' + data.message);
aiMessage(`User ${data.username} has joined the chat.`, false, botLoadingDelay);
});
socket.on('user_left', data => {
////alert('Printing data message: ' + data.message);
aiMessage(`User ${data.username} has left the chat.`, false, botLoadingDelay);
});
socket.on('error', data => {
////alert('Printing data message: ' + data.message);
aiMessage(errorMessage);
});