Hi, Iโm MeshBuddy โ Letโs make your brand stand out!
`
bodyElement.appendChild(chatMessagePopup)
// To remove the chat Message Popup
chatMessagePopup.querySelector('.popup-minimize-normal').onclick = ()=>{
chatMessagePopup.classList.remove("active")
}
chatMessagePopup.querySelector('.dropdownCloseBtn').onclick = ()=>{
chatMessagePopup.classList.remove("active")
}
// Which use to add the chat Body Content
const chatBody = (htmlData,noNeedFullRefresh=true)=>{
if(noNeedFullRefresh){
chatMessagePopup.querySelector(".popup-chat-main-body").innerHTML = htmlData
}
}
// For the feedBackForm Form
const feedBackForm = (data,livechatdata,question)=>{
data = data.split(",")
let feedBackFormData = document.createElement("div")
feedBackFormData.className = 'rating-chat-main-body'
feedBackFormData.innerHTML = `
Thank you for Contacting Us
Please rate our supportive team in the following areas
`
// Rating click Function
feedBackFormData.querySelectorAll(".ratingIcon").forEach((star, index)=>{
star.addEventListener('click', function() {
feedBackFormData.querySelectorAll(".ratingIcon").forEach(s => s.classList.remove('checked'));
for (let i = 0; i <= index; i++) {
feedBackFormData.querySelectorAll(".ratingIcon")[i].classList.add('checked');
}
if(!feedBackFormData.querySelector(".rating-fontawesome:checked")?.value || !bodyElement.querySelector(".feedBackData").value){
feedBackFormData.querySelector(".submitFeedBackBtn").disabled = true;
}else{
feedBackFormData.querySelector(".submitFeedBackBtn").disabled = false;
}
});
})
// feed back Form submit
feedBackFormData.querySelector(".submitFeedBackBtn").onclick = ()=>{
let feedBackData = {
starRating : feedBackFormData.querySelectorAll(".ratingIcon.checked").length,
problemRectified : feedBackFormData.querySelector(".rating-fontawesome:checked").value,
feedBackData : feedBackFormData.querySelector(".feedBackData").value
}
let data = {
message :JSON.stringify(feedBackData),
username : liveChatCust.username,
id : liveChatCust.id,
customerId :liveChatCust.id,
messageType: "feedBack"
}
postDataAPI(data,'broadcast-message').then((res)=>{
chatBody(messageConversation())
emojiLoader();
feedBackFormData.querySelectorAll(".ratingIcon").forEach(e => e.classList.remove("checked") );
if(feedBackFormData.querySelector(".rating-fontawesome:checked")) {
feedBackFormData.querySelector(".rating-fontawesome:checked").checked = false;
}
feedBackFormData.querySelector(".feedBackData").value = "";
chatMessagePopup.classList.remove("rating-section-body")
bodyElement.querySelector(".feedBackBtn").classList.add('d-none')
// To Scroll Down the Conversation
bodyElement.querySelector(".popup-messages").scrollBy(0, bodyElement.querySelector(".popup-messages").scrollHeight)
})
}
// To append the feedBackFormData
if(!chatMessagePopup.querySelector(".rating-chat-main-body")){
chatMessagePopup.appendChild(feedBackFormData)
bodyElement.querySelector(".feedBackData").oninput = (res=>{
if(feedBackFormData.querySelector(".rating-fontawesome:checked")?.value && bodyElement.querySelectorAll(".ratingIcon.checked").length && bodyElement.querySelector(".feedBackData").value){
bodyElement.querySelector(".submitFeedBackBtn").disabled = false
}else{
bodyElement.querySelector(".submitFeedBackBtn").disabled = true
}
})
}
window.handleChange = (event)=>{
if(bodyElement.querySelectorAll(".ratingIcon.checked").length && bodyElement.querySelector(".feedBackData").value){
feedBackFormData.querySelector(".submitFeedBackBtn").disabled = false;
}else{
feedBackFormData.querySelector(".submitFeedBackBtn").disabled = true;
}
};
function downloadTextFile(filename, textContent) {
const blob = new Blob([textContent], { type: 'text/plain' });
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = filename;
link.click();
URL.revokeObjectURL(url);
}
// For the Text file DownLoad
const filename = 'liveChatConversation.txt';
const modifiedData = livechatdata.map(item => `${item.created_at} - ${item.livechat_username} - ${item.message}`);
const textContent = JSON.stringify(modifiedData, null, 4);
feedBackFormData.querySelector(".downloadChart").onclick = ()=>{
downloadTextFile(filename, textContent);
}
// Send email the text file
feedBackFormData.querySelector(".emailChat").onclick = ()=>{
let userInfo = JSON.parse(localStorage.LiveChatCust)
const formData = new FormData();
formData.append('file', new Blob([textContent], { type: 'text/plain' }), filename);
formData.append('email', userInfo?.email);
fetch(`${domainName}/livechat/livechat-download-file`, {
method: 'POST',
body: formData,
headers: {
'X-Csrf-Token': 'N7J5vyQ9AcmVQW9dA2n4AJV1OcWzJ4pW2umV0QoI',
'X-Requested-With' : 'XMLHttpRequest',
'Accept':'application/json, text/javascript, */*; q=0.01',
},
}).then((res)=>res.json()).then(data=>{
alert(data.message)
})
}
}
let FlowChatConversation = []
// Welcome Form
const welcomeForm = (onFlowmessage,offlineSendMessage) => {
// To Get The IP
let ipAddress = []
let geolocationPermission = false
fetch('https://ipinfo.io/json')
.then(response => response.json())
.then(data => {
ipAddress = data
})
.catch((error) =>{
console.error('Error fetching IP address:', error)
ipAddress.ip = 'null'
ipAddress.city = 'null'
ipAddress.region = 'null'
ipAddress.timezone = 'null'
});
// To getting the Country Name
function getCountryName(countryCode) {
const countryMapping = {
"BD": "Bangladesh",
"BE": "Belgium",
"BF": "Burkina Faso",
"BG": "Bulgaria",
"BA": "Bosnia and Herzegovina",
"BB": "Barbados",
"WF": "Wallis and Futuna",
"BL": "Saint Barthelemy",
"BM": "Bermuda",
"BN": "Brunei",
"BO": "Bolivia",
"BH": "Bahrain",
"BI": "Burundi",
"BJ": "Benin",
"BT": "Bhutan",
"JM": "Jamaica",
"BV": "Bouvet Island",
"BW": "Botswana",
"WS": "Samoa",
"BQ": "Bonaire, Saint Eustatius and Saba ",
"BR": "Brazil",
"BS": "Bahamas",
"JE": "Jersey",
"BY": "Belarus",
"BZ": "Belize",
"RU": "Russia",
"RW": "Rwanda",
"RS": "Serbia",
"TL": "East Timor",
"RE": "Reunion",
"TM": "Turkmenistan",
"TJ": "Tajikistan",
"RO": "Romania",
"TK": "Tokelau",
"GW": "Guinea-Bissau",
"GU": "Guam",
"GT": "Guatemala",
"GS": "South Georgia and the South Sandwich Islands",
"GR": "Greece",
"GQ": "Equatorial Guinea",
"GP": "Guadeloupe",
"JP": "Japan",
"GY": "Guyana",
"GG": "Guernsey",
"GF": "French Guiana",
"GE": "Georgia",
"GD": "Grenada",
"GB": "United Kingdom",
"GA": "Gabon",
"SV": "El Salvador",
"GN": "Guinea",
"GM": "Gambia",
"GL": "Greenland",
"GI": "Gibraltar",
"GH": "Ghana",
"OM": "Oman",
"TN": "Tunisia",
"JO": "Jordan",
"HR": "Croatia",
"HT": "Haiti",
"HU": "Hungary",
"HK": "Hong Kong",
"HN": "Honduras",
"HM": "Heard Island and McDonald Islands",
"VE": "Venezuela",
"PR": "Puerto Rico",
"PS": "Palestinian Territory",
"PW": "Palau",
"PT": "Portugal",
"SJ": "Svalbard and Jan Mayen",
"PY": "Paraguay",
"IQ": "Iraq",
"PA": "Panama",
"PF": "French Polynesia",
"PG": "Papua New Guinea",
"PE": "Peru",
"PK": "Pakistan",
"PH": "Philippines",
"PN": "Pitcairn",
"PL": "Poland",
"PM": "Saint Pierre and Miquelon",
"ZM": "Zambia",
"EH": "Western Sahara",
"EE": "Estonia",
"EG": "Egypt",
"ZA": "South Africa",
"EC": "Ecuador",
"IT": "Italy",
"VN": "Vietnam",
"SB": "Solomon Islands",
"ET": "Ethiopia",
"SO": "Somalia",
"ZW": "Zimbabwe",
"SA": "Saudi Arabia",
"ES": "Spain",
"ER": "Eritrea",
"ME": "Montenegro",
"MD": "Moldova",
"MG": "Madagascar",
"MF": "Saint Martin",
"MA": "Morocco",
"MC": "Monaco",
"UZ": "Uzbekistan",
"MM": "Myanmar",
"ML": "Mali",
"MO": "Macao",
"MN": "Mongolia",
"MH": "Marshall Islands",
"MK": "Macedonia",
"MU": "Mauritius",
"MT": "Malta",
"MW": "Malawi",
"MV": "Maldives",
"MQ": "Martinique",
"MP": "Northern Mariana Islands",
"MS": "Montserrat",
"MR": "Mauritania",
"IM": "Isle of Man",
"UG": "Uganda",
"TZ": "Tanzania",
"MY": "Malaysia",
"MX": "Mexico",
"IL": "Israel",
"FR": "France",
"IO": "British Indian Ocean Territory",
"SH": "Saint Helena",
"FI": "Finland",
"FJ": "Fiji",
"FK": "Falkland Islands",
"FM": "Micronesia",
"FO": "Faroe Islands",
"NI": "Nicaragua",
"NL": "Netherlands",
"NO": "Norway",
"NA": "Namibia",
"VU": "Vanuatu",
"NC": "New Caledonia",
"NE": "Niger",
"NF": "Norfolk Island",
"NG": "Nigeria",
"NZ": "New Zealand",
"NP": "Nepal",
"NR": "Nauru",
"NU": "Niue",
"CK": "Cook Islands",
"XK": "Kosovo",
"CI": "Ivory Coast",
"CH": "Switzerland",
"CO": "Colombia",
"CN": "China",
"CM": "Cameroon",
"CL": "Chile",
"CC": "Cocos Islands",
"CA": "Canada",
"CG": "Republic of the Congo",
"CF": "Central African Republic",
"CD": "Democratic Republic of the Congo",
"CZ": "Czech Republic",
"CY": "Cyprus",
"CX": "Christmas Island",
"CR": "Costa Rica",
"CW": "Curacao",
"CV": "Cape Verde",
"CU": "Cuba",
"SZ": "Swaziland",
"SY": "Syria",
"SX": "Sint Maarten",
"KG": "Kyrgyzstan",
"KE": "Kenya",
"SS": "South Sudan",
"SR": "Suriname",
"KI": "Kiribati",
"KH": "Cambodia",
"KN": "Saint Kitts and Nevis",
"KM": "Comoros",
"ST": "Sao Tome and Principe",
"SK": "Slovakia",
"KR": "South Korea",
"SI": "Slovenia",
"KP": "North Korea",
"KW": "Kuwait",
"SN": "Senegal",
"SM": "San Marino",
"SL": "Sierra Leone",
"SC": "Seychelles",
"KZ": "Kazakhstan",
"KY": "Cayman Islands",
"SG": "Singapore",
"SE": "Sweden",
"SD": "Sudan",
"DO": "Dominican Republic",
"DM": "Dominica",
"DJ": "Djibouti",
"DK": "Denmark",
"VG": "British Virgin Islands",
"DE": "Germany",
"YE": "Yemen",
"DZ": "Algeria",
"US": "United States",
"UY": "Uruguay",
"YT": "Mayotte",
"UM": "United States Minor Outlying Islands",
"LB": "Lebanon",
"LC": "Saint Lucia",
"LA": "Laos",
"TV": "Tuvalu",
"TW": "Taiwan",
"TT": "Trinidad and Tobago",
"TR": "Turkey",
"LK": "Sri Lanka",
"LI": "Liechtenstein",
"LV": "Latvia",
"TO": "Tonga",
"LT": "Lithuania",
"LU": "Luxembourg",
"LR": "Liberia",
"LS": "Lesotho",
"TH": "Thailand",
"TF": "French Southern Territories",
"TG": "Togo",
"TD": "Chad",
"TC": "Turks and Caicos Islands",
"LY": "Libya",
"VA": "Vatican",
"VC": "Saint Vincent and the Grenadines",
"AE": "United Arab Emirates",
"AD": "Andorra",
"AG": "Antigua and Barbuda",
"AF": "Afghanistan",
"AI": "Anguilla",
"VI": "U.S. Virgin Islands",
"IS": "Iceland",
"IR": "Iran",
"AM": "Armenia",
"AL": "Albania",
"AO": "Angola",
"AQ": "Antarctica",
"AS": "American Samoa",
"AR": "Argentina",
"AU": "Australia",
"AT": "Austria",
"AW": "Aruba",
"IN": "India",
"AX": "Aland Islands",
"AZ": "Azerbaijan",
"IE": "Ireland",
"ID": "Indonesia",
"UA": "Ukraine",
"QA": "Qatar",
"MZ": "Mozambique"
};
return countryMapping[countryCode?.toUpperCase()] || 'Unknown Country';
}
// To get the User Browser Name
function getBrowserName() {
if (typeof navigator.userAgentData !== 'undefined') {
// Use navigator.userAgentData if available (Chrome, Edge, Opera)
return navigator.userAgentData.brands[navigator.userAgentData.brands.length - 1].brand;
} else {
// Fallback to parsing the User-Agent string
const userAgent = navigator.userAgent;
let browserName;
if (userAgent.match(/Firefox\//i)) {
browserName = "Firefox";
} else if (userAgent.match(/Chrome\//i)) {
browserName = "Chrome";
} else if (userAgent.match(/Edge\//i)) {
browserName = "Edge";
} else if (userAgent.match(/Safari\//i)) {
browserName = "Safari";
} else if (userAgent.match(/Opera\//i)) {
browserName = "Opera";
} else if (userAgent.match(/MSIE\//i)) {
browserName = "Internet Explorer";
} else {
browserName = "Unknown";
}
return browserName;
}
}
// To get the geolocation data
if(navigator.geolocation){
navigator.geolocation.getCurrentPosition(getLoc,errorlog)
}
function getLoc(data){
geolocationPermission = true
const latitude = data.coords.latitude;
const longitude = data.coords.longitude;
// Construct the Nominatim API URL
const apiUrl = `https://nominatim.openstreetmap.org/reverse?lat=${latitude}&lon=${longitude}&format=json`;
// Make a request to the API
fetch(apiUrl)
.then(response => response.json())
.then(data => {
if (data) {
const address = data;
geolocationPermission = address
} else {
console.error('Unable to retrieve address.');
}
})
.catch(error => {
console.error('Error fetching data from Nominatim API:', error);
});
}
function errorlog(data) {
geolocationPermission = false
}
// To send the form data to DB
myFunction = ()=>{
// To disabled the submit Button
bodyElement.querySelector("#chatUserdata [type='button']").disabled = true
let Userdata = bodyElement.querySelector("#chatUserdata");
const formData = new FormData(Userdata);
var name = formData.get('name');
var email = formData.get('email');
var mobile = formData.get('mobilenumber');
// Clear existing errors
Userdata.querySelectorAll('.errorFormMessage').forEach(elem => elem.classList.remove('errorFormMessage'));
Userdata.querySelectorAll('.text-danger').forEach(elem => elem.remove());
let errors = [];
// Check for name
if (!name) {
Userdata.querySelector("#username").classList.add("errorFormMessage");
errors.push({ element: "#username", message: "Please enter your full name" });
}
// Check for email
if (!email) {
Userdata.querySelector("#email").classList.add("errorFormMessage");
errors.push({ element: "#email", message: "Please enter your email" });
} else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
Userdata.querySelector("#email").classList.add("errorFormMessage");
errors.push({ element: "#email", message: "Please enter a valid email address." });
}
// Check for mobile
if (!mobile) {
Userdata.querySelector("#mobile").classList.add("errorFormMessage");
errors.push({ element: "#mobile", message: "Please enter your mobile number" });
}
errors.forEach(error => {
let errorSpan = document.createElement("span");
errorSpan.className = "text-danger ms-2";
errorSpan.innerText = error.message;
Userdata.querySelector(error.element).closest("div").appendChild(errorSpan);
});
if (errors.length > 0) {
bodyElement.querySelector("#chatUserdata [type='button']").disabled = false;
} else {
let postData
if(geolocationPermission){
postData = {
"name" : formData.get("name"),
"email" : formData.get("email"),
"mobilenumber" : formData.get("mobilenumber"),
"browserAndOSInfo" : getBrowserName(),
"flowChatMessages" : JSON.stringify(FlowChatConversation),
"loginurl" : location.href,
"fullAddress" : geolocationPermission.display_name,
"loginIp" : ipAddress.ip,
"city" : geolocationPermission.address.city,
"state" : geolocationPermission.address.state,
"timezone" : ipAddress.timezone,
"country" : geolocationPermission.address.country,
"visitoruniqueid" : localStorage.getItem("LiveChatVisitor") ? localStorage.getItem("LiveChatVisitor") : null,
}
}else{
postData = {
"name" : formData.get("name"),
"email" : formData.get("email"),
"mobilenumber" : formData.get("mobilenumber"),
"browserAndOSInfo" : getBrowserName(),
"flowChatMessages" : JSON.stringify(FlowChatConversation),
"loginurl" : location.href,
"fullAddress" : `${ipAddress.city}, ${ipAddress.region}, ${getCountryName(ipAddress.country)}`,
"loginIp" : ipAddress.ip,
"city" : ipAddress.city,
"state" : ipAddress.region,
"timezone" : ipAddress.timezone,
"country" : getCountryName(ipAddress.country),
"visitoruniqueid" : localStorage.getItem("LiveChatVisitor") ? localStorage.getItem("LiveChatVisitor") : null,
}
}
let processData = postDataAPI(postData,'customerdata')
processData.then(data=>{
let responceData = JSON.parse(data)
if(responceData.success){
if(localStorage.getItem("LiveChatVisitor")){
localStorage.removeItem("LiveChatVisitor");
}
localStorage.setItem("LiveChatCust",JSON.stringify(responceData.custdata))
// TO Add the customer Online
postDataAPI({custID : JSON.parse(localStorage.LiveChatCust).id},'customer-online').then((ele)=>{
})
// To send the First Message
if(onFlowmessage){
let firstMessageData = {
message : onFlowmessage,
username : responceData.custdata.username,
id : responceData.custdata.id,
customerId :responceData.custdata.id
}
// To Add the first Message
postDataAPI(firstMessageData,'broadcast-message').then(subdata=>{
// To Send the Offline Message
if(offlineSendMessage){
let liveChatCust = localStorage.LiveChatCust ? JSON.parse(localStorage.LiveChatCust) : []
let welcomeMessagedata = {
message :offlineSendMessage.errorMessage,
username : liveChatCust.username,
id : liveChatCust.id,
customerId :liveChatCust.id,
messageType: "welcomeMessage"
}
postDataAPI(welcomeMessagedata,'broadcast-message').then((ele)=>{
chatBody(messageConversation())
emojiLoader();
})
}else{
chatBody(messageConversation())
emojiLoader();
}
})
}
}
})
processData.catch(error=>{
console.log("error",error);
})
}
}
// To submit the form when the user presses the Enter key
setTimeout(() => {
bodyElement.getElementById("chatUserdata").addEventListener("keydown", function (event) {
if (event.key === "Enter") {
event.preventDefault(); // Prevent the default form submission
bodyElement.querySelector("#chatUserdata .wecomeFormSubmitBtn").click()
}
});
let submitDetailsButton = bodyElement.querySelector('.wecomeFormSubmitBtn');
const validationEvent = () => {
const usernameInput = bodyElement.querySelector('#username');
const mobileInput = bodyElement.querySelector('#mobile');
const emailInput = bodyElement.querySelector('#email');
const isUsernameValid = usernameInput.value.length > 4;
const isMobileValid = mobileInput.value.length > 6;
const isEmailValid = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(emailInput.value);
// Check all conditions
if (isUsernameValid && isMobileValid && isEmailValid) {
submitDetailsButton.disabled = false;
} else {
submitDetailsButton.disabled = true;
}
};
bodyElement.querySelector('#username').addEventListener('input', (ele) => {
if (ele.target.value.length <= 4) {
ele.target.classList.add('is-invalid');
ele.target.classList.remove('is-valid');
errorBtn = true;
validationEvent();
} else {
ele.target.classList.add('is-valid');
ele.target.classList.remove('is-invalid');
validationEvent();
}
})
bodyElement.querySelector('#mobile').addEventListener('input', (ele) => {
if (ele.target.value.length <= 6) {
ele.target.classList.add('is-invalid');
ele.target.classList.remove('is-valid');
validationEvent();
} else {
ele.target.classList.add('is-valid');
ele.target.classList.remove('is-invalid');
validationEvent();
}
})
bodyElement.querySelector('#email').addEventListener('input', (event) => {
const email = event.target.value;
const isValidEmail = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
if (!isValidEmail) {
event.target.classList.add('is-invalid');
event.target.classList.remove('is-valid');
validationEvent();
} else {
event.target.classList.remove('is-invalid');
event.target.classList.add('is-valid');
validationEvent();
}
});
}, 1000);
return (
`
Enter Basic Information
Kindly provide your name and email address before we begin
`
)
}
// To add the all Message conversation
let liveChatCust = localStorage.LiveChatCust ? JSON.parse(localStorage.LiveChatCust) : []
const messageConversation = ()=>{
// to Update the liveChatCust
liveChatCust = localStorage.LiveChatCust ? JSON.parse(localStorage.LiveChatCust) : []
let OfflineMessagePermission = false
sendMessage = ()=>{
if(liveChatCust && liveChatCust.userType == 'livevisitor'){
// To open The welcome Form
chatBody(welcomeForm(bodyElement.querySelector("#status_message").textContent,OfflineMessagePermission))
}else{
afterMessageSend = false
// To send the Typing Indication After message send
setTimeout(() => {
afterMessageSend = true
}, 500);
const now = new Date();
const hours = now.getHours();
const minutes = now.getMinutes();
const period = hours >= 12 ? "PM" : "AM";
function sanitizeHTML(input) {
const map = {
'&': '&',
'<': '<',
'>': '>',
'"': '"',
"'": ''',
'/': '/', // For forward slash
'`': '`', // Backtick
'=': '=' // Equals
};
return input.replace(/[&<>"'/`=]/g, function (char) {
return map[char];
});
}
const formattedTime = `${((hours + 11) % 12) + 1}:${minutes}${period}`;
if(bodyElement.querySelector("#status_message").textContent.trim()){
let data = {
message : sanitizeHTML(bodyElement.querySelector("#status_message").textContent),
username : liveChatCust.username,
id : liveChatCust.id,
customerId :liveChatCust.id
}
postDataAPI(data,'broadcast-message').then((ele)=>{
// For the Offline Message Send
var allDirectChatMsgs = bodyElement.querySelectorAll('.direct-chat-msg');
var filteredDirectChatMsgs = Array.from(allDirectChatMsgs).filter(function(element) {
return !element.classList.contains('right');
});
var lastDirectChatMsg = filteredDirectChatMsgs[filteredDirectChatMsgs.length - 1];
if(OfflineMessagePermission && lastDirectChatMsg.innerText.replace(/\b\d{1,2}:\d{2}[APMapm]{2}\b/, '').trim() != OfflineMessagePermission.errorMessage.trim()){
bodyElement.querySelector('.direct-chat-messages').appendChild(OfflineMessageIndication(OfflineMessagePermission.errorMessage))
// For the Message Seen Indication
if(chatMessagePopup.classList.contains('active')){
postDataAPI(JSON.parse(localStorage.LiveChatCust),'user-seen-messages-indication')
}
bodyElement.querySelector(".popup-messages").scrollBy(0, bodyElement.querySelector(".popup-messages").scrollHeight)
}
})
// let directChatMessages = bodyElement.querySelector(".direct-chat-messages")
// let custMessage = document.createElement("div");
// custMessage.className = "direct-chat-msg right"
// custMessage.innerHTML = `
//
`
return agentLi
}
let conversationDiv = document.createElement("div");
conversationDiv.className = "direct-chat-messages"
conversationDiv.style.overflow = "hidden"
getDataAPI(`singlecustdata/${JSON.parse(localStorage.LiveChatCust)?.id}`).then((data)=>{
if(data.nocustomerdatafound){
chatBody(messageConversationFlow())
localStorage.removeItem("LiveChatCust")
return false
}
// To modify the size of the Live Chat icon.
if(data.livechatcust.livechatIconSize == "large"){
popupButton.classList.add("chat-popup-lg")
}else{
popupButton.classList.remove("chat-popup-lg")
}
if(document.documentElement.getAttribute('dir') == 'rtl'){
chatMessagePopup.setAttribute('dir', 'ltr');
popupButton.setAttribute('dir', 'ltr');
}
// To Change the live Chat Position
if(data.livechatcust.livechatPosition == "left"){
mainLiveChatDiv.setAttribute('appearance', 'left');
appearance = "left";
chatMessagePopup.setAttribute('appearance', appearance)
popupButton.setAttribute('appearance', appearance)
chatMessagePopup.classList.add("chat-message-popup-right")
popupButton.classList.add("chat-popup-right")
}else{
mainLiveChatDiv.setAttribute('appearance', 'right');
appearance = "right";
chatMessagePopup.setAttribute('appearance', appearance)
popupButton.setAttribute('appearance', appearance)
chatMessagePopup.classList.remove("chat-message-popup-right")
popupButton.classList.remove("chat-popup-right")
}
if(data.livechatcust.banstatus == 'banned' && data.livechatcust.login_ip == localStorage.getItem('presentChatIp')){
// popupButton.classList.add("d-none")
}else{
popupButton.classList.remove("d-none")
popupButton.style.setProperty('--primary', data.livechatcust.livechatthemecolor);
}
bodyElement.querySelector(".chat-icon-text").classList.remove('d-none');
bodyElement.querySelector(".chat-icon-text").innerText = data.livechatcust.beforechatshowdata;
if(bodyElement.querySelector(".livechatpopuptitle")){
bodyElement.querySelector(".livechatpopuptitle").innerText = data?.livechatcust?.livechatpopuptitle;
}
if(bodyElement.querySelector(".livechatpopupsubtitle")){
bodyElement.querySelector(".livechatpopupsubtitle").innerText = data?.livechatcust?.livechatpopupsubtitle;
}
chatMessagePopup.style.setProperty('--primary', data.livechatcust.livechatthemecolor);
// To add the FeedBack Click Event
if(data.livechatcust.engage_conversation && JSON.parse(data.livechatcust.engage_conversation).length){
chatMessagePopup.querySelector(".feedBackBtn").classList.remove("d-none")
chatMessagePopup.querySelector(".feedBackBtn").onclick = ()=>{
chatMessagePopup.classList.add("rating-section-body")
feedBackForm(data.livechatcust.livechatFeedbackDropdown,data.livechatdata,data.livechatcust.LivechatCustFeedbackQuestion)
}
}
// For the Chat Flow Created Date
let currentDate = null;
// For the Chat Flow Messages
if(data.livechatcust.chat_flow_messages){
const messageDate = formatDateString(data.livechatcust.created_at);
conversationDiv.innerHTML += `
${messageDate}
`;
currentDate = messageDate;
JSON.parse(data.livechatcust.chat_flow_messages).map((flowMes)=>{
let updatedFlowMes = flowMes
updatedFlowMes.created_at = data.livechatcust.created_at
if(flowMes.authMessage == "agent"){
conversationDiv.appendChild(AgentMessage(updatedFlowMes))
}else{
conversationDiv.appendChild(customerMessage(updatedFlowMes))
}
})
}
let unreadIndexNumber = 0
// For the Messages append
data.livechatdata.map((chatdata)=>{
const messageDate = formatDateString(chatdata.created_at);
if (messageDate !== currentDate){
conversationDiv.innerHTML += `
${messageDate}
`;
// For the date of the Chat
currentDate = messageDate;
}{
if(!chatdata.livechat_cust_id && chatdata.status != "comment"){
conversationDiv.appendChild(AgentMessage(chatdata))
}else{
if(chatdata.status != "comment"){
conversationDiv.appendChild(customerMessage(chatdata))
}
}
}
// To get the get the unread index number
if(chatdata.livechat_user_id && chatdata.status != "comment" && chatdata.status != "seen"){
unreadIndexNumber = unreadIndexNumber + 1
}
})
// To add the Unread Index Number
if(unreadIndexNumber){
popupButton.querySelector('.unreadIndexNumberPopup').innerText = unreadIndexNumber
popupButton.querySelector('.unreadIndexNumberPopup').classList.remove('d-none')
}
// To show the LiveChat include Users informaction
if(data.livechatcust.engage_conversation){
let livechatInfo = document.createElement('div')
livechatInfo.innerHTML = `
`
let onlineUserNames = [];
JSON.parse(data.livechatcust.engage_conversation).map((user,index)=>{
let userSpan = document.createElement('span')
userSpan.className = `avatar avatar-sm brround`
userSpan.setAttribute('data-bs-toggle', 'tooltip');
userSpan.setAttribute('data-bs-custom-class', 'livechat-tooltip');
userSpan.setAttribute('data-bs-placement', 'top');
userSpan.setAttribute('data-bs-title', `${user.name}`);
userSpan.style.backgroundImage = `url('${user.profileimage}')`
if(index+1 <= 2){
livechatInfo.querySelector(".avatar-list-stacked").appendChild(userSpan)
}
onlineUserNames.push(user.name)
})
if(JSON.parse(data.livechatcust.engage_conversation).length > 2){
let userSpan = document.createElement('span')
userSpan.className = `avatar brround`
userSpan.setAttribute('data-bs-toggle', 'tooltip');
userSpan.setAttribute('data-bs-custom-class', 'livechat-tooltip');
userSpan.setAttribute('data-bs-placement', 'top');
userSpan.setAttribute('data-bs-title', `${data.livechatcust.LivechatCustWelcomeMsg}`);
userSpan.innerHTML = `+${JSON.parse(data.livechatcust.engage_conversation).length - 2}`
livechatInfo.querySelector(".avatar-list-stacked").appendChild(userSpan)
}
let span = document.createElement('span');
span.classList.add('className');
span.textContent = data.livechatcust?.LivechatCustWelcomeMsg;
livechatInfo.querySelector(".main-avatar").appendChild(span)
if(bodyElement.querySelector(".before-chatstart")){
if(bodyElement.querySelector(".onlineorofflinediv")){
bodyElement.querySelector(".onlineorofflinediv").remove()
}
bodyElement.querySelector(".before-chatstart").innerHTML = livechatInfo.innerHTML
}
}
// For No One joined At the time to show the online users info
if(!JSON.parse(data.livechatcust.engage_conversation).length && data.livechatcust.onlineUsers && JSON.parse(data.livechatcust.onlineUsers).length){
let livechatInfo = document.createElement('div')
livechatInfo.innerHTML = `
`
directChatMessages.querySelector("#uploadingIndication").remove()
directChatMessages.appendChild(custMessage)
// To add the Image Viwer
bodyElement.querySelectorAll(".imageMessageLiveChat").forEach((element)=>{
element.parentElement.onclick = ()=>{
window.open(element.getAttribute('imagesrc'))
}
})
bodyElement.querySelector(".popup-messages").scrollBy(0, bodyElement.querySelector(".popup-messages").scrollHeight)
})
.catch(error => {
console.error('Error:', error);
});
}else{
alert(ThereIsError.errorMessage)
}
}
}
// Offline no need to display chat
if(!parseInt(data.livechatcust.offlineDisplayLiveChat) && data.livechatcust.isonlineoroffline == "offline"){
chatMessagePopup.remove()
popupButton.remove()
}
// To remove the LiveChat
if(data.livechatcust.liveChatHidden == "true"){
chatMessagePopup.remove()
popupButton.remove()
}
// To remove the live chat online indaction
const beforeUnloadHandler = (event)=>{
postDataAPI({custID : data.livechatcust.id},'remove-customer-online').then((ele)=>{
})
setTimeout(() => {
if(bodyElement.querySelector(".chat-message-popup").classList.contains("active")){
postDataAPI({custID : JSON.parse(localStorage.LiveChatCust).id},'customer-online').then((ele)=>{
})
}
}, 3000);
event.returnValue = "Write something clever here.."
}
// Adding beforeunload event To Livechat BTN
bodyElement.querySelector("#chat-popup").addEventListener("click",()=>{
window.addEventListener('beforeunload', beforeUnloadHandler)
})
// TO Remove the beforeunload event To Livechat Close BTN
bodyElement.querySelector(".popup-minimize-normal").addEventListener("click",()=>{
window.removeEventListener('beforeunload', beforeUnloadHandler)
postDataAPI({custID : data.livechatcust.id},'remove-customer-online').then((ele)=>{
})
})
// To remove the online in the initial state
if(!bodyElement.querySelector(".chat-message-popup").classList.contains('active')){
postDataAPI({custID : data.livechatcust.id},'remove-customer-online').then((ele)=>{
})
}
})
// Typing
var debounceTimeout;
var afterMessageSend = true
customerTyping = (ele)=>{
clearTimeout(debounceTimeout);
debounceTimeout = setTimeout(function() {
if(afterMessageSend){
textAreaChanged(ele);
}
}, 500);
}
function textAreaChanged(textarea) {
let data = {
message :null,
username : liveChatCust.username,
id : null,
customerId :liveChatCust.id,
typingMessage : textarea.textContent
}
postDataAPI(data,'broadcast-message-typing')
}
// Enter Message Send Function
handleKeyDown = (event)=>{
if (event.key === 'Enter' && !event.shiftKey) {
event.preventDefault();
sendMessage()
}
}
return (
`
`
)
}
// Message flow conversation
const messageConversationFlow = ()=>{
let flowChatData
let OfflineMessagePermission = false
// Getting the chat Flow data
getDataAPI(`flow/${currentScriptElement.getAttribute('testitout') ? currentScriptElement.getAttribute('testitout') : null}/${localStorage.getItem('presentChatIp') ? localStorage.getItem('presentChatIp') : null}`).then((data)=>{
if(data.success){
// To modify the size of the Live Chat icon.
if(data.success.livechatIconSize == "large"){
popupButton.classList.add("chat-popup-lg")
}else{
popupButton.classList.remove("chat-popup-lg")
}
if(document.documentElement.getAttribute('dir') == 'rtl'){
chatMessagePopup.setAttribute('dir', 'ltr');
popupButton.setAttribute('dir', 'ltr');
}
// To Change the live Chat Position
if(data.success.livechatPosition == "left"){
mainLiveChatDiv.setAttribute('dir', 'rtl');
chatMessagePopup.classList.add("chat-message-popup-right")
popupButton.classList.add("chat-popup-right")
}else{
mainLiveChatDiv.setAttribute('dir', 'ltr');
chatMessagePopup.classList.remove("chat-message-popup-right")
popupButton.classList.remove("chat-popup-right")
}
if(data.success.ipbannedstatus != 'banned'){
popupButton.classList.remove("d-none")
popupButton.style.setProperty('--primary', data.success.livechatthemecolor);
}
bodyElement.querySelector(".chat-icon-text").classList.remove('d-none');
bodyElement.querySelector(".chat-icon-text").innerText = data.success.beforechatshowdata;
bodyElement.querySelector(".livechatpopuptitle").innerText = data.success.livechatpopuptitle;
bodyElement.querySelector(".livechatpopupsubtitle").innerText = data.success.livechatpopupsubtitle;
chatMessagePopup.style.setProperty('--primary', data.success.livechatthemecolor);
flowChatData = data.success.liveChatFlow ? JSON.parse(data.success.liveChatFlow).nodes : null
// To shoe the first Welcome Message
if(data.success.liveChatFlow && JSON.parse(data.success.liveChatFlow).nodes['1'].name == "Welcome Message" && !bodyElement.querySelector(".popup-messages")?.children.length){
AgentMessage(JSON.parse(data.success.liveChatFlow).nodes['1'])
}
// To show the LiveChat Info informaction
if(JSON.parse(data.success.onlineUsers).length){
bodyElement.querySelector('.onlineorofflinediv')?.remove();
let livechatInfo = document.createElement('div')
livechatInfo.className = "onlineorofflinediv mt-4 me-3"
livechatInfo.innerHTML = `
`
let onlineUserNames = []
JSON.parse(data.success.onlineUsers).map((user,index)=>{
let userSpan = document.createElement('span')
userSpan.className = `avatar brround`
userSpan.setAttribute('data-bs-toggle', 'tooltip');
userSpan.setAttribute('data-bs-custom-class', 'livechat-tooltip');
userSpan.setAttribute('data-bs-placement', 'top');
userSpan.setAttribute('data-bs-title', `${user.name}`);
userSpan.style.backgroundImage = `url('${user.profileurl}')`;
if(index+1 <= 2){
let onlineSpan = document.createElement('span')
onlineSpan.className = "avatar-status bg-green"
userSpan.appendChild(onlineSpan)
livechatInfo.querySelector(".avatar-list-stacked").appendChild(userSpan)
}
onlineUserNames.push(user.name)
})
if(JSON.parse(data.success.onlineUsers).length > 2){
let userSpan = document.createElement('span')
userSpan.className = `avatar brround`;
userSpan.setAttribute('data-bs-toggle', 'tooltip');
userSpan.setAttribute('data-bs-custom-class', 'livechat-tooltip');
userSpan.setAttribute('data-bs-placement', 'top');
userSpan.setAttribute('data-bs-title', `${data.success.LivechatCustWelcomeMsg}`);
userSpan.innerHTML = `+${JSON.parse(data.success.onlineUsers).length - 2}`
livechatInfo.querySelector(".avatar-list-stacked").appendChild(userSpan)
}
let span = document.createElement('span');
span.classList.add('className');
span.textContent = data.livechatcust?.LivechatCustWelcomeMsg;
livechatInfo.querySelector(".avatar-list-stacked").appendChild(span)
if(bodyElement.querySelector(".supportusersdata")){
bodyElement.querySelector(".supportusersdata").insertAdjacentElement('afterend', livechatInfo);
}
}else{
bodyElement.querySelector('.onlineorofflinediv')?.remove();
let livechatInfo = document.createElement('div')
livechatInfo.className = "onlineorofflinediv mt-4 me-3"
livechatInfo.innerHTML = `
`
// For the online user names
livechatInfo.querySelector('.infoNamesText').innerHTML = `
`
bodyElement.querySelector(".offline-msg")?.remove()
if(bodyElement.querySelector(".supportusersdata")){
bodyElement.querySelector(".supportusersdata").insertAdjacentElement('afterend', livechatInfo);
}
}
initializeTooltips();
// If it is Online
let statusIndicator = bodyElement.querySelector('.online-status-indicator');
console.log(data.success.isonlineoroffline);
console.log(statusIndicator);
if(data.success.isonlineoroffline == "online" && data.success.OnlineStatusMessage){
statusIndicator.classList.add('online')
statusIndicator.classList.remove('offline')
// To Add the Online Message Status
if (statusIndicator) {
statusIndicator.innerHTML = `
${data.success.OnlineStatusMessage}
`;
}
}
// If it is Offline
if(data.success.isonlineoroffline == "offline" && data.success.OfflineStatusMessage){
statusIndicator.classList.remove('online')
statusIndicator.classList.add('offline')
OfflineMessagePermission = { errorMessage: data.success.OfflineMessage}
// To Add the Offline Message Status
if (statusIndicator) {
statusIndicator.innerHTML = `
${data.success.OfflineStatusMessage}
`;
}
}
// For Offline remove liveChat
if(data.success.isonlineoroffline == "offline" && !parseInt(data.success.offlineDisplayLiveChat)){
chatMessagePopup.remove()
popupButton.remove()
}
// To remove the liveCht
if(data.success.liveChatHidden == "true"){
chatMessagePopup.remove()
popupButton.remove()
}
}
})
// Agent Message div
let AgentMessage = (data)=>{
// For the message div
let agentLi = document.createElement("div");
agentLi.className = "direct-chat-msg"
agentLi.innerHTML = `
${data.data.text}
`
// For the Option buttons
let liveChatOptionBtn = document.createElement("div")
liveChatOptionBtn.className = "d-flex flex-wrap liveChatOptionBtn"
let typeIndicator = document.createElement('div')
typeIndicator.className = 'typing-indicator';
typeIndicator.innerHTML = `
`
// connections node Loop
data.outputs.act.connections.map((connectedNode)=>{
let optionNode = document.createElement("div")
optionNode.onclick = ()=>{
// To remove the Options
bodyElement.querySelector(".liveChatOptionBtn").remove()
// Append the selected option as a customer message
bodyElement.querySelector(".popup-messages").appendChild(customerMessage(flowChatData[connectedNode.node]))
bodyElement.querySelector('.popup-messages').appendChild(typeIndicator)
setTimeout(() => {
// to loop the messages and options
if(flowChatData[connectedNode.node].inputs.text.connections[0]){
AgentMessage(flowChatData[flowChatData[connectedNode.node].inputs.text.connections[0].node])
}
bodyElement.querySelector('.popup-messages .typing-indicator')?.remove();
}, 1000);
}
optionNode.innerHTML = ``
liveChatOptionBtn.appendChild(optionNode)
bodyElement.querySelector('.popup-messages .typing-indicator')?.remove();
})
// For the Message
bodyElement.querySelector(".popup-messages")?.appendChild(agentLi);
// For the Options
bodyElement.querySelector(".popup-messages")?.appendChild(liveChatOptionBtn);
}
// Customer div
let customerMessage = (data)=>{
let custLi = document.createElement("div");
custLi.className = "direct-chat-msg right"
custLi.innerHTML = `
${data.data.optionName}
`
return custLi
}
function sanitizeHTML(input) {
const map = {
'&': '&',
'<': '<',
'>': '>',
'"': '"',
"'": ''',
'/': '/', // For forward slash
'`': '`', // Backtick
'=': '=' // Equals
};
return input.replace(/[&<>"'/`=]/g, function (char) {
return map[char];
});
}
sendMessage = ()=>{
if(bodyElement.querySelector("#status_message").textContent.length){
// For the Making Chat Flow Message Array
bodyElement.querySelectorAll(".popup-messages .direct-chat-msg").forEach((element)=>{
if(element.classList.contains('right')){
FlowChatConversation.push({
authMessage: 'cust',
message: element.querySelector(".direct-chat-text").innerText
})
}else{
FlowChatConversation.push({
authMessage: 'agent',
message: element.querySelector(".direct-chat-text").innerText
})
}
})
// To open The welcome Form
chatBody(welcomeForm(sanitizeHTML(bodyElement.querySelector("#status_message").textContent),OfflineMessagePermission))
bodyElement.querySelector('.popup-minimize-normal-fields')?.addEventListener('click', function() {
const targetElement = bodyElement.querySelector('.popup-fields');
if (targetElement) {
targetElement.classList.add('d-none');
chatBody(messageConversationFlow());
}
});
}
}
// Enter Message Send Function
handleKeyDown = (ele)=>{
if (ele.key === 'Enter' && !ele.shiftKey) {
ele.preventDefault();
sendMessage()
}
}
return (
`
`
)
}
// To add the Flow Message After the 24 Hours
const basedOnTimeMessageConversationFlow = ()=>{
let flowChatElement = document.createElement("div")
flowChatElement.className = "basedOnTimeMessageConversationFlowDiv"
let flowChatData
// Getting the chat Flow data
getDataAPI(`flow/null`).then((data)=>{
if(data.success){
flowChatData = JSON.parse(data.success.liveChatFlow).nodes
// To shoe the first Welcome Message
if(JSON.parse(data.success.liveChatFlow).nodes['1'].name == "Welcome Message"){
AgentMessage(JSON.parse(data.success.liveChatFlow).nodes['1'])
}
}
})
// Agent Message div
let AgentMessage = (data)=>{
// For the message div
let agentLi = document.createElement("div");
agentLi.className = "direct-chat-msg"
agentLi.innerHTML = `
${data.data.text}
`
// To send the Welcome Message as a message
let welcomeMessagedata = {
message :data.data.text,
username : liveChatCust.username,
id : liveChatCust.id,
customerId :liveChatCust.id,
messageType: "welcomeMessage"
}
postDataAPI(welcomeMessagedata,'broadcast-message')
// For the Option buttons
let liveChatOptionBtn = document.createElement("div")
liveChatOptionBtn.className = "d-flex flex-wrap liveChatOptionBtn"
let typeIndicator = document.createElement('div')
typeIndicator.className = 'typing-indicator';
typeIndicator.innerHTML = `
`
// connections node Loop
data.outputs.act.connections.map((connectedNode)=>{
let optionNode = document.createElement("div")
optionNode.onclick = ()=>{
// To remove the Options
bodyElement.querySelector(".liveChatOptionBtn").remove()
// Append the selected option as a customer message
bodyElement.querySelector(".basedOnTimeMessageConversationFlowDiv").appendChild(customerMessage(flowChatData[connectedNode.node]))
bodyElement.querySelector('.basedOnTimeMessageConversationFlowDiv').appendChild(typeIndicator)
// To send the Welcome Message as a message
let welcomeMessagedata = {
message :flowChatData[connectedNode.node].data.optionName,
username : liveChatCust.username,
id : liveChatCust.id,
customerId :liveChatCust.id,
}
setTimeout(() => {
postDataAPI(welcomeMessagedata,'broadcast-message').then((ele)=>{
// to loop the messages and options
if(flowChatData[connectedNode.node].inputs.text.connections[0]){
AgentMessage(flowChatData[flowChatData[connectedNode.node].inputs.text.connections[0].node])
}
bodyElement.querySelector('.basedOnTimeMessageConversationFlowDiv .typing-indicator')?.remove();
})
}, 1000);
}
optionNode.innerHTML = ``
liveChatOptionBtn.appendChild(optionNode)
bodyElement.querySelector('.basedOnTimeMessageConversationFlowDiv .typing-indicator')?.remove();
})
// For the Message
flowChatElement.appendChild(agentLi);
// For the Options
flowChatElement.appendChild(liveChatOptionBtn);
}
// Customer div
let customerMessage = (data)=>{
let custLi = document.createElement("div");
custLi.className = "direct-chat-msg right"
custLi.innerHTML = `
${data.data.optionName}
`
return custLi
}
return flowChatElement
}
// For the Offline Message Indication
const OfflineMessageIndication = (message)=>{
let offlineChatElement = document.createElement("div")
offlineChatElement.className = "direct-chat-msg"
// For the Corrent Time
function getCurrentTime() {
const currentDate = new Date();
let hours = currentDate.getHours();
let minutes = currentDate.getMinutes();
const ampm = hours >= 12 ? 'PM' : 'AM';
// Convert hours to 12-hour format
hours = hours % 12 || 12;
// Add leading zero to minutes if necessary
minutes = minutes < 10 ? '0' + minutes : minutes;
const currentTime = hours + ':' + minutes + ampm;
return currentTime;
}
// To post The Message
let welcomeMessagedata = {
message :message,
username : liveChatCust.username,
id : liveChatCust.id,
customerId :liveChatCust.id,
messageType: "welcomeMessage"
}
postDataAPI(welcomeMessagedata,'broadcast-message')
offlineChatElement.innerHTML = `
`
// To Open Image In the new Tab
if(custMessage.querySelector("img")){
custMessage.querySelector("img").onclick = ()=>{
window.open(custMessage.querySelector("img").getAttribute('imagesrc'));
}
}
directChatMessages?.appendChild(custMessage)
// To Scroll Down the Conversation
bodyElement.querySelector(".popup-messages")?.scrollBy(0, bodyElement.querySelector(".popup-messages").scrollHeight)
}
}
// For the Typing induction
if(!socket.message && socket.agentInfo && socket.customerId == liveChatCust?.id && socket.typingMessage){
// To remove the Typing induction
if(bodyElement.querySelector("#typingIndication")){
bodyElement.querySelector("#typingIndication").remove()
}
let directChatMessages = bodyElement.querySelector(".direct-chat-messages")
let custMessage = document.createElement("div");
custMessage.id = "typingIndication"
custMessage.className = "direct-chat-msg"
custMessage.innerHTML = `
Typing....
`
directChatMessages.appendChild(custMessage)
// To Scroll Down the Conversation
bodyElement.querySelector(".popup-messages").scrollBy(0, bodyElement.querySelector(".popup-messages").scrollHeight)
clearTimeout(debouncing2);
debouncing2 = setTimeout(function() {
if(bodyElement.querySelector("#typingIndication")){
bodyElement.querySelector("#typingIndication").remove()
}
}, 5000);
}
})
};
bodyElement.appendChild(script);
}
bodyElement.appendChild(link);
// To add the Main Live Chat Div
document.body.appendChild(mainLiveChatDiv);