1 2/* 3* Descripción: Este archivo maneja la lógica del chatbot, incluyendo la interacción con el usuario, el envÃo de mensajes a la API del modelo. 4* @package IAchatbotHCR 5* @version 1.0.0 6* Author: Skaphe TecnologÃa SAS 7* Sitio web author: https://www.skaphe.com 8*/ 9 10 11/* * Este script se ejecuta cuando el DOM está completamente cargado. 12 * Se encarga de inicializar el chatbot, manejar eventos de usuario y enviar mensajes a la API del modelo. 13 * También maneja la lógica de inactividad del usuario y muestra mensajes de despedida si es necesario. 14 * @package IAchatbotHCR 15 * @version 1.0.0 16 * Author: Skaphe TecnologÃa SAS 17 * Sitio web author: https://www.skaphe.com 18 */ 19document.addEventListener("DOMContentLoaded", function () { 20 /* 21 * función que se ejecuta al cargar el documento 22 */ 23 async function onload() { 24 if (sessionStorage.getItem("chat-alpha-dato_form") === "true") { 25 const form = document.getElementById("chat-alpha-dato_form"); 26 if (form) form.style.display = "none"; 27 // let chatOld = sessionStorage.getItem("saveChatIa"); 28 let chatOld = await getIndexedDBItem("saveChatIa"); 29 30 if (chatOld) { 31 chatOld = chatOld.replace(`<ul id="chatMessages">`, ""); 32 chatOld = chatOld.replace("</ul>", ""); 33 document.getElementById("chatMessages").innerHTML = chatOld; 34 reassignChatButtonEvents(); 35 }else if (chatOld === null ) { 36 window.clearChat(); 37 } 38 } else { 39 if (btnSubmit) { 40 btnSubmit.disabled = false; 41 btnSubmit.style.display = "none"; 42 } 43 } 44 45 const body_chat_ia = document.getElementById("body-chat_ia"); 46 body_chat_ia.scrollTop = body_chat_ia.scrollHeight; 47 } 48 onload(); 49 // Reasignar eventos a los botones del chat 50 function reassignChatButtonEvents() { 51 document.querySelectorAll(".itemTopic").forEach((button) => { 52 const text = button.textContent.trim(); 53 switch (text) { 54 case "Terminar y cerrar chat": 55 button.onclick = () => 56 closeChat( 57 "Gracias por utilizar nuestro servicio. El chat ha sido cerrado.", 58 4000 59 ); 60 break; 61 case "Volver al menu anterior": 62 button.onclick = () => { 63 const topicChatbot = 64 sessionStorage.getItem("message_init_tema") || null; 65 if (topicChatbot) getListSubTopic(JSON.parse(topicChatbot)); 66 }; 67 break; 68 case "Volver al menu principal": 69 button.onclick = () => listTema(); 70 break; 71 case "Para una consulta más profunda por favor consulte Grifo": 72 button.onclick = function () { 73 window.open("https://www.camara.gov.co/", "_blank"); 74 }; 75 break; 76 default: 77 button.onclick = () => 78 openFormContact(button.getAttribute("data-link")); 79 break; 80 } 81 }); 82 } 83 // Obtener la configuración 84 const urlApi = chatbotSettings["urlApi"]; 85 const client_key = chatbotSettings["client_key"]; 86 const text_wait = chatbotSettings["text_wait"]; 87 const logo_resp = chatbotSettings["logo_resp"]; 88 const titulo_chat = chatbotSettings["titulo_chat"]; 89 const img_chat_user = chatbotSettings["img_chat_user"]; 90 let list_link_contact = chatbotSettings["list_link_contact"]; 91 const time_inactivity = chatbotSettings["time_inactivity"]; 92 const color_chat = chatbotSettings["color_chat"]; 93 const topic = chatbotSettings["topic"]; 94 const url_sonido = chatbotSettings["url_sonido"]; 95 96 // Asignar las variables al objeto global window para que puedan ser accedidas desde otros scripts 97 window.topic_funtion = topic; 98 window.color_chat_funtion = color_chat; 99 window.list_link_contact_funtion = list_link_contact; 100 101 window.logo_resp_funtion = logo_resp; 102 window.img_chat_user_funtion = img_chat_user; 103 window.titulo_chat_funtion = titulo_chat; 104 window.urlApi = urlApi; 105 106 // variables para manipular el chat 107 const $form = document.querySelector("#form-chat_alpha");
108 const $chatMessages = document.querySelector("#chatMessages"); 109 const $body_chat_ia = document.querySelector("#body-chat_ia"); 110 const userMessageForm = document.querySelector("#userMessageForm"); 111 const btn_send_message_ia = document.querySelector("#btn-send_message_ia"); 112 const btnClear = document.querySelector("#clearButton"); 113 const btnNewChat = document.querySelector("#btn-new_message_ia"); 114 const svg_btn = document.querySelectorAll(".svg_btn"); 115 116 // eventos para los botones de enviar mensaje 117 $form.addEventListener("submit", async function (event) { 118 event.preventDefault(); 119 // Guardar la hora del último mensaje del usuario 120 const analyze_image = sessionStorage.getItem("analyze-image"); 121 122 sessionStorage.setItem("lastUserMessageTime", Date.now()); 123 if (sessionStorage.getItem("chatWithAdvisor") !== "true") { 124 btn_send_message_ia.disabled = true; 125 btnClear.disabled = true; 126 btnNewChat.disabled = true; 127 svg_btn.forEach((svg_btn) => { 128 svg_btn.setAttribute( 129 "style", 130 "fill: #a7aaad !important;cursor: not-allowed;" 131 ); 132 }); 133 } 134 135 userMessageForm.placeholder = text_wait; 136 137 const formData = new FormData($form); 138 const userMessage = formData.get("userMessage"); 139 140 const userMessageElement = document.createElement("li"); 141 142 let fecha = `${new Date() 143 .toLocaleDateString() 144 .replaceAll("/", "-")} ${new Date().toLocaleTimeString()}`; 145 146 const form_chat_alpha_active = sessionStorage.getItem( 147 "form-chat_alpha_active" 148 ); 149 150 // Verificar si el formulario de chat está activo para texto abierto 151 if (form_chat_alpha_active === "true") { 152 userMessageElement.classList.add("message-ia", "user"); 153 userMessageElement.innerHTML = `<span><img src="${img_chat_user}" alt="" style="width: 20px; height: 20px; margin-right: 5px;"/><strong>Tú</strong></span><p>${userMessage||''} <br> <small style="font-size:9px;float:right;">${fecha}</small> </p>`; 154 $chatMessages.appendChild(userMessageElement); 155 $body_chat_ia.scrollTop = $body_chat_ia.scrollHeight; 156 $body_chat_ia.scrollIntoView({ behavior: "smooth" }); 157 } 158 159 // Obtener el contenido del chat guardado en el sessionStorage 160 sessionStorageBodyContent = sessionStorage.getItem("bodyContent"); 161 162 let bodyContent = []; 163 if (sessionStorageBodyContent) { 164 bodyContent = JSON.parse(sessionStorageBodyContent); 165 const tema = sessionStorage.getItem("message_init_tema") 166 ? JSON.parse(sessionStorage.getItem("message_init_tema")) 167 : null; 168 const subTopic = sessionStorage.getItem("sub-topic"); 169 170 171 // Buscar y actualizar el objeto que contiene "sub-topic" 172 const subTopicIndex = bodyContent.findIndex(item => item.hasOwnProperty("sub-topic")); 173 if (subTopicIndex !== -1) { 174 if (tema.topic == "Reconocimiento de imágenes") { 175 bodyContent[subTopicIndex]["sub-topic"] = 176 "Analiza el hilo de la conversación y tómala como contexto antes de responder la pregunta relacionada con la imagen"; 177 } else { 178 bodyContent[subTopicIndex]["sub-topic"] = subTopic; 179 } 180 } else { 181 // Si no existe, agregar el objeto sub-topic 182 bodyContent.splice(1, 0, { "sub-topic": subTopic }); 183 } 184 185 bodyContent.push({ 186 sender: "user", 187 text: userMessage, 188 date: fecha, 189 }); 190 } else { 191 const message_init_tema = sessionStorage.getItem("message_init_tema"); 192 const tema = message_init_tema ? JSON.parse(message_init_tema) : null; 193 const newMessage = userMessage; 194 if (tema.topic == "Consulta abierta") { 195 bodyContent = [ 196 { 197 topic: "", 198 }, 199 { 200 "sub-topic": "", 201 }, 202 { 203 sender: "user", 204 text: newMessage, 205 date: fecha, 206 }, 207 ]; 208 } else { 209 bodyContent = [ 210 { 211 topic: tema ? tema.topic : "", 212 }, 213 { 214 "sub-topic": sessionStorage.getItem("sub-topic", ""), 215 }, 216 { 217 sender: "user", 218 text: newMessage, 219 date: fecha, 220 }, 221 ]; 222 } 223 } 224 window.addAnimationLoad(); // Añadir animación de carga 225 226 const bodyToSend = bodyContent 227 .map(({ date, ...rest }) => rest) 228 .filter( 229 (msg) => 230 !( 231 msg.text && 232 (msg.text.includes( 233 "¡Parece que has estado inactivo por un tiempo! Si necesitas algo más" 234 ) || 235 msg.text.includes( 236 "Si necesitas algo más, estaré aquà para ayudarte." 237 )) 238 ) 239 ); 240 const body = JSON.stringify(bodyToSend); 241 242 sessionStorage.setItem("bodyContent", JSON.stringify(bodyContent)); 243 244 if (analyze_image !== "true") { 245 const isResponseDefault = sessionStorage.getItem("response_default") || false; 246 console.log("isResponseDefault", isResponseDefault); 247 248 // Enviar el mensaje a la API del modelo 249 if ( 250 !isResponseDefault ||
251 isResponseDefault === "false" || 252 isResponseDefault == 0 253 ) { 254 fetch(urlApi, { 255 method: "POST", 256 headers: { 257 "Content-Type": "application/json", 258 }, 259 body: body, 260 }) 261 .then((resp) => resp.json()) 262 .then(async (data) => { 263 const pendingMessage = document.querySelector(".pending_ia"); 264 if (pendingMessage) { 265 pendingMessage.remove(); 266 } 267 268 fecha = `${new Date() 269 .toLocaleDateString() 270 .replaceAll("/", "-")} ${new Date().toLocaleTimeString()}`; 271 272 let responseBot = data.model_response.replace( 273 "<think>\n\n</think>\n\n", 274 "" 275 ); 276 let responseBotOrig = data.model_response.replace( 277 "<think>\n\n</think>\n\n", 278 "" 279 ); 280 responseBot = responseBot.replaceAll("**", ""); 281 responseBot = responseBot.replaceAll("[ ", "["); 282 responseBot = responseBot.replaceAll(" ]", "]"); 283 responseBot = responseBot.replaceAll("[", " "); 284 responseBot = responseBot.replaceAll("]", " "); 285 responseBot = responseBot.replaceAll("(", " "); 286 responseBot = responseBot.replaceAll(")", " "); 287 288 const regexMail = 289 /([a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6})/g; 290 291 // Reemplazar URLs primero 292 responseBot = responseBot.replaceAll( 293 /(https?:\/\/[^\s)",]+[^\s)",.])/g, 294 '<a href="$1" target="_blank" style="cursor: pointer;color: #0082ff;font-size:17px;">$1</a>' 295 ); 296 297 responseBot = responseBot.replaceAll( 298 /\[([^\]]+)\]/g, 299 '<br><strong style="font-weight: bold;">$1</strong><br>' 300 ); 301 302 // Reemplazar correos electrónicos 303 responseBot = responseBot.replaceAll( 304 regexMail, 305 '<a href="mailto:$1" target="_blank" style="cursor: pointer;color: #0082ff;font-size:17px;">$1</a>' 306 ); 307 // Reemplazar saltos de lÃnea con <br> 308 responseBot = responseBot.replaceAll(/\n/g, "<br>"); 309 310 const botMessageElement = document.createElement("li"); 311 botMessageElement.classList.add("message-ia", "bot"); 312 botMessageElement.innerHTML = `<span><img src="data:image/jpeg;base64,${logo_resp}" alt="" style="width: 20px; height: 20px; margin-right: 5px;"/><strong>${titulo_chat}</strong></span><p>${responseBot} <br> <small style="font-size:9px;float:right">${fecha}</small> </p>`; 313 $chatMessages.appendChild(botMessageElement); 314 $body_chat_ia.scrollTop = $body_chat_ia.scrollHeight; 315 $body_chat_ia.scrollIntoView({ behavior: "smooth" }); 316 btnClear.disabled = false; 317 btn_send_message_ia.disabled = false; 318 svg_btn.forEach((svg_btn) => { 319 svg_btn.setAttribute("style", "fill: #ffffff !important;"); 320 }); 321 btnNewChat.disabled = false; 322 323 startInactivityTimer(); // Reiniciar el temporizador después de que el bot responda 324 userMessageForm.placeholder = "Escribe un mensaje..."; 325 326 bodyContent.push({ 327 sender: "bot", 328 text: responseBotOrig, 329 date: fecha, 330 }); 331 332 // sessionStorage.setItem("saveChatIa", $body_chat_ia.innerHTML); 333 await setIndexedDBItem("saveChatIa", $body_chat_ia.innerHTML); 334 335 saveChatDb(bodyContent); 336 sessionStorage.setItem("bodyContent", JSON.stringify(bodyContent)); 337 338 addOptionEnd( 339 "Elige una de las siguientes opciones para continuar:" 340 ); 341 //Sonido de nuevo mensaje 342 const audio = new Audio(url_sonido); 343 audio.play(); 344 }) 345 .catch(async (error) => { 346 const pendingMessage = document.querySelector(".pending_ia"); 347 if (pendingMessage) { 348 pendingMessage.remove(); 349 } 350 351 fecha = `${new Date() 352 .toLocaleDateString() 353 .replaceAll("/", "-")} ${new Date().toLocaleTimeString()}`; 354 355 setTimeout(() => { 356 const botMessageElement = document.createElement("li"); 357 botMessageElement.classList.add("message-ia", "bot"); 358 botMessageElement.innerHTML = `<span><img src="data:image/jpeg;base64,${logo_resp}
358" alt="" style="width: 20px; height: 20px; margin-right: 5px;"/><strong>${titulo_chat}</strong></span><p>Lo siento, ha ocurrido un error en la petición. <br> <small style="font-size:9px;float:right">${fecha}</small></p>`; 359 $chatMessages.appendChild(botMessageElement); 360 $body_chat_ia.scrollTop = $body_chat_ia.scrollHeight; 361 $body_chat_ia.scrollIntoView({ behavior: "smooth" }); 362 addOptionEnd( 363 "Elige una de las siguientes opciones para continuar:" 364 ); 365 }, 1000); 366 367 btnClear.disabled = false; 368 btn_send_message_ia.disabled = false; 369 svg_btn.forEach((svg_btn) => { 370 svg_btn.setAttribute("style", "fill: #ffffff !important"); 371 }); 372 btnNewChat.disabled = false; 373 374 if (btn_send_message_ia && btn_send_message_ia.length > 0) { 375 btn_send_message_ia.disabled = false; 376 btn_send_message_ia.forEach((svg) => { 377 svg.setAttribute("style", "fill: #a7aaad !important"); 378 }); 379 userMessageForm.placeholder = "Escribe un mensaje..."; 380 } 381 382 bodyContent.push({ 383 sender: "bot", 384 text: "Lo siento, ha ocurrido un error en la petición", 385 }); 386 sessionStorage.setItem("bodyContent", JSON.stringify(bodyContent)); 387 388 // sessionStorage.setItem("saveChatIa", $body_chat_ia.innerHTML); 389 await setIndexedDBItem("saveChatIa", $body_chat_ia.innerHTML); 390 391 saveChatDb(bodyContent); 392 startInactivityTimer(); // Reiniciar el temporizador después de que el bot responda 393 const audio = new Audio(url_sonido); 394 audio.play(); 395 }); 396 } else { 397 // cortar en el tercer / https://ragapi.camara.gov.co/chat/completions/camararep 398 const baseUrl = urlApi.split("/").slice(0, 3).join("/"); 399 const msm = sessionStorage.getItem("sub-topic"); 400 const query = encodeURIComponent(msm); 401 const url_default_response = `${baseUrl}/documents/contains?service_name=camararep&query=${query}&limit=1`; 402 console.log("url_default_response", url_default_response); 403 fetch(url_default_response, { 404 method: "GET", 405 headers: { 406 "Content-Type": "application/json", 407 }, 408 }) 409 .then((resp) => resp.json()) 410 .then(async (data) => { 411 const pendingMessage = document.querySelector(".pending_ia"); 412 if (pendingMessage) { 413 pendingMessage.remove(); 414 } 415 if (data.documents.length === 0) { 416 const botMessageElement = document.createElement("li"); 417 botMessageElement.classList.add("message-ia", "bot"); 418 botMessageElement.innerHTML = `<span><img src="data:image/jpeg;base64,${logo_resp}" alt="" style="width: 20px; height: 20px; margin-right: 5px;"/><strong>${titulo_chat}</strong></span><p>No se encontraron resultados.</p>`; 419 $chatMessages.appendChild(botMessageElement); 420 $body_chat_ia.scrollTop = $body_chat_ia.scrollHeight; 421 $body_chat_ia.scrollIntoView({ behavior: "smooth" }); 422 addOptionEnd( 423 "Elige una de las siguientes opciones para continuar:" 424 ); 425 btnClear.disabled = false; 426 btn_send_message_ia.disabled = false; 427 svg_btn.forEach((svg_btn) => { 428 svg_btn.setAttribute( 429 "style", 430 "fill: #ffffff !important;" 431 ); 432 }); 433 btnNewChat.disabled = false; 434 435 startInactivityTimer(); // Reiniciar el temporizador después de que el bot responda 436 userMessageForm.placeholder = "Escribe un mensaje..."; 437 return; 438 } 439 440 fecha = `${new Date() 441 .toLocaleDateString() 442 .replaceAll("/", "-")} ${new Date().toLocaleTimeString()}`; 443 444 let responseBot = data.documents[0].replace( 445 "<think>\n\n</think>\n\n", 446 "" 447 ); 448 let responseBotOrig = data.documents[0].replace( 449 "<think>\n\n</think>\n\n", 450 "" 451 ); 452 responseBot = responseBot.replaceAll("**", ""); 453 responseBot = responseBot.replaceAll("[ ", "["); 454 responseBot = responseBot.replaceAll(" ]", "]"); 455 const regexMail = 456 /([a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6})/g; 457 458 // Reemplazar URLs primero 459 responseBot = responseBot.replaceAll( 460 /(https?:\/\/[^\s)",]+[^\s)",.])/g, 461 '<a href="$1" target="_blank" style="cursor: pointer;color: #0082ff;font-size:17px;">$1</a>' 462 ); 463 464 responseBot = responseBot.replaceAll( 465 /\[([^\]]+)\]/g, 466 '<br><strong style="font-weight: bold;">$1</strong><br>' 467 ); 468 469 // Reemplazar correos electrónicos 470 responseBot = responseBot.replaceAll( 471 regexMail, 472 '<a href="mailto:$1" target="_blank" style="cursor: pointer;color: #0082ff;font-size:17px;">$1</a>' 473 ); 474 // Reemplazar saltos de lÃnea con <br> 475 responseBot = responseBot.replaceAll(/\n/g, "<br>"); 476 477 const botMessageElement = document.createElement("li"); 478 botMessageElement.classList.add("message-ia", "bot"); 479 botMessageElement.innerHTML = `<span><img src="data:image/jpeg;base64,${logo_resp}
479" alt="" style="width: 20px; height: 20px; margin-right: 5px;"/><strong>${titulo_chat}</strong></span><p>${responseBot} <br> <small style="font-size:9px;float:right">${fecha}</small> </p>`; 480 $chatMessages.appendChild(botMessageElement); 481 $body_chat_ia.scrollTop = $body_chat_ia.scrollHeight; 482 $body_chat_ia.scrollIntoView({ behavior: "smooth" }); 483 484 btnClear.disabled = false; 485 btn_send_message_ia.disabled = false; 486 svg_btn.forEach((svg_btn) => { 487 svg_btn.setAttribute("style", "fill: #ffffff !important;"); 488 }); 489 btnNewChat.disabled = false; 490 491 startInactivityTimer(); // Reiniciar el temporizador después de que el bot responda 492 userMessageForm.placeholder = "Escribe un mensaje..."; 493 494 bodyContent.push({ 495 sender: "bot", 496 text: responseBotOrig, 497 date: fecha, 498 }); 499 500 // sessionStorage.setItem("saveChatIa", $body_chat_ia.innerHTML); 501 await setIndexedDBItem("saveChatIa", $body_chat_ia.innerHTML); 502 503 saveChatDb(bodyContent); 504 sessionStorage.setItem("bodyContent", JSON.stringify(bodyContent)); 505 506 addOptionEnd( 507 "Elige una de las siguientes opciones para continuar:" 508 ); 509 510 //Sonido de nuevo mensaje 511 const audio = new Audio(url_sonido); 512 audio.play(); 513 sessionStorage.removeItem("response_default"); 514 }) 515 .catch(async (error) => { 516 sessionStorage.clear("response_default"); 517 518 const pendingMessage = document.querySelector(".pending_ia"); 519 if (pendingMessage) { 520 pendingMessage.remove(); 521 } 522 523 fecha = `${new Date() 524 .toLocaleDateString() 525 .replaceAll("/", "-")} ${new Date().toLocaleTimeString()}`; 526 527 setTimeout(() => { 528 const botMessageElement = document.createElement("li"); 529 botMessageElement.classList.add("message-ia", "bot"); 530 botMessageElement.innerHTML = `<span><img src="data:image/jpeg;base64,${logo_resp}" alt="" style="width: 20px; height: 20px; margin-right: 5px;"/><strong>${titulo_chat}</strong></span><p>Lo siento, ha ocurrido un error en la petición. <br> <small style="font-size:9px;float:right">${fecha}</small></p>`; 531 $chatMessages.appendChild(botMessageElement); 532 $body_chat_ia.scrollTop = $body_chat_ia.scrollHeight; 533 $body_chat_ia.scrollIntoView({ behavior: "smooth" }); 534 addOptionEnd( 535 "Elige una de las siguientes opciones para continuar:" 536 ); 537 }, 1000); 538 539 btnClear.disabled = false; 540 btn_send_message_ia.disabled = false; 541 svg_btn.forEach((svg_btn) => { 542 svg_btn.setAttribute("style", "fill: #ffffff !important"); 543 }); 544 btnNewChat.disabled = false; 545 546 if (btn_send_message_ia && btn_send_message_ia.length > 0) { 547 btn_send_message_ia.disabled = false; 548 btn_send_message_ia.forEach((svg) => { 549 svg.setAttribute("style", "fill: #a7aaad !important"); 550 }); 551 userMessageForm.placeholder = "Escribe un mensaje..."; 552 } 553 554 bodyContent.push({ 555 sender: "bot", 556 text: "Lo siento, ha ocurrido un error en la petición", 557 }); 558 sessionStorage.setItem("bodyContent", JSON.stringify(bodyContent)); 559 560 // sessionStorage.setItem("saveChatIa", $body_chat_ia.innerHTML); 561 await setIndexedDBItem("saveChatIa", $body_chat_ia.innerHTML); 562 563 saveChatDb(bodyContent); 564 startInactivityTimer(); // Reiniciar el temporizador después de que el bot responda 565 const audio = new Audio(url_sonido); 566 audio.play(); 567 }); 568 } 569 } else { 570 571 // Buscar el último mensaje del usuario (no el pending_ia) 572 const userMessages = $chatMessages.querySelectorAll("li.message-ia.user");
573 const lastUserMessage = userMessages[userMessages.length - 1]; 574 575 if (lastUserMessage) { 576 const lastParagraph = lastUserMessage.querySelector("p"); 577 if (lastParagraph) { 578 const userImageUpload = document.querySelector("#userImageUpload"); 579 if (userImageUpload && userImageUpload.files.length > 0) { 580 const imageUrl = URL.createObjectURL(userImageUpload.files[0]); 581 // quitar el small existente (usar regex más especÃfico) 582 lastParagraph.innerHTML = lastParagraph.innerHTML.replace( 583 /<small[^>]*>.*?<\/small>/g, 584 "" 585 ); 586 lastParagraph.innerHTML += `<img src="${imageUrl}" alt="Imagen enviada" style="max-width: 100px; max-height: 100px; border-radius: 5px; margin-top: 5px;"/>`; 587 // Usar la variable fecha ya existente 588 lastParagraph.innerHTML += `<br> <small style="font-size:9px;float:right">${fecha}</small>`; 589 } 590 } 591 } 592 593 const prompt = userMessage; 594 const userImageUpload = document.querySelector("#userImageUpload"); 595 596 // validar que tenga archivo 597 if (!userImageUpload || userImageUpload.files.length === 0) { 598 const pendingMessage = document.querySelector(".pending_ia"); 599 if (pendingMessage) { 600 pendingMessage.remove(); 601 } 602 const botMessageElement = document.createElement("li"); 603 botMessageElement.classList.add("message-ia", "bot"); 604 botMessageElement.innerHTML = `<span><img src="data:image/jpeg;base64,${logo_resp}" alt="" style="width: 20px; height: 20px; margin-right: 5px;"/><strong>${titulo_chat}</strong></span><p style="margin-bottom: 10px;">Por favor, sube una imagen para analizar. <br> <small style="font-size:9px;float:right">${fecha}</small></p>`; 605 $chatMessages.appendChild(botMessageElement); 606 $body_chat_ia.scrollTop = $body_chat_ia.scrollHeight; 607 $body_chat_ia.scrollIntoView({ behavior: "smooth" }); 608 btnClear.disabled = false; 609 btn_send_message_ia.disabled = false; 610 svg_btn.forEach((svg_btn) => { 611 svg_btn.setAttribute("style", "fill: #ffffff !important;"); 612 }); 613 btnNewChat.disabled = false; 614 startInactivityTimer(); // Reiniciar el temporizador después de que el bot responda 615 userMessageForm.placeholder = "Escribe un mensaje..."; 616 bodyContent.push({ 617 sender: "bot", 618 text: "Por favor, sube una imagen para analizar.", 619 }); 620 sessionStorage.setItem("bodyContent", JSON.stringify(bodyContent)); 621 // sessionStorage.setItem("saveChatIa", $body_chat_ia.innerHTML); 622 await setIndexedDBItem("saveChatIa", $body_chat_ia.innerHTML); 623 saveChatDb(bodyContent); 624 return; 625 } 626 const body = new FormData(); 627 body.append("file", userImageUpload.files[0]); 628 // la imagen no puede superar el tamaño 1920x1080 ni de ancho ni de alto 629 630 const extencionValidas = [".jpg", ".jpeg", ".png"]; 631 if (!extencionValidas.includes(userImageUpload.files[0].name.slice(-4))) { 632 const pendingMessage = document.querySelector(".pending_ia"); 633 if (pendingMessage) { 634 pendingMessage.remove(); 635 } 636 const botMessageElement = document.createElement("li"); 637 botMessageElement.classList.add("message-ia", "bot"); 638 botMessageElement.innerHTML = `<span><img src="data:image/jpeg;base64,${logo_resp}" alt="" style="width: 20px; height: 20px; margin-right: 5px;"/><strong>${titulo_chat}</strong></span><p style="margin-bottom: 10px;">Por favor, sube una imagen en formato JPG, JPEG o PNG. <br> <small style="font-size:9px;float:right">${fecha}</small></p>`; 639 $chatMessages.appendChild(botMessageElement); 640 $body_chat_ia.scrollTop = $body_chat_ia.scrollHeight; 641 $body_chat_ia.scrollIntoView({ behavior: "smooth" }); 642 btnClear.disabled = false; 643 btn_send_message_ia.disabled = false; 644 svg_btn.forEach((svg_btn) => { 645 svg_btn.setAttribute("style", "fill: #ffffff !important;"); 646 }); 647 btnNewChat.disabled = false; 648 startInactivityTimer(); // Reiniciar el temporizador después de que el bot responda 649 userMessageForm.placeholder = 650 "Por favor, sube una imagen para analizar."; 651 bodyContent.push({ 652 sender: "bot", 653 text: "Por favor, sube una imagen en formato JPG, JPEG o PNG.", 654 }); 655 sessionStorage.setItem("bodyContent", JSON.stringify(bodyContent)); 656 // sessionStorage.setItem("saveChatIa", $body_chat_ia.innerHTML); 657 await setIndexedDBItem("saveChatIa", $body_chat_ia.innerHTML); 658 saveChatDb(bodyContent); 659 return; 660 } 661 662 if (userImageUpload.files[0].size > 1920 * 1080) { 663 const pendingMessage = document.querySelector(".pending_ia"); 664 if (pendingMessage) { 665 pendingMessage.remove(); 666 } 667 const botMessageElement = document.createElement("li"); 668 botMessageElement.classList.add("message-ia", "bot"); 669 botMessageElement.innerHTML = `<span><img src="data:image/jpeg;base64,${logo_resp}
669" alt="" style="width: 20px; height: 20px; margin-right: 5px;"/><strong>${titulo_chat}</strong></span><p style="margin-bottom: 10px;">La imagen no puede superar el tamaño de 1920x1080 pÃxeles. Por favor, sube una imagen más pequeña. <br> <small style="font-size:9px;float:right">${fecha}</small></p>`; 670 $chatMessages.appendChild(botMessageElement); 671 $body_chat_ia.scrollTop = $body_chat_ia.scrollHeight; 672 $body_chat_ia.scrollIntoView({ behavior: "smooth" }); 673 btnClear.disabled = false; 674 btn_send_message_ia.disabled = false; 675 svg_btn.forEach((svg_btn) => { 676 svg_btn.setAttribute("style", "fill: #ffffff !important;"); 677 }); 678 btnNewChat.disabled = false; 679 startInactivityTimer(); // Reiniciar el temporizador después de que el bot responda 680 userMessageForm.placeholder = 681 "Por favor, sube una imagen para analizar."; 682 bodyContent.push({ 683 sender: "bot", 684 text: "La imagen no puede superar el tamaño de 1920x1080 pÃxeles. Por favor, sube una imagen más pequeña.", 685 }); 686 sessionStorage.setItem("bodyContent", JSON.stringify(bodyContent)); 687 // sessionStorage.setItem("saveChatIa", $body_chat_ia.innerHTML); 688 await setIndexedDBItem("saveChatIa", $body_chat_ia.innerHTML); 689 saveChatDb(bodyContent); 690 // Limpiar el input de archivo después de enviar 691 userImageUpload.value = ""; 692 return; 693 } 694 695 userImageUpload.value = ""; 696 697 const svgSelectImage = document.getElementById("svgSelectImage"); 698 699 fetch( 700 `https://ragapi.camara.gov.co/search-with-image?prompt=busca información&service_name=camararep`, 701 { 702 method: "POST", 703 body: body, 704 } 705 ) 706 .then((resp) => resp.json()) 707 .then(async (data) => { 708 const pendingMessage = document.querySelector(".pending_ia"); 709 if (pendingMessage) { 710 pendingMessage.remove(); 711 } 712 713 fecha = `${new Date() 714 .toLocaleDateString() 715 .replaceAll("/", "-")} ${new Date().toLocaleTimeString()}`; 716 let responseBot = data.model_response.replace( 717 "<think>\n\n</think>\n\n", 718 "" 719 ); 720 let responseBotOrig = data.model_response.replace( 721 "<think>\n\n</think>\n\n", 722 "" 723 ); 724 responseBot = responseBot.replaceAll("**", ""); 725 responseBot = responseBot.replaceAll("[ ", "["); 726 responseBot = responseBot.replaceAll(" ]", "]"); 727 const regexMail = /([a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6})/g; 728 729 // Reemplazar URLs primero 730 responseBot = responseBot.replaceAll( 731 /(https?:\/\/[^\s)",]+[^\s)",.])/g, 732 '<a href="$1" target="_blank" style="cursor: pointer;color: #0082ff;font-size:17px;">$1</a>' 733 ); 734 735 responseBot = responseBot.replaceAll( 736 /\[([^\]]+)\]/g, 737 '<br><strong style="font-weight: bold;">$1</strong><br>' 738 ); 739 740 // Reemplazar correos electrónicos 741 responseBot = responseBot.replaceAll( 742 regexMail, 743 '<a href="mailto:$1" target="_blank" style="cursor: pointer;color: #0082ff;font-size:17px;">$1</a>' 744 ); 745 // Reemplazar saltos de lÃnea con <br> 746 responseBot = responseBot.replace(/\n/g, "<br>"); 747 748 const botMessageElement = document.createElement("li"); 749 botMessageElement.classList.add("message-ia", "bot"); 750 botMessageElement.innerHTML = `<span><img src="data:image/jpeg;base64,${logo_resp}" alt="" style="width: 20px; height: 20px; margin-right: 5px;"/><strong>${titulo_chat}</strong></span><p>${responseBot} <br> <small style="font-size:9px;float:right">${fecha}</small> </p>`; 751 $chatMessages.appendChild(botMessageElement); 752 $body_chat_ia.scrollTop = $body_chat_ia.scrollHeight; 753 $body_chat_ia.scrollIntoView({ behavior: "smooth" }); 754 btnClear.disabled = false; 755 btn_send_message_ia.disabled = false;
756 svg_btn.forEach((svg_btn) => { 757 svg_btn.setAttribute("style", "fill: #ffffff !important;"); 758 }); 759 btnNewChat.disabled = false; 760 761 startInactivityTimer(); // Reiniciar el temporizador después de que el bot responda 762 userMessageForm.placeholder = 763 "Por favor, sube una imagen para analizar."; 764 765 bodyContent.push({ 766 sender: "bot", 767 text: responseBotOrig, 768 date: fecha, 769 }); 770 771 // sessionStorage.setItem("saveChatIa", $body_chat_ia.innerHTML); 772 await setIndexedDBItem("saveChatIa", $body_chat_ia.innerHTML); 773 774 saveChatDb(bodyContent); 775 sessionStorage.setItem("bodyContent", JSON.stringify(bodyContent)); 776 777 addOptionEnd("Elige una de las siguientes opciones para continuar:"); 778 //Sonido de nuevo mensaje 779 const audio = new Audio(url_sonido); 780 audio.play(); 781 // sessionStorage.setItem("analyze-image", "false"); 782 }) 783 .catch(async (error) => { 784 // sessionStorage.setItem("analyze-image", "false"); 785 786 const pendingMessage = document.querySelector(".pending_ia"); 787 if (pendingMessage) { 788 pendingMessage.remove(); 789 } 790 791 fecha = `${new Date() 792 .toLocaleDateString() 793 .replaceAll("/", "-")} ${new Date().toLocaleTimeString()}`; 794 795 setTimeout(() => { 796 const botMessageElement = document.createElement("li"); 797 botMessageElement.classList.add("message-ia", "bot"); 798 botMessageElement.innerHTML = `<span><img src="data:image/jpeg;base64,${logo_resp}" alt="" style="width: 20px; height: 20px; margin-right: 5px;"/><strong>${titulo_chat}</strong></span><p>Lo siento, ha ocurrido un error en la petición. <br> <small style="font-size:9px;float:right">${fecha}</small></p>`; 799 $chatMessages.appendChild(botMessageElement); 800 $body_chat_ia.scrollTop = $body_chat_ia.scrollHeight; 801 $body_chat_ia.scrollIntoView({ behavior: "smooth" }); 802 addOptionEnd( 803 "Elige una de las siguientes opciones para continuar:" 804 ); 805 }, 1000); 806 807 btnClear.disabled = false; 808 btn_send_message_ia.disabled = false; 809 svg_btn.forEach((svg_btn) => { 810 svg_btn.setAttribute("style", "fill: #ffffff !important"); 811 }); 812 btnNewChat.disabled = false; 813 814 if (btn_send_message_ia && btn_send_message_ia.length > 0) { 815 btn_send_message_ia.disabled = false; 816 btn_send_message_ia.forEach((svg) => { 817 svg.setAttribute("style", "fill: #a7aaad !important"); 818 }); 819 userMessageForm.placeholder = 820 "Por favor, sube una imagen para analizar."; 821 } 822 823 bodyContent.push({ 824 sender: "bot", 825 text: "Lo siento, ha ocurrido un error en la petición", 826 }); 827 sessionStorage.setItem("bodyContent", JSON.stringify(bodyContent)); 828 829 // sessionStorage.setItem("saveChatIa", $body_chat_ia.innerHTML); 830 await setIndexedDBItem("saveChatIa", $body_chat_ia.innerHTML); 831 832 saveChatDb(bodyContent); 833 startInactivityTimer(); // Reiniciar el temporizador después de que el bot responda 834 const audio = new Audio(url_sonido); 835 audio.play(); 836 }); 837 if (svgSelectImage) { 838 // Regresar el SVG a su estado original (blanco) 839 svgSelectImage.setAttribute("fill", "#ffffff"); 840 841 // Regresar el path original del clip 842 const pathElement = svgSelectImage.querySelector("path"); 843 if (pathElement) { 844 pathElement.setAttribute( 845 "d", 846 "M720-330q0 104-73 177T470-80q-104 0-177-73t-73-177v-370q0-75 52.5-127.5T400-880q75 0 127.5 52.5T580-700v350q0 46-32 78t-78 32q-46 0-78-32t-32-78v-370h80v370q0 13 8.5 21.5T470-320q13 0 21.5-8.5T500-350v-350q-1-42-29.5-71T400-800q-42 0-71 29t-29 71v370q-1 71 49 120.5T470-160q70 0 119-49.5T640-330v-390h80v390Z" 847 ); 848 } 849 } 850 } 851 $form.reset(); 852 }); 853 854 // función para adicionar opciones al final del chat 855 async function addOptionEnd(response) { 856 console.log("addOptionEnd response:", response); 857 fecha = `${new Date() 858 .toLocaleDateString() 859 .replaceAll("/", "-")} ${new Date().toLocaleTimeString()}`; 860 861 let list_link_contact_array = JSON.parse(list_link_contact); 862 863 let listOptions = []; 864 865 for (let i = 0; i < list_link_contact_array.length; i++) { 866 if (list_link_contact_array[i].estado === "1") { 867 listOptions.push({ 868 area: list_link_contact_array[i].area, 869 orden: list_link_contact_array[i].orden, 870 isForm: list_link_contact_array[i].isForm || false, 871 link: list_link_contact_array[i].linkchat, 872 }); 873 } 874 } 875 876 877 const botMessageElement = document.createElement("li"); 878 botMessageElement.classList.add("message-ia", "bot"); 879 880 // Contenedor principal fuera del párrafo 881 const messageContainer = document.createElement("div"); 882 messageContainer.style.width = "100%"; 883 messageContainer.style.paddingTop = "15px"; 884 885 // Encabezado del mensaje 886 const header = document.createElement("div"); 887 header.style.display = "flex"; 888 header.style.alignItems = "center"; 889 890 header.innerHTML = ` 891 <span> 892 <img src="data:image/jpeg;base64,${logo_resp}"
893 alt="" style="width: 20px; height: 20px; margin-right: 5px;"/> 894 <strong>${titulo_chat}</strong> 895 </span> 896 897 `; 898 899 // Texto del mensaje 900 const messageText = document.createElement("p"); 901 messageText.className = "messageTextP"; 902 903 messageText.style.borderRadius = "6px 6px 0 0 "; 904 905 messageText.style.margin = "2px 0 0 0"; 906 messageText.style.marginBottom = "0 !important"; 907 messageText.innerHTML = response ? response : `<br>`; 908 909 // Contenedor de botones 910 const buttonsContainer = document.createElement("div"); 911 buttonsContainer.style.backgroundColor = "#e4e6eb"; 912 buttonsContainer.style.display = "flex"; 913 buttonsContainer.style.flexWrap = "wrap"; 914 buttonsContainer.style.gap = "10px"; 915 buttonsContainer.style.padding = "10px"; 916 917 // Crear botones 918 listOptions.forEach((options) => { 919 const button = document.createElement("button"); 920 button.className = "itemTopic"; 921 button.style.cssText = ` 922 border: 1px solid ${color_chat}; 923 cursor: pointer; 924 text-decoration: none; 925 padding: 10px 15px; 926 border-radius: 11px; 927 text-align: center; 928 font-size: 14px; 929 flex-grow: 1; 930 min-width: 120px; 931 margin: 0; 932 `; 933 934 // Asignar la función correcta según el texto 935 if (options.area == "Terminar y cerrar chat") { 936 button.onclick = function () { 937 disabledButtons(button); 938 closeChat( 939 "Gracias por utilizar nuestro servicio. El chat ha sido cerrado.", 940 2000 941 ); 942 }; 943 } else if (options.area == "Volver al menu anterior") { 944 button.onclick = function () { 945 disabledButtons(button); 946 const topicChatbot = 947 sessionStorage.getItem("message_init_tema") || null; 948 if (topicChatbot) { 949 getListSubTopic(JSON.parse(topicChatbot, null)); 950 } 951 }; 952 } else if (options.area == "Volver al menu principal") { 953 button.onclick = function () { 954 disabledButtons(button); 955 listTema(); 956 }; 957 } else if ( 958 options.area == 959 "Para una consulta más profunda por favor consulte Grifo" 960 ) { 961 button.setAttribute("data-link", "https://www.camara.gov.co/"); 962 button.onclick = function () { 963 disabledButtons(button); 964 window.open(options.link, "_blank"); 965 }; 966 } else if (options.isForm == "1") { 967 button.setAttribute("data-link", options.link || ""); 968 button.onclick = function () { 969 disabledButtons(button); 970 openFormContact(options.link); 971 }; 972 } 973 button.textContent = options.area; 974 buttonsContainer.appendChild(button); 975 }); 976 977 // Pie de fecha 978 const footer = document.createElement("div"); 979 footer.style.backgroundColor = "#e4e6eb"; 980 footer.style.fontSize = "9px"; 981 footer.style.width = "100%;"; 982 footer.style.display = "flex"; 983 984 footer.style.justifyContent = "flex-end"; 985 footer.style.padding = "10px"; 986 footer.textContent = fecha; 987 footer.style.marginBottom = "15px"; 988 footer.style.borderRadius = "0 0 6px 6px"; 989 990 // Ensamblar el mensaje 991 messageContainer.appendChild(header); 992 messageContainer.appendChild(messageText); 993 messageContainer.appendChild(buttonsContainer); 994 messageContainer.appendChild(footer); 995 botMessageElement.appendChild(messageContainer); 996 997 $chatMessages.appendChild(botMessageElement); 998 $body_chat_ia.scrollTop = $body_chat_ia.scrollHeight; 999 $body_chat_ia.scrollIntoView({ behavior: "smooth" }); 1000 // sessionStorage.setItem("saveChatIa", $body_chat_ia.innerHTML); 1001 await setIndexedDBItem("saveChatIa", $body_chat_ia.innerHTML); 1002 } 1003 1004 1005 function disabledButtons(button) { 1006 button.disabled = true; 1007 button.style.backgroundColor = "rgb(74, 144, 226) !important"; 1008 1009 // Verificar que el botón tenga un padre antes de acceder a sus hermanos 1010 if (button.parentNode) { 1011 //botones hermanos 1012 const siblings = Array.from(button.parentNode.children).filter( 1013 (child) => child !== button 1014 );
1015 siblings.forEach((sibling) => { 1016 sibling.disabled = true; 1017 sibling.style.setProperty("background-color", "rgb(173, 177, 187)", "important"); 1018 sibling.style.cursor = "not-allowed"; 1019 }); 1020 } 1021 } 1022 1023 // Define el temporizador globalmente 1024 window.inactivityTimeout = null; 1025 1026 // Función para mostrar el mensaje de despedida 1027 async function showGoodbyeMessage() { 1028 let fecha = `${new Date() 1029 .toLocaleDateString() 1030 .replaceAll("/", "-")} ${new Date().toLocaleTimeString()}`; 1031 1032 const textMsm = `¡Parece que has estado inactivo por un tiempo! Si necesitas algo más, estaré aquà para ayudarte. ${text_link_whatsapp} 1033 <br> <small style="font-size:9px;float:right">${fecha}</small>`; 1034 const goodbyeMessageElement = document.createElement("li"); 1035 goodbyeMessageElement.classList.add("message-ia", "bot"); 1036 goodbyeMessageElement.innerHTML = `<span><img src="data:image/jpeg;base64,${logo_resp}" 1037 alt="" style="width: 20px; height: 20px; margin-right: 5px;"/><strong>${titulo_chat}</strong></span><p>${textMsm}</p>`; 1038 1039 $chatMessages.appendChild(goodbyeMessageElement); 1040 $body_chat_ia.scrollTop = $body_chat_ia.scrollHeight; 1041 $body_chat_ia.scrollIntoView({ behavior: "smooth" }); 1042 1043 sessionStorageBodyContent = sessionStorage.getItem("bodyContent"); 1044 1045 bodyContent = JSON.parse(sessionStorageBodyContent); 1046 bodyContent.push({ 1047 sender: "bot", 1048 text: textMsm, 1049 }); 1050 saveChatDb(bodyContent); 1051 closeChat( 1052 `El chat ha sido cerrado por inactividad. Si tienes alguna otra pregunta, no dudes en contactarnos.`, 1053 15000 1054 ); 1055 // sessionStorage.setItem("bodyContent", JSON.stringify(bodyContent)); 1056 1057 // sessionStorage.setItem("saveChatIa", $body_chat_ia.innerHTML); 1058 await setIndexedDBItem("saveChatIa", $body_chat_ia.innerHTML); 1059 } 1060 1061 // Función para cerrar el chat 1062 function closeChat(message, timeClose) { 1063 const chatId = sessionStorage.getItem("&&&%%%$$$$&&$$####$$$####%$"); 1064 1065 fetch(ajax_object.ajaxurl, { 1066 method: "POST", 1067 headers: { 1068 "Content-Type": "application/x-www-form-urlencoded", 1069 }, 1070 body: new URLSearchParams({ 1071 action: "close_chat", 1072 chat_id: chatId, 1073 nonce: ajax_object.nonce, 1074 }), 1075 }) 1076 .then((response) => response.json()) 1077 .then((data) => { 1078 if (data.success) { 1079 let fecha = `${new Date() 1080 .toLocaleDateString() 1081 .replaceAll("/", "-")} ${new Date().toLocaleTimeString()}`; 1082 const textMsm = `${message} 1083 <br> <small style="font-size:9px;float:right">${fecha}</small>`; 1084 const goodbyeMessageElement = document.createElement("li"); 1085 goodbyeMessageElement.classList.add("message-ia", "bot"); 1086 goodbyeMessageElement.innerHTML = `<span><img src="data:image/jpeg;base64,${logo_resp}" 1087 alt="" style="width: 20px; height: 20px; margin-right: 5px;margin-button:10px "/><strong>${titulo_chat}</strong></span><p>${textMsm}</p>`; 1088 1089 $chatMessages.appendChild(goodbyeMessageElement); 1090 $body_chat_ia.scrollTop = $body_chat_ia.scrollHeight; 1091 $body_chat_ia.scrollIntoView({ behavior: "smooth" }); 1092 1093 sessionStorageBodyContent = sessionStorage.getItem("bodyContent"); 1094 1095 bodyContent = JSON.parse(sessionStorageBodyContent); 1096 bodyContent.push({ 1097 sender: "bot", 1098 text: textMsm, 1099 }); 1100 1101 setTimeout(() => { 1102 const btn_new_message_ia = document.querySelector( 1103 "#btn-new_message_ia" 1104 ); 1105 //simular el click del boton de nuevo mensaje 1106 if (btn_new_message_ia) { 1107 btn_new_message_ia.click(); 1108 } 1109 }, timeClose || 4000); 1110 } else { 1111 } 1112 }) 1113 .catch((error) => { 1114 console.error("Error en la solicitud AJAX:", error); 1115 }); 1116 } 1117 window.closeChat = closeChat; // Exponer la función para que pueda ser llamada desde fuera 1118 1119 // Función para iniciar el temporizador de inactividad 1120 function startInactivityTimer() { 1121 const timeInMinutes = time_inactivity; // Tiempo de inactividad en minutos time_inactivity 1122 clearTimeout(window.inactivityTimeout); // Limpia cualquier temporizador previo 1123 1124 window.inactivityTimeout = setTimeout(() => {
1125 const lastAdvisorMessageTime = parseInt( 1126 sessionStorage.getItem("lastAdvisorMessageTime"), 1127 10 1128 ); 1129 const lastUserMessageTime = 1130 parseInt(sessionStorage.getItem("lastUserMessageTime"), 10) || 0; 1131 1132 // Mostrar mensaje solo si no está con un asesor 1133 if (sessionStorage.getItem("chatWithAdvisor") !== "true") { 1134 showGoodbyeMessage(); // Mostrar mensaje de despedida 1135 } 1136 }, timeInMinutes * 60 * 1000); // Convertir minutos a milisegundos 1137 } 1138 1139 // funcion para guardar el chat en la base de datos 1140 function saveChatDb(bodyContent) { 1141 const chat_new = sessionStorage.getItem("exit_chat") ? false : true; 1142 if (typeof chatbotAjax !== "undefined") { 1143 fetch(chatbotAjax.ajax_url, { 1144 method: "POST", 1145 headers: { 1146 "Content-Type": "application/x-www-form-urlencoded", 1147 // "Content-Type": "application/json", 1148 }, 1149 body: new URLSearchParams({ 1150 action: "save_chat", 1151 security: chatbotAjax.nonce, 1152 bodyContent: JSON.stringify(bodyContent), 1153 user_id: sessionStorage.getItem("idUser_chatbot"), 1154 topic: sessionStorage.getItem("topic_chatbot"), 1155 chat_new: chat_new, 1156 }), 1157 }) 1158 .then((response) => response.json()) 1159 .then((result) => { 1160 if (result.success) { 1161 sessionStorage.setItem("exit_chat", "true"); 1162 sessionStorage.setItem("&&&%%%$$$$&&$$####$$$####%$", result.data); 1163 } else { 1164 console.log("Error al guardar el chat: " + result); 1165 } 1166 }) 1167 .catch((error) => { 1168 console.error("Error en la solicitud AJAX:", error); 1169 }); 1170 } else { 1171 // console.error("Error: chatbotAjax no está definido."); 1172 } 1173 } 1174}); 1175 1176 1177//Funcion para satisfacción del usuario 1178async function handleSatisfactionResponse(response) { 1179 const chatId = sessionStorage.getItem("&&&%%%$$$$&&$$####$$$####%$"); // Obtén el ID del chat desde el sessionStorage 1180 if (!chatId) { 1181 console.error("No se encontró el ID del chat en el sessionStorage."); 1182 return; 1183 } 1184 1185 // Mensajes personalizados según la respuesta del usuario 1186 const userResponseMessage = { 1187 sender: "user", 1188 text: `${response}`, 1189 }; 1190 1191 const advisorResponseMessage = { 1192 sender: "Asesor", 1193 text: 1194 response === "SÃ" 1195 ? "Gracias por tu respuesta. ¡Nos alegra haberte ayudado! Que tengas un excelente dÃa." 1196 : "Proporciona más detalles de tu consulta para poder ayudarte.", 1197 }; 1198 1199 // Desactivar los botones de satisfacción 1200 const satisfactionButtons = document.querySelectorAll( 1201 'button[onclick^="satisfactionQuestion"]' 1202 ); 1203 if (satisfactionButtons.length > 0) { 1204 satisfactionButtons.forEach((button) => { 1205 button.disabled = true; // Desactivar el botón 1206 button.style.cursor = "not-allowed"; 1207 button.style.opacity = "0.5"; 1208 }); 1209 } 1210 1211 // Mostrar los mensajes en el chat 1212 const fecha = `${new Date() 1213 .toLocaleDateString() 1214 .replaceAll("/", "-")} ${new Date().toLocaleTimeString()}`; 1215 const userMessageElement = document.createElement("li"); 1216 userMessageElement.classList.add("message-ia", "user"); 1217 userMessageElement.innerHTML = `<span><img src="${chatbotSettings.img_chat_user}" alt="" style="width: 20px; height: 20px; margin-right: 5px;"/><strong>Tú</strong></span><p>${userResponseMessage.text} <br> <small style="font-size:9px;float:right;">${fecha}</small> </p>`; 1218 document.querySelector("#chatMessages").appendChild(userMessageElement); 1219 document.querySelector("#body-chat_ia").scrollTop = 1220 document.querySelector("#body-chat_ia").scrollHeight; 1221 1222 const advisorMessageElement = document.createElement("li"); 1223 advisorMessageElement.classList.add("message-ia", "bot"); 1224 advisorMessageElement.innerHTML = `<span><img src="data:image/jpeg;base64,${chatbotSettings.logo_resp}" alt="" style="width: 20px; height: 20px; margin-right: 5px;"/><strong>Asesor</strong></span><p>${advisorResponseMessage.text} <br> <small style="font-size:9px;float:right">${fecha}</small> </p>`; 1225 document.querySelector("#chatMessages").appendChild(advisorMessageElement); 1226 document.querySelector("#body-chat_ia").scrollTop = 1227 document.querySelector("#body-chat_ia").scrollHeight; 1228 1229 // Guardar los mensajes en el sessionStorage 1230 const bodyContent = JSON.parse(sessionStorage.getItem("bodyContent")) || []; 1231 bodyContent.push(userResponseMessage, advisorResponseMessage); 1232 1233 // Actualizar el estado del chat en la base de datos si respondió "SÃ" 1234 if (response === "SÃ") { 1235 fetch(ajax_object.ajaxurl, { 1236 method: "POST", 1237 headers: { 1238 "Content-Type": "application/x-www-form-urlencoded", 1239 }, 1240 body: new URLSearchParams({ 1241 action: "update_chat_status", 1242 nonce: ajax_object.nonce, 1243 chat_id: chatId, 1244 resolved: 1, // Valor para indicar que el chat está resuelto 1245 }), 1246 }) 1247 .then((response) => response.json()) 1248 .then((data) => { 1249 if (data.success) { 1250 console.log( 1251 "Estado del chat actualizado correctamente:", 1252 data.message 1253 ); 1254 } else { 1255 console.error( 1256 "Error al actualizar el estado del chat:", 1257 data.message 1258 ); 1259 } 1260 }) 1261 .catch((error) => { 1262 console.error( 1263 "Error en la solicitud AJAX al actualizar el estado:", 1264 error 1265 ); 1266 }); 1267 1268 // Iniciar el temporizador de 10 segundos después de "SÃ" 1269 setTimeout(() => { 1270 newChat(); // Llama a la función para limpiar y reiniciar el chat 1271 }, 10000); // 10 segundos 1272 } 1273 1274 // Guardar los mensajes en la base de datos 1275 fetch(chatbotAjax.ajax_url, { 1276 method: "POST", 1277 headers: { 1278 "Content-Type": "application/x-www-form-urlencoded", 1279 }, 1280 body: new URLSearchParams({ 1281 action: "save_chat", 1282 security: chatbotAjax.nonce, 1283 bodyContent: JSON.stringify(bodyContent), 1284 chatId: chatId, 1285 actionUpdate: true, // Indica que es una actualización 1286 }), 1287 }) 1288 .then((response) => response.json()) 1289 .then((result) => { 1290 if (result.success) { 1291 console.log("Chat y estado actualizados correctamente."); 1292 } else { 1293 console.error("Error al guardar los mensajes:", result.message); 1294 } 1295 }) 1296 .catch((error) => { 1297 console.error( 1298 "Error en la solicitud AJAX al guardar los mensajes:", 1299 error 1300 ); 1301 });
1302 1303 // Actualizar sessionStorage con los nuevos mensajes 1304 sessionStorage.setItem("bodyContent", JSON.stringify(bodyContent)); 1305 1306 // sessionStorage.setItem( 1307 // "saveChatIa", 1308 // document.getElementById("body-chat_ia").innerHTML 1309 // ); 1310 1311 await setIndexedDBItem("saveChatIa", document.getElementById("body-chat_ia").innerHTML); 1312} 1313 1314// Abre o crea la base de datos IndexedDB para simular sessionStorage 1315function openIndexedDB() { 1316 return new Promise((resolve, reject) => { 1317 const request = indexedDB.open("chatbotDB", 1); 1318 1319 request.onupgradeneeded = (event) => { 1320 const db = event.target.result; 1321 if (!db.objectStoreNames.contains("chatsIA")) { 1322 db.createObjectStore("chatsIA", { keyPath: "key" }); // key = saveChatIa 1323 } 1324 }; 1325 1326 request.onsuccess = () => resolve(request.result); 1327 request.onerror = () => reject(request.error); 1328 }); 1329} 1330// Simular sessionStorage.setItem 1331async function setIndexedDBItem(key, value) { 1332 const db = await openIndexedDB(); 1333 return new Promise((resolve, reject) => { 1334 const tx = db.transaction("chatsIA", "readwrite"); 1335 const store = tx.objectStore("chatsIA"); 1336 const request = store.put({ key, value }); // sobreescribe si ya existe 1337 1338 request.onsuccess = () => resolve(true); 1339 request.onerror = () => reject(request.error); 1340 }); 1341} 1342// Simular sessionStorage.getItem 1343async function getIndexedDBItem(key) { 1344 const db = await openIndexedDB(); 1345 return new Promise((resolve, reject) => { 1346 const tx = db.transaction("chatsIA", "readonly"); 1347 const store = tx.objectStore("chatsIA"); 1348 const request = store.get(key); 1349 1350 request.onsuccess = () => { 1351 const result = request.result; 1352 resolve(result ? result.value : null); 1353 }; 1354 request.onerror = () => reject(request.error); 1355 }); 1356} 1357 1358// Simular sessionStorage.removeItem 1359async function removeIndexedDBItem(key) { 1360 const db = await openIndexedDB(); 1361 return new Promise((resolve, reject) => { 1362 const tx = db.transaction("chatsIA", "readwrite"); 1363 const store = tx.objectStore("chatsIA"); 1364 const request = store.delete(key); 1365 1366 request.onsuccess = () => resolve(true); 1367 request.onerror = () => reject(request.error); 1368 }); 1369} 1370 1371window.removeIndexedDBItem = removeIndexedDBItem;
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.