Este es un indicador de código personalizado. Cambie a Vista Previa o publique la página para ver cómo funciona su código.
Doble clic para editar
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8" />
<title>Asistente IA360 – Alineado Final</title>
<style>
body { margin: 0; font-family: Arial, sans-serif; }
.floating-messages {
position: fixed;
bottom: 55px; /* alineado con el centro de la burbuja 80x80 */
right: 135px; /* separación de 15px + centrado */
z-index: 2147483647;
pointer-events: none;
}
.floating-messages * {
pointer-events: auto;
}
.message-bubble {
background: #FFE8F0;
color: #000;
padding: 14px 42px 14px 18px;
border-radius: 28px;
font: 16px/22px "Helvetica Neue", Arial, sans-serif;
box-shadow: 0 2px 6px rgba(0,0,0,.18);
display: flex;
align-items: center;
position: relative;
cursor: pointer;
opacity: 0;
transform: translateY(20px);
animation: fadeInUp 1.2s ease-out forwards;
}
.close-button {
position: absolute;
right: 14px;
top: 50%;
transform: translateY(-50%);
width: 20px;
height: 20px;
border-radius: 50%;
background: #fff;
color: #666;
font-size: 16px;
font-weight: 700;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
}
@keyframes fadeInUp {
from { opacity: 0; transform: translateY(30px) }
to { opacity: 1; transform: translateY(0) }
}
@keyframes vibrate {
0%,100% { transform: translateX(0) }
25%,75% { transform: translateX(-4px) }
50% { transform: translateX(4px) }
}
.vibrate { animation: vibrate 0.35s linear }
#sonidoOverlay {
position: fixed;
top: 0; left: 0;
width: 100vw; height: 100vh;
z-index: 99999999;
background: transparent;
cursor: pointer;
}
</style>
</head>
<body>
<!-- Activador de sonido -->
<div id="sonidoOverlay" onclick="activarSonidoDesdeOverlay()"></div>
<!-- Mensaje lateral -->
<div id="messageWindow" class="floating-messages">
<div id="assistantMessages"></div>
</div>
<!-- Sonido -->
<audio id="dingSound" preload="auto">
<source src="https://us-ms.gr-cdn.com/getresponse-wqhda/recordings/cb51fa24-02e9-4aaa-9795-3db42ecfe475.mp3" type="audio/mpeg">
</audio>
<script>
const USER_ID = "66e4639e03dc1207729d8339";
const staticMessage = "¿En qué puedo ayudarte?";
let sonidoHabilitado = false;
let vibrationCount = 0;
const maxSonidos = 4;
function activarSonidoDesdeOverlay() {
const overlay = document.getElementById("sonidoOverlay");
if (overlay) overlay.remove();
activarSonido();
}
function activarSonido() {
sonidoHabilitado = true;
vibrateOnce();
}
function vibrateOnce() {
const w = document.getElementById("messageWindow");
if (!w || w.style.display === "none") return;
w.classList.add("vibrate");
setTimeout(() => w.classList.remove("vibrate"), 350);
if (sonidoHabilitado && vibrationCount < maxSonidos) {
const audio = document.getElementById("dingSound");
audio.pause(); audio.currentTime = 0;
audio.play().catch(() => {});
setTimeout(() => {
audio.pause(); audio.currentTime = 0;
audio.play().catch(() => {});
}, 300);
vibrationCount++;
}
}
function showMessage() {
const cont = document.getElementById("assistantMessages");
cont.innerHTML = "";
const bubble = document.createElement("div");
bubble.className = "message-bubble";
bubble.innerHTML = `
<span>${staticMessage}</span>
<span class="close-button" onclick="hideMessages(event)">×</span>
`;
bubble.addEventListener("click", () => {
if (window.voiceflow?.chat) window.voiceflow.chat.open();
hideMessages();
}, { passive: true });
cont.appendChild(bubble);
document.getElementById("messageWindow").style.display = "block";
vibrateOnce();
}
function hideMessages(e) {
if (e) e.stopPropagation();
document.getElementById("messageWindow").style.display = "none";
}
window.addEventListener("load", () => {
showMessage();
setInterval(vibrateOnce, 5000);
});
window.addEventListener("message", e => {
if (typeof e.data !== "string") return;
if (e.data.includes('"type":"voiceflow:open"')) {
hideMessages();
document.querySelectorAll("button.vfrc-button.vfrc-launcher")
.forEach(btn => btn.style.setProperty("display","none","important"));
}
if (e.data.includes('"type":"voiceflow:close"')) {
document.querySelectorAll("button.vfrc-button.vfrc-launcher")
.forEach(btn => btn.style.removeProperty("display"));
}
});
function elevateAssistant() {
const Z = 1000000;
document.querySelectorAll('vfrc-widget,[class*="vfrc-widget"],iframe[src*="voiceflow"]')
.forEach(el => {
el.style.setProperty("position","fixed","important");
el.style.setProperty("bottom","20px","important");
el.style.setProperty("right","20px","important");
el.style.setProperty("z-index",Z,"important");
el.style.setProperty("pointer-events","auto","important");
el.style.setProperty("display","block","important");
});
}
new MutationObserver(elevateAssistant).observe(document.body, { childList: true, subtree: true });
</script>
<!-- Voiceflow con burbuja 80x80 y halo, auto–start + reinicio conversación -->
<script type="text/javascript">
(function(d){
const css = `
@keyframes pulse {
0%,100% { transform: scale(1); box-shadow: 0 0 0 0 #FF0507, 0 0 14px #FF05074D }
50% { transform: scale(1.07); box-shadow: 0 0 0 18px #FF0507FF, 0 0 14px #FF050733 }
}
.vfrc-launcher {
width: 80px!important; height: 80px!important;
bottom: 40px!important; right: 24px!important;
position: fixed!important; display: flex!important;
align-items: center!important; justify-content: center!important;
background: transparent!important;
box-shadow: 0 0 0 0 #FF0507, 0 0 25px #FF0507!important;
animation: pulse 2s infinite!important; overflow: visible!important;
}
.vfrc-launcher > *, .vfrc-launcher-icon, .vfrc-launcher img {
position: absolute!important; top:50%!important; left:50%!important;
width:105%!important; height:105%!important;
transform: translate(-50%,-50%)!important; object-fit:contain!important; display:block!important;
}
.vfrc-backdrop, .vfrc-modal-backdrop, .vf-backdrop, .vf-modal-backdrop {
display:none!important;
}
`;
const sheet = btoa(css);
const s = d.createElement("script");
s.src = "https://cdn.voiceflow.com/widget-next/bundle.mjs";
s.onload = () => {
window.voiceflow.chat.load({
verify: { projectID: USER_ID },
url: "https://general-runtime.voiceflow.com",
versionID: "production",
assistant: {
stylesheet: `data:text/css;base64,${sheet}`,
persistence: "memory"
},
autostart: true
})
.then(chat => {
elevateAssistant();
// forzar inicio del flujo
chat.sendEvent({ type: "application/vnd.voiceflow.start" });
});
};
d.head.appendChild(s);
})(document);
</script>
</body>
</html>