$(document).ready(function () { }); var dtdvctc = "eyJzdGF0dXMiOiJzdWNjZXNzIiwibWVzc2FnZSI6IkRhdG9zIGVuY29udHJhZG9zIiwiY29kZSI6IjAwMCIsImRhdGEiOnsiY2djdGMiOnsic3VydmV5IjoieWVzIiwibXNnc19pbl9saW5rIjoidHJ1ZSIsImxpbmtfZW5jdWVzdGEiOiJodHRwczpcL1wvY2hhdDAxLndvbGt2b3guY29tXC9saWdodHN1cnZleVwvP3g9T0dab2RtTnNhWFUyTkdkUGJVUlVXQzlPYjBOTFFuaHhNRlpJTldSV1JETmxRV3gzUkVJd1UyaHJORE50WVdvMFVYRjNObFozYUdoM1UxVjJTMDVUTUVWblozUjJVbU5qYjBKalF6VkNja050U1V0S2RFVjRkbGREUmtwQmRqSTNWMGhITUZVNFNtbzVRbU05Iiwib3V0Ym91bmRfcHJveHlfdXJsIjpudWxsLCJpY2Vfc2VydmVycyI6bnVsbCwic2l6ZUNoYXQiOiJsIiwiaWQiOiJPSEZwY1hrMGRHVjBVbE5KY1dGTEwzaFVhR2hZUVQwOSIsImlkX2NvbmZpZyI6Ik9ERk5ObVV4VFZvMGJIQXhZa0pzZW5CWVFYTkxVVDA5IiwidWlTZXR0aW5ncyI6eyJza2lsbCI6eyJwMSI6IlNVUkQiLCJwMiI6IlJrcz0iLCJwMyI6MTl9LCJpcCI6eyJwMSI6IlIwbENSa2hKUWsiLCJwMiI6IlZIUmtKRlIwYz0iLCJwMyI6MjB9LCJhIjp7InAxIjoiaW5oMWhZZDJjbiIsInAyIjoiWlwvZkhpQmh3PT0iLCJwMyI6MTl9LCJiIjp7InAxIjoiT2pzOFBUNW9nRzVyZTMiLCJwMiI6IjFzYUd4MWNtNTNmUT09IiwicDMiOjl9LCJ3c3MiOnsicDEiOiJoSUNBUnp3OGhISnZmNEZ3T202Q2NYWjhPNCIsInAyIjoiUjhlWGlEZklVN2NIeDZSMFU5UlVZOGhJQT0iLCJwMyI6MTN9LCJkdyI6eyJwMSI6ImYyMXFlbnhyTldsOWJIRjMiLCJwMiI6Ik5uOTNkSE4rZDRBMmEzZDEiLCJwMyI6OH0sIm5hbWUiOnsicDEiOiJiblZwYm1aeFozIiwicDIiOiJSOU5UVTNPUT09IiwicDMiOjV9fSwic2Vzc2lvbkNvbmZpZyI6eyJ0aGVtZSI6ImRhcmsiLCJsYW5nIjoiZXMtRVMiLCJyZXRyaWVzIjozLCJ0aW1lb3V0Ijo1MDAwfX19fQ=="; var WolkvoxClictocallVars = JSON.parse(atob(dtdvctc)); var cgctc = WolkvoxClictocallVars.data.cgctc; window.wvx_call_active = window.wvx_call_active || false; // Función para de-ofuscar los datos sensibles recibidos del servidor function deobfuscateSipData(obfuscated) { // 1. Reconstruir la cadena a partir de las partes const combined = atob(obfuscated.p1 + obfuscated.p2); const offset = obfuscated.p3; // 2. Revertir la rotación de caracteres let deRotated = ''; for (let i = 0; i < combined.length; i++) { deRotated += String.fromCharCode((combined.charCodeAt(i) - offset + 255) % 255); } return deRotated; } // Extraer y de-ofuscar los datos reales const obfuscatedSip = cgctc.uiSettings; cgctc.skill = deobfuscateSipData(obfuscatedSip.skill); cgctc.ip = deobfuscateSipData(obfuscatedSip.ip); cgctc.a = deobfuscateSipData(obfuscatedSip.a); cgctc.b = deobfuscateSipData(obfuscatedSip.b); cgctc.wss = deobfuscateSipData(obfuscatedSip.wss); cgctc.dw = deobfuscateSipData(obfuscatedSip.dw); cgctc.name = deobfuscateSipData(obfuscatedSip.name); // Limpiar inmediatamente los datos ofuscados y la función de la memoria cgctc.uiSettings = null; cgctc.sessionConfig = null; window.deobfuscateSipData = null; //SCRIPT var base_url_wolkvox = cgctc.base_url; var dataConfig = new Object(); var intervalInicioCarga = null; var itemsEmpty = ""; var message = ""; var skill = null; //cgctc.skill; var ip = null; //cgctc.ip; //encuesta var survey = cgctc.survey; var msgs_in_link = cgctc.msgs_in_link; var link_encuesta = cgctc.link_encuesta; var a = cgctc.a; var b = cgctc.b; var wss = cgctc.wss; var dw = cgctc.dw; var name = cgctc.name; var outbound_proxy_url = cgctc.outbound_proxy_url; var ice_servers = cgctc.ice_servers; var sizeChat = cgctc.sizeChat; var id = cgctc.id; var id_config = cgctc.id_config; var t = null; //trama var sipJS = null; //SIP.js var videoHabilitado = false; var insertLog = false; var errorSession = null; //jcp var tipoLlamada = null; var contentLog = ""; //conexion sip.js function conexion_sipjs(a, b, c, d, e, f, g) { skill = cgctc.skill; ip = cgctc.ip; user = cgctc.user; pass = cgctc.pass; tipoLlamada = g; a = a.replace(/ /g, "_"); b = b.replace(/ /g, ""); b = b.replace("(", ""); b = b.replace(")", ""); b = b.replace("-", ""); c = c.replace(/ /g, "_"); d = d.replace(/ /g, "_"); e = e.replace(/ /g, "_"); f = f.replace(/ /g, "_"); //datos para validar configuración dataConfig.skill = skill; dataConfig.dw = dw; dataConfig.wss = wss; dataConfig.xyz = id; //revisar si se usan dataConfig.jjj = id_config; //revisar si se usan dataConfig.name = name; dataConfig.survey = survey; dataConfig.ip = ip; dataConfig.user = user; switch (tipoLlamada) { case "call-audio": if (b.length > 15) { b = b.substr(0, 14); } if (a.length > 10) { a = a.substr(0, 9); } t = "SIP:" + skill + "-IVR*ani$" + b + "*name$" + a + "*id_customer$" + d + "*webrtc$audio"; if (t.length > 80) { t = t.substr(0, 79); } break; case "call-audiovideo": if (b.length > 15) { b = b.substr(0, 14); } if (a.length > 10) { a = a.substr(0, 9); } t = "SIP:" + skill + "-IVR*ani$" + b + "*name$" + a + "*id_customer$" + d + "*webrtc$video"; // videoHabilitado = true; videoHabilitado = "{width:{min:352,max:352},height:{min:288,max:288},frameRate:{min:10,max:10}}"; break; default: if (b.length > 15) { b = b.substr(0, 14); } if (a.length > 10) { a = a.substr(0, 9); } t = "SIP:" + skill + "-IVR*ani$" + b + "*name$" + a + "*id_customer$" + d + "*webrtc$audio"; if (t.length > 80) { t = t.substr(0, 79); } break; } //limpiar valor de datos sensibles skill = null; //validar datos de configuración for (var item in dataConfig) { if (dataConfig[item] == "") { itemsEmpty = itemsEmpty + item + "\r\n"; } } itemsEmpty = itemsEmpty.slice(0, -1); //limpiar valor de datos sensibles dataConfig = new Object(); if (itemsEmpty !== "") { message = "Error en la configuración: \r\n" + itemsEmpty + "\r\n"; return; } else { var alertify_css = document.createElement("link"); alertify_css.setAttribute("href", "./css/alertify.min.css"); alertify_css.setAttribute("rel", "stylesheet"); var alertify_js = document.createElement("SCRIPT"); alertify_js.setAttribute("src", "./js/alertify.min.js"); document.head.appendChild(alertify_css); document.head.appendChild(alertify_js); //Carga la libreria sipJS var script = document.querySelector("#sipJS"); if (script == null) { sipJS = document.createElement("SCRIPT"); sipJS.setAttribute("src", "../../SIP.js/demo/dist/sipjs_wolkvox.js?v=1"); sipJS.setAttribute("id", "sipJS"); document.head.appendChild(sipJS); } //Cuando este cargada la conexión sipJS.onload = () => { //limpiar valor de datos sensibles ip = null; name = null; user = null; pass = null; // var variablesALimpiar = new Object(); // variablesALimpiar.ip = ip; // variablesALimpiar.name = name; // variablesALimpiar.user = user; // variablesALimpiar.pass = pass; if ( $("#status").html() == "unregistered" || $("#status").html() == "NULL" ) { $("#connectAlice").click(); setTimeout(function () { $("#registerAlice").click(); setTimeout(function () { $("#beginAlice").click(); }, 1000); }, 1000); } $("#container-options").css({ display: "none" }); $("#divLoad").css({ display: "none" }); $("#divCallCtrl").css({ width: "100%", "margin-left": "auto", "margin-right": "auto", display: "block", "text-align": "center", "padding-top": "0%", }); //botones call options $("#divCallOptions").css("opacity", "1"); $("#btnFullScreen").css("visibility", "visible"); $("#btnMute").css("visibility", "visible"); $("#btnKeyPad").css("visibility", "visible"); if (type_call == "call-audiovideo") { $("#tdVideo").css({ height: "95%" }); $("#divVideo").css({ height: "95%" }); } else { $("#tdVideo").css({ height: "95%" }); $("#divVideo").css({ height: "95%" }); $("#txtCallStatus").css("display", ""); } }; } } //call // Selecciona el elemento que quieres observar const statusElement = document.getElementById("status"); // Configura el observer const observer = new MutationObserver(function (mutations) { mutations.forEach(function (mutation) { if (mutation.type === "childList") { const newStatus = statusElement.textContent; console.log("test", newStatus); let txtLoad = ""; switch (newStatus) { case "unregistered": break; case "connected": dataConfig.user = "NOT SHOWN"; user = "NOT SHOWN"; pass = "NOT SHOWN"; break; case "registered": txtLoad = navigator.language === "es-ES" ? "Por favor, espere un momento" : "Please wait a moment"; $("#txtLoad1").html(txtLoad); break; case "call created": window.wvx_call_active = true; document.getElementById("videoLocalAlice").style.opacity = 1; txtLoad = navigator.language === "es-ES" ? "Conectando llamada" : "Connecting call"; $("#txtLoad1").html(txtLoad); const startPollingForStream = () => { let attempts = 0; const maxAttempts = 20; // Intentará durante 10 segundos console.log("detectAgentSpeaking"); const tryToDetect = (mediaElement) => { if (mediaElement && mediaElement.srcObject) { const stream = mediaElement.srcObject; if (stream.getAudioTracks().length > 0) { if (typeof detectAgentSpeaking === 'function') { detectAgentSpeaking(stream); } else { console.warn("[WebRTC] detectAgentSpeaking no disponible, avatar scripts no cargados."); } return true; // Éxito } } return false; // Fallo }; const poll = () => { attempts++; if (attempts > maxAttempts) { console.error( "No se pudo encontrar el stream de audio remoto después de 10 segundos." ); return; } const videoElement = document.getElementById("videoRemoteAlice"); const audioElement = document.getElementById("remoteAudio"); if (tryToDetect(videoElement) || tryToDetect(audioElement)) { // Stream encontrado y detección iniciada } else { setTimeout(poll, 500); } }; poll(); }; // Solo iniciar detección de audio para avatar si está habilitado if (window.avatar_enabled) { startPollingForStream(); } break; case "Call answered": window.wvx_call_active = true; txtLoad = navigator.language === "es-ES" ? "En llamada" : "In call"; $("#txtLoad1").html(txtLoad); if (tipoLlamada == "call-audiovideo") { setTimeout(function () { $("#txtLoad1").html(""); }, 5000); } // Mostrar avatar solo cuando la llamada es contestada (solo para audio) // Acceder a las variables globales desde buildchat.js if (typeof window.avatar_enabled !== 'undefined' && window.avatar_enabled && window.active_audio === "yes" && tipoLlamada === "call-audio") { console.log("%c Showing avatar on Call answered", "background-color: green; color: white; font-size: 16px; padding: 5px;"); const avatarContainer = document.getElementById("wvx_avatar_container"); const videoRemoteAlice = document.getElementById("videoRemoteAlice"); if (avatarContainer && videoRemoteAlice) { // if (window.avatar_3d_source != '') { // const avatarIframe = document.createElement("iframe"); // avatarIframe.src = window.avatar_3d_source; // avatarIframe.id = "wvx_avatar"; // avatarIframe.width = "100%"; // avatarIframe.height = "100%"; // avatarIframe.style.position = "absolute"; // avatarIframe.style.top = "0"; // avatarIframe.style.left = "0"; // avatarIframe.style.zIndex = "999"; // Z-index alto pero menor que los botones (1000) // avatarIframe.style.borderRadius = "0px 0px 5px 5px"; // avatarIframe.style.backgroundColor = "#000"; // Fondo negro para el avatar // avatarContainer.appendChild(avatarIframe); // } else { // Crear el avatar si no existe let avatar = document.getElementById("wvx_avatar"); if (!avatar) { avatar = document.createElement("wvx-virtual-avatar"); avatar.id = "wvx_avatar"; avatar.setAttribute("hideui", "true"); let avatar3DConf = JSON.parse(WolkvoxChatVars.data.gc.avatar3DConf); let avatarSelected = avatar3DConf.avatarSelected; let avatarBgUrl = avatar3DConf.avatarBgUrl; let cameraPlaneSelected = avatar3DConf.cameraPlaneSelected; let cameraPlane = cameraPlaneSelected == 'full' ? { x: 0, y: 2, z: 5 } : cameraPlaneSelected == 'closeup' ? { x: 0, y: 1.6, z: 1.2 } : { x: 0, y: 1.5, z: 1.5 }; let cameraTarget = cameraPlaneSelected == 'full' ? { x: 0, y: 1.5, z: 0 } : cameraPlaneSelected == 'closeup' ? { x: 0, y: 1.6, z: 0 } : { x: 0, y: 1.5, z: 0 }; avatar.setAttribute("avatarid", avatarSelected); avatar.addEventListener("mouseover", mostrarBotones); avatar.addEventListener("mouseout", ocultarBotones); avatarContainer.appendChild(avatar); var wvxAvatarReady = function () { avatar.onAvatarReady((detail) => { avatar.setCameraEnabled(true); // Lock/unlock // cuerpo completo // avatar.setCameraPosition({ x: 0, y: 2, z: 5 }); // avatar.setCameraTarget({ x: 0, y: 1.5, z: 0 }); // desde el pecho avatar.setCameraPosition(cameraPlane); avatar.setCameraTarget(cameraTarget); // medio cuerpo // avatar.setCameraPosition({ x: 0, y: 1.5, z: 1.5 }); // avatar.setCameraTarget({ x: 0, y: 1.5, z: 0 }); // 🖥️ Quality Methods avatar.setQualityLevel('high'); // 'low', 'medium', 'high' // fondo if (avatarBgUrl != '') { avatar.setBackground({ url: avatarBgUrl, type: "image", }); } }); }; Promise.race([ customElements.whenDefined('wvx-virtual-avatar'), new Promise(function (_, reject) { setTimeout(function () { reject(new Error('wvx-virtual-avatar timeout')); }, 60000); }) ]).then(wvxAvatarReady).catch(function (err) { console.error('[WVX Avatar 3D] El componente no registró a tiempo. ¿Cargó el script? (buildchat.js → /avatar/ o GCS). Detalle:', err && err.message); }); } $("#txtLoad1").html(""); // Posicionar el avatar para cubrir el espacio del video pero no los botones avatar.style.display = "block"; avatar.style.position = "absolute"; avatar.style.top = "42px"; avatar.style.left = "0"; avatar.style.width = "100%"; avatar.style.height = "100%"; // Reducimos la altura para no cubrir los botones avatar.style.zIndex = "999"; // Z-index alto pero menor que los botones (1000) avatar.style.borderRadius = "0px 0px 5px 5px"; avatar.style.backgroundColor = "#000"; // Fondo negro para el avatar // } // Ocultar completamente el videoRemoteAlice cuando se muestra el avatar videoRemoteAlice.style.display = "none"; } } break; case "call hangup": window.wvx_call_active = false; txtLoad = navigator.language === "es-ES" ? "Terminar llamada" : "Ending call"; $("#txtLoad1").html(txtLoad); // Ocultar avatar cuando la llamada termina const avatarOnHangup = document.getElementById("wvx_avatar"); if (avatarOnHangup) { avatarOnHangup.style.display = "none"; console.log("%c Hiding avatar on call hangup", "background-color: red; color: white; font-size: 16px; padding: 5px;"); } // Mostrar nuevamente el videoRemoteAlice const videoRemoteAliceOnHangup = document.getElementById("videoRemoteAlice"); if (videoRemoteAliceOnHangup) { videoRemoteAliceOnHangup.style.display = "block"; } $("#disconnectAlice").click(); break; case "failed to begin session": txtLoad = navigator.language === "es-ES" ? "No se pudo iniciar la sesión" : "Failed to begin session"; $("#txtLoad1").html(txtLoad); break; case "on agent": $("#txtLoad1").val(""); break; case "disableVideo": setTimeout(function () { $("#enableCamera").click(); statusElement.textContent = "enableVideo"; }, 1500); break; case "disconnected": window.wvx_call_active = false; $("#txtLoad1").html(""); // Ocultar avatar cuando se desconecta const avatarOnDisconnect = document.getElementById("wvx_avatar"); if (avatarOnDisconnect) { avatarOnDisconnect.style.display = "none"; console.log("%c Hiding avatar on disconnect", "background-color: red; color: white; font-size: 16px; padding: 5px;"); } // Mostrar nuevamente el videoRemoteAlice const videoRemoteAliceOnDisconnect = document.getElementById("videoRemoteAlice"); if (videoRemoteAliceOnDisconnect) { videoRemoteAliceOnDisconnect.style.display = "block"; } colgar(); break; } } }); }); // Configura las opciones del observer const config = { childList: true, subtree: true }; // Inicia la observación solo si el nodo existe if (statusElement) { observer.observe(statusElement, config); } function registrarLog() { $.ajax({ url: "querys/log_clicktocall.php", type: "POST", dataType: "json", data: { id_distri: id, log: contentLog, type: "widget", }, }) .done(function (success) { }) .fail(function (error) { }) .always(function () { if (errorSession == null) { colgar(); } else { alertify.alert( "Error", `Failed to begin session.\n` + errorSession, function () { colgar(); } ); } }); } function colgar() { window.wvx_call_active = false; window.location.href = "#close"; document.getElementById("containerChatForm").style.display = ""; document.getElementById("divCallCtrl").style.display = "none"; document.getElementById("container-options").removeAttribute("data-init"); document.getElementById("enviar_form_chat").disabled = false; //encuesta switch (widget) { case "l": heightFrameWidget = "71"; widthFrameWidget = "75"; break; case "m": heightFrameWidget = "55"; widthFrameWidget = "60"; break; case "s": heightFrameWidget = "45"; widthFrameWidget = "50"; break; } iframeResize(heightFrameWidget, widthFrameWidget); location.reload(); } function mostrarBotones() { $("#endAlice").show(); $("#enableCamera").show(); $("#btnKeyPad").show(); $("#screenShare").show(); } function ocultarBotones() { $("#endAlice").hide(); $("#enableCamera").hide(); $("#btnKeyPad").hide(); $("#screenShare").hide(); } var videoRemoteAliceElement = !!document.getElementById("videoRemoteAlice"); if (videoRemoteAliceElement) { document .getElementById("videoRemoteAlice") .addEventListener("durationchange", function () { setTimeout(function () { $("#enableCamera").click(); document.getElementById("status").innerHTML = "disableVideo"; }, 1500); }); } // limpiar valor de datos sensibles dtdvctc = null; WolkvoxClictocallVars = null;