1// wkli_socket = io(`${WKprotocol}${WKscript}`, { 2// 'reconnection': true, 3// 'reconnectionDelay': 1000, 4// 'reconnectionDelayMax': 5000, 5// 'reconnectionAttempts': 5, 6// 'transports': ['websocket'], 7// 'rememberUpgrade': true 8// }); 9var wkli_socket; 10var wkli_isSocketConnected = false 11const initializeSocket = () => { 12 return new Promise((resolve, reject) => { 13 if(!wkli_socket) { 14 wkli_socket = io(`${WKprotocol}${WKscript}`, { 15 'reconnection': true, 16 'reconnectionDelay': 1000, 17 'reconnectionDelayMax': 5000, 18 // 'reconnectionAttempts': 5, 19 'transports': ['websocket'], 20 'rememberUpgrade': true 21 }); 22 user.getMessageFromOperator() 23 user.socketRejoin(); 24 setTimeout(()=>{ 25 if(typeof media == 'object' && media) 26 media.connectingSocket(); 27 },3000) 28 } 29 resolve(wkli_socket) 30 }) 31} 32const Ids = { 33 MAIN_COINTAINER: "wk-cw-liveChatCointainer", 34 OPTION_CONTAINER: "wk-cw-livechatOptionModel", 35 MODEL_COINTAINER: "wk-cw-liveChatModel", 36 MAINTENANCE_CONTAINER: "wk-cw-maintenanceModel", 37 REGISTRATION_FROM_ID: "wk-ch-livechat-registrationFrom", 38 REGISTRATION_FROM_CLOSE_BTN_ID: "wk-ch-livechat-registrationFrom-close", 39 OPEN_CHAT_MODEL_BTN_ID: "wk-cw-openChatModelButton", 40 SKIP_REGISTRATIONFORM_ID: "wk-cw-skip-to-chat", 41 SEND_MSG_BTN_ID: "wk-cw-chatbot-sendMessage-button", 42 CHATBOT: "wk-cw-chatbot", 43 MESSAGE: "wk-cw-message", 44 user_operator_chat_holder: "wk-cw-user-operator-chat", 45 formSubmit: "wk-cw-submit-form-control", 46 normalChatBtn: "wk-cw-normal-chat-btn", 47 whatsappChatBtn: "wk-cw-whatsapp-chat-btn", 48 wkEndChat: "wkEndChat", 49 wkConfirmationCancel: "wk-confirmation-cancel", 50 wkConfirmationConfirm: "wk-confirmation-confirm", 51 unreadMessage: "wk-ch-unreadMessageCount", 52 sendEndMail: 'wk-confirmation-confirm-sendMail', 53 attachmentButton: 'wk-cw-attachment-button', 54 attachmentClose: "wk-ch-chatbot-attachment-close", 55 replyBlockClose: "wk-ch-chatbot-replyBlock-close", 56 cancleNewSendEmail: "wk-confirmation-cancle-sendMail-newEmail", 57 confirmNewSendEmail: "wk-confirmation-confirm-sendMail-newEmail", 58 chatWithAgent: "wk-cw-chatbot-chatWithAgent", 59 Text_Container: "wk-cw-chatbot-textCointainer", 60 start_autoResponse: "wk-cw-start-autoResponse", 61 autoResponseAction: "wk-cw-autoResponse-action", 62 circleWidget: "wk-cw-circleWidget", 63 chatHistory: 'wk-cw-chat-history', 64 progressBar: 'wk-progress-bar', 65 countDown: 'wk-countdown', 66 chatWithChatbot: "wk-cw-chat-with-chatbot", 67 agentChat: "wk-cw-agetChat-button" 68} 69 70let is_Typing = ''; 71let localStorageVar = "ChatSupport"; 72let localAutoChat = "autoChat"; 73let query_status = false; 74//"chat with agent" clicked before the client is registered: the request waits here until 75//sendMessageAckOfUser() has written the client record, then startChatWithAgent() replays it 76let wkli_pending_agent_chat = null; 77let wkli_chat = []; 78let wkli_modalVisiblity = false; 79let wkli_selectedChatOption = 'normal' // normal or whatsapp 80let wkli_whatsappFormField = document.getElementById(wkli_wa_form_field_id); 81let wkli_normalReplyData = ''; 82let ai_message = {} 83let disconnectAt = -1; 84var wkli_isChatwithchatbot = false 85let wkli_mailRegex = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; 86let wkli_maintenance_mode = false;
87let preventSendingMsg = false; 88//set once verify-client refuses this ip/email, stops every further registration attempt 89let wkli_client_blocked = false; 90//restart on change: the pending conversation-end-ack should open a new chat instead of closing the widget 91let wkli_restart_chat_pending = false; 92 93class Helper { 94 constructor() { 95 this.user_operator_conversation = []; 96 this.reSendMessages=[] 97 this.isOffline = false; 98 this.unreadMessageCount = 0; 99 this.http_regex = new RegExp('(http|https|www)://([^ ])*', 'g'); 100 this.image_regex = /\.(?:jpe?g|gif|png|svg)/i; 101 this.link_exp = /(\b(www|http|https|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig;; 102 this.checkAttachment = ['csv', 'pdf', 'application/pdf', 'txt', 'jpg', 'jpeg', 'png', 'gif', 'ods', 'xls', 'xlsx', 'php', 'js', 'odt', 'ott', 'odm', 'html', 'oth', 'ots', 'odg', 'otg', 'odp', 'otp', 'odf', 'odb', 'oxt', 'mp3']; 103 this.checkImg = ['jpeg', 'jpg', 'png', 'PNG', 'svg', 'SVG', 'gif', 'GIF']; 104 this.storage = false; 105 this.in_queue = false; 106 } 107 108 getElement(id) { 109 if (id) { 110 return document.getElementById(id); 111 } 112 return false; 113 } 114 //history is fetched by the client email, so the three dot menu shows only once getOldChatHistory() has one to send 115 toggleChatHistory() { 116 let dropdown = this.getElement('wk-cw-chat-history-dropdown'); 117 if (!dropdown) 118 return; 119 let session = JSON.parse(localStorage.getItem(localStorageVar)); 120 let restricted = JSON.parse(localStorage.getItem('restrictChatHistory')); 121 let hasEmail = session ? session.clientEmail && session.senderId : restricted && restricted.clientEmail; 122 dropdown.style.display = wkli_show_chat_history && !wkli_client_blocked && hasEmail ? '' : 'none'; 123 } 124 setClickListener(id, callback) { 125 let element = this.getElement(id); 126 if (element) 127 element.addEventListener('click', callback); 128 } 129 setKeyListener(id, callback) { 130 let element = this.getElement(id); 131 if (element) 132 element.addEventListener('keydown', callback); 133 } 134 changeDisplayProperty(id, property = '') { 135 let element = helper.getElement(id) 136 if(!wkli_showUvdeskWidget || id == Ids.MODEL_COINTAINER || id == Ids.OPEN_CHAT_MODEL_BTN_ID) { 137 if (property == '') { 138 let css = getComputedStyle(element) 139 if (element.style.display == 'none' || css.display == "none") { 140 element.style.display = "block" 141 } else { 142 element.style.display = "none" 143 } 144 } else { 145 element.style.display = property 146 } 147 } 148 } 149 showHoverMsg() { 150 if(document.querySelector('.wk-cw-openChatModelButton').classList.contains("wk-cw-checked")) { 151 helper.getElement(Ids.circleWidget).removeAttribute("title"); 152 } else { 153 helper.getElement(Ids.circleWidget).setAttribute('title', wkli_hoverMsg); 154 } 155 } 156 startNewSession() { 157 if(wkli_client_blocked) 158 return false; 159 // document.getElementById("startNewChat").remove(); 160 let enableAutoChatApi = false; 161 wkli_autoChatBotType = wkli_autoChatBotType_db 162 let autoChatApi = JSON.parse(localStorage.getItem('autoChatApi')) 163 if(wkli_autoChatBotType && wkli_autoChatBotType == '2'){ 164 if(!autoChatApi){ 165 localStorage.setItem('autoChatApi',true) 166 } 167 enableAutoChatApi = true; 168 } else { 169 localStorage.removeItem('autoChatApi') 170 } 171 wkli_registration_in_process = false 172 document.getElementById("wk-cw-chatbot-textCointainer").style.display = "grid"; 173 helper.getElement(Ids.user_operator_chat_holder).innerHTML = ""; 174 document.getElementById("wk-ch-operatorOnline").style.display = enableAutoChatApi ? "inline-block" : "none"; 175 document.getElementById("operatorName").textContent = enableAutoChatApi ? wkli_botName : wkli_welcomeText; 176 if (wkli_showForm) { 177 helper.changeDisplayProperty(Ids.CHATBOT, 'none'); 178 helper.changeDisplayProperty(Ids.REGISTRATION_FROM_ID, 'block') 179 } else { 180 if (new URL(location.href).searchParams.get('name')) 181 wkli_socket.emit('sendAutoResponseInNoReg', { domain: new URL(location.href).searchParams.get('name'), enableAutoResponse: wkli_enableAutoResponse, organisationId: wkli_organisationId, AI_chatbot: wkli_AI_chatbot, enableAutoChatApi }); 182 else 183 wkli_socket.emit('sendAutoResponseInNoReg', { domain: location.hostname, enableAutoResponse: wkli_enableAutoResponse, organisationId: wkli_organisationId, AI_chatbot: wkli_AI_chatbot, enableAutoChatApi }); 184 } 185 user.disableChatWithAgent() 186 if(document.getElementById('wkli_technicalError')) { 187 document.getElementById('wkli_technicalError').remove() 188 } 189 } 190 191 chnageQuestionView(element){ 192 element.style.background = wkli_theamColor; 193 element.style.color = '#ffffff'; 194 element.style.borderColor = wkli_theamColor; 195 } 196 197 resetQuestionView(element){ 198 element.style.background = "#ffffff"; 199 element.style.color = wkli_theamColor; 200 } 201 202 clearAllTimeoutAndInterval() { 203 clearTimeout(wkli_chat_timeout) 204 clearTimeout(wkli_confirm_timeout) 205 clearInterval(wkli_countdownInterval); 206 } 207 208 startChatTimeout() { 209 this.clearAllTimeoutAndInterval()
210 if(wkli_auto_chat_end && localStorage.getItem(localStorageVar)) { 211 // console.log('timeout start') 212 wkli_chat_timeout = setTimeout(() => {helper.getElement(Ids.wkEndChat).click()}, wkli_chat_timeout_duration); 213 } 214 } 215 216 startConfirmTimeout() { 217 this.clearAllTimeoutAndInterval() 218 if(wkli_auto_chat_end && localStorage.getItem(localStorageVar)) { 219 // console.log('confirm timeout start') 220 this.startCountDown() 221 if(!document.querySelector('.wk-cw-openChatModelButton').classList.contains("wk-cw-checked")) { // this code for when widget is closed and need to open widget while start countDown 222 user.openChatBlock(); 223 } 224 wkli_confirm_timeout = setTimeout(() => {helper.getElement(Ids.wkConfirmationConfirm).click()}, wkli_confirm_timeout_duration) 225 } 226 } 227 228 startCountDown() { 229 wkli_countDownValue = wkli_confirm_timeout_duration/1000; 230 const countdownElement = helper.getElement(Ids.countDown); 231 countdownElement.display = 'block'; 232 const progressBar = helper.getElement(Ids.progressBar); 233 progressBar.display = 'block'; 234 progressBar.max = wkli_countDownValue 235 progressBar.value = wkli_countDownValue; 236 wkli_countdownInterval = setInterval(() => { 237 wkli_countDownValue--; 238 239 if (wkli_countDownValue >= 0) { 240 countdownElement.innerText = `${wkli_countdownText}${wkli_countDownValue}`; 241 this.updateProgressBar(); 242 } else { 243 clearInterval(wkli_countdownInterval); 244 countdownElement.innerText = wkli_timesUpText; 245 progressBar.value = 0; 246 } 247 }, 1000); 248 } 249 250 updateProgressBar() { 251 const progressBar = document.getElementById("wk-progress-bar"); 252 progressBar.value = wkli_countDownValue; 253 } 254 255 refreshBasicChatbot() { 256 setWkli_isChatwithchatbot(true) 257 wkli_option_event = null
258 wkli_option_step = 'label' 259 wkli_orderId = '' 260 wkli_reason = '' 261 } 262 263 checkRestrictAgentChatCondition() { 264 let liveChatPermission = document.getElementById('wk-ch-liveChatPermission'); 265 let autoChatApi = JSON.parse(localStorage.getItem('autoChatApi')) 266 if(wkli_agentChatPermission && liveChatPermission && liveChatPermission.value && liveChatPermission.value == '1' && (wkli_autoChatBotType != 2 || (wkli_autoChatBotType == 2 && !autoChatApi))) { 267 return true 268 } else { 269 return false; 270 } 271 } 272} 273 274const helper = new Helper() 275 276class Form { 277 278 isMobile () { 279 let isMobile = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent); 280 if (isMobile) { 281 return true; 282 } else { 283 let webkitVer = parseInt(/WebKit\/([0-9]+)|$/.exec(navigator.appVersion)[1], 10); // also matches AppleWebKit 284 let isGoogle = webkitVer && navigator.vendor.indexOf('Google') === 0; // Also true for Opera Mobile and maybe others 285 let isAndroid = isGoogle && navigator.userAgent.indexOf('Android') > 0; // Careful - Firefox and Windows Mobile also have Android in user agent 286 let androidDesktopMode = !isAndroid && isGoogle && (navigator.platform.indexOf('Linux a') === 0) && 'ontouchstart' in document.documentElement; 287 288 let iOSAgent = window.navigator.userAgent.match(/iPhone|iPod|iPad/); 289 let iOSPlatform = window.navigator.platform && window.navigator.platform.match(/iPhone|iPod|iPad/); 290 let iOSRequestDesktop = (!iOSAgent && iOSPlatform); 291 292 let androidDesktopModeUsingFireFox = (navigator.vendor == '') && (navigator.appVersion.includes('Android')) 293 294 if (androidDesktopMode || iOSRequestDesktop || androidDesktopModeUsingFireFox) 295 return true; 296 else 297 return false; 298 } 299 } 300 301 changeWidgetIcon(preOpenOption = false) { 302 let img = document.querySelector('.wk-cw-openChatModelButton img').src; 303 let file_name = img.substring(img.lastIndexOf('/') + 1); 304 if (file_name != "down-arrow.svg" || wkli_modalVisiblity) { 305 document.querySelector('.wk-cw-openChatModelButton img').src = '' 306 if(!preOpenOption) { 307 document.getElementById(Ids.MODEL_COINTAINER).classList.add('wk-cw-show') 308 } 309 else { 310 document.getElementById(Ids.OPTION_CONTAINER).classList.add('wk-cw-show') 311 if(helper.checkRestrictAgentChatCondition()){ 312 document.getElementById(Ids.whatsappChatBtn).classList.add('wk-cw-hideWhatsapp') 313 }else{ 314 document.getElementById(Ids.whatsappChatBtn).classList.remove('wk-cw-hideWhatsapp') 315 } 316 } 317 document.querySelector('.wk-cw-openChatModelButton img').src = wkli_down_arrow_svg 318 document.querySelector('.wk-cw-openChatModelButton').classList.add("wk-cw-checked"); 319 document.querySelector('.wk-cw-openChatModelButton').style.border = '1px solid' + wkli_theamColor 320 sessionStorage.setItem('auto_open_widget', 'true') 321 if(user.isMobile() && !JSON.parse(localStorage.getItem(localStorageVar)) && !preOpenOption){ 322 document.getElementById(Ids.REGISTRATION_FROM_CLOSE_BTN_ID).style.display = 'block'; 323 helper.changeDisplayProperty(Ids.circleWidget, 'none') 324 document.getElementById(Ids.MODEL_COINTAINER).style.bottom = '0px' 325 } else if(user.isMobile()){ 326 document.getElementById(Ids.REGISTRATION_FROM_CLOSE_BTN_ID).style.display = 'none'; 327 helper.changeDisplayProperty(Ids.circleWidget, 'block') 328 document.getElementById(Ids.MODEL_COINTAINER).style.bottom = '80px' 329 } 330 } else { 331 document.querySelector('.wk-cw-openChatModelButton img').src = '' 332 document.getElementById(Ids.MODEL_COINTAINER).classList.remove('wk-cw-show') 333 document.getElementById(Ids.OPTION_CONTAINER).classList.remove('wk-cw-show')
334 if(wkli_icon) 335 document.querySelector('.wk-cw-openChatModelButton img').src = wkli_icon 336 else 337 document.querySelector('.wk-cw-openChatModelButton img').src = wkli_message_svg 338 document.querySelector('.wk-cw-openChatModelButton').classList.remove("wk-cw-checked"); 339 sessionStorage.setItem('auto_open_widget', 'false') 340 if(user.isMobile()){ 341 document.getElementById(Ids.REGISTRATION_FROM_CLOSE_BTN_ID).style.display = 'none'; 342 helper.changeDisplayProperty(Ids.circleWidget, 'block') 343 document.getElementById(Ids.MODEL_COINTAINER).style.bottom = '80px' 344 } 345 if(!(localStorage.getItem(localStorageVar))){ 346 helper.startNewSession() 347 } 348 } 349 } 350 351 preOpenchatBlockOption() { 352 wkli_modalVisiblity = !wkli_modalVisiblity; 353 if(JSON.parse(localStorage.getItem(localStorageVar))){ 354 // normal chat continue 355 this.openChatBlock(); 356 } else{ 357 new Form().changeWidgetIcon(true); 358 } 359 360 } 361
362 actionOnSelectedChatOption(chatOption) { 363 wkli_selectedChatOption = chatOption 364 document.getElementById(Ids.OPTION_CONTAINER).classList.remove('wk-cw-show') 365 if(chatOption == 'normal') { 366 if(wkli_whatsappFormField) 367 wkli_whatsappFormField.style.display = 'none'; 368 document.getElementById("wk-cw-submit-form-control").innerText = wkli_buttonText.normalChatSubmitButton 369 document.getElementById("wk-cw-submit-form-control").classList.remove('wk-whatsapp-button') 370 // socket already opened by a whatsapp registration: its one-time no-reg auto response was 371 // dropped by the whatsapp guard in getAllMessages, so ask for it again for this normal chat 372 if(wkli_socket && !wkli_showForm && !JSON.parse(localStorage.getItem(localStorageVar))) 373 helper.startNewSession(); 374 }else if(chatOption == 'whatsapp') { 375 if(wkli_whatsappFormField) 376 wkli_whatsappFormField.style.display = 'block'; 377 let wa_button = `<div style='display: flex;justify-content: center;'><img src = "${wkli_whatsapp_message_icon}"><span style='margin: auto 0; margin-left: 5px'>${wkli_buttonText.whatsappChatSubmitButton}</span></div>` 378 document.getElementById("wk-cw-submit-form-control").innerHTML = wa_button 379 document.getElementById("wk-cw-submit-form-control").classList.add('wk-whatsapp-button') 380 // WhatsApp always registers through the form - it needs the visitor's number. openChatBlock() 381 // would skip the form for an existing session or when auto registration turned wkli_showForm off. 382 this.openWhatsappRegistration(); 383 return; 384 } 385 this.openChatBlock(); 386 } 387 388 openWhatsappRegistration() { 389 helper.getElement(Ids.unreadMessage).style.display = "none" 390 helper.getElement(Ids.unreadMessage).innerHTML = "" 391 new Form().changeWidgetIcon(); 392 helper.changeDisplayProperty(Ids.CHATBOT, 'none'); 393 helper.changeDisplayProperty(Ids.REGISTRATION_FROM_ID, 'block'); 394 let element = helper.getElement("wk-chat-end-confirmation") 395 if(element && element.style.display != 'none') 396 element.style.display = 'none' 397 helper.showHoverMsg(); 398 } 399 400 openChatBlock() { 401 helper.getElement(Ids.unreadMessage).style.display = "none" 402 helper.getElement(Ids.unreadMessage).innerHTML = "" 403 404 new Form().changeWidgetIcon(); 405 406 if(JSON.parse(localStorage.getItem(localStorageVar))) { 407 helper.changeDisplayProperty(Ids.REGISTRATION_FROM_ID, 'none') 408 // helper.changeDisplayProperty(Ids.CHATBOT, 'block'); 409 410 if(document.getElementById(Ids.MODEL_COINTAINER).classList.contains('wk-cw-show')) { 411 let user = JSON.parse(localStorage.getItem(localStorageVar)) 412 user.enable = true; 413 localStorage.setItem(localStorageVar, JSON.stringify(user)) 414 if (JSON.parse(localStorage.getItem(localStorageVar)).senderId && helper.unreadMessageCount > 0) { 415 wkli_socket.emit("getAllMessageAck", { 416 receiverId: JSON.parse(localStorage.getItem(localStorageVar)).senderId, 417 seenTimestamp: new Date().toISOString(), 418 domain: JSON.parse(localStorage.getItem(localStorageVar)).domain, 419 userId: JSON.parse(localStorage.getItem(localStorageVar)).senderId 420 }) 421 helper.unreadMessageCount = 0 422 } 423 if(document.getElementById("wk-incoming-call")) 424 document.getElementById("wk-incoming-call").style.display = "none"; 425 } else { 426 if(document.getElementById("wk-incoming-call") && document.getElementById('wk-media-model').style.display == 'flex') { 427 document.getElementById("wk-incoming-call").style.display = "block"; 428 } 429 let user = JSON.parse(localStorage.getItem(localStorageVar)) 430 user.enable = false;
431 localStorage.setItem(localStorageVar, JSON.stringify(user)) 432 } 433 } else { 434 if(wkli_showForm) { 435 helper.changeDisplayProperty(Ids.CHATBOT, 'none'); 436 helper.changeDisplayProperty(Ids.REGISTRATION_FROM_ID, 'block') 437 } else { 438 initializeSocket().then(() => { 439 helper.changeDisplayProperty(Ids.CHATBOT, 'block'); 440 helper.changeDisplayProperty(Ids.REGISTRATION_FROM_ID, 'none') 441 }).catch(err => console.log(err)) 442 } 443 let element = helper.getElement("wk-chat-end-confirmation") 444 if(element && element.style.display != 'none') { 445 element.style.display = 'none' 446 } 447 } 448 this.scrollHeight(); 449 helper.showHoverMsg(); 450 // code comment due to on open chat block or close chat widget should be in privious state 451 // let element = helper.getElement("wk-chat-end-confirmation") 452 // if(element && element.style.display != 'none') { 453 // element.style.display = 'none' 454 // } 455 } 456 457 showChatBlock(showDirectChatBoard) { 458 if (showDirectChatBoard) { 459 helper.changeDisplayProperty(Ids.REGISTRATION_FROM_ID, 'none') 460 helper.changeDisplayProperty(Ids.CHATBOT, 'block') 461 } else { 462 new Form().changeWidgetIcon(); 463 } 464 if (JSON.parse(localStorage.getItem(localStorageVar)) && JSON.parse(localStorage.getItem(localStorageVar)).senderId) { 465 wkli_socket.emit("getAllMessageAck", { 466 receiverId: JSON.parse(localStorage.getItem(localStorageVar)).senderId, 467 seenTimestamp: new Date().toISOString(), 468 domain: JSON.parse(localStorage.getItem(localStorageVar)).domain, 469 userId: JSON.parse(localStorage.getItem(localStorageVar)).senderId, 470 }) 471 } 472 473 if (JSON.parse(localStorage.getItem(localStorageVar))) { 474 let user = JSON.parse(localStorage.getItem(localStorageVar)) 475 user.enable = helper.getElement(Ids.CHATBOT).style.display == 'none' ? false : true; 476 localStorage.setItem(localStorageVar, JSON.stringify(user)) 477 } 478 helper.showHoverMsg(); 479 } 480 481 getMessageFromUser(e) { 482 if (e.keyCode == 8) { 483 helper.getElement("wk-cw-message").rows = 1; 484 } else if (e.keyCode == 13 && !e.shiftKey) { 485 if (helper.getElement("wk-cw-message").value || (helper.getElement("wk-cw-attachment-button-hide").value && helper.getElement("wk-cw-attachment-button-hide").files.length)) { 486 this.getMessageInfo(); 487 } 488 e.preventDefault(); 489 } else { 490 helper.getElement("wk-cw-message").rows = 2; 491 } 492 } 493 494 495 buildMessage(msg, type, callback) { 496 let data = { 497 message: msg.replace(/</g, "<").replace(/>/g, ">"), 498 messageId: '_' + Math.random().toString(36).substr(2, 16), 499 sendTimestamp: new Date().toISOString(), 500 // domain: location.host.split(".")[0], 501 domain: location.host, 502 type: type, 503 reply: wkli_normalReplyData != '' ? wkli_normalReplyData : null, 504 chatInitiateNoti: true, 505 uniqueId: '_' + Math.random().toString(36).substr(2, 16) + '_', 506 end: 'sender', 507 isOffline: helper.isOffline 508 } 509 if (document.getElementsByClassName("wk-cw-user-to-operator-msg").length > 1) { 510 data.isOffline = false; 511 } 512 callback(data); 513 } 514 515 chnageMessageDetails(data, callback) { 516 if (JSON.parse(localStorage.getItem(localStorageVar))) { 517 data.senderId = JSON.parse(localStorage.getItem(localStorageVar)).senderId 518 if (JSON.parse(localStorage.getItem(localStorageVar)).departmentId) 519 data.departmentId = JSON.parse(localStorage.getItem(localStorageVar)).departmentId 520 data.uniqueId = JSON.parse(localStorage.getItem(localStorageVar)).uniqueId 521 if (JSON.parse(localStorage.getItem(localStorageVar)).operator) 522 data.receiverId = JSON.parse(localStorage.getItem(localStorageVar)).operator
523 } else 524 data.uniqueId = '_' + Math.random().toString(36).substr(2, 16); 525 callback(data) 526 } 527 528 getMessageInfo() { 529 if(preventSendingMsg || wkli_client_blocked){ 530 return false; 531 } 532 //for ai chatbot and basic chatbot 533 if(wkli_option_event) { 534 if(helper.getElement("wk-cw-message").value.trim()) { 535 if(['question', 'optionalQuestion', 'reason', 'email', 'otp'].includes(wkli_option_step)) { 536 if(wkli_option_step == 'email') { 537 let email = helper.getElement("wk-cw-message").value.trim() 538 if(!wkli_mailRegex.test(email)) { 539 helper.getElement("wk-cw-attachment-error").style.display = "block"; 540 helper.getElement("wk-cw-attachment-error").textContent = 'Invalid Email Id' 541 return false 542 } 543 helper.getElement("wk-cw-attachment-error").style.display = "none"; 544 helper.getElement("wk-cw-attachment-error").textContent = '' 545 if (localStorage.getItem(localStorageVar) && JSON.parse(localStorage.getItem(localStorageVar))) { 546 let user = JSON.parse(localStorage.getItem(localStorageVar)) 547 user.clientEmail = email 548 localStorage.setItem(localStorageVar, JSON.stringify(user)) 549 helper.toggleChatHistory() 550 } 551 } 552 this.processingNextOption(helper.getElement("wk-cw-message").value.trim()) 553 } 554 } 555 return false 556 } 557 // end 558 if (helper.getElement("wk-cw-message").value.trim() || (helper.getElement("wk-cw-attachment-button-hide").value && helper.getElement("wk-cw-attachment-button-hide").files.length)) { 559 if (document.getElementsByClassName("wk-cw-user-to-operator-msg").length == 0 && !wkli_showForm) { 560 if(!wkli_registration_in_process) { 561 wkli_registration_in_process = true 562 let clientEmail = this.getRegistrationEmail() 563 this.getClientToken(false, clientEmail, cb => { 564 if(cb && cb.data) { 565 this.sendChatInitiateNoti(cb.data, clientEmail); 566 } else { 567 //blocked client or verification failure, release the lock to allow a retry 568 wkli_registration_in_process = false 569 } 570 }) 571 } 572 } 573 if (helper.getElement("wk-cw-attachment-button-hide").value && helper.getElement("wk-cw-attachment-button-hide").files.length) { 574 helper.getElement("wk-cw-chatbot-attachment-name").style.display = "none" 575 helper.getElement("wk-cw-chatbot-reply-block").style.display = "none" 576 helper.getElement("wk-cw-attachment-error").style.display = "block"; 577 helper.getElement("wk-cw-attachment-error").textContent = wkli_sendingText 578 let fd = new FormData(); 579 let msg = (helper.getElement("wk-cw-message").value).trim(); 580 fd.append('file', helper.getElement("wk-cw-attachment-button-hide").files[0]); 581 helper.getElement("wk-cw-message").value = ""; 582 helper.getElement("wk-cw-message").rows = 1; 583 document.getElementById("wk-cw-attachment-button-hide").value = ""; 584 let senderId = JSON.parse(localStorage.getItem(localStorageVar)).senderId 585 if(senderId){ 586 fd.append('senderId',senderId) 587 } 588 fetch(`${WKprotocol}${WKscript}/wkcs/uploadClientFile`, { 589 method: 'POST', 590 processData: false, 591 contentType: false, 592 body: fd 593 }).then(res => res.json()) 594 .then(response => { 595 if (response.status == 1) { 596 helper.getElement("wk-cw-attachment-error").textContent = '' 597 helper.getElement("wk-cw-attachment-error").style.display = "none" 598 this.buildMessage(msg, 1, (data) => { 599 this.chnageMessageDetails(data, (updatedMessage) => { 600 helper.user_operator_conversation.push(updatedMessage) 601 updatedMessage.message = `${response.link} \n${updatedMessage.message}`; 602 this.buildMessageInDom(updatedMessage) 603 }) 604 }) 605 } else { 606 console.log(response) 607 } 608 }) 609 .catch(error => { 610 console.error('Error:', error) 611 inValidFile('File sending failed..try again') 612 }); 613 } 614 else { 615 if (document.getElementsByClassName("wk-cw-user-to-operator-msg").length > 0 || wkli_showForm) { 616 if ((helper.getElement("wk-cw-message").value).trim()) { 617 let msg = (helper.getElement("wk-cw-message").value).trim(); 618 this.buildMessage(msg, 1, (data) => { 619 this.chnageMessageDetails(data, (updatedMessage) => { 620 helper.user_operator_conversation = []; 621 helper.user_operator_conversation.push(updatedMessage) 622 this.buildMessageInDom(updatedMessage) 623 }) 624 }) 625 626 } 627 helper.getElement("wk-cw-message").value = ""; 628 helper.getElement("wk-cw-message").rows = 1; 629 helper.getElement("wk-cw-message").focus(); 630 document.getElementById("wk-cw-attachment-button-hide").value = ""; 631 } 632 } 633 } 634 635 } 636 637 buildMessageInDom(data, statusForSendMsgBysendOperatorMessage = true) { 638 if (data.type == 1) { 639 let parentClass = helper.user_operator_conversation[0].end == 'sender' ? "wk-cw-user-to-operator-msg" : "wk-cw-operator-to-user-msg" 640 let childClass = helper.user_operator_conversation[0].end == 'sender' ? "user-to-operator-msg" : "o
640perator-to-user-msg" 641 let msg = helper.user_operator_conversation[0].message.replace(/</g, "<").replace(/>/g, ">").split(' \n'); 642 let getext = msg[0].split('.') 643 let ext = getext[getext.length - 1] 644 if (helper.link_exp.test(helper.user_operator_conversation[0].message) || (helper.checkAttachment.includes(ext))) { 645 if (msg[0].includes(".s3.amazonaws.com")) { 646 this.buildAttachmentInDom(1, helper.user_operator_conversation[0], parentClass, childClass); 647 } else { 648 this.buildAttachmentInDom(2, helper.user_operator_conversation[0], parentClass, childClass); 649 } 650 } else { 651 this.buildAttachmentInDom(2, helper.user_operator_conversation[0], parentClass, childClass); 652 } 653 } 654 if(statusForSendMsgBysendOperatorMessage) 655 this.sendMessage() 656 else{ 657 if(new URL(location.href).searchParams.get('name')) 658 helper.user_operator_conversation[0].domain = new URL(location.href).searchParams.get('name'); 659 wkli_socket.emit("getQueryResult",helper.user_operator_conversation[0]); 660 } 661 } 662 663 /** 664 * The token minted by getClientToken() is bound to this address and registerUser() rejects 665 * the registration when the two differ, so the token call and the registration payload have 666 * to resolve the email the same way. The form input wins when it exists because it already 667 * carries the url parameter over injected page value precedence. 668 */ 669 getRegistrationEmail() { 670 if (wkli_userEmail && document.getElementById(wkli_userEmail)) 671 return document.getElementById(wkli_userEmail).value.trim(); 672 return wkli_shopify_customer.email ? wkli_shopify_customer.email : ''; 673 } 674 675 getRegistrationName() { 676 if (wkli_userName && document.getElementById(wkli_userName)) 677 return document.getElementById(wkli_userName).value.trim(); 678 return wkli_shopify_customer.name ? wkli_shopify_customer.name : ''; 679 } 680 681 /** 682 * Resolves the department select to the id the backend expects. The select is built and 683 * prefilled even when the form is skipped, so this works for the auto register flow too. 684 */ 685 getSelectedDepartmentId() { 686 if (!wkli_depRegistration || !wkli_userDepartment) 687 return ''; 688 let element = document.getElementById(wkli_userDepartment); 689 if (!element || !element.value || element.value == 'SELECT') 690 return ''; 691 let department = (wkli_departmentArr || []).filter(x => x.handleName == element.value) 692 return department.length ? department[0].departmentId : ''; 693 } 694 695 /** 696 * Custom registration fields are not stored on the client record, they are pushed to the 697 * operator as the first chat message. Shared by the form flow and the auto register flow. 698 * Do NOT clear the inputs after reading: every registration path is already gated on the 699 * empty ".wk-cw-user-to-operator-msg" list, so this runs once per chat session anyway, and 700 * a "Start New" chat (no page reload) must re-read the page-injected/auto values instead of 701 * finding them wiped. 702 */ 703 sendCustomFieldMessage(useQueryResult = false) { 704 if (!wkli_customInput || !document.getElementsByClassName("customInput").length) 705 return false; 706 let customMsg = ''; 707 Array.from(document.getElementsByClassName('customInput')).forEach( 708 function (element, index, array) { 709 customMsg += `${element.name}: ${element.value.replace(/</g, "<").replace(/>/g, ">")} \n`; 710 } 711 ); 712 this.buildMessage(customMsg, 1, (data) => { 713 data.chatInitiateNoti = true; 714 this.chnageMessageDetails(data, (updatedMessage) => { 715 helper.user_operator_conversation = []; 716 helper.user_operator_conversation.push(updatedMessage) 717 if(useQueryResult){ 718 updatedMessage.tick = true; 719 this.buildMessageInDom(updatedMessage, false) 720 } 721 else 722 this.buildMessageInDom(updatedMessage) 723 }) 724 }) 725 return true; 726 } 727 728 /** 729 * Custom registration fields as a { handleName: value } object, persisted on the client 730 * record (chatSupportUser.customFields) at register time. Ke
730yed by the field handleName 731 * (data-handle, stamped by the loader); same escaping as the custom field chat message. 732 * Returns null when there are no custom inputs. 733 */ 734 getCustomFieldsObject() { 735 if (!wkli_customInput || !document.getElementsByClassName("customInput").length) 736 return null; 737 let customFields = {}; 738 Array.from(document.getElementsByClassName('customInput')).forEach( 739 function (element) { 740 let key = element.dataset.handle || element.name; 741 customFields[key] = element.value.replace(/</g, "<").replace(/>/g, ">"); 742 } 743 ); 744 return customFields; 745 } 746 747 sendChatInitiateNoti(tokenData = null, clientEmail = null) { 748 if(helper.checkRestrictAgentChatCondition()){ 749 return 750 } 751 if(document.getElementById('wkli_technicalError')) { 752 document.getElementById('wkli_technicalError').remove() 753 } 754 let msg = `<------ ${location.href} ------>` 755 this.buildMessage(msg, 2, (data) => { 756 data.chatInitiateNoti = false; 757 if(tokenData && !wkli_showForm) { 758 data.clientToken = tokenData 759 data.in_queue = helper.in_queue 760 //must match the address the token was minted with or registerUser() rejects it 761 data.email = clientEmail !== null ? clientEmail : this.getRegistrationEmail() 762 data.name = this.getRegistrationName() 763 let departmentId = this.getSelectedDepartmentId() 764 if(departmentId) 765 data.departmentId = departmentId 766 let customFields = this.getCustomFieldsObject() 767 if(customFields) 768 data.customFields = customFields 769 } 770 this.chnageMessageDetails(data, (updatedMessage) => { 771 if (updatedMessage.departmentId && wkli_departmentArr?.length && wkli_departmentNamePermission) { 772 let dept = wkli_departmentArr.find( 773 d => d.departmentId == updatedMessage.departmentId 774 ); 775 if (dept?.name) { 776 updatedMessage.message += `<br><strong>Chat initiated for Department:</strong> ${dept.name}`; 777 } 778 } 779 helper.user_operator_conversation.push(updatedMessage); 780 if(wkli_enableAutoResponse && wkli_showForm && wkli_selectedChatOption != 'whatsapp'){ 781 if(new URL(location.href).searchParams.get('name')) 782 updatedMessage.domain = new URL(location.href).searchParams.get('name'); 783 wkli_socket.emit("getQueryResult",updatedMessage); 784 helper.user_operator_conversation.pop() 785 }else{ 786 this.sendMessage() 787 } 788 }) 789 }) 790 setTimeout(() => { 791 wkli_registration_in_process = false 792 //whatsapp custom fields already went out as customMsg, and its session is dropped on ack 793 if (document.getElementsByClassName("wk-cw-user-to-operator-msg").length == 0 && !wkli_showForm && wkli_selectedChatOption != 'whatsapp') { 794 //custom fields came from the page instead of the form, push them before the query 795 this.sendCustomFieldMessage() 796 if ((helper.getElement("wk-cw-message").value).trim()) { 797 let msg = (helper.getElement("wk-cw-message").value).trim(); 798 this.buildMessage(msg, 1, (data) => { 799 this.chnageMessageDetails(data, (updatedMessage) => { 800 helper.user_operator_conversation = []; 801 helper.user_operator_conversation.push(updatedMessage) 802 this.buildMessageInDom(updatedMessage) 803 helper.getElement("wk-cw-message").value = ""; 804 helper.getElement("wk-cw-message").rows = 1 805 }) 806 }) 807 808 } 809 } 810 }, 1000) 811 } 812 813 sendMessage() { 814 this.scrollHeight(); 815 if (new URL(location.href).searchParams.get('name')) 816 helper.user_operator_conversation[0].domain = new URL(location.href).searchParams.get('name') 817 if (document.getElementsByClassName("wk-cw-user-to-operator-msg").length > 1 || (wkli_customInput && document.getElementsByClassName("wk-cw-user-to-operator-msg").length <= 1)) { 818 helper.user_operator_conversation[0].isOffline = false;
819 } 820 if (wkli_customInput && document.getElementsByClassName("wk-cw-user-to-operator-msg").length == 2) { 821 if (helper.isOffline) 822 helper.user_operator_conversation[0].isOffline = true; 823 else { 824 helper.user_operator_conversation[0].isOffline = false; 825 } 826 } 827 if (!wkli_showForm && !wkli_prefill['Email']) { 828 helper.user_operator_conversation[0].isOffline = false; 829 } 830 if(wkli_basic_chatbot && document.getElementsByClassName("wk-cw-user-to-operator-msg").length == 1 && wkli_shopify_customer.email) { 831 helper.user_operator_conversation[0].isOffline = helper.isOffline 832 } 833 let localAutoReponseData = JSON.parse(localStorage.getItem(localAutoChat)); 834 let queries = document.getElementsByClassName("wk-cw-operator-to-user-queries"); 835 let agentFirstMsg = JSON.parse(localStorage.getItem('agentChatFirstMsg')); 836 if(localAutoReponseData || (queries && queries.length) || agentFirstMsg){ 837 Array.from(queries).forEach(el=>el.remove()); 838 helper.user_operator_conversation[0].updateChatStatus = true; 839 helper.user_operator_conversation[0].organisationId = wkli_organisationId 840 if(localAutoReponseData || agentFirstMsg) 841 helper.user_operator_conversation[0].isFirstMsg = true; 842 localStorage.removeItem(localAutoChat); 843 let data = JSON.parse(localStorage.getItem(localStorageVar)) 844 if(data && data.operator){ 845 delete data.operator; 846 delete data.operatorStatus; 847 data.name = wkli_requestedText 848 document.getElementById("operatorName").textContent = wkli_requestedText 849 localStorage.setItem(localStorageVar, JSON.stringify(data)); 850 document.getElementById("wk-ch-operatorOnline").style.display = "none"; 851 // delete helper.user_operator_conversation[0].receiverId; 852 } 853 localStorage.removeItem('agentChatFirstMsg'); 854 } 855 if(wkli_AI_chatbot && !helper.user_operator_conversation[0].message.includes('http')) { 856 // if(!ai_message.question) { 857 // ai_message = { 858 // question: helper.user_operator_conversation[0].message, 859 // history: [] 860 // } 861 // } else if(ai_message.question) { 862 // if(!ai_message.history) 863 // ai_message.history = [] 864 // ai_message.history.splice(0, ai_message.history.length-4) 865 // ai_message.history.push({ 866 // "type": "human", 867 // "text": helper.user_operator_conversation[0].message 868 // }) 869 // } 870 ai_message.question = helper.user_operator_conversation[0].message 871 helper.user_operator_conversation[0].AI_chatbot = wkli_AI_chatbot 872 helper.user_operator_conversation[0].ai_message = ai_message 873 } 874 helper.reSendMessages.push(helper.user_operator_conversation[0]) 875 if(helper.user_operator_conversation[0].updateChatStatus) 876 helper.user_operator_conversation[0].isOffline = helper.isOffline; 877 if(helper.user_operator_conversation[0].senderId) 878 helper.user_operator_conversation[0].userId = helper.user_operator_conversation[0].senderId 879 let autoChatApi = JSON.parse(localStorage.getItem('autoChatApi')) 880 if(wkli_autoChatBotType && wkli_autoChatBotType == '2' && autoChatApi && wkli_selectedChatOption == 'normal'){ 881 let prevMsg = []; 882 let firstUserMessageFound = false; 883 let user = JSON.parse(localStorage.getItem(localStorageVar)); 884 wkli_chat.filter(el => { 885 if (!user) { 886 return; 887 } 888 let domain = user.domain; 889 if(el.senderId){ 890 if(['sp-seller.webkul.com','docs.qloapps.com','sakshi-p-store1.myshopify.com','rupesh-trunk-subscription.myshopify.com'].includes(domain)) { 891 if (firstUserMessageFound && el.senderId) { 892 if (el.senderId == (user.senderId)) { 893 prevMsg.push({ 'role': 'user', 'content': el.message }); 894 } else if (el.senderId != (user.senderId)) { 895 prevMsg.push({ 'role': 'assistant', 'content': el.message }); 896 } 897 } 898 if (!firstUserMessageFound) { 899 if (el.senderId == (user.senderId)) { 900 firstUserMessageFound = true; 901 } 902 } 903 } else { 904 if (el.senderId == (user.senderId)) { 905 prevMsg.push({ 'role': 'user', 'content': el.message }); 906 } else if (el.senderId != (user.senderId)) { 907 prevMsg.push({ 'role': 'assistant', 'content': el.message }); 908 } 909 } 910 } 911 }) 912 helper.user_operator_conversation[0].prevMsg = prevMsg 913 helper.user_operator_conversation[0].is_operator_online = user?.is_operator_online 914 document.getElementById("operatorName").textContent = wkli_botName; 915 document.getElementById("wk-ch-operatorOnline").style.background = "chartreuse"; 916 let liveChatPermission = document.getElementById('wk-ch-l
916iveChatPermission'); 917 if(wkli_agentChatPermission && liveChatPermission && liveChatPermission.value && liveChatPermission.value == '1') { 918 helper.user_operator_conversation[0].botToAgentRestrict = true; 919 } 920 preventSendingMsg = true; 921 if (wkli_customInput && document.getElementsByClassName("wk-cw-user-to-operator-msg").length <= 1) { 922 helper.user_operator_conversation[0].botCustomeMsg = true; 923 preventSendingMsg = false; 924 } 925 wkli_socket.emit('sendAutoMessage', helper.user_operator_conversation[0]); 926 }else{ 927 wkli_socket.emit('sendOperatorMessage', helper.user_operator_conversation[0]); 928 } 929 setWkli_isChatwithchatbot(true) 930 helper.user_operator_conversation.pop(); 931 helper.getElement("wk-cw-chatbot-reply-block").style.display = "none"; 932 wkli_normalReplyData = ''; 933 let active = document.querySelectorAll('.wk-cw-active') 934 if(active.length){ 935 active.forEach((chat) => { 936 chat.classList.remove('wk-cw-active') 937 }) 938 } 939 user.replyButtonAct(); 940 helper.startChatTimeout(); 941 } 942 943 getUserOperatorData() { 944 if (JSON.parse(localStorage.getItem(localStorageVar))) { 945 946 } 947 } 948 949 formatChatMessage(message, isBotMessage, textColor) { 950 if (!message) return ''; 951 if (/<\/?[a-z][\s\S]*>/i.test(message)) { 952 return message.replace( 953 /<a /g, 954 '<a class="wk-ch-seller-buyer-url" ' 955 ); 956 } 957 let safeMsg = message.replace(/</g, "<").replace(/>/g, ">"); 958 959 safeMsg = safeMsg.replace( 960 helper.link_exp, 961 `<a href="$1" class="wk-ch-seller-buyer-url" target="_blank">$1</a>` 962 ); 963 safeMsg = safeMsg.replace(/\n/g, "<br>"); 964 return safeMsg; 965 } 966 967 buildAttachmentInDom(type, data, parentClass, childClass, msgColor = 3) { 968 console.log('updatedMessage', data); 969 const isBotMessage = data.opSenderName === 'Bot' || data.responseBy === 'ai'; 970 wkli_chat.push(data); 971 // translate chat notices for display only, wkli_chat keeps the saved message 972 data = Object.assign({}, data, { message: wkli_translateLog(data.message) }); 973 let div = document.createElement('div'); 974 let usrData = JSON.parse(localStorage.getItem(localStorageVar)); 975 div.className = parentClass; 976 977 let childDiv = document.createElement("div"); 978 childDiv.classList.add(childClass); 979 980 if(data.messageId) { 981 childDiv.setAttribute('id', 'wkli'+data.messageId) 982 } 983 data.message = data.message.replace(/ /g, ''); 984 if(data.reply) { 985 let replyDiv = document.createElement("div"); 986 replyDiv.classList.add('wk-cw-replyMsg'); 987 replyDiv.setAttribute('id', 'wk-cw-replyMsg') 988 let replyData = JSON.stringify(data.reply) 989 childDiv.setAttribute("onclick",`wkli_gotoMsgReplyFor(${replyData})`); 990 let senderName = wkli_replyYouText 991 992 if(data.reply.senderId == usrData.operator) { 993 senderName = wkli_replySupportText 994 } 995 996 // the sender label is admin configured text, so it goes in as text and never as markup 997 let replyNameEl = document.createElement('small') 998 replyNameEl.className = 'wk-cw-reply-sender-name' 999 replyNameEl.textContent = senderName 1000 let replyMsgEl = document.createElement('small') 1001 replyMsgEl.className = 'wk-cw-reply-chat-msg' 1002 replyMsgEl.innerHTML = this.buildReplyMessage(data.reply.message) 1003 replyDiv.appendChild(replyNameEl) 1004 replyDiv.appendChild(document.createElement('br')) 1005 replyDiv.appendChild(replyMsgEl) 1006 div.appendChild(replyDiv); 1007 childDiv.appendChild(replyDiv); 1008 } 1009 1010 if (type == 1) { 1011 console.log("typeone hai") 1012 // let msg = data.message.replace(/</g, "<").replace(/>/g, ">").split(' \n') 1013 let msg; 1014 if (isBotMessage && /<\/?[a-z][\s\S]*>/i.test(data.message)) { 1015 msg = [data.message]; // keep HTML intact 1016 } else { 1017 msg = isBotMessage 1018 ? data.message.split('\n') 1019 : data.message.replace(/</g, "<").replace(/>/g, ">").split('\n'); 1020 } 1021 let getext = msg[0].split('/')
1022 let checkImgExt = msg[0].split('.') 1023 let attachmentName = getext[getext.length - 1] 1024 const audioTypes = ['mp3','ogg','wav'] 1025 if (helper.checkImg.includes(checkImgExt[checkImgExt.length - 1])) { 1026 let img = document.createElement("img"); 1027 img.setAttribute('src', msg[0]); 1028 img.classList.add('wk-ch-livechat-image'); 1029 let br = document.createElement("br"); 1030 childDiv.appendChild(img) 1031 childDiv.appendChild(br) 1032 } else if(audioTypes.indexOf(checkImgExt.pop()) !== -1) { 1033 childDiv.style.minWidth = '230px' 1034 let audio = document.createElement("audio"); 1035 audio.style.width = "100%"; 1036 audio.setAttribute('src', msg[0]); 1037 audio.setAttribute('controls', ''); 1038 let br = document.createElement("br"); 1039 childDiv.appendChild(audio) 1040 childDiv.appendChild(br) 1041 } 1042 let anchor = document.createElement("A"); 1043 anchor.setAttribute("href", msg[0]); 1044 anchor.setAttribute("download", attachmentName); 1045 let downloadDiv = document.createElement("div"); 1046 downloadDiv.classList.add("wk-ch-livechat-download-button") 1047 let attachmentNameDiv = document.createElement("div"); 1048 attachmentNameDiv.appendChild(document.createTextNode(attachmentName.replace(/</g, "<").replace(/>/g, ">"))); 1049 attachmentNameDiv.classList.add("wk-ch-livechat-attachmentName"); 1050 anchor.appendChild(downloadDiv) 1051 anchor.appendChild(attachmentNameDiv) 1052 anchor.style.textDecoration = 'none' 1053 let textColor = "#111111" 1054 if (msgColor == 1) { 1055 if ((usrData && usrData.senderId && usrData.senderId != data.senderId) || data.onlineStatus) 1056 childDiv.style.background = wkli_theamColor; 1057 if (childClass == "user-to-operator-msg" && parentClass == "wk-cw-user-to-operator-msg") { 1058 textColor = '#111111' 1059 } else { 1060 textColor = '#ffffff' 1061 } 1062 } else if (msgColor == 2) { 1063 childDiv.style.background = wkli_theamColor; 1064 textColor = '#ffffff' 1065 } 1066 anchor.style.color = textColor; 1067 childDiv.appendChild(anchor) 1068 if (msg.length > 1 && msg[1] != "") { 1069 let br = document.createElement("br"); 1070 childDiv.appendChild(br) 1071 let childDivForTxt = document.createElement('div'); 1072 // childDivForTxt.innerHTML = msg[1].replace(helper.link_exp, `<a href="$1" class="wk-ch-seller-buyer-url" target="_blank" style="color:${textColor}">$1</a>`); 1073 childDivForTxt.innerHTML = this.formatChatMessage(msg[1], isBotMessage, textColor); 1074 childDivForTxt.style.color = textColor; 1075 childDivForTxt.classList.add("wk-ch-livechat-textWithAttachment") 1076 childDiv.appendChild(childDivForTxt) 1077 } 1078 div.appendChild(childDiv) 1079 }else if(type == 3){ 1080 // let textColor = "#111111" 1081 let textColor = "#fff" 1082 if (msgColor == 3) { 1083 childDiv.style.background = wkli_theamColor; 1084 textColor = '#ffffff' 1085 } 1086 // childDiv.innerHTML += data.message.replace(helper.link_exp, `<a href="$1" class="wk-ch-seller-buyer-url" target="_blank" style="color:${textColor}">$1</a>`); 1087 childDiv.innerHTML += this.formatChatMessage(data.message, isBotMessage, textColor); 1088 div.appendChild(childDiv); 1089 } else if(type == 4) { 1090 let textColor = "#ffffff" 1091 childDiv.innerHTML += data.message 1092 div.appendChild(childDiv); 1093 textColor = '#ffffff' 1094 let br = document.createElement("br"); 1095 childDiv.appendChild(br) 1096 let imgTag = new DOMParser().parseFromString(data.message,'text/xml') 1097 if(imgTag.getElementsByTagName('img')?.[0]?.getAttribute('src')) { 1098 let imgSrc= imgTag.getElementsByTagName('img')[0].getAttribute('src') 1099 let getext = imgSrc.split('/') 1100 let attachmentNames = getext[getext.length - 1] 1101 var length = 25; 1102 var attachmentName = attachmentNames.substring(0, length); 1103 let anchor = document.createElement("A"); 1104 anchor.setAttribute("href", imgSrc); 1105 anchor.setAttribute("download", attachmentName); 1106 let downloadDiv = document.createElement("div");
1107 downloadDiv.classList.add("wk-ch-livechat-download-button") 1108 let attachmentNameDiv = document.createElement("div"); 1109 attachmentNameDiv.appendChild(document.createTextNode(attachmentName.replace(/</g, "<").replace(/>/g, ">"))); 1110 attachmentNameDiv.classList.add("wk-ch-livechat-attachmentName"); 1111 anchor.appendChild(downloadDiv) 1112 anchor.appendChild(attachmentNameDiv) 1113 anchor.style.textDecoration = 'none' 1114 textColor = "#ffffff" 1115 anchor.style.color = textColor; 1116 childDiv.appendChild(anchor) 1117 } 1118 } 1119 else { 1120 let textColor = "#111111" 1121 if (msgColor == 1) { 1122 if ((usrData && usrData.senderId && usrData.senderId != data.senderId) || data.onlineStatus || data.type == 3) 1123 childDiv.style.background = wkli_theamColor; 1124 if (childClass == "user-to-operator-msg" && parentClass == "wk-cw-user-to-operator-msg") { 1125 textColor = '#111111' 1126 } else { 1127 textColor = '#ffffff' 1128 } 1129 } else if (msgColor == 2) { 1130 childDiv.style.background = wkli_theamColor; 1131 textColor = '#ffffff' 1132 } 1133 if(data.forClient || data.allreadyTicketCreated){ 1134 const ticketContent = data.message 1135 const lines = ticketContent.split("/"); 1136 const ticketNumber = lines[lines.length - 1]; 1137 if(data.allreadyTicketCreated){ 1138 childDiv.innerHTML += data.message 1139 }else{ 1140 childDiv.innerHTML += data.message.replace(helper.link_exp, `Thank you for reaching out to us. Unfortunately, none of our operators are available at the moment. But don't worry! We are creating a ticket on your behalf, and you will be notified over email once the team gets back to you.\n\n <a href=${data.message} class="wk-ch-seller-buyer-url" target="_blank" style="color:${textColor}"><u>Click here to access the ticket #${ticketNumber}</u></a>`); 1141 } 1142 }else{ 1143 // childDiv.innerHTML += data.message.replace(helper.link_exp, `<a href="$1" class="wk-ch-seller-buyer-url" target="_blank" style="color:${textColor}">$1</a>`); 1144 childDiv.innerHTML += this.formatChatMessage(data.message, isBotMessage, textColor); 1145 } 1146 div.appendChild(childDiv); 1147 } 1148 let dateTime = document.createElement("div"); 1149 dateTime.classList.add('wk-cw-parent-dateTime'); 1150 let replyButton = document.createElement("span"); 1151 replyButton.classList.add('wk-cw-reply-button'); 1152 let d1 = JSON.stringify(data); 1153 replyButton.setAttribute("id","rep"+data.messageId); 1154 replyButton.setAttribute("onclick",`wkli_replyButtonBody(${d1})`); 1155 1156 let span = document.createElement("span"); 1157 span.classList.add('wk-cw-dateTime') 1158 1159 let messageStatusTrue = document.createElement("span"); 1160 messageStatusTrue.classList.add('wk-cw-message-send'); 1161 1162 let messageStatusWait = document.createElement("span"); 1163 messageStatusWait.classList.add('wk-cw-message-wait'); 1164 1165 // span.innerHTML = new Date().toLocaleString(); 1166 if(data.sendTimestamp) { 1167 span.innerHTML = getLocalTimestamp(data.sendTimestamp) 1168 } else { 1169 span.innerHTML = getLocalTimestamp(new Date()) 1170 } 1171 if(data.tick) { 1172 dateTime.appendChild(messageStatusTrue); 1173 } else { 1174 dateTime.appendChild(messageStatusWait); 1175 } 1176 dateTime.appendChild(span); 1177 if(data.messageId && !data.forClient){ 1178 dateTime.appendChild(replyButton); 1179 } 1180 div.appendChild(dateTime); 1181 helper.getElement(Ids.user_operator_chat_holder).appendChild(div); 1182 } 1183 1184 buildQueriesInDom(type, data, parentClass, childClass, msgColor = 3){ 1185 let div = document.createElement('div'); 1186 div.className = parentClass; 1187 let childDiv = document.createElement("div"); 1188 childDiv.classList.add(childClass); 1189 // childDiv.style.color = wkli_theamColor; 1190 // childDiv.setAttribute("onmouseover","helper.chnageQuestionView(this)"); 1191 // childDiv.setAttribute("onmouseout","helper.resetQuestionView(this)"); 1192 childDiv.setAttribute("onclick",`new Form().getQueryResult(this)`); 1193 childDiv.setAttribute("id", data._id); 1194 childDiv.style.background = wkli_theamColor; 1195 childDiv.innerHTML = data.question.replace(helper.link_exp, `<a href="$1" class="wk-ch-seller-buyer-url" target="_blank" style="color:${wkli_theamColor}">$1</a>`); 1196 div.appendChild(childDiv); 1197 let dateTime = document.createElement("div"); 1198 dateTime.classList.add('wk-cw-parent-dateTime'); 1199 let span = document.createElement("span"); 1200 span.classList.add('wk-cw-dateTime')
1201 // span.innerHTML = new Date().toLocaleString(); 1202 if(data.sendTimestamp) { 1203 span.innerHTML = getLocalTimestamp(data.sendTimestamp) 1204 } 1205 dateTime.appendChild(span); 1206 div.appendChild(dateTime); 1207 helper.getElement(Ids.user_operator_chat_holder).appendChild(div); 1208 } 1209 1210 //for ai chatbot and basic chatbot 1211 buildOptionsInDom(data, parentClass, childClass) { 1212 let div = document.createElement('div'); 1213 div.className = parentClass; 1214 let childDiv = document.createElement("div"); 1215 childDiv.classList.add(childClass); 1216 childDiv.setAttribute("onclick",`new Form().processingNextOption(this)`); 1217 childDiv.setAttribute("id", data.id); 1218 childDiv.style.background = wkli_theamColor; 1219 childDiv.innerHTML = data.label.replace(helper.link_exp, `<a href="$1" class="wk-ch-seller-buyer-url" target="_blank" style="color:${wkli_theamColor}">$1</a>`); 1220 div.appendChild(childDiv); 1221 helper.getElement(Ids.user_operator_chat_holder).appendChild(div); 1222 } 1223 1224 proceedToRegistration() { 1225 return new Promise((resolve, reject) => { 1226 let customer_email = this.getRegistrationEmail() 1227 let customer_name = this.getRegistrationName() 1228 this.getClientToken(false, customer_email, cb => { 1229 if(cb && cb.data) { 1230 let msg = `<------ ${location.href} ------>` 1231 this.buildMessage(msg, 2, (data) => { 1232 data.chatInitiateNoti = false; 1233 data.clientToken = cb.data; 1234 this.chnageMessageDetails(data, (updatedMessage) => { 1235 if(customer_email) 1236 updatedMessage.email = customer_email 1237 if(customer_name) 1238 updatedMessage.name = customer_name 1239 let departmentId = this.getSelectedDepartmentId() 1240 if(departmentId) 1241 updatedMessage.departmentId = departmentId 1242 let customFields = this.getCustomFieldsObject() 1243 if(customFields) 1244 updatedMessage.customFields = customFields 1245 let option = { 1246 method: 'POST', 1247 headers: {'Content-Type': 'application/json'}, 1248 body: JSON.stringify(updatedMessage) 1249 } 1250 fetch(`${WKprotocol}${WKscript}/wkcs/register-client`,option).then(res => res.json()).then(data => { 1251 console.log(data) 1252 if(data && data.status == 1 && data.data) { 1253 let client = data.data 1254 let save = { 1255 domain: client.domain, 1256 senderId: client.senderId, 1257 uniqueId: client.uniqueId, 1258 enable: true 1259 } 1260 if(client.saveOperatorData) { 1261 save.name = wkli_showOperatorName ? wkli_botName : wkli_opName; 1262 save.operator = client.receiverId; 1263 save.operatorStatus = true; 1264 document.getElementById("wk-ch-operatorOnline").style.display = "inline-block"; 1265 document.getElementById("wk-ch-operatorOnline").style.background = "chartreuse"; 1266 document.getElementById("operatorName").textContent = wkli_showOperatorName ? wkli_botName : wkli_opName; 1267 } 1268 if(client.email) 1269 save.clientEmail = client.email 1270 if(client.name) 1271 save.clientName = client.name 1272 if (!JSON.parse(localStorage.getItem(localStorageVar))) { 1273 if (wkli_restart_chat_field) 1274 save.restartChatValue = wkli_getInjectedValue(wkli_restart_chat_field) 1275 localStorage.setItem(localStorageVar, JSON.stringify(save)); 1276 helper.toggleChatHistory() 1277 if(typeof(media) == 'object') { 1278 media.senderName = client.name ? client.name : client.uniqueId; 1279 media.senderId = client.uniqueId; 1280 media.senderEmail = client.email ? client.email : client.uniqueId; 1281 } 1282 } 1283 } 1284 resolve(true) 1285 }).catch(error => { 1286 console.log(error) 1287 resolve(false) 1288 }) 1289 }) 1290 }) 1291 } else { 1292 resolve(false) 1293 } 1294 }) 1295 }) 1296 } 1297 1298 async processingNextOption(element) {
1299 if(wkli_client_blocked) 1300 return false; 1301 let reg_status = false 1302 if(!JSON.parse(localStorage.getItem(localStorageVar))) { 1303 reg_status = await this.proceedToRegistration(); 1304 if(!reg_status) 1305 return false 1306 this.sendCustomFieldMessage() 1307 } 1308 if(!wkli_option_event && element.getAttribute('id')) { 1309 wkli_option_event = element.getAttribute('id') 1310 if ((element.textContent).trim()) { 1311 let msg = (element.textContent).trim(); 1312 this.buildMessage(msg, 1, (data) => { 1313 this.chnageMessageDetails(data, (updatedMessage) => { 1314 updatedMessage.tick = true 1315 this.buildAttachmentInDom(3, updatedMessage, "wk-cw-user-to-operator-msg", "user-to-operator-msg", 2); 1316 this.scrollHeight(); 1317 updatedMessage.reg_status = reg_status 1318 updatedMessage.option_id = wkli_option_event;
1319 updatedMessage.option_step = wkli_option_step; 1320 updatedMessage.domainName = location.hostname 1321 updatedMessage.Shopify_shop_name = Shopify ? Shopify.shop : location.hostname 1322 if (location.hostname.includes('localhost')) 1323 updatedMessage.domainName = 'saurabh-store-openai.myshopify.com' 1324 localStorage.setItem(localAutoChat, JSON.stringify({id: wkli_option_event})); 1325 if(localStorage.getItem(localStorageVar) && JSON.parse(localStorage.getItem(localStorageVar))) { 1326 updatedMessage.customer_email = JSON.parse(localStorage.getItem(localStorageVar)).clientEmail 1327 } 1328 if(wkli_shopify_customer.email) { 1329 updatedMessage.customer_email = wkli_shopify_customer.email 1330 } 1331 wkli_socket.emit("processSelfService",updatedMessage); 1332 this.disableChatWithAgent() 1333 }) 1334 }) 1335 } 1336 } else if(wkli_option_event) { 1337 this.buildMessage(element, 1, (data) => { 1338 this.chnageMessageDetails(data, (updatedMessage) => { 1339 updatedMessage.tick = true 1340 this.buildAttachmentInDom(3, updatedMessage, "wk-cw-user-to-operator-msg", "user-to-operator-msg", 2); 1341 this.scrollHeight(); 1342 updatedMessage.option_id = wkli_option_event;
1343 updatedMessage.option_step = wkli_option_step; 1344 updatedMessage.orderId = wkli_orderId 1345 updatedMessage.reason = wkli_reason 1346 updatedMessage.domainName = location.hostname 1347 updatedMessage.Shopify_shop_name = Shopify ? Shopify.shop : location.hostname 1348 if (location.hostname.includes('localhost')) { 1349 updatedMessage.domainName = 'saurabh-store-openai.myshopify.com' 1350 updatedMessage.customerId = '' 1351 } 1352 // localStorage.setItem(localAutoChat, JSON.stringify({id: wkli_option_event})); 1353 if(wkli_shopify_customer.id) { 1354 updatedMessage.customerId = wkli_shopify_customer.id 1355 } 1356 if(localStorage.getItem(localStorageVar) && JSON.parse(localStorage.getItem(localStorageVar))) { 1357 updatedMessage.customer_email = JSON.parse(localStorage.getItem(localStorageVar)).clientEmail 1358 } 1359 if(wkli_shopify_customer.email) { 1360 updatedMessage.customer_email = wkli_shopify_customer.email 1361 } 1362 wkli_socket.emit("processSelfService",updatedMessage); 1363 if(document.getElementById("wk-cw-typing-loader")) 1364 document.getElementById("wk-cw-typing-loader").remove() 1365 this.buildTypingLoaderInDom() 1366 this.disableChatWithAgent() 1367 }) 1368 }) 1369 } 1370 } 1371 //end 1372 1373 showAITyping() { 1374 if(wkli_AI_chatbot) { 1375 let div = document.createElement('div') 1376 div.classList.add('wk-cw-livechat-opeTyping') 1377 div.innerHTML = `<span class="wk-cw-livechat-dot"></span><span class="wk-cw-livechat-dot"></span><span class="wk-cw-livechat-dot"></span>` 1378 helper.getElement(Ids.user_operator_chat_holder).appendChild(div) 1379 } 1380 } 1381 1382 removeAITyping() { 1383 const typingDiv = document.querySelectorAll('.wk-cw-livechat-opeTyping'); 1384 typingDiv.forEach(div => { 1385 div.remove(); 1386 }); 1387 } 1388 1389 buildReplyMessage(data) { 1390 if(data.includes('chatwhizz-new.s3.amazonaws.com')) { 1391 let arr = data.split('/') 1392 if(arr && arr.length) { 1393 return arr[arr.length-1] 1394 } else 1395 return data 1396 } else 1397 return data 1398 } 1399 1400 buildTypingLoaderInDom(){ 1401 let div = document.createElement('div'); 1402 let span1 = document.createElement('span'); 1403 let span2 = document.createElement('span'); 1404 let span3 = document.createElement('span'); 1405 1406 div.classList.add("wk-cw-typing-loader"); 1407 div.setAttribute("id", "wk-cw-typing-loader"); 1408 1409 span1.classList.add("wk-cw-typing-loader-first-child", "wk-cw-typing-loader-child"); 1410 span1.setAttribute("id", "wk-cw-typing-loader-first-child"); 1411 div.appendChild(span1); 1412 1413 span2.classList.add("wk-cw-typing-loader-second-child", "wk-cw-typing-loader-child"); 1414 span2.setAttribute("id", "wk-cw-typing-loader-second-child"); 1415 div.appendChild(span2); 1416 1417 span3.classList.add("wk-cw-typing-loader-third-child", "wk-cw-typing-loader-child"); 1418 span3.setAttribute("id", "wk-cw-typing-loader-third-child"); 1419 div.appendChild(span3); 1420 1421 helper.getElement(Ids.user_operator_chat_holder).appendChild(div); 1422 this.scrollHeight() 1423 } 1424 1425 preClientQueries () { 1426 //for ai chatbot and basic chatbot 1427 if(!wkli_basic_chatbot) { 1428 wkli_question.forEach((data,i)=>{ 1429 setTimeout(()=>{ 1430 this.buildQueriesInDom(2, data, 'wk-cw-operator-to-user-queries', 'operator-to-user-queries', 1); 1431 this.scrollHeight(); 1432 },(i+1) * 1000); 1433 }) 1434 } else { 1435 console.log('running self serivce') 1436 helper.refreshBasicChatbot() 1437 wkli_basic_chatbot_option.forEach((data, i) => { 1438 if(data.status) { 1439 setTimeout(()=>{ 1440 this.buildOptionsInDom(data, 'wk-cw-operator-to-user-queries', 'operator-to-user-queries'); 1441 this.scrollHeight(); 1442 }); 1443 } 1444 }) 1445 } 1446 } 1447 //end 1448 reconnectResendMessage(){ 1449 setTimeout(() => { 1450 if (helper.reSendMessages.length && localStorage.getItem(localStorageVar)) {
1451 helper.reSendMessages.forEach((msg)=>{ 1452 helper.user_operator_conversation.push(msg) 1453 this.sendMessage() 1454 }) 1455 helper.user_operator_conversation = []; 1456 } else { 1457 helper.reSendMessages.forEach((msg)=>{ 1458 document.querySelector(`#wkli${msg.messageId}`).parentElement.remove(); 1459 }) 1460 } 1461 }, 2000); 1462 } 1463 1464 getOldChatHistory() { 1465 if(wkli_client_blocked) 1466 return false; 1467 if(localStorage.getItem(localStorageVar) && JSON.parse(localStorage.getItem(localStorageVar))) { 1468 let localData = JSON.parse(localStorage.getItem(localStorageVar)) 1469 if(localData.clientEmail && localData.clientEmail && localData.senderId) { 1470 let clientEmail = localData.clientEmail; 1471 let domain = localData.domain; 1472 let senderId = localData.senderId 1473 wkli_socket.emit('get-chat-history', {clientEmail: clientEmail, domain: domain, senderId: senderId}) 1474 } 1475 }else if(JSON.parse(localStorage.getItem('restrictChatHistory')) && JSON.parse(localStorage.getItem('restrictChatHistory')).clientEmail){ 1476 let localDataRestrictChat = JSON.parse(localStorage.getItem('restrictChatHistory')) 1477 let clientEmail = localDataRestrictChat.clientEmail; 1478 let domain = localDataRestrictChat.domain; 1479 wkli_socket.emit('get-chat-history', {clientEmail: clientEmail, domain: domain}) 1480 } 1481 } 1482 1483 getMessageFromOperator() { 1484 1485 this.getUserOperatorData() 1486 1487 wkli_socket.on('connect', () => { 1488 if (JSON.parse(localStorage.getItem(localStorageVar)) && JSON.parse(localStorage.getItem(localStorageVar)).uniqueId) { 1489 wkli_socket.emit('socketReconnect', JSON.parse(localStorage.getItem(localStorageVar))); 1490 this.reconnectResendMessage() 1491 1492 if(disconnectAt >= 0) { 1493 setTimeout(() => { 1494 // document.getElementById('wk-cw-user-operator-chat').innerHTML = ''; 1495 user.socketRejoin(true); 1496 }, 4000); 1497 fetch(`${WKprotocol}${WKscript}/wkcs/reconnected-client`).then(res => res.json()).then(data => { 1498 console.log(data) 1499 if(data.maintenance) { 1500 this.switchMaintenanceMode(); 1501 setTimeout(() => { 1502 document.getElementById(Ids.MAIN_COINTAINER).remove(); 1503 createMaintenanceWidget(); 1504 }, 5000) 1505 } 1506 }).catch(error => { 1507 console.log(error) 1508 }) 1509 } 1510 disconnectAt ++; 1511 } 1512 wkli_isSocketConnected = true 1513 wkli_checkRestartChat() 1514 let wifiDissconnect = document.getElementById('wkInternetDissconnect'); 1515 wifiDissconnect.style.display ="none"; 1516 }) 1517 1518 wkli_socket.on('disconnect', () => { 1519 wkli_isSocketConnected = false 1520 let wifiDissconnect = document.getElementById('wkInternetDissconnect'); 1521 wifiDissconnect.style.display ="flex"; 1522 }); 1523 1524 wkli_socket.on("sendMessageAckOfUser", (data) => { 1525 if(data && data.isChatEnd && data.messageId && document.querySelector(`#wkli${data.messageId}`)){ 1526 document.querySelector(`#wkli${data.messageId}`).parentElement.remove(); 1527 return 1528 } 1529 1530 if (data.sendTimestamp && data.messageId && helper.reSendMessages.length) { 1531 helper.reSendMessages = helper.reSendMessages.filter((msg) => { 1532 if (data.messageId !== msg.messageId) { 1533 return true; // Keep the element in the filtered array 1534 } 1535 return false; // Exclude the element from the filtered array 1536 }); 1537 } 1538 if(data.type == 6 && data.agentChataInitiated){ 1539 let user = JSON.parse(localStorage.getItem(localStorageVar)) 1540 user.operator = ''; 1541 localStorage.setItem(localStorageVar, JSON.stringify(user)); 1542 return; 1543 }
1544 if(wkli_selectedChatOption == 'whatsapp'){ 1545 localStorage.removeItem(localStorageVar); 1546 return; 1547 } 1548 1549 if(data && data.messageId && document.querySelector(`#wkli${data.messageId}`)){ 1550 document.querySelector(`#wkli${data.messageId}`).nextElementSibling.children[0].classList.remove('wk-cw-message-wait'); 1551 document.querySelector(`#wkli${data.messageId}`).nextElementSibling.children[0].classList.add('wk-cw-message-send'); 1552 } 1553 let save = { 1554 domain: data.domain, 1555 senderId: data.senderId, 1556 uniqueId: data.uniqueId, 1557 enable: true 1558 } 1559 if(data.name) 1560 save.clientName=data.name 1561 if(data.email) 1562 save.clientEmail=data.email 1563 1564 if(data.saveOperatorData){ 1565 save.name = wkli_showOperatorName ? wkli_botName : wkli_opName; 1566 save.operator = data.receiverId; 1567 save.operatorStatus = true; 1568 document.getElementById("wk-ch-operatorOnline").style.display = "inline-block"; 1569 document.getElementById("wk-ch-operatorOnline").style.background = "chartreuse"; 1570 document.getElementById("operatorName").textContent = wkli_showOperatorName ? wkli_botName : wkli_opName; 1571 } 1572 let autoChatApi = JSON.parse(localStorage.getItem('autoChatApi')) 1573 if(wkli_autoChatBotType && wkli_autoChatBotType == '2' && autoChatApi){ 1574 document.getElementById("operatorName").textContent = wkli_botName; 1575 } 1576 if (!JSON.parse(localStorage.getItem(localStorageVar))) { 1577 if (wkli_restart_chat_field) 1578 save.restartChatValue = wkli_getInjectedValue(wkli_restart_chat_field) 1579 localStorage.setItem(localStorageVar, JSON.stringify(save)); 1580 helper.toggleChatHistory() 1581 if(typeof(media) == 'object') { 1582 media.senderName = data.name ? data.name : data.uniqueId; 1583 media.senderId = data.uniqueId; 1584 media.senderEmail = data.email ? data.email : data.uniqueId; 1585 } 1586 } 1587 if(data.isbotOperator && !JSON.parse(localStorage.getItem(localStorageVar)).operator){ 1588 let user = JSON.parse(localStorage.getItem(localStorageVar)) 1589 user.operator = data.receiverId; 1590 user.botOpStatus = true; 1591 localStorage.setItem(localStorageVar, JSON.stringify(user)); 1592 } 1593 1594 if (!wkli_showForm && document.getElementsByClassName("wk-cw-user-to-operator-msg").length == 0 && data.saveOperatorData) { 1595 if ((helper.getElement("wk-cw-message").value).trim()) { 1596 let msg = (helper.getElement("wk-cw-message").value).trim(); 1597 this.buildMessage(msg, 1, (data) => { 1598 this.chnageMessageDetails(data, (updatedMessage) => { 1599 helper.user_operator_conversation.push(updatedMessage) 1600 this.buildMessageInDom(updatedMessage) 1601 helper.getElement("wk-cw-message").value = ""; 1602 helper.getElement("wk-cw-message").rows = 1 1603 }) 1604 }) 1605 1606 } 1607 } 1608 1609 //the client record exists now, so the agent request that triggered this registration 1610 //can go out with its senderId 1611 if (wkli_pending_agent_chat && JSON.parse(localStorage.getItem(localStorageVar))) { 1612 let pendingAgentChat = wkli_pending_agent_chat; 1613 wkli_pending_agent_chat = null; 1614 this.startChatWithAgent(pendingAgentChat.initType, pendingAgentChat.msgData); 1615 } 1616 1617 let endChat = document.getElementById('wkEndChat'); 1618 endChat.style.display = "flex"; 1619 1620 // helper.isOffline = false; 1621 }) 1622 //for ai chatbot and basic chatbot 1623 wkli_socket.on("processSelfService", (data) => {
1624 wkli_option_step = data.option_step 1625 wkli_orderId = data.orderId ? data.orderId : '' 1626 wkli_reason = data.reason ? data.reason : '' 1627 if(['question', 'response', 'optionalQuestion', 'reason', 'email', 'otp'].includes(data.option_step)) { 1628 if(document.getElementById("wk-cw-typing-loader")) 1629 document.getElementById("wk-cw-typing-loader").remove() 1630 this.buildAttachmentInDom(3, data, "wk-cw-operator-to-user-msg", "operator-to-user-msg", 3); 1631 this.scrollHeight(); 1632 if(!data.orderno && data.event == 'getOrderNo' || data.option_step == 'question' || data.option_step == 'optionalQuestion' || data.option_step == 'reason' || data.option_step == 'email' || data.option_step == 'otp') { 1633 this.enableChatWithAgent() 1634 } 1635 } 1636 }) 1637 //to initiate operator agent chat if ai failed 1638 wkli_socket.on('initiateAgetChat',(data)=>{ 1639 let user = JSON.parse(localStorage.getItem(localStorageVar)) 1640 if(data.operatorOnline){ 1641 this.startChatWithAgent(2,data) 1642 if(user?.is_operator_online == false){ 1643 user.is_operator_online = true 1644 } 1645 }else{ 1646 user.is_operator_online = false 1647 document.getElementById("wk-ch-operatorOnline").style.background = "chartreuse"; 1648 } 1649 localStorage.setItem(localStorageVar, JSON.stringify(user)) 1650 }) 1651 // socket reconnect check operator 1652 wkli_socket.on('reconnectionOp',(data)=>{ 1653 this.assignOperatorChat(data) 1654 }) 1655 //end 1656 1657 wkli_socket.on("msgToFrontUser", (data) => { 1658 if(!document.getElementById(Ids.MODEL_COINTAINER).classList.contains('wk-cw-show')) { 1659 helper.getElement(Ids.unreadMessage).style.display = "inline-block" 1660 helper.getElement(Ids.unreadMessage).innerHTML = helper.unreadMessageCount + 1 1661 helper.unreadMessageCount += 1 1662 } 1663 document.getElementById("wk-cw-isTyping").style.display = "none" 1664 let autoChatApi = JSON.parse(localStorage.getItem('autoChatApi')) 1665 //a reply landed, so the send lock goes regardless of who answered. assignOperatorChat() 1666 //clears autoChatApi on operator takeover, and gating this on it left the client locked out 1667 preventSendingMsg = false; 1668 if(wkli_autoChatBotType && wkli_autoChatBotType == '2' && autoChatApi){ 1669 document.getElementById("operatorName").textContent = wkli_botName; 1670 document.getElementById("wk-ch-operatorOnline").style.background = "chartreuse"; 1671 1672 } 1673 if (data.type != 2) { 1674 // let msg = data.message.replace(/</g, "<").replace(/>/g, ">").split(' \n'); 1675 let msg; 1676 if (data.responseBy === 'ai' || data.opSenderName === 'Bot') { 1677 msg = data.message.split('\n'); 1678 } else { 1679 msg = data.message.replace(/</g, "<").replace(/>/g, ">").split(' \n'); 1680 } 1681 let getext = msg[0].split('.') 1682 let ext = getext[getext.length - 1] 1683 if (/<img[^>]+src="([^">]+)/.test(data.message)) { 1684 this.buildAttachmentInDom(4, data, "wk-cw-operator-to-user-msg", "operator-to-user-msg", 1); 1685 } 1686 else if (helper.link_exp.test(data.message) || (helper.checkAttachment.includes(ext))) { 1687 if (msg[0].includes(".s3.amazonaws.com")) { 1688 this.buildAttachmentInDom(1, data, "wk-cw-operator-to-user-msg", "operator-to-user-msg", 2); 1689 } else { 1690 this.buildAttachmentInDom(2, data, "wk-cw-operator-to-user-msg", "operator-to-user-msg", 2); 1691 } 1692 } else { 1693 this.buildAttachmentInDom(2, data, "wk-cw-operator-to-user-msg", "operator-to-user-msg", 2); 1694 } 1695 } 1696 this.scrollHeight(); 1697 // let component = helper.getElement(Ids.CHATBOT) 1698 // let css = getComputedStyle(component) 1699 if (document.getElementById(Ids.MODEL_COINTAINER).classList.contains('wk-cw-show')) 1700 data.seenTimestamp = new Date().toISOString(); 1701 else 1702 data.delieverdTimestamp = new Date().toISOString(); 1703 1704 // this.messageSound(100, 520, 200) 1705 this.messageSound(); 1706 data.userId = data.receiverId 1707 wkli_socket.emit("operatormsgRecieveAck", data); 1708
1709 if(wkli_AI_chatbot) { 1710 if(ai_message.question) { 1711 ai_message.history.push({"type": "human", "text": ai_message.question}) 1712 ai_message.history.push({"type": "ai", "text": data.message}) 1713 } 1714 if(data.responseBy == 'ai') { 1715 this.removeAITyping() 1716 } 1717 } 1718 1719 if(helper.getElement("wk-chat-end-confirmation").style.display == 'block') { 1720 helper.getElement(Ids.wkConfirmationCancel).click() 1721 } else { 1722 helper.startChatTimeout() 1723 } 1724 }) 1725 1726 wkli_socket.on('getAllMessages', (response) => { 1727 preventSendingMsg = false; 1728 if(wkli_selectedChatOption == 'whatsapp') 1729 return; 1730 if(helper.checkRestrictAgentChatCondition()){ 1731 helper.getElement(Ids.Text_Container).style.display = "none"; 1732 let data = { 1733 message: wkli_errorPermissionMsg 1734 } 1735 this.buildErrorAttachInDom(data) 1736 return 1737 } 1738 if (response.unseenCount > 0 && response.messages) { 1739 helper.getElement(Ids.unreadMessage).style.display = "inline-block" 1740 helper.getElement(Ids.unreadMessage).innerHTML = response.unseenCount 1741 helper.unreadMessageCount = response.unseenCount 1742 } 1743 let usrData = JSON.parse(localStorage.getItem(localStorageVar)); 1744 if(response.isOperatorOnline && usrData) { 1745 usrData.isOperatorOnline = response.isOperatorOnline; 1746 localStorage.setItem(localStorageVar, JSON.stringify(usrData)) 1747 document.getElementById("wk-ch-operatorOnline").style.background = "chartreuse"; 1748 } 1749 let parentClass, childClass; 1750 let endChat = document.getElementById('wkEndChat'); 1751 if(response.reconnect) 1752 document.getElementById('wk-cw-user-operator-chat').innerHTML = ''; 1753 if(response.messages && response.messages.length){ 1754 if(helper.getElement("wk-chat-end-confirmation").style.display == 'block') { 1755 helper.getElement(Ids.wkConfirmationCancel).click() 1756 } else { 1757 helper.startChatTimeout() 1758 } 1759 response.messages.forEach(data => { 1760 if (usrData && usrData.senderId && usrData.senderId == data.senderId && data.type != 3) {4 1761 endChat.style.display = 'flex'; 1762 parentClass = "wk-cw-user-to-operator-msg"; 1763 childClass = "user-to-operator-msg"; 1764 data.tick = true; 1765 } else if(data.type == 3 || true) { 1766 parentClass = "wk-cw-operator-to-user-msg"; 1767 childClass = "operator-to-user-msg"; 1768 } 1769 if (data.type != 2 && data.message) { 1770 let msg = data.message.replace(/</g, "<").replace(/>/g, ">").split(' \n'); 1771 let getext = msg[0].split('.') 1772 let ext = getext[getext.length - 1] 1773 if (/<img[^>]+src="([^">]+)/.test(data.message)) { 1774 this.buildAttachmentInDom(4, data, "wk-cw-operator-to-user-msg", "operator-to-user-msg", 1); 1775 } 1776 else if (helper.link_exp.test(data.message) || (helper.checkAttachment.includes(ext))) { 1777 if (msg[0].includes(".s3.amazonaws.com")) { 1778 this.buildAttachmentInDom(1, data, parentClass, childClass, 1); 1779 } else { 1780 this.buildAttachmentInDom(2, data, parentClass, childClass, 1); 1781 } 1782 } else { 1783 data.onlineStatus = response.onlineStatus 1784 this.buildAttachmentInDom(2, data, parentClass, childClass, 1) 1785 }
1786 if(wkli_AI_chatbot && data.responseBy && data.responseBy != 'ai-init') { 1787 // if(!ai_message.question) { 1788 // ai_message.question = data.message 1789 // } else { 1790 if(!ai_message.history) 1791 ai_message.history = [] 1792 ai_message.history.push({ 1793 "type": data.responseBy, 1794 "text": data.message 1795 }) 1796 // } 1797 } 1798 } 1799 // if(data.message.includes("Ticket has been created")){ 1800 // this.ticketCreatedByOperator(data) 1801 // } 1802 }); 1803 } 1804 if (document.getElementById("loader-skin")) 1805 document.getElementById("loader-skin").style.display = "none"; 1806 this.scrollHeight(); 1807 let autoChatApi = JSON.parse(localStorage.getItem('autoChatApi')) 1808 if (response.offline && !autoChatApi) { 1809 helper.isOffline = true; 1810 document.getElementById("wk-ch-operatorOnline").style.background = "red"; 1811 } else { 1812 helper.isOffline = false; 1813 } 1814 if (response.isChatEnd) { 1815 let data = { 1816 message: "<------ Your chat has been ended ------>" 1817 } 1818 this.chatEndByOperatorNotification(data) 1819 } 1820 let localAutoReponseData = JSON.parse(localStorage.getItem(localAutoChat)); 1821 if(localAutoReponseData && typeof(localAutoReponseData) == "object"){ 1822 localAutoReponseData.domain = location.host; 1823 localAutoReponseData.onlyQuestion = true; 1824 wkli_socket.emit("getOnlyQuestion", localAutoReponseData); 1825 } else if(localAutoReponseData) { 1826 this.preClientQueries(); 1827 } 1828 this.disableChatWithAgent() 1829 if(response.in_queue) { 1830 helper.in_queue = response.in_queue 1831 } 1832 if(response.hasOwnProperty('autoChatEnd')) { 1833 this.autoChatEndChangedByOperator(response.autoChatEnd) 1834 } 1835 }) 1836 1837 wkli_socket.on('preClientQueries', ()=>{ 1838 //for ai chatbot and basic chatbot 1839 if(wkli_autoChatBotType != '2'){ 1840 if(!wkli_basic_chatbot && wkli_autoChatBotType != '2') { 1841 wkli_question.forEach((data,i)=>{ 1842 setTimeout(()=>{ 1843 this.buildQueriesInDom(2, data, 'wk-cw-operator-to-user-queries', 'operator-to-user-queries', 1); 1844 this.scrollHeight(); 1845 // document.getElementById("wk-cw-typing-loader").remove(); 1846 },(i+1) * 1000); 1847 // if(i <= question.length-1){ 1848 // setTimeout(()=>{ 1849 // this.buildTypingLoaderInDom() 1850 // },(i+1) * 700); 1851 // } 1852 }) 1853 } else { 1854 console.log('running self serivce') 1855 helper.refreshBasicChatbot() 1856 helper.getElement(Ids.autoResponseAction).style.display = "grid"; 1857 wkli_basic_chatbot_option.forEach((data, i) => { 1858 if(data.status) { 1859 setTimeout(()=>{ 1860 this.buildOptionsInDom(data, 'wk-cw-operator-to-user-queries', 'operator-to-user-queries'); 1861 this.scrollHeight(); 1862 }); 1863 } 1864 }) 1865 } 1866 } 1867 //end 1868 if (document.getElementById("loader-skin")) 1869 document.getElementById("loader-skin").style.display = "none"; 1870 }) 1871 1872 wkli_socket.on('queryNextLevel', result => { 1873 result.forEach((data,i)=>{ 1874 if(!data.isAnswer){ 1875 setTimeout(()=>{ 1876 this.buildQueriesInDom(2, data, 'wk-cw-operator-to-user-queries', 'operator-to-user-queries', 1); 1877 this.scrollHeight(); 1878 },(1+i)*1000) 1879 } 1880 }) 1881 query_status = false 1882 }) 1883 1884 wkli_socket.on('queryResult', result => { 1885 result.forEach((data,i)=>{ 1886 setTimeout(()=>{ 1887 data.message = data.answer; 1888 delete data.answer; 1889 data.senderId = ""; 1890 this.buildAttachmentInDom(2, data, 'wk-cw-operator-to-user-msg', 'operator-to-user-msg', 2); 1891 this.scrollHeight(); 1892 // document.getElementById("wk-cw-typing-loader").remove(); 1893 },(1+i)*1000) 1894 // if(i <= question.length-1){ 1895 // setTimeout(()=>{ 1896 // this.buildTypingLoaderInDom() 1897 // },(i+1) * 700); 1898 // } 1899 }) 1900 }) 1901 1902 wkli_socket.on('noQueryResponseData', result => { 1903 query_status = false 1904 }) 1905 1906 wkli_socket.on('assineOperatorToUserReqAck', (data) => { 1907 this.assignOperatorChat(data) 1908 }) 1909 1910 1911 wkli_socket.on("transferClient", data => { 1912 // the new operator's display name is used only while the domain is configured for it 1913 let operatorName = (wkli_useOperatorDisplayName && data.displayName) ? data.displayName : data.name 1914 if (wkli_showOperatorName) { 1915 document.getElementById("operatorName").innerHTML = operatorName 1916 } 1917 if (data && JSON.parse(localStorage.getItem(localStorageVar))) { 1918 if (JSON.parse(localStorage.getItem(localStorageVar)).uniqueId == data.uniqueId) { 1919 document.getElementById("wk-ch-operatorOnline").style.display = "inline-block" 1920 let user = JSON.parse(localStorage.getItem(localStorageVar)) 1921 user.operator = data.operatorId; 1922 user.name = operatorName 1923 if (data.operatorStatus == 1) { 1924 document.getElementById("wk-ch-operatorOnline").style.background = "chartreuse"; 1925 user.operatorStatus = true; 1926 } else { 1927 document.getElementById("wk-ch-operatorOnline").style.background = "red"; 1928 user.operatorStatus = false;
1929 } 1930 localStorage.setItem(localStorageVar, JSON.stringify(user)) 1931 this.getUserOperatorData() 1932 } 1933 } 1934 }) 1935 1936 wkli_socket.on('sendUserDetailsAck', (data) => { 1937 wkli_registration_in_process = false 1938 let save = { 1939 // name: data.name, 1940 clientName: data.name, 1941 clientEmail: data.email, 1942 departmentId: data.departmentId, 1943 domain: data.domainName, 1944 senderId: data.senderId, 1945 uniqueId: data.uniqueId, 1946 enable: true, 1947 } 1948 if(data?.operator){ 1949 save.operator = data.operator.botOperatorId 1950 } 1951 if (new URL(location.href).searchParams.get('name')) 1952 save.domain = new URL(location.href).searchParams.get('name') 1953 if (!JSON.parse(localStorage.getItem(localStorageVar))) { 1954 if (wkli_restart_chat_field) 1955 save.restartChatValue = wkli_getInjectedValue(wkli_restart_chat_field) 1956 localStorage.setItem(localStorageVar, JSON.stringify(save)) 1957 if(typeof(media) == 'object') { 1958 media.senderName = data.name; 1959 media.senderId = data.uniqueId; 1960 media.senderEmail = data.email; 1961 } 1962 } 1963 if (document.getElementsByClassName("wk-cw-user-to-operator-msg").length == 0) { 1964 this.sendChatInitiateNoti(); 1965 if(data.isWhatsAppClient) { 1966 // let msg = `email: ${data.email}` 1967 // if(user.isMobile()){ 1968 // window.open(`https://api.whatsapp.com/send?phone=${wkli_waba_number}&text=Hi`,"_blank"); 1969 // } else{ 1970 // window.open(`https://web.whatsapp.com/send?phone=${wkli_waba_number}&text=Hi`,"_blank"); 1971 // } 1972 wkli_modalVisiblity = false; 1973 user.openChatBlock(); 1974 return; 1975 } 1976 } 1977 if (wkli_customInput && document.getElementsByClassName("customInput").length > 0) { 1978 setTimeout(() => { 1979 this.sendCustomFieldMessage(wkli_enableAutoResponse) 1980 if(wkli_enableAutoResponse) 1981 this.preClientQueries(); 1982 }, 1000) 1983 1984 } 1985 }) 1986 1987 wkli_socket.on("conversation-end-ack", data => { 1988 ai_message = {} 1989 helper.getElement(Ids.user_operator_chat_holder).innerHTML = ""; 1990 let endChat = document.getElementById('wkEndChat'); 1991 document.getElementById("wk-ch-operatorOnline").style.display = "none" 1992 endChat.style.display = 'none'; 1993 helper.getElement("wk-cw-attachment-button-hide").value = ''; 1994 helper.getElement("wk-cw-chatbot-attachment-name").style.display = "none"; 1995 helper.getElement("wk-cw-chatbot-reply-block").style.display = "none"; 1996 helper.getElement("wk-cw-attachment-error").style.display = "none"; 1997 helper.getElement("operatorName").innerHTML = wkli_welcomeText; 1998 localStorage.removeItem(localStorageVar); 1999 helper.toggleChatHistory() 2000 localStorage.removeItem(localAutoChat); 2001 if (wkli_restart_chat_pending) { 2002 //ended because the tracked custom input changed, keep the widget as it is and open a fresh chat 2003 wkli_restart_chat_pending = false; 2004 helper.startNewSession(); 2005 } else 2006 new Form().showChatBlock(false); 2007 if (new URL(location.href).searchParams.get('name')) 2008 location.reload(); 2009 // if (!wkli_showForm) { 2010 // if (new URL(location.href).searchParams.get('name')) 2011 // wkli_socket.emit('sendAutoResponseInNoReg', { domain: new URL(location.href).searchParams.get('name'), enableAutoResponse: wkli_enableAutoResponse, organisationId: wkli_organisationId, AI_chatbot: wkli_AI_chatbot }); 2012 // else 2013 // wkli_socket.emit('sendAutoResponseInNoReg', { domain: location.hostname, enableAutoResponse: wkli_enableAutoResponse, organisationId: wkli_organisationId, AI_chatbot: wkli_AI_chatbot }); 2014 // }
2015 if(wkli_enableAutoResponse){ 2016 // question = conf.autoGenerateQuestions 2017 if(!JSON.parse(localStorage.getItem(localAutoChat)) && !JSON.parse(localStorage.getItem(localStorageVar))) { 2018 localStorage.setItem(localAutoChat, JSON.stringify(true)); 2019 this.disableChatWithAgent(); 2020 } 2021 } 2022 if(typeof(media) == 'object') { 2023 media.disconnectCallOnChatEnd(); 2024 } 2025 wkli_autoChatBotType = wkli_autoChatBotType_db 2026 let autoChatApi = JSON.parse(localStorage.getItem('autoChatApi')) 2027 if(wkli_autoChatBotType && wkli_autoChatBotType == '2'){ 2028 if(!autoChatApi){ 2029 localStorage.setItem('autoChatApi',true) 2030 createLoadingWidget('enable') 2031 } 2032 let user = JSON.parse(localStorage.getItem(localStorageVar)) 2033 if(user?.is_operator_online == false){ 2034 user.is_operator_online = true 2035 localStorage.setItem(localStorageVar, JSON.stringify(user)) 2036 } 2037 } else { 2038 localStorage.removeItem('autoChatApi') 2039 } 2040 }) 2041 2042 wkli_socket.on("conversation-end-by-operator", data => { 2043 this.chatEndByOperatorNotification(data) 2044 }) 2045 2046 wkli_socket.on("operator-IsTyping-ToUser", (data) => { 2047 if (JSON.parse(localStorage.getItem(localStorageVar))) { 2048 if (data.receiverId == JSON.parse(localStorage.getItem(localStorageVar)).senderId) { 2049 document.getElementById("wk-cw-isTyping").style.display = "block" 2050 is_Typing = new Date().valueOf(); 2051 this.disableIsTyping() 2052 } 2053 } 2054 }) 2055 2056 wkli_socket.on("signOut-Operator-Status", data => { 2057 if (JSON.parse(localStorage.getItem(localStorageVar)) && JSON.parse(localStorage.getItem(localStorageVar)).uniqueId == data) { 2058 document.getElementById("wk-ch-operatorOnline").style.background = "red" 2059 let user = JSON.parse(localStorage.getItem(localStorageVar)) 2060 user.operatorStatus = false; 2061 localStorage.setItem(localStorageVar, JSON.stringify(user)) 2062 } 2063 }) 2064 2065 wkli_socket.on("operatorConnection", data => { 2066 if (JSON.parse(localStorage.getItem(localStorageVar)) && JSON.parse(localStorage.getItem(localStorageVar)).uniqueId == data.id) { 2067 if (data.status) 2068 document.getElementById("wk-ch-operatorOnline").style.background = "chartreuse" 2069 else 2070 document.getElementById("wk-ch-operatorOnline").style.background = "red" 2071 let user = JSON.parse(localStorage.getItem(localStorageVar)) 2072 user.operatorStatus = true; 2073 localStorage.setItem(localStorageVar, JSON.stringify(user)) 2074 } 2075 }) 2076 2077 wkli_socket.on('technicalError', data => { 2078 wkli_registration_in_process = false 2079 //registration failed, no sendMessageAckOfUser is coming to replay it 2080 wkli_pending_agent_chat = null 2081 console.log('technicalError') 2082 document.getElementById('wk-cw-chatbot-textCointainer').innerHTML = ''; 2083 helper.getElement(Ids.user_operator_chat_holder).innerHTML = ""; 2084 let div = document.createElement('i') 2085 div.id="wkli_technicalError" 2086 div.style.color = '#FF5252' 2087 let errorMessage = data.errorMsg ? data.errorMsg : 'You are not providing email address. Kindly reload this page and try again.' 2088 div.innerHTML = `<h5 style="text-align: center;">ERROR</h5><p>${errorMessage}</p>` 2089 helper.getElement(Ids.user_operator_chat_holder).appendChild(div); 2090 }) 2091 2092 wkli_socket.on('ai-typing', (data) => { 2093 if (JSON.parse(localStorage.getItem(localStorageVar))) { 2094 if (data.senderId == JSON.parse(localStorage.getItem(localStorageVar)).senderId) { 2095 this.showAITyping() 2096 } 2097 } 2098 }) 2099 wkli_socket.on('old-chat-history', data => { 2100 let msg = '' 2101 if(data && data.link && data.link.length) {
2102 msg = wkli_chatHistoryLinkText + ' \n\n' 2103 data.link.forEach(i => { 2104 let a = document.createElement('a') 2105 a.href = `${WKprotocol}${WKscript}/wkcs/live-chat/${i._id}` 2106 a.target="_blank" 2107 a.text = 'Click Here' 2108 // console.log(a) 2109 msg += getLocalTimestamp(i.createdAt) + ' ' + a + '\n\n' 2110 }) 2111 } else { 2112 msg = wkli_chatHistoryEmptyText 2113 } 2114 let parentClass = "wk-cw-operator-to-user-msg"; 2115 let childClass = "operator-to-user-msg"; 2116 this.buildAttachmentInDom(2, {message: msg}, parentClass, childClass, 1) 2117 this.scrollHeight(); 2118 }) 2119 2120 wkli_socket.on('autoChatEndByOperator', data => { 2121 if(data.clientId && localStorage.getItem(localStorageVar)) { 2122 let senderId = JSON.parse(localStorage.getItem(localStorageVar)).senderId; 2123 if(data.clientId == senderId) { 2124 this.autoChatEndChangedByOperator(data.autoChatEnd) 2125 } 2126 } 2127 }) 2128 2129 wkli_socket.on('underMaintainance', data => { 2130 this.switchMaintenanceMode(); 2131 setTimeout(() => { 2132 document.getElementById(Ids.MAIN_COINTAINER).remove(); 2133 createMaintenanceWidget(); 2134 }, 5000) 2135 }) 2136 } 2137 2138 switchMaintenanceMode() { 2139 document.getElementById(Ids.MODEL_COINTAINER).style.display = "none" 2140 document.getElementById(Ids.OPTION_CONTAINER).style.display = "none" 2141 document.getElementById(Ids.MAINTENANCE_CONTAINER).style.display = "block" 2142 } 2143 2144 autoChatEndChangedByOperator(autoChatEnd) { 2145 if(autoChatEnd) { 2146 wkli_auto_chat_end = true 2147 helper.getElement("wk-countdown-div").style.display = 'block' 2148 } else { 2149 wkli_auto_chat_end = false; 2150 helper.getElement("wk-countdown-div").style.display = 'none' 2151 } 2152 if(helper.getElement("wk-chat-end-confirmation").style.display == 'block') { 2153 helper.getElement(Ids.wkConfirmationCancel).click() 2154 } else { 2155 helper.startChatTimeout() 2156 } 2157 } 2158 2159 chatEndByOperatorNotification(data) { 2160 helper.clearAllTimeoutAndInterval() 2161 document.getElementById("wk-cw-chatbot-textCointainer").style.display = "none"; 2162 let endChat = document.getElementById('wkEndChat'); 2163 endChat.style.display = 'none'; 2164 document.getElementById("wk-ch-operatorOnline").style.background = "red" 2165 helper.storage = JSON.parse(localStorage.getItem(localStorageVar)); 2166 localStorage.removeItem(localStorageVar); 2167 helper.toggleChatHistory() 2168 localStorage.removeItem(localAutoChat); 2169 let div = document.createElement('i') 2170 div.className = 'wk-cw-notify-User' 2171 div.innerHTML = wkli_translateLog(data.message).replace(/</g, "<").replace(/>/g, ">"); 2172 helper.getElement(Ids.user_operator_chat_holder).appendChild(div); 2173 let button = document.createElement('button'); 2174 var buttonTxt = document.createTextNode(wkli_startNewText); 2175 button.appendChild(buttonTxt); 2176 button.className = 'wk-ch-livechat-startNewChat' 2177 button.style.background = wkli_theamColor; 2178 button.setAttribute("onclick", 'helper.startNewSession()'); 2179 helper.getElement(Ids.user_operator_chat_holder).appendChild(button); 2180 if (!document.getElementById("sendMailButton") && wkli_endConversionMail) { 2181 let sendMailButton = document.createElement('button'); 2182 var sendMailButtonTxt = document.createTextNode(wkli_sendMailText); 2183 sendMailButton.setAttribute("title", wkli_sendMailTitle); 2184 sendMailButton.appendChild(sendMailButtonTxt); 2185 sendMailButton.className = 'wk-ch-livechat-startNewChat'; 2186 sendMailButton.style.background = wkli_theamColor 2187 sendMailButton.id = "sendMailButton"; 2188 sendMailButton.setAttribute("onclick", 'new Form().endConversationSendM
2188ail(false)'); 2189 helper.getElement(Ids.user_operator_chat_holder).appendChild(sendMailButton); 2190 } 2191 helper.getElement("wk-cw-attachment-button-hide").value = ''; 2192 helper.getElement("wk-cw-chatbot-attachment-name").style.display = "none"; 2193 helper.getElement("wk-cw-attachment-error").style.display = "none"; 2194 this.scrollHeight(); 2195 2196 if(wkli_enableAutoResponse){ 2197 // question = conf.autoGenerateQuestions 2198 if(!JSON.parse(localStorage.getItem(localAutoChat)) && !JSON.parse(localStorage.getItem(localStorageVar))) { 2199 localStorage.setItem(localAutoChat, JSON.stringify(true)); 2200 this.disableChatWithAgent(); 2201 } 2202 } 2203 let elem = helper.getElement("wk-chat-end-confirmation") 2204 if(elem.style.display == 'block') { 2205 elem.style.display = 'none'; 2206 elem.classList.remove('wk-cw-show') 2207 helper.changeDisplayProperty(Ids.CHATBOT) 2208 } 2209 if(wkli_auto_chat_end) { 2210 helper.getElement("wk-countdown-div").style.display = 'block' 2211 } 2212 helper.getElement(Ids.chatWithChatbot).style.display = 'none' 2213 } 2214 2215 messageSound() { 2216 let playPromise; 2217 if(wkli_clientNotifySoundStatus) { 2218 playPromise = aud.play() 2219 } 2220 if(playPromise) { 2221 playPromise.catch((e) => { 2222 if (e.name === 'NotAllowedError' || e.name === 'NotSupportedError') { 2223 console.log(e.name); 2224 } 2225 }).then(()=>{}) 2226 } 2227 2228 } 2229 2230 disableIsTyping() { 2231 setTimeout(() => { 2232 if (new Date().valueOf() - is_Typing > 1800) { 2233 document.getElementById("wk-cw-isTyping").style.display = "none" 2234 } 2235 }, 2000); 2236 } 2237 2238 scrollHeight() { 2239 let element = helper.getElement("wk-cw-user-operator-chat"); 2240 if (element) 2241 element.scrollTop = element.scrollHeight; 2242 } 2243 2244 endAutoChat(){ 2245 if(wkli_enableAutoResponse){ 2246 document.getElementById(Ids.Text_Container).style.display = "none" 2247 } 2248 helper.getElement(Ids.user_operator_chat_holder).innerHTML = ""; 2249 } 2250 //for ai chatbot and basic chatbot 2251 enableChatWithAgent() { 2252 if(wkli_client_blocked) 2253 return false; 2254 helper.getElement(Ids.MESSAGE).value = ""; 2255 document.getElementById(Ids.Text_Container).style.display = "grid" 2256 helper.getElement(Ids.autoResponseAction).style.display = "none"; 2257 helper.getElement("wk-cw-attachment-button-hide").disabled = true 2258 helper.getElement(Ids.MESSAGE).focus(); 2259 } 2260 //end 2261 2262 socketRejoin(reconnect = 'false') { 2263 let enableAutoChatApi = false; 2264 let autoChatApi = JSON.parse(localStorage.getItem('autoChatApi')) 2265 if(wkli_autoChatBotType && wkli_autoChatBotType == '2' && autoChatApi){ 2266 enableAutoChatApi = true; 2267 } 2268 preventSendingMsg = false; 2269 if (!new URL(location.href).searchParams.get('name')){ 2270 helper.getElement(Ids.MAIN_COINTAINER).style.display = "block" 2271 } 2272 if (JSON.parse(localStorage.getItem(localStorageVar)) && JSON.parse(localStorage.getItem(localStorageVar)).uniqueId) { 2273 if (JSON.parse(localStorage.getItem(localStorageVar)).enable == true && !new URL(location.href).searchParams.get('name')) 2274 new Form().showChatBlock(true); 2275 if (JSON.parse(localStorage.getItem(localStorageVar)).operatorStatus == true) 2276 document.getElementById("wk-ch-operatorOnline").style.background = "chartreuse" 2277 else 2278 document.getElementById("wk-ch-operatorOnline").style.background = "red" 2279 if (JSON.parse(localStorage.getItem(localStorageVar)).operator) 2280 document.getElementById("wk-ch-operatorOnline").style.display = "inline-block" 2281 if (document.getElementById("loader-skin")) 2282 document.getElementById("loader-skin").style.display = "block"; 2283 wkli_socket.emit('socketRejoin', {localData: JSON.parse(localStorage.getItem(localStorageVar)), enableAutoResponse: wkli_enableAutoResponse, reconnect: reconnect, AI_chatbot: wkli_AI_chatbot,enableAutoChatApi}); 2284 wkli_socket.emit("getAllMessageAck", { 2285 receiverId: JSON.parse(localStorage.getItem(localStorageVar)).senderId, 2286 delieverdTimestamp: new Date().toISOString(), 2287 domain: JSON.parse(localStorage.getItem(localStorageVar)).domain, 2288 userId: JSON.parse(localStorage.getItem(localStorageVar)).senderId 2289 }) 2290 } else { 2291 if (!wkli_showForm) { 2292 if (new URL(location.href).searchParams.get('name')) 2293 wkli_socket.emit('sendAutoResponseInNoReg', { domain: new URL(location.href).searchParams.get('name'),enableAutoResponse: wkli_enableAutoResponse, organisationId: wkli_organisationId, AI_chatbot: wkli_AI_chatbot,enableAutoChatApi }); 2294 else 2295 wkli_socket.emit('sendAutoResponseInNoReg', { domain: location.hostname, enableAutoResponse: wkli_enableAutoResponse, organisationId: wkli_organisationId, AI_chatbot: wkli_AI_chatbot,enableAutoChatApi }); 2296 } 2297 } 2298 } 2299 2300 2301 sendUserDetails() { 2302 let mailRegex = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; 2303 let contactRegex = /(^|\s|[^0-9])[\+]?[(]?[0-9]{3}[)]?[-\s\.]?[0-9]{3}[-\s\.]?[0-9]{4,6}(\s|[^0-9]|$)/ig; 2304 // let contactRegex = /^[0-9]{10}$/; 2305 2306 //new validation code 2307 let status = true; 2308 Array.from(document.querySelectorAll('#wk-ch-livechat-content .wk-cw-input')).forEac
2308h( 2309 function (element, index, array) { 2310 let warning = document.getElementById('warning-' + element.id); 2311 let field = element.dataset.label || element.name; 2312 if(element.id == 'wk-cw-selected-cc') 2313 warning = document.querySelector('.warning-wk-cw-selected-cc') 2314 if (element.required) { 2315 if (element.type == 'text' && status && !element.value.trim() && element.value.trim() == '' && element.id != 'wk-cw-selected-cc') { 2316 warning.innerText = wkli_requiredFieldText.split('{field}').join(field); 2317 wkli_scrollToElement(element.id) 2318 document.getElementById(element.id).focus() 2319 status = false; 2320 return false; 2321 } else if (wkli_selectedChatOption == 'whatsapp' && element.type == 'number' && element.value.trim() == '' && status) { 2322 warning.innerText = wkli_invalidFieldText.split('{field}').join(field); 2323 wkli_scrollToElement(element.id) 2324 document.getElementById(element.id).focus() 2325 status = false; 2326 return false; 2327 } else if (element.type == 'email' && !mailRegex.test(element.value) && status) { 2328 warning.innerText = wkli_invalidFieldText.split('{field}').join(field); 2329 wkli_scrollToElement(element.id) 2330 document.getElementById(element.id).focus() 2331 status = false; 2332 return false; 2333 } else if (element.type == 'select-one' && status && (element.value == "SELECT" || element.value == '')) { 2334 warning.innerText = wkli_requiredFieldText.split('{field}').join(field); 2335 wkli_scrollToElement(element.id) 2336 document.getElementById(element.id).focus() 2337 status = false; 2338 return false; 2339 } else if (wkli_selectedChatOption == 'whatsapp' && status && !wkli_country_code_list.some(country => country.dial_code == element.value) && element.id == 'wk-cw-selected-cc') { 2340 document.querySelector('.warning-wk-cw-selected-cc').innerHTML = `Please select valid country code from list`; 2341 wkli_scrollToElement(element.id) 2342 document.getElementById(element.id).focus() 2343 status = false; 2344 return false; 2345 } 2346 } 2347 if (status) { 2348 warning.innerHTML = '' 2349 } 2350 } 2351 ); 2352 2353 if (status && !wkli_registration_in_process) { 2354 wkli_registration_in_process = true 2355 let domainName = '' 2356 if (location.hostname.includes('localhost')) 2357 domainName = 'chatwhizz.com' 2358 else if (new URL(location.href).searchParams.get('name')) 2359 domainName = new URL(location.href).searchParams.get('name') 2360 else 2361 domainName = location.hostname 2362 2363 // form input when present, page injected value otherwise - the whatsapp form can be 2364 // built with the number field alone, so the name/email still come from the page 2365 let clientEmail = this.getRegistrationEmail() 2366 this.getClientToken(domainName, clientEmail, cb => { 2367 if(cb && cb.data) { 2368 initializeSocket().then(() => { 2369 if(wkli_selectedChatOption != 'whatsapp') 2370 new Form().showChatBlock(true); 2371 2372 let clientName = this.getRegistrationName(); 2373 if (clientName) 2374 clientName = clientName.replace(/</g, "<").replace(/>/g, ">"); 2375 let userData = { 2376 email: clientEmail, 2377 name: clientName, 2378 type: 1, 2379 uniqueId: '_' + Math.random().toString(36).substr(2, 16) + '_', 2380 domainName: domainName, 2381 customInput: wkli_customInput, 2382 clientToken: cb.data 2383 } 2384 if (wkli_depRegistration && document.getElementById(wkli_userDepartment) && document.getElementById(wkli_userDepartment).value && wkli_showForm) { 2385 let handleName = document.getElementById(wkli_userDepartment).value; 2386 let department = wkli_departmentArr.filter(x => { 2387 return x.handleName == handleName 2388 }) 2389 userData.departmentId = department[0].departmentId; 2390 // userData.departmentId = document.getElementById(wkli_userDepartment).value; 2391 } 2392 userData.enableAutoResponse = wkli_enableAutoResponse; 2393 let customFields = this.getCustomFieldsObject(); 2394 if (customFields) 2395 userData.customFields = customFields; 2396 // userData.domainName = "admin.webkul.com";
2397 if(wkli_selectedChatOption == 'whatsapp') { 2398 // read without clearing - the next whatsapp registration (no page reload) 2399 // must still find the page injected / prefilled values, same as sendCustomFieldMessage() 2400 let customMsg = '' 2401 Array.from(document.getElementsByClassName('customInput')).forEach( 2402 function (element, index, array) { 2403 customMsg += `${element.name}: ${element.value.replace(/</g, "<").replace(/>/g, ">")} \n`; 2404 } 2405 ); 2406 userData.customMsg = customMsg; 2407 userData.isWhatsAppClient = true; 2408 userData.whatsAppDetails = { 2409 number: document.getElementById(wkli_phoneNumber) ? document.getElementById('wk-cw-selected-cc').value.trim().substr(1) + document.getElementById(wkli_phoneNumber).value.trim().replace('+','').replace('-','') : null, 2410 isChatEnd: false, 2411 domainWaBusinessNumber: wkli_waba_number 2412 } 2413 if(!userData.whatsAppDetails.number){ 2414 if(!document.getElementById('wk-cw-no-wa')){ 2415 let error = document.createElement('small'); 2416 error.innerHTML = "you can't proceed without whatsapp number" 2417 error.style.color = 'red'; 2418 error.id = 'wk-cw-no-wa' 2419 document.getElementById('wk-cw-userDetails').insertBefore(error, document.getElementById('wk-cw-submit-form-control')) 2420 } 2421 wkli_registration_in_process = false; // release the lock, the visitor has to retry 2422 return false; 2423 } 2424 2425 if(user.isMobile()){ 2426 window.open(`https://api.whatsapp.com/send?phone=${wkli_waba_number}&text=Hi`,"_blank"); 2427 } else{ 2428 window.open(`https://web.whatsapp.com/send?phone=${wkli_waba_number}&text=Hi`,"_blank"); 2429 } 2430 } 2431 userData.AI_chatbot = wkli_AI_chatbot 2432 helper.getElement(Ids.user_operator_chat_holder).innerHTML = ""; 2433 let autoChatApi = JSON.parse(localStorage.getItem('autoChatApi')) 2434 if(helper.checkRestrictAgentChatCondition() && !wkli_enableAutoResponse){ 2435 helper.getElement(Ids.Text_Container).style.display = "none"; 2436 let data = { 2437 message: wkli_errorPermissionMsg 2438 } 2439 this.buildErrorAttachInDom(data) 2440 if(domainName && clientEmail){ 2441 let dataForRestrictChat = { 2442 clientEmail:clientEmail, 2443 domain: domainName 2444 } 2445 localStorage.setItem('restrictChatHistory', JSON.stringify(dataForRestrictChat)); 2446 helper.toggleChatHistory() 2447 } 2448 return 2449 } 2450 if(wkli_autoChatBotType && wkli_autoChatBotType == '2' && autoChatApi){ 2451 userData.enableAutoChatApi = true; 2452 } 2453 let liveChatPermission = document.getElementById('wk-ch-liveChatPermission'); 2454 if(wkli_agentChatPermission && liveChatPermission && liveChatPermission.value && liveChatPermission.value == '1') { 2455 userData.botToAgentRestrict = true; 2456 2457 } 2458 wkli_socket.emit('sendUserDetails', userData) 2459 // Array.from(document.getElementsByClassName('wk-cw-input')).forEac
2459h( 2460 // function (element, index, array) { 2461 // if (element.type == 'select-one') { 2462 // element.value = "SELECT"; 2463 // } else { 2464 // element.value = ""; 2465 // } 2466 // } 2467 // ); 2468 if(user.isMobile()){ 2469 document.getElementById(Ids.REGISTRATION_FROM_CLOSE_BTN_ID).style.display = 'none'; 2470 helper.changeDisplayProperty(Ids.circleWidget, 'block') 2471 document.getElementById(Ids.MODEL_COINTAINER).style.bottom = '80px' 2472 } 2473 }).catch((err) => { 2474 wkli_registration_in_process = false 2475 console.log(err) 2476 }) 2477 } else { 2478 wkli_registration_in_process = false 2479 } 2480 }) 2481 } 2482 2483 } 2484 2485 getClientToken(domain, email, cb) { 2486 if(wkli_autoChatBotType_db != 2) { 2487 localStorage.removeItem('autoChatApi') 2488 wkli_autoChatBotType = wkli_autoChatBotType_db 2489 // a new chat goes straight to an agent, hide the agent button left from an earlier bot chat 2490 createLoadingWidget('disable') 2491 } else { 2492 localStorage.setItem('autoChatApi', true) 2493 createLoadingWidget('enable') 2494 } 2495 if(!domain) { 2496 if (location.hostname.includes('localhost')) 2497 domain = 'chatwhizz.com' 2498 else if (new URL(location.href).searchParams.get('name')) 2499 domain = new URL(location.href).searchParams.get('name') 2500 else 2501 domain = location.hostname 2502 } 2503 let option = { 2504 method: 'POST', 2505 headers: {'Content-Type': 'application/json'}, 2506 body: JSON.stringify({ 2507 domain: domain, 2508 email: email, 2509 organisationId: wkli_organisationId, 2510 }) 2511 } 2512 fetch(`${WKprotocol}${WKscript}/wkcs/verify-client`,option).then(res => { 2513 return res.json().then(data => { return {ok: res.ok, data: data} }) 2514 }).then(response => { 2515 let data = response.data 2516 if(data.maintenance) { 2517 this.switchMaintenanceMode(); 2518 setTimeout(() => { 2519 document.getElementById(Ids.MAIN_COINTAINER).remove(); 2520 createMaintenanceWidget(); 2521 }, 5000) 2522 return 2523 } 2524 if(!response.ok) { 2525 //blocked ip or email, the response carries an error string and never a token 2526 this.showClientBlockedError(data.data) 2527 cb(false) 2528 return 2529 } 2530 if(wkli_autoChatBotType_db != data?.autoChatBotType) { 2531 if(data?.autoChatBotType == 2) { 2532 if(data?.autoChatBotConfig?.showAgentChatButton) 2533 wkli_agentChatButtonStatus = true 2534 switchToAutoChatBot("enable"); 2535 } 2536 else 2537 switchToAutoChatBot("disable") 2538 } 2539 cb(data) 2540 }).catch(error => { 2541 console.log(error) 2542 cb(false) 2543 }) 2544 } 2545 2546 /** 2547 * verify-client answers 404 for a blocked client. fetch() does not reject on 404, so the 2548 * caller has to be told explicitly rather than being handed the error text as a token. 2549 */ 2550 showClientBlockedError(message) { 2551 if (wkli_client_blocked) 2552 return; 2553 wkli_client_blocked = true; 2554 createLoadingWidget('disable') 2555 //drop the textarea itself, not just its display - several flows put the container 2556 //back on screen and a blocked client must have nothing left to type into 2557 if(helper.getElement(Ids.Text_Container)) 2558 helper.getElement(Ids.Text_Container).remove(); 2559 helper.getElement(Ids.autoResponseAction).style.display = "none"; 2560 helper.getElement(Ids.chatWithChatbot).style.display = "none"; 2561 //three dot menu only holds chat history, a blocked client must not reach it 2562 if(helper.getElement('wk-cw-chat-history-dropdown')) 2563 helper.getElement('wk-cw-chat-history-dropdown').style.display = "none"; 2564 //drop the chatbot option buttons, a blocked client must not be able to keep selecting them 2565 Array.from(document.getElementsByClassName("wk-cw-operator-to-user-queries")).forEac
2565h(el => el.remove()); 2566 this.buildErrorAttachInDom({ 2567 message: message && typeof message == 'string' ? message : 'You are not allowed to chat' 2568 }) 2569 this.scrollHeight(); 2570 } 2571 2572 endConversation() { 2573 if(!wkli_isSocketConnected) { 2574 return false 2575 } 2576 wkli_modalVisiblity = false 2577 let arr = JSON.parse(localStorage.getItem(localStorageVar)); 2578 if (arr) { 2579 let msg = (helper.getElement("wk-cw-message").value).trim(); 2580 let data = { 2581 isChatEnd: true, 2582 message: msg.replace(/</g, "<").replace(/>/g, ">"), 2583 sendTimestamp: new Date().toISOString(), 2584 domain: location.host, 2585 type: 2, 2586 end: 'sender', 2587 receiverId: arr.operator || '', 2588 senderId: arr.senderId, 2589 uniqueId: arr.uniqueId, 2590 chatInitiateNoti: true, 2591 addonUniqueName: wkli_addOnUniqueName 2592 } 2593 if (new URL(location.href).searchParams.get('name')) 2594 data.domain = new URL(location.href).searchParams.get('name') 2595 if (arr.departmentId && wkli_showForm) { 2596 data.departmentId = arr.departmentId 2597 } 2598 if(arr.isOperatorOnline) { 2599 data.isOperatorOnline = arr.isOperatorOnline 2600 } 2601 if(arr.clientName) { 2602 data.clientName = arr.clientName 2603 } 2604 if(arr.clientEmail) { 2605 data.clientEmail = arr.clientEmail 2606 } 2607 if(location.host.includes('localhost')) 2608 data.domain = 'chatwhizz.com' 2609 wkli_socket.emit("conversation-end", data); 2610 ai_message = {} 2611 } 2612 let element = helper.getElement("wk-chat-end-confirmation"); 2613 element.style.display = 'none'; 2614 if(wkli_auto_chat_end) { 2615 helper.getElement("wk-countdown-div").style.display = 'block' 2616 } 2617 helper.getElement(Ids.chatWithChatbot).style.display = 'none' 2618 } 2619 2620 endConversationSendMail(clientEnd = true) { 2621 if(!wkli_isSocketConnected) { 2622 return false 2623 } 2624 if(JSON.parse(localStorage.getItem(localStorageVar)) && JSON.parse(localStorage.getItem(localStorageVar)).senderId) 2625 helper.storage = JSON.parse(localStorage.getItem(localStorageVar)) 2626 let storage = helper.storage ? helper.storage : JSON.parse(localStorage.getItem(localStorageVar)) 2627 //the address the client registered with - form input, or the page injected / auto registered 2628 //one when there is no form. Only ask for an email when none of them is known. 2629 let registeredEmail = (storage && storage.clientEmail) ? storage.clientEmail : this.getRegistrationEmail() 2630 if (storage && registeredEmail) { 2631 if (clientEnd) { 2632 new Form().endConversation(); 2633 } else { 2634 document.getElementById("sendMailButton").style.display = "none"; 2635 } 2636 storage.clientEmail = registeredEmail 2637 wkli_socket.emit("ClientConversationMailOnEndChat", storage) 2638 } else { 2639 helper.getElement("wk-cw-displayEmail-errMsg").innerHtml = "" 2640 helper.getElement("wk-chat-end-confirmation").style.display = "flex" 2641 document.getElementById("wk-confirmation-child").style.display = 'none'; 2642 document.getElementById("wk-cw-email-withoutRegistration-parent").style.display = 'block'; 2643 } 2644 } 2645 2646 closeNewEmailPopUp() { 2647 if (JSON.parse(localStorage.getItem(localStorageVar))) { 2648 document.getElementById("wk-confirmation-child").style.display = 'block'; 2649 } else { 2650 helper.getElement("wk-chat-end-confirmation").style.display = "none"; 2651 } 2652 document.getElementById("wk-cw-email-withoutRegistration-parent").style.display = 'none'; 2653 } 2654 2655 confirmNewSendEmailChat() { 2656 if(!wkli_isSocketConnected) { 2657 return false 2658 } 2659 let mailRegex = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; 2660 let email = document.getElementById("wk-cw-email-withoutRegistration") 2661 if (email && !mailRegex.test(email.value)) { 2662 document.getElementById("wk-cw-displayEmail-errMsg").innerText = wkli_invalidEmailText; 2663 return false;
2664 } else { 2665 document.getElementById("wk-cw-displayEmail-errMsg").innerHTML = '' 2666 document.getElementById("wk-cw-email-withoutRegistration-parent").style.display = 'none'; 2667 document.getElementById("wk-confirmation-child").style.display = 'block'; 2668 new Form().endConversation(); 2669 if(JSON.parse(localStorage.getItem(localStorageVar)) && JSON.parse(localStorage.getItem(localStorageVar)).senderId) 2670 helper.storage = JSON.parse(localStorage.getItem(localStorageVar)) 2671 let data = helper.storage ? helper.storage : JSON.parse(localStorage.getItem(localStorageVar)); 2672 data.clientEmail = email.value.replace(/</g, "<").replace(/>/g, ">") 2673 wkli_socket.emit("ClientConversationMailOnEndChat", data) 2674 if (helper.getElement("sendMailButton")) { 2675 helper.getElement("sendMailButton").style.display = "none"; 2676 } 2677 } 2678 } 2679 2680 openAttachmentBox() { 2681 if(localStorage.getItem(localStorageVar) && JSON.parse(localStorage.getItem(localStorageVar)).senderId) { 2682 helper.getElement("wk-cw-attachment-error").textContent = '' 2683 helper.getElement("wk-cw-attachment-error").style.display = "none" 2684 document.getElementById("wk-cw-attachment-button-hide").click(); 2685 } else { 2686 let is_chatwithchatbot_enable = 0 2687 if(helper.getElement(Ids.chatWithChatbot).style.display == 'block') { 2688 is_chatwithchatbot_enable = 1 2689 } 2690 helper.getElement("wk-cw-attachment-error").style.display = "block"; 2691 helper.getElement("wk-cw-attachment-error").textContent = wkli_startChatFirstText 2692 helper.getElement(Ids.chatWithChatbot).style.display = "none" 2693 setTimeout(() => { 2694 helper.getElement("wk-cw-attachment-error").textContent = '' 2695 helper.getElement("wk-cw-attachment-error").style.display = "none" 2696 if(is_chatwithchatbot_enable && !wkli_option_event) { 2697 helper.getElement(Ids.chatWithChatbot).style.display = "block" 2698 } 2699 }, 2000) 2700 } 2701 } 2702 2703 closeAttachment() { 2704 helper.getElement("wk-cw-chatbot-attachment-name").style.display = "none"; 2705 document.getElementById("wk-cw-attachment-button-hide").value = ''; 2706 user.replyButtonAct(); 2707 } 2708 2709 closeReplyBlock() { 2710 helper.getElement("wk-cw-chatbot-reply-block").style.display = "none"; 2711 helper.getElement("wk-cw-user-operator-chat").style.maxHeight = "370px"; 2712 wkli_normalReplyData = ''; 2713 let active = document.querySelectorAll('.wk-cw-active') 2714 if(active.length){ 2715 active.forEach((chat) => { 2716 chat.classList.remove('wk-cw-active') 2717 }) 2718 } 2719 } 2720 2721 isTyping(data) { 2722 wkli_socket.emit("clientIsTyping", data) 2723 } 2724 2725 getQueryResult(element){ 2726 if(query_status || wkli_client_blocked) 2727 return false; 2728 query_status = true; 2729 if(!JSON.parse(localStorage.getItem(localStorageVar))){ 2730 //pass the resolved email so the blocklist can match on it, not just on the ip 2731 this.getClientToken(false, this.getRegistrationEmail(), cb => { 2732 if(!cb || !cb.data) { 2733 query_status = false; 2734 return false; 2735 } 2736 if(cb && cb.data) { 2737 let msg = `<------ ${location.href} ------>` 2738 this.buildMessage(msg, 2, (data) => { 2739 data.chatInitiateNoti = false; 2740 data.clientToken = cb.data; 2741 this.chnageMessageDetails(data, (updatedMessage) => { 2742 //registration rides on this message, same as proceedToRegistration(): 2743 //the email must match the address the token was minted with or registerUser() rejects it 2744 let customer_email = this.getRegistrationEmail() 2745 let customer_name = this.getRegistrationName() 2746 if(customer_email) 2747 updatedMessage.email = customer_email 2748 if(customer_name) 2749 updatedMessage.name = customer_name
2750 let departmentId = this.getSelectedDepartmentId() 2751 if(departmentId) 2752 updatedMessage.departmentId = departmentId 2753 let customFields = this.getCustomFieldsObject() 2754 if(customFields) 2755 updatedMessage.customFields = customFields 2756 if(new URL(location.href).searchParams.get('name')) 2757 updatedMessage.domain = new URL(location.href).searchParams.get('name'); 2758 wkli_socket.emit("getQueryResult",updatedMessage); 2759 }) 2760 }) 2761 setTimeout(()=>{ 2762 if ((element.textContent).trim()) { 2763 let msg = (element.textContent).trim(); 2764 this.buildMessage(msg, 1, (data) => { 2765 this.chnageMessageDetails(data, (updatedMessage) => { 2766 updatedMessage.tick= true; 2767 this.buildAttachmentInDom(3, updatedMessage, "wk-cw-user-to-operator-msg", "user-to-operator-msg", 2); 2768 this.scrollHeight(); 2769 updatedMessage.id = element.getAttribute('id'); 2770 localStorage.setItem(localAutoChat, JSON.stringify({id: element.getAttribute('id')})); 2771 if(new URL(location.href).searchParams.get('name')) 2772 updatedMessage.domain = new URL(location.href).searchParams.get('name'); 2773 wkli_socket.emit("getQueryResult",updatedMessage); 2774 this.disableChatWithAgent() 2775 }) 2776 }) 2777 } 2778 },1000); 2779 } 2780 }) 2781 } else { 2782 setTimeout(()=>{ 2783 if ((element.textContent).trim()) { 2784 let msg = (element.textContent).trim(); 2785 this.buildMessage(msg, 1, (data) => { 2786 this.chnageMessageDetails(data, (updatedMessage) => { 2787 updatedMessage.tick= true; 2788 this.buildAttachmentInDom(3, updatedMessage, "wk-cw-user-to-operator-msg", "user-to-operator-msg", 2); 2789 this.scrollHeight(); 2790 updatedMessage.id = element.getAttribute('id'); 2791 localStorage.setItem(localAutoChat, JSON.stringify({id: element.getAttribute('id')})); 2792 if(new URL(location.href).searchParams.get('name')) 2793 updatedMessage.domain = new URL(location.href).searchParams.get('name'); 2794 wkli_socket.emit("getQueryResult",updatedMessage); 2795 this.disableChatWithAgent() 2796 }) 2797 }) 2798 } 2799 },1000); 2800 } 2801 } 2802 buildErrorAttachInDom(data){ 2803 let div = document.createElement('div'); 2804 div.className = ".wk-cw-plan-upgrade-error-msg"; 2805 2806 let childDiv = document.createElement("div"); 2807 childDiv.classList.add("plan-upgrade-error-msg"); 2808 let textColor = "#111111" 2809 // childDiv.innerHTML += data.message.replace(helper.link_exp, `<a href="$1" class="wk-ch-seller-buyer-url" target="_blank" style="color:${textColor}">$1</a>`); 2810 childDiv.innerHTML += data.message 2811 div.appendChild(childDiv); 2812 helper.getElement(Ids.user_operator_chat_holder).appendChild(div); 2813 } 2814 2815 chatWithAgent() { // while click on chat with agent button 2816 if(wkli_client_blocked) 2817 return false; 2818 let liveChatPermission = document.getElementById('wk-ch-liveChatPermission'); 2819 if(wkli_agentChatPermission && liveChatPermission && liveChatPermission.value && liveChatPermission.value == '1'){ 2820 this.displayAndFadeOutErrorMessage() 2821 return false 2822 }else{ 2823 helper.getElement(Ids.Text_Container).style.display = "grid"; 2824 helper.getElement(Ids.autoResponseAction).style.display = "none"; 2825 helper.getElement(Ids.MESSAGE).value = ""; 2826 helper.getElement(Ids.MESSAGE).focus() 2827 helper.refreshBasicChatbot() 2828 setWkli_isChatwithchatbot(false) 2829 let active = document.querySelectorAll('.wk-cw-reply-button') 2830 if(active && active.length){ 2831 active.forEach((chat) => { 2832 chat.style.display ="block"; 2833 }) 2834 } 2835 } 2836 } 2837 assignOperatorChat(data){ 2838 // an operator's display name replaces the real name only while the domain is configured for it 2839 let operatorName = (wkli_useOperatorDisplayName && data.name.displayName) ? data.name.displayName : data.name.firstName + ' ' + data.name.lastName 2840 document.getElementById("operatorName").innerHTML = wkli_showOperatorName ? operatorName : wkli_opName 2841 if (data && JSON.parse(localStorage.getItem(localStorageVar))) { 2842 document.getElementById("wk-ch-operatorOnline").style.display = "inline-block"; 2843 document.getElementById("wk-ch-operatorOnline").style.background = "chartreuse"; 2844 let user = JSON.parse(localStorage.getItem(localStorageVar)) 2845 user.operator = data.operatorId; 2846 user.name = operatorName; 2847 user.operatorStatus = true 2848 localStorage.setItem(localStorageVar, JSON.stringify(user)) 2849 this.getUserOperatorData() 2850 let autoChatApi = JSON.parse(localStorage.getItem('autoChatApi')) 2851 if (autoChatApi) { 2852 localStorage.setItem('autoChatApi', JSON.stringify(false)) 2853 createLoadingWidget('disable') 2854 } 2855 2856 } 2857 } 2858 displayAndFadeOutErrorMessage() { 2859 const errMsg = document.getElementsByClassName(".wk-cw-plan-upgrade-error-msg"); 2860 if (errMsg.length > 0) { 2861 return; 2862 } 2863 const data = { 2864 message: wkli_errorPermissionMsg, 2865 }; 2866 this.buildErrorAttachInDom(data); 2867 2868 const chatWithChatbotElement = helper.getElement(Ids.chatWithChatbot); 2869 if (chatWithChatbotElement) { 2870 chatWithChatbotElement.style.display = 'none'; 2871 } 2872 setTimeout(() => { 2873 const divs = document.getElementsByClassName('.wk-cw-plan-upgrade-error-msg'); 2874
2875 Array.from(divs).forEach(div => { 2876 div.classList.add('wk-cw-fade-out'); 2877 setTimeout(() => { 2878 div.remove(); 2879 }, 700); 2880 }); 2881 }, 4000); 2882 2883 this.scrollHeight(); 2884 } 2885 disableChatWithAgent() { 2886 if(wkli_client_blocked) 2887 return false; 2888 let localAutoResponseData = JSON.parse(localStorage.getItem(localAutoChat)); 2889 if(localAutoResponseData) { 2890 helper.getElement(Ids.Text_Container).style.display = "none"; 2891 if (localAutoResponseData && typeof (localAutoResponseData) == "object") { 2892 helper.getElement(Ids.autoResponseAction).style.display = "grid"; 2893 } else if (localAutoResponseData) { 2894 helper.getElement(Ids.autoResponseAction).style.display = "none"; 2895 } 2896 let active = document.querySelectorAll('.wk-cw-reply-button') 2897 if(active && active.length){ 2898 active.forEach((chat) => { 2899 chat.style.display ="none"; 2900 2901 }) 2902 } 2903 } else { 2904 helper.getElement(Ids.Text_Container).style.display = "grid"; 2905 helper.getElement(Ids.MESSAGE).focus() 2906 } 2907 if(helper.getElement("wk-cw-attachment-button-hide")) 2908 helper.getElement("wk-cw-attachment-button-hide").disabled = false 2909 helper.getElement(Ids.chatWithChatbot).style.display = 'none'; 2910 } 2911 2912 startChatWithAgent(initType=1,msgData={}) { 2913 let liveChatPermission = document.getElementById('wk-ch-liveChatPermission'); 2914 if(wkli_agentChatPermission && liveChatPermission && liveChatPermission.value && liveChatPermission.value == '1'){ 2915 this.displayAndFadeOutErrorMessage() 2916 preventSendingMsg = false; 2917 return false; 2918 }else{ 2919 if(!wkli_isSocketConnected) { 2920 return false 2921 } 2922 //auto registration builds no form, so the bot can be answering while the client record 2923 //does not exist yet. getMessageInfo() registers on the first typed message, but this 2924 //button bypasses it - without the token/email the request reaches registerUser() with 2925 //nothing and a regMandatory domain answers with technicalError. Register, then replay. 2926 if(!wkli_showForm && !JSON.parse(localStorage.getItem(localStorageVar))) { 2927 if(!wkli_registration_in_process) { 2928 wkli_registration_in_process = true 2929 let clientEmail = this.getRegistrationEmail() 2930 this.getClientToken(false, clientEmail, cb => { 2931 if(cb && cb.data) { 2932 wkli_pending_agent_chat = {initType: initType, msgData: msgData} 2933 this.sendChatInitiateNoti(cb.data, clientEmail) 2934 } else { 2935 //blocked client or verification failure, release the lock to allow a retry 2936 wkli_registration_in_process = false 2937 } 2938 }) 2939 } 2940 return false 2941 } 2942 let autoChatApi = JSON.parse(localStorage.getItem('autoChatApi')) 2943 if(autoChatApi){ 2944 localStorage.setItem('autoChatApi',false) 2945 localStorage.setItem('agentChatFirstMsg',true) 2946 } 2947 createLoadingWidget('disable') 2948 preventSendingMsg = false; 2949 let msg; 2950 if(initType == 1){ 2951 msg = "<------ The client requested to connect with a live agent. ------>" 2952 }else{ 2953 msg = "<------ The chat is automatically switched to a live agent ------>" 2954 } 2955 let allMsgArr = [] 2956 allMsgArr.push(msg) 2957 if(msgData && msgData.onlineOpName){ 2958 let usernameMsg = `Live Agents <------ ${msgData.onlineOpName} ------>` 2959 allMsgArr.push(usernameMsg) 2960 } 2961 allMsgArr.forEach((el)=>{ 2962 this.buildMessage(el, 1, (data) => { 2963 this.chnageMessageDetails(data, (updatedMessage) => { 2964 updatedMessage.agentChataInitiated = true 2965 helper.user_operator_conversation.push(updatedMessage) 2966 this.sendMessage() 2967 }) 2968 }) 2969 }) 2970 return 2971 } 2972 2973 } 2974 2975 2976 replyButtonAct(){ 2977 let file = helper.getElement("wk-cw-attachment-button-hide") 2978 if(file.value && file.files.length > 0){ 2979 helper.getElement("wk-cw-chatbot-reply-block").style.display = "none"; 2980 wkli_normalReplyData = ''; 2981 let active = document.querySelectorAll('.wk-cw-reply-button') 2982 if(active.length){ 2983 active.forEach((chat) => { 2984 chat.style.display ="none"; 2985 chat.classList.remove('wk-cw-active') 2986 }) 2987 } 2988 2989 }else{ 2990 let active = document.querySelectorAll('.wk-cw-reply-button') 2991 if(active.length){ 2992 active.forEach((chat) => { 2993 chat.style.display ="block"; 2994 }) 2995 } 2996 } 2997 } 2998} 2999 3000const user = new Form(); 3001 3002if(wkli_showUvdeskWidget){ 3003 helper.setClickListener(Ids.OPEN_CHAT_MODEL_BTN_ID, () => user.openChatBlock()) 3004}else{ 3005 helper.setClickListener(Ids.OPEN_CHAT_MODEL_BTN_ID, wkli_waba_number ? () => user.preOpenchatBlockOption() : () => user.openChatBlock()) 3006} 3007 3008helper.setClickListener(Ids.REGISTRATION_FROM_CLOSE_BTN_ID, wkli_waba_number ? () => user.preOpenchatBlockOption() : () => user.openChatBlock()) 3009 3010helper.setClickListener(Ids.SEND_MSG_BTN_ID, () => user.getMessageInfo()); 3011 3012helper.setClickListener(Ids.formSubmit, () => user.sendUserDetails()); 3013 3014helper.setClickListener(Ids.normalChatBtn, () => user.actionOnSelectedChatOption('normal')); 3015helper.setClickListener(Ids.whatsappChatBtn, () => user.actionOnSelectedChatOption('whatsapp')); 3016 3017 3018helper.setClickListener(Ids.wkEndChat, () => { 3019 if(!wkli_isSocketConnected) { 3020 return false 3021 } 3022 let element = helper.getElement("wk-chat-end-confirmation"); 3023 element.style.display = 'block'; 3024 element.classList.add('wk-cw-show') 3025 helper.changeDisplayProperty(Ids.CHATBOT, 'none') 3026 helper.startConfirmTimeout() 3027}); 3028 3029helper.setClickListener(Ids.wkConfirmationCancel, () => { 3030 console.log('resume chat') 3031 let element = helper.getElement("wk-chat-end-confirmation"); 3032 element.style.display = 'none'; 3033 element.classList.remove('wk-cw-show') 3034 helper.changeDisplayProperty(Ids.CHATBOT, 'block') 3035 helper.startChatTimeout() 3036}); 3037 3038helper.setClickListener(Ids.wkConfirmationConfirm, () => user.endConversation()); 3039 3040helper.setClickListener(Ids.sendEndMail, () =>
3040 user.endConversationSendMail()); 3041 3042helper.setClickListener(Ids.attachmentButton, () => user.openAttachmentBox()); 3043 3044helper.setClickListener(Ids.attachmentClose, () => user.closeAttachment()); 3045 3046helper.setClickListener(Ids.replyBlockClose, () => user.closeReplyBlock()); 3047 3048helper.setClickListener(Ids.cancleNewSendEmail, () => user.closeNewEmailPopUp()) 3049 3050helper.setClickListener(Ids.confirmNewSendEmail, () => user.confirmNewSendEmailChat()) 3051 3052helper.setKeyListener(Ids.MESSAGE, (e) => { 3053 if (e.keyCode == 13 || e.keyCode == 8) 3054 user.getMessageFromUser(e) 3055 else { 3056 if (JSON.parse(localStorage.getItem(localStorageVar)) && JSON.parse(localStorage.getItem(localStorageVar)).senderId && JSON.parse(localStorage.getItem(localStorageVar)).operator && document.getElementById("wk-cw-message").value != "") { 3057 user.isTyping({ 3058 senderId: JSON.parse(localStorage.getItem(localStorageVar)).senderId, 3059 receiverId: JSON.parse(localStorage.getItem(localStorageVar)).operator 3060 }); 3061 } 3062 } 3063}); 3064 3065helper.setClickListener(Ids.chatWithAgent, () => user.chatWithAgent()) 3066 3067helper.setClickListener(Ids.start_autoResponse, () => user.preClientQueries()) 3068 3069helper.setClickListener(Ids.chatHistory, () => user.getOldChatHistory()) 3070helper.toggleChatHistory() 3071 3072helper.setClickListener(Ids.chatWithChatbot, () => user.disableChatWithAgent()) 3073helper.setClickListener(Ids.agentChat, () => user.startChatWithAgent()) 3074 3075 3076function validateAttachment() { 3077 let file = helper.getElement("wk-cw-attachment-button-hide") 3078 let txt = ''; 3079 let status = true; 3080 let ValidFileTypes = ["text/plain", "text/csv", "application/pdf", "image/png", "image/jpeg", "image/gif", "application/vnd.oasis.opendocument.spreadsheet", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "application/vnd.ms-excel", "text/javascript", "application/x-php", "application/vnd.oasis.opendocument.text", "application/vnd.oasis.opendocument.text-template", "application/vnd.oasis.opendocument.text-master", "text/html", "application/vnd.oasis.opendocument.text-web", "application/vnd.oasis.opendocument.spreadsheet-template", "application/vnd.oasis.opendocument.graphics", "application/vnd.oasis.opendocument.graphics-template", "application/vnd.oasis.opendocument.presentation", "application/vnd.oasis.opendocument.presentation-template", "application/vnd.oasis.opendocument.formula", "application/vnd.oasis.opendocument.database", "application/vnd.openofficeorg.extension", "audio/mpeg"]; 3081 if (file.value && file.files.length > 0) { 3082 if ('files' in file) { 3083 for (var i = 0; i < file.files.length; i++) { 3084 var fileContent = file.files[i]; 3085 if ('name' in fileContent) { 3086 txt = fileContent.name; 3087 } 3088 if ('size' in fileContent) { 3089 if (fileContent.size > 10485760) { 3090 status = false; 3091 txt = wkli_fileSizeText; 3092 } 3093 } 3094 if (!ValidFileTypes.includes(fileContent.type)) { 3095 status = false; 3096 txt = wkli_invalidFileText; 3097 } 3098 } 3099 if (status) { 3100 helper.getElement("wk-cw-chatbot-attachment-name").style.display = "block" 3101 helper.getElement("wk-ch-chatbot-attachment-close").style.display = "block" 3102 helper.getElement("wk-ch-chatbot-fileAttachment-name").textContent = txt; 3103 user.replyButtonAct(); 3104 } 3105 else { 3106 helper.getElement("wk-cw-attachment-button-hide").value = ''; 3107 inValidFile(txt); 3108 } 3109 helper.getElement(Ids.MESSAGE).focus() 3110 } else { 3111 if (file.value == "") { 3112 inValidFile(wkli_selectFileText) 3113 } 3114 } 3115 } else { 3116 inValidFile(wkli_selectFileText) 3117 } 3118} 3119 3120function inValidFile(txt) { 3121 helper.getElement("wk-cw-chatbot-attachment-name").style.display = "none" 3122 helper.getElement("wk-cw-attachment-error").style.display = "block"; 3123 helper.getElement("wk-cw-attachment-error").textContent = txt 3124 setTimeout(() => { 3125 helper.getElement("wk-cw-attachment-error").textContent = '' 3126 helper.getElement("wk-cw-attachment-error").style.display = "none" 3127 }, 3000); 3128} 3129let aud; 3130if(wkli_clientNotifySoundStatus) {
3131 if(wkli_clientNotifySound == '1') { 3132 aud = new Audio(`${WKprotocol}${WKscript}/uploads/1.wav`); 3133 } else if(wkli_clientNotifySound == '2') { 3134 aud = new Audio(`${WKprotocol}${WKscript}/uploads/2.wav`); 3135 } else { 3136 aud = new Audio(`${WKprotocol}${WKscript}/uploads/3.wav`); 3137 } 3138} 3139 3140function getLocalTimestamp(date = false) { 3141 let today = new Date(); 3142 // the admin picked language, or the visitor's own browser locale when none is set 3143 let locale = (typeof wkli_locale != 'undefined' && wkli_locale) ? wkli_locale : undefined; 3144 date = date ? new Date(date) : new Date(); 3145 if (date.toDateString() == today.toDateString()) { 3146 let todayText = (typeof wkli_todayText != 'undefined' && wkli_todayText) ? wkli_todayText : 'Today'; 3147 return todayText + ', ' + date.toLocaleTimeString(locale); 3148 } 3149 return date.toLocaleString(locale); 3150} 3151function wkli_replyButtonBody(data){ 3152 let active = document.querySelectorAll('.wk-cw-active') 3153 if(active.length){ 3154 active.forEach((chat) => { 3155 chat.classList.remove('wk-cw-active') 3156 }) 3157 } 3158 if(wkli_normalReplyData != '' && data.sendTimestamp && wkli_normalReplyData.message == data.message && wkli_normalReplyData.timestamp == data.sendTimestamp) { 3159 wkli_normalReplyData = ''; 3160 3161 }else{ 3162 wkli_normalReplyData = { 3163 message : data.message, 3164 senderId : data.senderId, 3165 timestamp : data.sendTimestamp, 3166 messageId: data.messageId 3167 }; 3168 let elem = document.getElementById("rep"+data.messageId) 3169 if(elem){ 3170 elem.classList.add('wk-cw-active'); 3171 } 3172 } 3173 if(wkli_normalReplyData != ''){ 3174 let usrData = JSON.parse(localStorage.getItem(localStorageVar)); 3175 let senderName = wkli_replyYouText 3176 if(wkli_normalReplyData.senderId == usrData.operator) { 3177 senderName = wkli_replySupportText 3178 } 3179 let replyMessage 3180 let msg = data.message.replace(/</g, "<").replace(/>/g, ">").split(' \n'); 3181 let getText = msg[0].split('/') 3182 let checkImgExt = msg[0].split('.') 3183 let imgName = getText[getText.length - 1] 3184 const audioTypes = ['mp3','ogg','wav'] 3185 if(helper.checkImg.includes(checkImgExt[checkImgExt.length - 1]) || (helper.checkAttachment.includes(checkImgExt[checkImgExt.length - 1])) || audioTypes.indexOf(checkImgExt.pop()) !== -1){ 3186 replyMessage = imgName; 3187 }else{ 3188 replyMessage = data.message; 3189 } 3190 helper.getElement("wk-cw-chatbot-reply-block").style.display = "block" 3191 helper.getElement("wk-ch-chatbot-replyBlock-name").textContent = senderName; 3192 helper.getElement("wk-ch-chatbot-replyBlock-message").innerHTML = replyMessage; 3193 helper.getElement('wk-cw-message').focus(); 3194 helper.getElement("wk-cw-user-operator-chat").style.maxHeight = "305px"; 3195 }else{ 3196 helper.getElement("wk-cw-chatbot-reply-block").style.display = "none" 3197 helper.getElement("wk-cw-user-operator-chat").style.maxHeight = "370px"; 3198 } 3199} 3200 3201function wkli_gotoMsgReplyFor(msg) { 3202 wkli_chat.forEach((chat) => { 3203 if(chat.messageId == msg.messageId || (chat.message == msg.message && chat.sendTimestamp == msg.timestamp)) { 3204 let elem = document.getElementById('wkli'+chat.messageId) 3205 if(elem && elem.parentNode) { 3206 elem.parentNode.classList.add('wk-cw-msg-highlighter'); 3207 setTimeout(() => elem.parentNode.classList.remove('wk-cw-msg-highlighter'), 3000) 3208 wkli_scrollToMsg('wkli'+chat.messageId); 3209 } 3210 } 3211 }) 3212} 3213 3214function wkli_scrollToMsg(msgId) { 3215 let scrollTo = document.querySelector('#'+msgId); 3216 let element = helper.getElement("wk-cw-user-operator-chat"); 3217 element.scrollTop = scrollTo.offsetTop -150 3218 // let container = document.querySelectorAll('#wk-cw-user-operator-chat'); 3219 // if(scrollTo.length) 3220 // container.scrollTop(scrollTo.offset().top - container.offset().top + container.scrollTop() - 15); 3221} 3222 3223function wkli_scrollToElement(id) { 3224 // center the field wrapper (input + warning) in whatever scrolls the form 3225 document.getElementById(id).parentElement.scrollIntoView({ block: 'center' }); 3226} 3227 3228function setWkli_isChatwithchatbot(newValue) { 3229 console.log(newValue) 3230 if(newValue != wkli_isChatwithchatbot) { 3231 wkli_isChatwithchatbot = newValue 3232 if(newValue) { 3233 console.log('disable') 3234 helper.getElement(Ids.chatWithChatbot).style.display = 'none' 3235 } else { 3236 console.log('enable') 3237 helper.getElement(Ids.chatWithChatbot).style.display = 'block' 3238 } 3239 } 3240} 3241 3242if(wkli_autoOpenWidget && !new URL(location.href).searchParams.get('name')){
3243 if(wkli_showUvdeskWidget){ 3244 user.openChatBlock() 3245 }else{ 3246 wkli_waba_number ? user.preOpenchatBlockOption() : user.openChatBlock() 3247 } 3248} 3249 3250if(JSON.parse(localStorage.getItem(localStorageVar))) { 3251 initializeSocket().then(()=> { 3252 }).catch(err => console.log(err)) 3253} 3254 3255/** 3256 * Restart chat on change. A chat belongs to the value of one page-injected custom input 3257 * (wkli_chatwhizz_<handleName>), stamped on the session as restartChatValue when the chat registers. 3258 * The page only changes that value on reload, so this runs when the socket connects: a different 3259 * value ends the chat and opens a new one. An empty/missing input is no signal and never ends the chat. 3260 */ 3261function wkli_checkRestartChat() { 3262 if (!wkli_restart_chat_field || wkli_restart_chat_pending || wkli_client_blocked) 3263 return; 3264 let value = wkli_getInjectedValue(wkli_restart_chat_field); 3265 let session = JSON.parse(localStorage.getItem(localStorageVar)); 3266 if (!value || !session) 3267 return; 3268 if (!session.restartChatValue) { 3269 //chat registered before the setting was on, or on a page without the input 3270 session.restartChatValue = value; 3271 localStorage.setItem(localStorageVar, JSON.stringify(session)); 3272 return; 3273 } 3274 if (session.restartChatValue == value) 3275 return; 3276 wkli_restart_chat_pending = true; 3277 helper.clearAllTimeoutAndInterval(); 3278 user.endConversation(); 3279} 3280 3281let wkli_liveChatContent = document.getElementById('wk-ch-livechat-content'); 3282 3283wkli_liveChatContent.addEventListener('scroll', function(e) { 3284 if(wkli_liveChatContent.scrollTop != 0) { 3285 document.getElementById('wk-cw-welcomeText').style.borderBottom = '1px solid #999'; 3286 } else { 3287 document.getElementById('wk-cw-welcomeText').style.borderBottom = '1px solid #fff'; 3288 } 3289})
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.