// ==================================================================
// JS.JS - VERSIÓN FINAL CON GESTIÓN DE CONTEXTO (BOT vs AGENTE)
// ==================================================================
try {
var context = atob(JSON.parse(atob(WolkvoxChat)).context);
} catch (error) {
// console.error(error.message);
}
var base_url = base_url;
var url = avatar;
var avatarBot = avatarBot;
var transparent = transparent;
var agente_asignado = "";
var agente = "";
var session = idsessionNew;
var session2 = idsessionNew;
var audio = new Audio('https://storage.googleapis.com/wvx-digital-widget-staticresources-pdn/sounds/new.wav');
var recibir = '';
var lastRoutingReentrySkill = '';
var write = '';
var from_chat = '';
var idmsg = 0;
var title = document.title;
var newTitle = '';
var count = 0;
var INDEX = 0;
var heightFrameWidget = "";
var widthFrameWidget = "";
var chatCircleImgWidthSend = chatCircleImgWidthSend;
var chatCircleImgHeightSend = chatCircleImgHeightSend;
var heightFrameChat = "";
var widthFrameChat = "";
var type_call = "";
// Flag global para saber si hay una llamada activa (audio/video).
// Se actualiza desde js.js (inicio) y clicktocall.js (estados SIP).
window.wvx_call_active = window.wvx_call_active || false;
var chat_id = 0;
var atstrt = 0;
var startedChat = 0;
var height_mobile = height_mobile;
function wvxCanAutoRedirectSurvey(linkEl) {
try {
if (!linkEl || linkEl.tagName.toLowerCase() !== 'a') return false;
// Bloquear auto-redirect durante llamada activa (defensa en profundidad)
if (window.wvx_call_active || type_call) return false;
// Si el backend envía la URL sin "campana", no abrir pestaña automáticamente
if (linkEl.href) {
var u = new URL(linkEl.href, window.location.href);
if (u.searchParams.has('campana') && !u.searchParams.get('campana')) return false;
}
return true;
} catch (e) {
// Si no se puede parsear la URL, no auto-redirigir
return false;
}
}
var pollerInterval = null; // Para controlar el timer del polling
var lastDisplayedMessageId = 0; // Para saber cuál fue el último mensaje mostrado
// SISTEMA DE POLLING HÍBRIDO INTELIGENTE
var pollerConfig = {
frequencies: {
ACTIVE: 3000, // 3 segundos - cuando hay actividad o mensajes pendientes
SEMI_ACTIVE: 15000, // 15 segundos - actividad moderada
INACTIVE: 60000, // 60 segundos - poca actividad
STOPPED: null // Detenido completamente
},
currentFrequency: 3000,
lastActivity: Date.now(),
maxInactiveTime: 23 * 60 * 60 * 1000, // 23 horas
hasPendingMessages: false
};
var iti;
var init_routing = 0;
// FUNCIÓN PARA DETERMINAR LA FRECUENCIA DE POLLING INTELIGENTE
function determinePollingFrequency() {
var now = Date.now();
var timeSinceActivity = now - pollerConfig.lastActivity;
// Si hay mensajes pendientes, mantener frecuencia activa
if (pollerConfig.hasPendingMessages) {
return pollerConfig.frequencies.ACTIVE;
}
// Si ha pasado demasiado tiempo, detener
if (timeSinceActivity > pollerConfig.maxInactiveTime) {
return pollerConfig.frequencies.STOPPED;
}
// Frecuencias adaptativas basadas en tiempo de inactividad
if (timeSinceActivity < 2 * 60 * 1000) { // Menos de 2 minutos
return pollerConfig.frequencies.ACTIVE;
} else if (timeSinceActivity < 5 * 60 * 1000) { // Menos de 5 minutos
return pollerConfig.frequencies.SEMI_ACTIVE;
} else {
return pollerConfig.frequencies.INACTIVE;
}
}
// FUNCIÓN PARA ACTUALIZAR LA ACTIVIDAD DEL USUARIO
function updateUserActivity() {
pollerConfig.lastActivity = Date.now();
}
// FUNCIÓN PRINCIPAL DE POLLING INTELIGENTE
function startIntelligentPoller(sessionId, operationId) {
// Detener cualquier poller existente
if (pollerInterval) {
clearInterval(pollerInterval);
pollerInterval = null;
}
// Actualizar actividad
updateUserActivity();
// Función recursiva para polling adaptativo
function scheduleNextPoll() {
var frequency = determinePollingFrequency();
if (frequency === pollerConfig.frequencies.STOPPED) {
pollerInterval = null;
return;
}
// Si la frecuencia cambió, actualizarla
if (frequency !== pollerConfig.currentFrequency) {
pollerConfig.currentFrequency = frequency;
}
// Programar siguiente ejecución
pollerInterval = setTimeout(function () {
pollForNewMessages(sessionId, operationId);
scheduleNextPoll(); // Programar la siguiente iteración
}, frequency);
}
// Ejecutar primera consulta inmediatamente
pollForNewMessages(sessionId, operationId);
// Programar siguientes consultas
scheduleNextPoll();
}
switch (widget) {
case "l":
heightFrameWidget = '71';
widthFrameWidget = '75';
break;
case "m":
heightFrameWidget = '55';
widthFrameWidget = '60';
break;
case "s":
heightFrameWidget = '45';
widthFrameWidget = '50';
break;
}
switch (chat) {
case "l":
heightFrameChat = '543';
widthFrameChat = '288';
break;
case "m":
heightFrameChat = '455';
widthFrameChat = '288';
break;
case "s":
heightFrameChat = '400';
widthFrameChat = '288';
break;
case "full":
heightFrameChat = '100%';
widthFrameChat = '100%';
document.getElementById("chat-logs").style.height == "78% !importan"
break;
}
var device = getDeviceType();
if (device == "mobile") {
widthFrameChat = '100%';
heightFrameChat = height_mobile ? height_mobile + '%' : '100%';
}
$id_config = id_config;
$skill_bd = skill;
$skill = $("#skill").val();
$text4 = '';
$prefA = '';
$routing = '';
if (transparent == 1) {
heightFrameWidget = (parseInt(chatCircleImgHeightSend) + parseInt(20));
widthFrameWidget = (parseInt(chatCircleImgWidthSend) + parseInt(20));
}
function popUpAlert(text) {
document.getElementById("popUpChat_chat_micro_alert_txt").innerHTML = "" + text + "";
document.getElementById("popUpChat_chat_micro_alert").classList.toggle("show");
}
// Nueva función para mostrar notificaciones no bloqueantes tipo toast
function showToastNotification(message, type = 'error', duration = 4000) {
// Crear el elemento toast si no existe
var toastId = 'chat-toast-notification';
var toast = document.getElementById(toastId);
if (!toast) {
toast = document.createElement('div');
toast.id = toastId;
toast.style.cssText = `
position: fixed;
top: 20px;
left: 50%;
transform: translateX(-50%);
background-color: ${type === 'error' ? '#f44336' : '#4CAF50'};
color: white;
padding: 16px 24px;
border-radius: 8px;
box-shadow: 0 4px 12px rgba(0,0,0,0.3);
z-index: 10000;
font-family: Custom-Condensed, Arial, sans-serif;
font-size: 14px;
max-width: 90%;
text-align: center;
opacity: 0;
transition: opacity 0.3s ease-in-out;
pointer-events: none;
`;
document.body.appendChild(toast);
}
// Actualizar mensaje y estilo según el tipo
toast.innerHTML = '' + message + '';
toast.style.backgroundColor = type === 'error' ? '#f44336' : '#4CAF50';
// Mostrar toast con animación
setTimeout(() => {
toast.style.opacity = '1';
}, 10);
// Ocultar automáticamente después de la duración especificada
setTimeout(() => {
toast.style.opacity = '0';
}, duration);
}
function cargarDatosLocalStorage(event) {
var s_value;
try {
if ((s_value = window.localStorage.getItem('chat.wolkvox.form.text1'))) {
$("#text1").val(s_value);
$("#textNombre").addClass("mdc-floating-label--float-above");
// $("#textNombre").css('background-color', '#fff');
// $("#textNombre").css('padding','0 4px;');
}
if (event == "closed") {
if ((s_value = window.localStorage.getItem('chat.wolkvox.form.text2'))) {
iti.setNumber(s_value);
}
} else {
if ((s_value = window.localStorage.getItem('chat.wolkvox.form.text2'))) {
$("#textPhone").addClass("mdc-floating-label--float-above");
// $("#textPhone").css('background-color', '#fff');
// $("#textPhone").css('padding','0 4px;');
}
}
if ((s_value = window.localStorage.getItem('chat.wolkvox.form.text3'))) {
$("#text3").val(s_value);
$("#textEmail").addClass("mdc-floating-label--float-above");
// $("#textEmail").css('background-color', '#fff');
// $("#textEmail").css('padding','0 4px;');
}
if ((s_value = window.localStorage.getItem('chat.wolkvox.form.text4'))) {
$("#text4").val(s_value);
$("#textIdentification").addClass("mdc-floating-label--float-above");
// $("#textIdentification").css('background-color', '#fff');
// $("#textIdentification").css('padding','0 4px;');
}
if ((s_value = window.localStorage.getItem('chat.wolkvox.form.text5'))) {
$("#text5").val(s_value);
// $("#text5").addClass("mdc-floating-label--float-above");
// $("#text5").css('background-color', '#fff');
// $("#text5").css('padding','0 4px;');
}
if ((s_value = window.localStorage.getItem('chat.wolkvox.form.text6'))) {
$("#text6").val(s_value);
// $("#text6").addClass("mdc-floating-label--float-above");
// $("#text6").css('background-color', '#fff');
// $("#text6").css('padding','0 4px;');
}
} catch (error) {
}
}
function sleep(milliseconds) {
var start = new Date().getTime();
for (var i = 0; i < 1e7; i++) {
if ((new Date().getTime() - start) > milliseconds) {
break;
}
}
}
var count = 3;
do {
if (typeof mdc !== "undefined") {
mdc.autoInit();
count = 0;
}
else {
sleep(2000);
count--;
}
} while (count != 0);
$(document).ready(function () {
cargarDatosLocalStorage("init");
// enforceFormat y formatToPhone removidos: conflictaban con el filtro de dígitos
// delegado en document y formateaban con estilo US incompatible con teléfonos locales.
//
document.addEventListener('input', function (event) {
// Verificar si el elemento que disparó el evento es un input
if (event.target.tagName.toLowerCase() === 'input') {
// Verificar si el input es de tipo "file"
if (event.target.type.toLowerCase() === 'file') {
// No hagas nada con inputs de tipo "file"
return;
}
// Obtener el valor actual del input
var valorInput = event.target.value;
// Sanitizar el valor del input
var valorSanitizado = DOMPurify.sanitize(valorInput);
// Asignar el valor sanitizado de vuelta al input
event.target.value = valorSanitizado;
}
});
//
});
$('input[type="file"]').change(
function (e) {
var file = e.target.files;
var completeSize = 0;
for (var i = 0; i < file.length; i++) {
completeSize = completeSize + file[i].size;
}
if (completeSize > 5242880) {
showToastNotification("El archivo es demasiado grande. Tamaño máximo: 5MB", 'error', 4000);
document.getElementById("chat_input_attach").value = "";
return;
}
sendFileAttached(file);
}
);
function sendFileAttached(file) {
var formData = new FormData();
for (var i = 0; i < file.length; i++) {
formData.append(i, file[i]);
}
formData.append('ses', session);
formData.append('operation', $("#idcliente").val());
formData.append('skill', $("#skill").val());
var uriAttach = "";
$.ajax({
url: "querys/sendAttach.php",
data: formData,
type: "POST",
dataType: "json",
processData: false,
contentType: false,
beforeSend: function () {
document.getElementById("alerta").innerHTML = "Uploading...";
document.getElementById("alerta").style.display = "";
},
success: (data) => {
sendMsgType = data.sendMsgType;
if (typeof data.error != "undefined") {
showToastNotification(data.error, 'error', 4000);
document.getElementById("alerta").innerHTML = "" + data.error + "";
}
else {
for (var i = 0; i <= data.name.length - 1; i++) {
generate_message(data.name[i], 'self', " ", " ", data.data[i]);
}
document.getElementById("alerta").innerHTML = "Uploaded";
}
setTimeout(function () {
document.getElementById("alerta").style.display = "none";
document.getElementById("alerta").innerHTML = "";
}, 1200);
document.getElementById("chat_input_attach").value = "";
uriAttach = data.ext + "|" + data.data;
if (sendMsgType == 1) {//revisar
$msg = uriAttach;
$idcliente = $idcliente.replace(" ", "");//revisar
$skill = $skill.replace(" ", "");//revisar
chatbotmsg($text1, $text2, $text3, $text4, $text5, $text6, $idsession, $idcliente, $skill, $msg, "");
}
},
error: function (xhr, status, error) {
console.error("AJAX Error Details:", status, error, xhr.responseText);
document.getElementById("alerta").innerHTML = "loading...";
setTimeout(function () {
document.getElementById("alerta").style.display = "none";
document.getElementById("alerta").innerHTML = "";
}, 1200);
document.getElementById("chat_input_attach").value = "";
}
});
}
function iframeResize(height, width, bottom) {
parent.postMessage("resize::" + height + "||" + width + "||1%||" + bottom, "*");
}
function setInputFilter(textbox, inputFilter) {
["input", "keydown", "keyup", "mousedown", "mouseup", "select", "contextmenu", "drop"].forEach(function (event) {
textbox.addEventListener(event, function () {
if (inputFilter(this.value)) {
this.oldValue = this.value;
this.oldSelectionStart = this.selectionStart;
this.oldSelectionEnd = this.selectionEnd;
} else if (this.hasOwnProperty("oldValue")) {
this.value = this.oldValue;
this.setSelectionRange(this.oldSelectionStart, this.oldSelectionEnd);
}
});
});
}
// Filtro de solo dígitos para el campo de teléfono - usa event delegation para evitar
// condiciones de carrera donde text2 aún no existe cuando js.js se ejecuta.
(function () {
var phoneDigitFilter = /^\d*$/;
["keydown", "keyup", "mousedown", "mouseup", "select", "contextmenu", "drop"].forEach(function (eventName) {
document.addEventListener(eventName, function (e) {
var el = e.target;
if (!el || el.id !== "text2") return;
if (phoneDigitFilter.test(el.value)) {
el._oldPhoneValue = el.value;
el._oldPhoneSelStart = el.selectionStart;
el._oldPhoneSelEnd = el.selectionEnd;
} else if (el.hasOwnProperty("_oldPhoneValue")) {
el.value = el._oldPhoneValue;
el.setSelectionRange(el._oldPhoneSelStart, el._oldPhoneSelEnd);
}
});
});
document.addEventListener("input", function (e) {
var el = e.target;
if (!el || el.id !== "text2") return;
if (phoneDigitFilter.test(el.value)) {
el._oldPhoneValue = el.value;
el._oldPhoneSelStart = el.selectionStart;
el._oldPhoneSelEnd = el.selectionEnd;
} else if (el.hasOwnProperty("_oldPhoneValue")) {
el.value = el._oldPhoneValue;
el.setSelectionRange(el._oldPhoneSelStart, el._oldPhoneSelEnd);
}
var maxLen = (typeof window.phoneMaxLength !== 'undefined' && window.phoneMaxLength > 0) ? window.phoneMaxLength : 0;
var minLen = (typeof window.phoneMinLength !== 'undefined' && window.phoneMinLength > 0)
? window.phoneMinLength
: maxLen; // si solo se configura el máximo, se usa como umbral mínimo para el aviso
var hintEl = document.getElementById("phone-hint");
if (maxLen > 0 && el.value.length > maxLen) {
el.value = el.value.slice(0, maxLen);
}
if (!hintEl) {
var phoneLabel = document.getElementById("test") || el.closest("label");
if (phoneLabel && phoneLabel.parentNode) {
hintEl = document.createElement("div");
hintEl.setAttribute("id", "phone-hint");
phoneLabel.parentNode.insertBefore(hintEl, phoneLabel.nextSibling);
}
}
if (!hintEl) return;
if (minLen > 0 && el.value.length > 0 && el.value.length < minLen) {
hintEl.textContent = "Mínimo " + minLen + " dígitos requeridos";
hintEl.style.display = "block";
} else {
hintEl.style.display = "none";
hintEl.textContent = "";
}
});
})();
$("#enviar_form_chat").on("click", validate);
$(document).on("click", "#start_chat_options", function () {
wvxUserChoseChat = true;
submit_form();
});
$("#btn-audio").on("click", clicktocall_audio);
$("#btn-video").on("click", clicktocall_video);
$("#btn-callback").on("click", callback);
$('#record-submit').click(startRecording);
$('#stop-record-submit').click(stopRecording);
$('#cancel-record-submit').click(cancelRecording);
function validateEmail(email) {
var re = /^(([^<>()[\]\\.,;:\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,}))$/;
return re.test(email);
}
function clicktocall_audio() {
$operation = $("#idcliente").val();
$pais_selected = document.getElementsByClassName("iti__selected-flag")[0].title.replace(/[^0-9]+/g, "");
$text2 = $pais_selected;
$text2 += $("#text2").val();
document.getElementById("divLoad").style.display = "";
type_call = "call-audio";
window.wvx_call_active = true;
$text1 = $("#text1").val();
$text3 = $("#text3").val();
$text4 = $text4 == '' && typeof $text4 !== 'undefined' ? $("#text4").val() : $text4;
$text5 = $("#text5").val();
$text6 = $("#text6").val();
$text1 = typeof $text1 !== 'undefined' ? $text1.replace(/(<([^>]+)>)/ig, "") : '';
$text2 = typeof $text2 !== 'undefined' ? $text2.replace(/(<([^>]+)>)/ig, "") : '';
$text3 = typeof $text3 !== 'undefined' ? $text3.replace(/(<([^>]+)>)/ig, "") : '';
$text4 = typeof $text4 !== 'undefined' ? $text4.replace(/(<([^>]+)>)/ig, "") : '';
$text5 = typeof $text5 !== 'undefined' ? $text5.replace(/(<([^>]+)>)/ig, "") : '';
$text6 = typeof $text6 !== 'undefined' ? $text6.replace(/(<([^>]+)>)/ig, "") : '';
conexion_sipjs($text1, $text2, $text3, $text4, $text5, $text6, type_call);
}
function clicktocall_video() {
$operation = $("#idcliente").val();
$pais_selected = document.getElementsByClassName("iti__selected-flag")[0].title.replace(/[^0-9]+/g, "");
$text2 = $pais_selected;
$text2 += $("#text2").val();
document.getElementById("divLoad").style.display = "";
type_call = "call-audiovideo";
window.wvx_call_active = true;
$text1 = $("#text1").val();
$text3 = $("#text3").val();
$text4 = $text4 == '' && typeof $text4 !== 'undefined' ? $("#text4").val() : $text4;
$text5 = $("#text5").val();
$text6 = $("#text6").val();
$text1 = typeof $text1 !== 'undefined' ? $text1.replace(/(<([^>]+)>)/ig, "") : '';
$text2 = typeof $text2 !== 'undefined' ? $text2.replace(/(<([^>]+)>)/ig, "") : '';
$text3 = typeof $text3 !== 'undefined' ? $text3.replace(/(<([^>]+)>)/ig, "") : '';
$text4 = typeof $text4 !== 'undefined' ? $text4.replace(/(<([^>]+)>)/ig, "") : '';
$text5 = typeof $text5 !== 'undefined' ? $text5.replace(/(<([^>]+)>)/ig, "") : '';
$text6 = typeof $text6 !== 'undefined' ? $text6.replace(/(<([^>]+)>)/ig, "") : '';
conexion_sipjs($text1, $text2, $text3, $text4, $text5, $text6, type_call);
}
function callback() {
// $pais_selected = document.getElementsByClassName("iti__selected-flag")[0].title.replace(/[^0-9]+/g, "");
type_call = "callback";
$text1 = $("#text1").val();
$text2 = $("#text2").val();
$text3 = $("#text3").val();
$text4 = $text4 == '' && typeof $text4 !== 'undefined' ? $("#text4").val() : $text4;
$text5 = $("#text5").val();
$text6 = $("#text6").val();
$text1 = typeof $text1 !== 'undefined' ? $text1.replace(/(<([^>]+)>)/ig, "") : '';
$text2 = typeof $text2 !== 'undefined' ? $text2.replace(/[`~!@#$%^&*()_|+\-=?;:'",.<>\{\}\[\]\\\/ ]/gi, "") : '';
$text3 = typeof $text3 !== 'undefined' ? $text3.replace(/(<([^>]+)>)/ig, "") : '';
$text4 = typeof $text4 !== 'undefined' ? $text4.replace(/(<([^>]+)>)/ig, "") : '';
$text5 = typeof $text5 !== 'undefined' ? $text5.replace(/(<([^>]+)>)/ig, "") : '';
$text6 = typeof $text6 !== 'undefined' ? $text6.replace(/(<([^>]+)>)/ig, "") : '';
callback_register($text1, $text2, $text3, $text4, $text5, $text6, type_call);
}
function validate() {
var email = $("#text3").val();
var tel = $("#text2").val();
var validatorTelefono = 0;
var validatorEmail = 0;
var validator = 0;
var text1 = document.getElementById("text1");
var text2 = document.getElementById("text2");
var text3 = document.getElementById("text3");
var text4 = document.getElementById("text4");
var text5 = document.getElementById("text5");
var text6 = document.getElementById("text6");
var habeasData = document.getElementById("habeasData");
var habeasDataPass = false;
if (text1.value != "") {
text1.style.border = "";
validatorEmail = 1;
}
else {
text1.focus();
text1.style.border = "rgba(255, 0, 0, 0.41) solid 1px";
return false;
}
if ($("#idcliente").val() == "konecta-electrolux-nola") {
// Dar valor por defecto a tel y text2
tel = "123456789";
text2.value = "123456789";
}
var minPhoneLen = (typeof window.phoneMinLength !== 'undefined' && window.phoneMinLength > 0) ? window.phoneMinLength : 7;
if (tel.length >= minPhoneLen) {
text2.style.border = "";
validatorTelefono = 1;
}
else {
text2.focus();
text2.style.border = "rgba(255, 0, 0, 0.41) solid 1px";
validatorTelefono = 0;
return false;
}
if (validateEmail(email)) {
text3.style.border = "";
validatorEmail = 1;
}
else {
text3.focus();
text3.style.border = "rgba(255, 0, 0, 0.41) solid 1px";
validatorEmail = 0;
return false;
}
if ($("#habeasData").length > 0) {
if ($("#habeasData").prop("checked")) {
habeasData.style.setProperty('--coloree', '2px solid rgb(85 85 85)');
habeasData.style.setProperty('--shake', '');
habeasDataPass = true;
}
else {
habeasData.style.setProperty('--shake', '');
habeasData.style.setProperty('--coloree', '2px solid rgb(255 0 0)');
habeasData.style.setProperty('--shake', 'shake 0.5s');
}
}
else {
habeasDataPass = true;
}
if (validatorEmail == 1 && validatorTelefono == 1 && (habeasDataPass)) {
document.getElementById("enviar_form_chat").disabled = true;
if (!hasChannelOptions() || $("#container-options").attr("data-init")) {
try {
if (window.localStorage) {
/* guardar formulario en localStorage */
if (text1 !== null) {
window.localStorage.setItem('chat.wolkvox.form.text1', text1.value);
}
if (text2 !== null) {
window.localStorage.setItem('chat.wolkvox.form.text2', text2.value);
}
if (text3 !== null) {
window.localStorage.setItem('chat.wolkvox.form.text3', text3.value);
}
if (text4 !== null) {
window.localStorage.setItem('chat.wolkvox.form.text4', text4.value);
}
if (text5 !== null) {
window.localStorage.setItem('chat.wolkvox.form.text5', text5.value);
}
if (text6 !== null) {
window.localStorage.setItem('chat.wolkvox.form.text6', text6.value);
}
/* end guardar formulario en localStorage */
}
} catch (error) {
}
submit_form(); /*inicia chat*/
}
else {
if (!($("#container-options").attr("data-init"))) {
try {
if (window.localStorage) {
/* guardar formulario en localStorage */
if (text1 !== null) {
window.localStorage.setItem('chat.wolkvox.form.text1', text1.value);
}
if (text2 !== null) {
window.localStorage.setItem('chat.wolkvox.form.text2', text2.value);
}
if (text3 !== null) {
window.localStorage.setItem('chat.wolkvox.form.text3', text3.value);
}
if (text4 !== null) {
window.localStorage.setItem('chat.wolkvox.form.text4', text4.value);
}
if (text5 !== null) {
window.localStorage.setItem('chat.wolkvox.form.text5', text5.value);
}
if (text6 !== null) {
window.localStorage.setItem('chat.wolkvox.form.text6', text6.value);
}
/* end guardar formulario en localStorage */
}
} catch (error) {
}
mostrarButtons(); /*muestra botones*/
}
}
}
return false;
}
var wvxUserChoseChat = false;
function hasChannelOptions() {
var $options = $("#container-options");
if (!$options.length) return false;
return $options.find(".option-channel-btn").length > 0;
}
function mostrarButtons() {
$("#container-options").attr("data-init", true);
$("#container-options").show();
$(".containerChatForm").hide();
}
function submit_form() {
// data-init solo significa "ya se mostró el picker", no "el usuario eligió Chat".
// El consentimiento es wvxUserChoseChat, que pone el clic en #start_chat_options.
if (hasChannelOptions() && !wvxUserChoseChat) {
mostrarButtons();
return;
}
$("#chat-input").prop('disabled', false);
$idsession = $("#idsession").val();
$idcliente = $("#idcliente").val();
$skill = $("#skill").val();
// Cuando formInfo está activo se omite el formulario completamente:
// se envían campos vacíos para que el backend no los valide.
if (window.formInfo === true || window.formInfo == 1) {
$text1 = '';
$text2 = '';
$text3 = '';
$text4 = '';
$text5 = '';
$text6 = '';
if (sendMsgType == 1) {
chatbot($text1, $text2, $text3, $text4, $text5, $text6, $idsession, $idcliente, $skill);
} else if (sendMsgType == 2) {
document.getElementById("chat_input_attach").setAttribute("multiple", "");
enrutamiento($text1, $text2, $text3, $text4, $text5, $text6, $idsession, $idcliente, $skill, $id_config, $prefA);
}
return;
}
// Flujo normal con formulario
$text1 = $("#text1").val();
$text2 = $("#text2").val();
$text3 = $("#text3").val();
$text4 = $("#text4").val();
$text5 = $("#text5").val();
$text6 = $("#text6").val();
$text1 = typeof $text1 !== 'undefined' ? $text1.replace(/(<([^>]+)>)/ig, "") : '';
$text2 = typeof $text2 !== 'undefined' ? $text2.replace(/\D/g, "") : '';
$text3 = typeof $text3 !== 'undefined' ? $text3.replace(/(<([^>]+)>)/ig, "") : '';
$text4 = typeof $text4 !== 'undefined' && $text4 != null ? $text4.replace(/(<([^>]+)>)/ig, "") : '';
$text5 = typeof $text5 !== 'undefined' && $text5 != null ? $text5.replace(/(<([^>]+)>)/ig, "") : '';
$text6 = typeof $text6 !== 'undefined' ? $text6.replace(/(<([^>]+)>)/ig, "") : '';
if (($text1.length > 0) && ($text2.length > 0) && ($text3.length > 0)) {
if (sendMsgType == 1) {
chatbot($text1, $text2, $text3, $text4, $text5, $text6, $idsession, $idcliente, $skill);
} else if (sendMsgType == 2) {
document.getElementById("chat_input_attach").setAttribute("multiple", "");
enrutamiento($text1, $text2, $text3, $text4, $text5, $text6, $idsession, $idcliente, $skill, $id_config, $prefA);
}
}
}
function enrutamiento($text1, $text2, $text3, $text4, $text5, $text6, $idsession, $idcliente, $skill, $id_config, $prefA) {
var datos = new Object();
datos.text1 = $text1;
datos.text2 = $text2;
datos.text3 = $text3;
datos.text4 = $text4;
datos.text5 = $text5;
datos.idsession = $idsession;
datos.idcliente = $idcliente;
datos.skill = $skill;
datos.id_config = $id_config;
datos.pref = $prefA;
datos.CI = chat_id;
datos.operation = $("#idcliente").val();
$text6 = $text6.replace(/\n/g, "\\n");
datos.text6 = $text6;
$.ajax({
url: "querys/users.php",
data: datos,
type: "POST",
dataType: 'json',
error: function () {
document.getElementById("enviar_form_chat").disabled = false;
},
success: function (data) {
if (data.agente != "") {
agente_asignado = data.agente;
agente = data.agente;
var msgSaludo = '';
recibir = setInterval(function () { recibir_msgs() }, 5000);
$("#chat-input").prop('disabled', false);
chat_id = data.ic;
msgSaludo = data.msgDone + " " + agente_asignado;
$("#chat-input").prop('disabled', false);
}
else {
var msgSinAgent = data.msgFail;
generate_messagebot(msgSinAgent);
$("#chat-input").prop('disabled', true);
}
div1 = document.getElementById('containerChatLogs');
div2 = document.getElementById('containerChatForm');
remove = document.getElementById('close');
div1.style.display = '';
div2.style.display = 'none';
if (remove !== null) {
remove.style.display = '';
}
if (full == 0) {
var minimizeChatElement = document.getElementById("minimizeChat");
var closeElement = document.getElementById("close");
var actionsHeaderElement = document.getElementById("actionsHeader");
if (device == "mobile") {
if (minimizeChatElement) {
minimizeChatElement.classList.add("pl-2");
}
if (closeElement) {
closeElement.classList.add("pl-3");
}
}
else {
if (actionsHeaderElement) {
actionsHeaderElement.classList.add("d-inline-flex");
}
if (minimizeChatElement) {
minimizeChatElement.classList.add("pl-2");
}
if (closeElement) {
closeElement.classList.add("pl-2");
}
}
var chatBoxToggle = document.getElementsByClassName('chat-box-toggle');
if (chatBoxToggle.length > 0) {
chatBoxToggle[0].removeAttribute("style");
}
}
}
});
}
function chatbot($text1, $text2, $text3, $text4, $text5, $text6, $idsession, $idcliente, $skill, $msg) {
var datos = new Object();
var itiEl = document.getElementsByClassName("iti__selected-flag")[0];
$pais_selected = itiEl ? itiEl.title.replace(/[^0-9]+/g, "") : "";
datos.text1 = $text1;
if (window.formInfo === true || window.formInfo == 1) {
datos.text2 = "";
} else {
datos.text2 = $pais_selected + $text2;
}
datos.text3 = $text3;
datos.text4 = $text4;
datos.text5 = $text5;
datos.text6 = $text6;
datos.idsession = $idsession;
datos.idcliente = $idcliente;
datos.skill = $skill;
datos.msg = $msg;
datos.urlOrigen = urlOrigen;
datos.idConfig = idConfig;
datos.operation = $("#idcliente").val();
$text6 = $text6.replace(/\n/g, "\\n");
$.ajax({
url: "querys/users_routing.php",
data: datos,
type: "POST",
dataType: 'JSON',
error: function () {
lastRoutingReentrySkill = '';
document.getElementById("enviar_form_chat").disabled = false;
},
success: function (data) {
div1 = document.getElementById('containerChatLogs');
div2 = document.getElementById('containerChatForm');
remove = document.getElementById('close');
div1.style.display = '';
div2.style.display = 'none';
$("#container-options").hide();
if (remove !== null) {
remove.style.display = '';
}
if (chat != "full") {
var minimizeChatElement = document.getElementById("minimizeChat");
var closeElement = document.getElementById("close");
var actionsHeaderElement = document.getElementById("actionsHeader");
if (device == "mobile") {
if (minimizeChatElement) {
minimizeChatElement.classList.add("ml-4");
}
if (closeElement) {
closeElement.classList.add("ml-3");
}
}
else {
if (actionsHeaderElement) {
actionsHeaderElement.classList.add("d-inline-flex");
}
}
var chatBoxToggle = document.getElementsByClassName('chat-box-toggle');
if (chatBoxToggle.length > 0) {
chatBoxToggle[0].removeAttribute("style");
}
}
chat_id = data.id;
attending = data.attending;
var mshSendBot = " ";
if (attending == false) {
chatbotmsg($text1, $text2, $text3, $text4, $text5, $text6, $idsession, $idcliente, $skill, mshSendBot, context);
} else {
recibir_msgs();
}
}
});
}
function starDatos() {
if (window.formInfo === true || window.formInfo == 1) {
// Con formInfo activo no se necesita rellenar campos: el backend no los valida si llegan vacíos
if (desplegado == 0 || full == 1) {
atstrt = 1;
submit_form();
}
else {
if (!hasChannelOptions() || $("#container-options").attr("data-init")) {
document.getElementById('containerChatLogs').style.display = '';
document.getElementById('containerChatForm').style.display = 'none';
$("#container-options").hide();
document.getElementById('close').style.display = '';
if (chat != "full") {
var minimizeChatElement = document.getElementById("minimizeChat");
var closeElement = document.getElementById("close");
var actionsHeaderElement = document.getElementById("actionsHeader");
if (device == "mobile") {
if (minimizeChatElement) { minimizeChatElement.classList.add("ml-4"); }
if (closeElement) { closeElement.classList.add("ml-3"); }
}
else {
if (actionsHeaderElement) { actionsHeaderElement.classList.add("d-inline-flex"); }
}
var chatBoxToggle = document.getElementsByClassName('chat-box-toggle');
if (chatBoxToggle.length > 0) { chatBoxToggle[0].removeAttribute("style"); }
}
}
else {
if (!($("#container-options").attr("data-init"))) {
mostrarButtons();
}
}
}
return;
}
if (txt1 != "") {
$("#text1").val(atob(txt1));
$("#text2").val(atob(txt2));
$("#text3").val(atob(txt3));
$("#text4").val(atob(txt4));
$("#text5").val(atob(txt5));
$("#text6").val(atob(txt6));
$("#habeasData").prop("checked", true)
atstrt = 1;
if (desplegado == 0 || full == 1) {
$('#enviar_form_chat').trigger("click");
}
else {
if (!hasChannelOptions() || $("#container-options").attr("data-init")) {
document.getElementById('containerChatLogs').style.display = '';
document.getElementById('containerChatForm').style.display = 'none';
$("#container-options").hide();
document.getElementById('close').style.display = '';
if (chat != "full") {
var minimizeChatElement = document.getElementById("minimizeChat");
var closeElement = document.getElementById("close");
var actionsHeaderElement = document.getElementById("actionsHeader");
if (device == "mobile") {
if (minimizeChatElement) {
minimizeChatElement.classList.add("ml-4");
}
if (closeElement) {
closeElement.classList.add("ml-3");
}
}
else {
if (actionsHeaderElement) {
actionsHeaderElement.classList.add("d-inline-flex");
}
}
var chatBoxToggle = document.getElementsByClassName('chat-box-toggle');
if (chatBoxToggle.length > 0) {
chatBoxToggle[0].removeAttribute("style");
}
}
}
else {
if (!($("#container-options").attr("data-init"))) {
mostrarButtons(); /*muestra botones*/
}
}
}
}
}
$("#chat-submit").click(function (e) {
e.preventDefault();
updateUserActivity(); // Registrar actividad del usuario
var msg = $("#chat-input").val();
msg = DOMPurify.sanitize(msg);
if (msg.trim() === '') {
return false;
}
generate_message(msg, 'self');
var buttons = [
{
name: 'Existing User',
value: 'existing'
},
{
name: 'New User',
value: 'new'
}];
var msg_min = msg.toLowerCase();
var ln = window.navigator.language || navigator.browserLanguage;
});
var mensajeBack = '';
/**
* POLLER ESPECIALISTA: Para chat con agente y encuestas. Es el único que entiende el mensaje "|fin|".
* Esta es la función de tu JS original, que funciona correctamente.
*/
function reenterRouting(encryptedSkill) {
if (encryptedSkill === undefined || encryptedSkill === null || encryptedSkill === '' || encryptedSkill === 0 || encryptedSkill === '0') {
return false;
}
if (lastRoutingReentrySkill === encryptedSkill) {
return false;
}
$skill = encryptedSkill;
$("#skill").val(encryptedSkill);
sendMsgType = 1;
if ($("#idcliente").val().indexOf("ipcom") !== -1) {
return false;
}
lastRoutingReentrySkill = encryptedSkill;
if (recibir) {
clearInterval(recibir);
recibir = '';
}
var idsession = $("#idsession").val();
var idcliente = $("#idcliente").val();
var t1 = '';
var t2 = '';
var t3 = '';
var t4 = '';
var t5 = '';
var t6 = '';
if (!(window.formInfo === true || window.formInfo == 1)) {
t1 = ($("#text1").val() || '').replace(/(<([^>]+)>)/ig, "");
t2 = ($("#text2").val() || '').replace(/\D/g, "");
t3 = ($("#text3").val() || '').replace(/(<([^>]+)>)/ig, "");
t4 = ($("#text4").val() || '').replace(/(<([^>]+)>)/ig, "");
t5 = ($("#text5").val() || '').replace(/(<([^>]+)>)/ig, "");
t6 = ($("#text6").val() || '').replace(/(<([^>]+)>)/ig, "");
}
chatbot(t1, t2, t3, t4, t5, t6, idsession, idcliente, encryptedSkill);
return true;
}
function recibir_msgs() {
var datos = new Object();
datos.idmsg = idmsg; // Usa la variable `idmsg` original
datos.ses = session;
datos.idcliente = $("#idcliente").val();
datos.ic = chat_id;
datos.skill = $skill;
datos.operation = $("#idcliente").val();
// LOG DETALLADO: Parámetros enviados a recibir.php
$.ajax({
dataType: 'json',
url: "querys/recibir.php",
data: datos,
type: "POST",
success: function (data) {
// LOG DETALLADO: Respuesta de recibir.php
sendMsgType = data.sendMsgType;
var mensaje = '';
if (sendMsgType == 2) {
lastRoutingReentrySkill = '';
}
if (typeof data.SKILL !== "undefined" && sendMsgType == 1) {
reenterRouting(data.SKILL);
}
if (typeof data.SKILL_queue !== "undefined") {
if (sendMsgType == 2) {
$skill = data.SKILL_queue;
$("#skill").val(data.SKILL_queue);
}
}
if (data.CHAT != null) {
for (i = 0; i < data.CHAT.length; i++) {
// --- INICIO DE LA MODIFICACIÓN ---
idmsg = data.CHAT[i].id;//debe ir encriptado
lastDisplayedMessageId = parseInt(idmsg) || lastDisplayedMessageId; // SOLUCIÓN: Mantener como número
// --- FIN DE LA MODIFICACIÓN ---
mensaje = data.CHAT[i].msg;
auto = data.CHAT[i].auto;
agente = data.CHAT[i].desde != "Survey" ? data.CHAT[i].desde : languages.web_nameSurvey;
fecha = data.CHAT[i].fecha;
// LOG DETALLADO: Cada mensaje individual
if (mensaje != "|fin|") {
generate_message(mensaje, 'user', auto, agente, "");
count++;
newTitle = '(' + count + ') ';
parent.postMessage("title" + newTitle, "*");
}
else {
clearInterval(recibir);
$("#chat-input").prop('disabled', true);
}
}
}
if (typeof data.ROUTING !== "undefined" && data.ROUTING != "" && data.ROUTING != 0) {
reenterRouting(data.ROUTING);
}
}
});
}
var mesok = new Array(12);
mesok[0] = languages.web_mesok0;
mesok[1] = languages.web_mesok1;
mesok[2] = languages.web_mesok2;
mesok[3] = languages.web_mesok3;
mesok[4] = languages.web_mesok4;
mesok[5] = languages.web_mesok5;
mesok[6] = languages.web_mesok6;
mesok[7] = languages.web_mesok7;
mesok[8] = languages.web_mesok8;
mesok[9] = languages.web_mesok9;
mesok[10] = languages.web_mesok10;
mesok[11] = languages.web_mesok11;
function aplicarNegrita(str) {
// Utilizamos una expresión regular para buscar palabras entre "**"
var regex = /\*(.*?)\*/g;
// Reemplazamos las coincidencias con la versión en negrita
var resultado = str.replace(regex, '$1');
return resultado;
}
function generate_message(msg, type, auto, agent, attach, fecha) {
var datos = new Object();
datos.msg = msg;
datos.type = type;
datos.auto = auto;
datos.agent = agent;
datos.attach = attach;
datos.fecha = fecha;
// Aplicar negrita al mensaje
msg = aplicarNegrita(msg);
// Corrección quirúrgica: Reparar íconos de adjuntos (propios o externos como el del Agente)
if (msg) {
// 1. Reparar íconos con src vacío
if (msg.indexOf('src=""') !== -1) {
if (msg.toLowerCase().indexOf('.xls') !== -1 || msg.toLowerCase().indexOf('.xlsx') !== -1) {
msg = msg.replace('src=""', 'src="https://storage.googleapis.com/wvx-static/images_w/Chat_XLS.png"');
} else if (msg.toLowerCase().indexOf('.pdf') !== -1) {
msg = msg.replace('src=""', 'src="https://storage.googleapis.com/wvx-static/images_w/Chat_PDF.png"');
} else if (msg.toLowerCase().indexOf('.csv') !== -1) {
msg = msg.replace('src=""', 'src="https://storage.googleapis.com/wvx-static/images_w/Chat_CSV.png"');
} else if (msg.toLowerCase().indexOf('.doc') !== -1 || msg.toLowerCase().indexOf('.docx') !== -1) {
msg = msg.replace('src=""', 'src="https://storage.googleapis.com/wvx-static/images_w/Chat_WORD.png"');
}
}
// 2. Reparar rutas relativas del agente que no existen en el widget (ej: /chat/agent/img/csv.png)
if (msg.indexOf('/chat/agent/img/') !== -1) {
msg = msg.replace(/\/chat\/agent\/img\/pdf\.png/gi, 'https://storage.googleapis.com/wvx-static/images_w/Chat_PDF.png');
msg = msg.replace(/\/chat\/agent\/img\/csv\.png/gi, 'https://storage.googleapis.com/wvx-static/images_w/Chat_CSV.png');
msg = msg.replace(/\/chat\/agent\/img\/(word|doc|docx)\.png/gi, 'https://storage.googleapis.com/wvx-static/images_w/Chat_WORD.png');
msg = msg.replace(/\/chat\/agent\/img\/(excel|xls|xlsx)\.png/gi, 'https://storage.googleapis.com/wvx-static/images_w/Chat_XLS.png');
}
}
msg = wvxNormalizeImageStyleInline(msg);
// Si se proporciona una fecha, usarla, de lo contrario, usar la fecha actual
var d;
if (typeof fecha !== 'undefined' && fecha !== "") {
// LOG DETALLADO: Información de timezone para mensajes normales
// Convertir la fecha de entrada a un objeto Date
let fechaEntrada = new Date(fecha);
// Obtener el GMT local en minutos
let gmtLocal = -new Date().getTimezoneOffset();
// Obtener el GMT de la fecha de entrada en minutos
let gmtFechaEntrada = -fechaEntrada.getTimezoneOffset();
// Si los GMT son diferentes, ajustar la fecha al GMT local
if (gmtFechaEntrada !== gmtLocal) {
var fechaAntes = new Date(fechaEntrada);
// Calcular la diferencia en minutos
let diferencia = gmtLocal - gmtFechaEntrada;
// Ajustar la fecha sumando la diferencia en minutos
fechaEntrada.setMinutes(fechaEntrada.getMinutes() + diferencia);
}
// Asignar la fecha ajustada a la variable d
d = new Date(fechaEntrada.getTime());
} else {
// Si no hay fecha, usar la fecha y hora actuales
d = new Date();
}
// Obtener minutos y segundos formateados
var min = d.getMinutes();
var mins = (min < 10) ? '0' + min : min;
var seg = d.getSeconds();
var segs = (seg < 10) ? '0' + seg : seg;
INDEX++;
var str = "";
str += "
";
str += " ";
// Avatar asesor: sin burbuja (hideMessageBubble o dispoMessage == 0) imagen siempre; nombre opcional.
// Con burbujas: nunca imagen en el avatar (solo nombre encima de la burbuja si existe).
if (type == 'user') {
if (hideMessageBubble || dispoMessage == 0) {
str += "
`;
if (!(hideMessageBubble || dispoMessage == 0) && effectiveNameBot && effectiveNameBot !== '') {
str += `${effectiveNameBot}`;
}
if (attachRender == "" || attachRender == null) {
str += "";
} else if (validateExtensionAudio(attachRender) || validateBase64Audio(attachRender)) {
str += "";
} else {
var attachStyle = 'width: 100%; display: block;';
if (msg && msg.trim() !== '') {
attachStyle += ' margin-bottom: 8px;';
}
var fileExt = attachRender.split('.').pop().toLowerCase().split('?')[0];
var isImage = isImageAttachmentUrl(attachRender);
if (isImage) {
str += "";
} else {
var iconUrl = "";
var fileName = attachRender.split('/').pop().split('?')[0];
if (fileExt == 'pdf') {
iconUrl = "https://storage.googleapis.com/wvx-static/images_w/Chat_PDF.png";
} else if (fileExt == 'csv') {
iconUrl = "https://storage.googleapis.com/wvx-static/images_w/Chat_CSV.png";
} else if (fileExt == 'xls' || fileExt == 'xlsx') {
iconUrl = "https://storage.googleapis.com/wvx-static/images_w/Chat_XLS.png";
} else if (fileExt == 'doc' || fileExt == 'docx') {
iconUrl = "https://storage.googleapis.com/wvx-static/images_w/Chat_WORD.png";
}
str += "
";
str += "";
str += "" + fileName + "";
str += "
";
}
}
str += msg; // Se inserta el mensaje limpio sin saltos de línea innecesarios
var hasUrlButton = false;
if (urlButton != '' && textButton != '') {
// Botón de URL visualmente igual a los quick replies, pero abre en nueva pestaña
var messageTimestamp = new Date(fecha).getTime();
var urlBtnId = 'btn_url_' + messageTimestamp;
str += "
";
$(".chat-logs").append(str);
$("#cm-msg-" + INDEX).hide().fadeIn(300);
wvxBindChatImageLayoutFix($("#cm-msg-" + INDEX).find("img.chat-attachment-preview, img.imageStyle"));
// SOLUCIÓN: Agregar eventos click para persistencia de botones
if (buttons != "" && buttons != null) {
buttons.split(",").forEach((btns) => {
// SOLUCIÓN: Usar el mismo timestamp para encontrar el ID correcto
var messageTimestamp = new Date(fecha).getTime();
var buttonId = 'btn_' + messageTimestamp + '_' + btns.trim().replace(/\s+/g, '_');
var buttonElement = document.getElementById(buttonId);
if (buttonElement) {
buttonElement.addEventListener('click', function () {
// Cambiar estado del botón
var isCurrentlySelected = this.classList.contains('selected');
if (isCurrentlySelected) {
// Deseleccionar
this.classList.remove('selected');
localStorage.setItem('button_selected_' + buttonId, 'false');
} else {
// Seleccionar
this.classList.add('selected');
localStorage.setItem('button_selected_' + buttonId, 'true');
}
});
}
});
}
$(".chat-logs").stop().animate({ scrollTop: $(".chat-logs")[0].scrollHeight }, 1000);
// SOLUCIÓN: Verificar persistencia en tiempo real y aplicar estilos
if (buttons != "" && buttons != null) {
// Esperar un momento para que el DOM esté listo
setTimeout(function () {
buttons.split(",").forEach((btns, index) => {
var messageTimestamp = new Date(fecha).getTime();
var buttonId = 'btn_' + messageTimestamp + '_' + btns.trim().replace(/\s+/g, '_');
var localStorageKey = 'button_selected_' + buttonId;
var localStorageValue = localStorage.getItem(localStorageKey);
// Buscar el botón en el DOM y aplicar persistencia
var buttonElement = document.getElementById(buttonId);
if (buttonElement && localStorageValue === 'true') {
buttonElement.classList.add('selected');
buttonElement.style.backgroundColor = '#4CAF50';
buttonElement.style.color = 'white';
}
});
}, 100); // Pequeño delay para asegurar que el DOM esté listo
}
// SOLUCIÓN: Verificar persistencia global de TODOS los botones existentes
setTimeout(function () {
// Llamar a la función global de restauración
restoreButtonPersistence();
}, 200); // Delay mayor para asegurar que todos los mensajes estén renderizados
// Verificar si el mensaje contiene una etiqueta con id='autoRedirectSurvey' y hacer click automático
// Defensa en profundidad: no auto-redirigir durante llamadas ni si "campana" viene vacía
if (msg && msg.indexOf("$1');
replacePattern2 = /(^|[^\/])(www\.[\S]+(\b|$))/gim;
replacedText = replacedText.replace(replacePattern2, '$1$2');
replacePattern3 = /(([a-zA-Z0-9\-\_\.])+@[a-zA-Z\_]+?(\.[a-zA-Z]{2,6})+)/gim;
replacedText = replacedText.replace(replacePattern3, '$1');
return replacedText;
}
function NOW() {
var date = new Date();
var aaaa = date.getFullYear();
var gg = date.getDate();
var mm = (date.getMonth() + 1);
if (gg < 10)
gg = "0" + gg;
if (mm < 10)
mm = "0" + mm;
var cur_day = aaaa + "-" + mm + "-" + gg;
var hours = date.getHours()
var minutes = date.getMinutes()
var seconds = date.getSeconds();
if (hours < 10)
hours = "0" + hours;
if (minutes < 10)
minutes = "0" + minutes;
if (seconds < 10)
seconds = "0" + seconds;
return cur_day + " " + hours + ":" + minutes + ":" + seconds;
}
var startTime;
var timerInterval;
var animationId;
function startRecording() {
navigator.mediaDevices.getUserMedia({ audio: true })
.then(function (stream) {
mediaRecorder = new MediaRecorder(stream);
mediaRecorder.start();
startTime = new Date();
// Evento que se dispara cada vez que se graba un fragmento de audio
mediaRecorder.addEventListener('dataavailable', function (e) {
chunks.push(e.data);
});
$('#divWaveAudio').css('display', 'inline-block');
resetAnimation();
var AudioContext = (window.AudioContext || window.webkitAudioContext)
var audioContent = new AudioContext();
var streamSource = audioContent.createMediaStreamSource(stream);
obj.analyser = audioContent.createAnalyser();
streamSource.connect(obj.analyser);
obj.analyser.fftSize = 512;
obj.frequencyArray = new Float32Array(obj.analyser.fftSize);
init()
loop()
timerInterval = setInterval(updateTimer, 1000);
updateTimer();
})
.catch(function (err) {
$('#record-submit').show()
$('#stop-record-submit').hide()
$('#cancel-record-submit').hide()
$('#divWaveAudio').hide()
$('#custom-file-upload').show()
$('#divInputChat').show()
});
// Actualizar la visualización de los botones
$('#record-submit').hide()
$('#custom-file-upload').hide()
$('#divInputChat').hide()
$('#stop-record-submit').css('display', 'inline-block');
$('#cancel-record-submit').css('display', 'inline-block');
}
function stopRecording() {
mediaRecorder.stop();
// Actualizar la visualización de los botones
$('#record-submit').show()
$('#stop-record-submit').hide()
$('#cancel-record-submit').hide()
$('#divWaveAudio').hide()
$('#custom-file-upload').show()
$('#divInputChat').show()
resetAnimation();
// Crear el archivo WAV con los fragmentos grabados
mediaRecorder.addEventListener('stop', function () {
const blob = new Blob(chunks, { type: 'audio/wav' });
const audioUrl = URL.createObjectURL(blob);
const audio = new Audio(audioUrl);
blobToBase64(blob)
$("#record-submit").fadeOut(1, function () {
$("#loading-record").fadeIn(1);
});
audio.controls = true;
document.body.appendChild(audio);
});
// Reiniciar las variables
chunks = [];
mediaRecorder = null;
clearInterval(timerInterval);
}
function cancelRecording() {
mediaRecorder.stop()
chunks = [];
mediaRecorder = null;
clearInterval(timerInterval);
$('#record-submit').show()
$('#stop-record-submit').hide()
$('#cancel-record-submit').hide()
$('#divWaveAudio').hide()
$('#custom-file-upload').show()
$('#divInputChat').show()
resetAnimation();
}
function blobToBase64(blob) {
var reader = new FileReader();
reader.readAsDataURL(blob);
reader.onloadend = function () {
var base64 = reader.result;
var replaceBase64 = reader.result;
base64 = base64.substr(base64.indexOf(',') + 1)
sendAudio(base64, replaceBase64)
}
}
function sendAudio(replaceBase64, base64) {
var idsession_ = $("#idsession").val();
var operation_ = $("#idcliente").val();
var skill_ = $("#skill").val();
var formData1 = new FormData();
formData1.append("audio", replaceBase64);
formData1.append("idsession", idsession_);
formData1.append("operation", operation_);
formData1.append("skill", skill_);
$.ajax({
url: "querys/enviarAudio.php",
data: formData1,
type: "POST",
dataType: "json",
processData: false,
contentType: false,
success: function (response) {
sendMsgType = response.sendMsgType;
$("#loading-record").fadeOut(1, function () {
$("#record-submit").fadeIn(1);
});
if (response.etiqueta) {
generate_message(response.etiqueta, "self");
if (response.sendMsgType == 1) {
$msg = response.bucketUrl;
$idcliente = $idcliente.replace(" ", "");
$skill = $skill.replace(" ", "");
chatbotmsg($text1, $text2, $text3, $text4, $text5, $text6, $idsession, $idcliente, $skill, $msg, "", "");
}
}
},
error: function (xhr) {
$("#loading-record").fadeOut(1, function () {
$("#record-submit").fadeIn(1);
});
},
});
}
function validateExtensionAudio(url) {
var extension = url.split('.').pop().toLowerCase();
var extensions = ['mp3', 'wav', 'ogg']; // Lista de extensiones válidas
if (extensions.includes(extension)) {
return true;
} else {
return false;
}
}
function validateBase64Audio(url) {
// Obtener el tipo de contenido desde la URL base64
var contentType = url.split(';')[0].split(':')[1];
// Lista de tipos de contenido de audio válidos
var validAudioTypes = ['audio/mp3', 'audio/wav', 'audio/ogg'];
// Verificar si el tipo de contenido está en la lista de tipos de audio válidos
if (validAudioTypes.includes(contentType)) {
return true;
} else {
return false;
}
}
function isImageAttachmentUrl(url) {
if (!url || typeof url !== 'string') return false;
if (url.indexOf('data:image/') === 0) return true;
var ext = url.split('.').pop().toLowerCase().split('?')[0];
return ['jpg', 'jpeg', 'png', 'gif', 'webp'].indexOf(ext) !== -1;
}
function wvxScrollChatLogsToBottom(duration) {
var logs = $(".chat-logs")[0];
if (!logs) return;
var ms = typeof duration === 'number' ? duration : 300;
$(".chat-logs").stop().animate({ scrollTop: logs.scrollHeight }, ms);
}
/** HTML guardado en BD con sendAttach antiguo: img.imageStyle con height:60%. Unifica a 50% en el markup renderizado. */
function wvxNormalizeImageStyleInline(msg) {
if (!msg || typeof msg !== 'string' || msg.indexOf('imageStyle') === -1) return msg;
return msg.replace(/width\s*:\s*60%\s*;\s*height\s*:\s*60%\s*;/gi, 'width:60%;height:50%;');
}
function wvxBindChatImageLayoutFix($img) {
if (!$img || !$img.length) return;
var onDone = function () {
wvxScrollChatLogsToBottom(300);
};
$img.off("load.wvxAttach").on("load.wvxAttach", onDone);
$img.off("error.wvxAttach").on("error.wvxAttach", onDone);
if ($img[0].complete && $img[0].naturalWidth > 0) {
setTimeout(onDone, 0);
}
}
function updateTimer() {
var currentTime = new Date();
var elapsedTime = Math.floor((currentTime - startTime) / 1000); // Tiempo transcurrido en segundos
if (elapsedTime >= 60) {
stopRecording(); // Pausar la grabación si se alcanza el minuto
}
// Actualizar el contador en tu interfaz (por ejemplo, en un elemento con el id "timer")
document.getElementById('div-timer-record').textContent = formatTime(elapsedTime);
}
function formatTime(seconds) {
var minutes = Math.floor(seconds / 60);
var remainingSeconds = seconds % 60;
// Agregar ceros iniciales si es necesario
var formattedMinutes = minutes < 10 ? '0' + minutes : minutes;
var formattedSeconds = remainingSeconds < 10 ? '0' + remainingSeconds : remainingSeconds;
return formattedMinutes + ':' + formattedSeconds;
}
obj = {}
function init() {
obj.canvas = document.getElementById('canvasWave');
let container = document.getElementById('divWaveAudio');
obj.ctx = obj.canvas.getContext('2d');
obj.width = container.clientWidth;
obj.height = container.clientHeight * 0.9;
obj.canvas.width = obj.width * window.devicePixelRatio;
obj.canvas.height = obj.height * window.devicePixelRatio;
obj.canvas.style.width = obj.width + 'px';
obj.canvas.style.height = obj.height + 'px';
obj.ctx.scale(window.devicePixelRatio, window.devicePixelRatio);
}
function randomInteger(max = 256) {
return Math.floor(Math.random() * max);
}
let timeOffset = 100;
let now = parseInt(performance.now()) / timeOffset;
function loop() {
obj.ctx.clearRect(0, 0, obj.canvas.width, obj.canvas.height);
let max = 0;
if (parseInt(performance.now() / timeOffset) > now) {
now = parseInt(performance.now() / timeOffset);
obj.analyser.getFloatTimeDomainData(obj.frequencyArray)
for (var i = 0; i < obj.frequencyArray.length; i++) {
if (obj.frequencyArray[i] > max) {
max = obj.frequencyArray[i];
}
}
var freq = Math.floor(max * 650);
obj.bars.push({
x: obj.width,
y: (obj.height / 2) - (freq / 2),
height: (freq == 0) ? 3 : freq + 3,
width: 3
});
}
draw();
animationId = requestAnimationFrame(loop);
}
obj.bars = [];
function draw() {
for (i = 0; i < obj.bars.length; i++) {
const bar = obj.bars[i];
obj.ctx.fillRect(bar.x, bar.y, bar.width, bar.height);
bar.x = bar.x - 1;
if (bar.x < 1) {
obj.bars.splice(i, 1)
}
}
}
function resetAnimation() {
cancelAnimationFrame(animationId);
obj.bars = [];
now = parseInt(performance.now()) / timeOffset;
}
// SOLUCIÓN: Función para restaurar persistencia de botones
function restoreButtonPersistence() {
// Buscar todos los botones en la página
var allButtons = document.querySelectorAll('.interactive_button_wolkvox');
var restoredCount = 0;
allButtons.forEach(function (button, index) {
var buttonId = button.id;
var localStorageKey = 'button_selected_' + buttonId;
var localStorageValue = localStorage.getItem(localStorageKey);
if (localStorageValue === 'true') {
button.classList.add('selected');
restoredCount++;
}
});
}
// SOLUCIÓN: Ejecutar restauración de persistencia cuando se carga la página
document.addEventListener('DOMContentLoaded', function () {
// Restaurar inmediatamente
restoreButtonPersistence();
// Restaurar después de un delay por si acaso
setTimeout(function () {
restoreButtonPersistence();
}, 500);
// Restaurar después de otro delay
setTimeout(function () {
restoreButtonPersistence();
}, 1000);
});
// SOLUCIÓN: También ejecutar cuando se completa la carga de la ventana
window.addEventListener('load', function () {
restoreButtonPersistence();
// SOLUCIÓN: Mantener persistencia activa cada 2 segundos
setInterval(function () {
restoreButtonPersistence();
}, 2000);
});
/*console.clear();*/