PageSourceSearch

https://www.camara.gov.co/wp-content/plugins/IAchatbotHCR/public/assets/js/api-alpha.js

js camara.gov.co collected 2026-10-02 03:07:43 UTC 56,731 bytes, 1,371 lines download raw bytes

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.