Funciones avanzadas, personalizaciones e integraciones para usuarios avanzados.
El widget expone un objeto CompaninWidget global para control programático. Esto te permite integrar el widget profundamente en la experiencia de usuario de tu aplicación, activando acciones del widget basadas en el comportamiento del usuario o el estado de la aplicación.
La API se carga de forma asíncrona, así que siempre verifica si existe antes de llamar a métodos. También puedes escuchar un evento personalizado cuando esté listo.
Estos métodos te dan control programático total sobre la visibilidad y el comportamiento del widget.
<script id="companin-widget-script-sales" src="https://widget.companin.tech/widget.js" data-widget-key="YOUR_WIDGET_KEY" data-instance-id="sales-widget"></script> <script> // Ensure the widget has loaded before calling methods window.addEventListener('load', () => { const salesWidget = window.CompaninWidgets?.get('sales-widget') || window.CompaninWidget; if (salesWidget) { salesWidget.show(); salesWidget.sendMessage && salesWidget.sendMessage('Hello from page'); } }); </script>Escucha eventos del widget usando la API postMessage. Esto es perfecto para rastrear el compromiso del usuario, activar la lógica de la aplicación basada en interacciones del widget, o sincronizar el estado del widget con tu aplicación.
Casos de uso comunes:
<script> window.addEventListener('message', (event) => { if (event.origin !== 'https://widget.companin.tech') return; const { type, data } = event.data || {}; switch (type) { case 'WIDGET_INIT_CONFIG': console.log('Widget is ready'); break; case 'WIDGET_SHOW': console.log('Widget was opened'); break; case 'WIDGET_MESSAGE': console.log('User sent message:', data?.message); break; } }); </script>Mientras que la interfaz de configuración proporciona amplias opciones de estilo, puedes ir aún más lejos con CSS personalizado para personalizaciones avanzadas. Esto es útil cuando necesitas efectos visuales únicos, animaciones o estilos que no están disponibles en la configuración estándar.
Consideraciones importantes:
!important con moderación — solo cuando sea necesario para anular el aislamiento de iframeDirige elementos del widget usando la clase contenedora. Agrega tu CSS personalizado ya sea en el campo de CSS personalizado de la configuración del widget o en la hoja de estilo global de tu sitio:
/* Target the widget container */ .companin-widget-container { /* Custom styles */ } /* Style the collapsed button */ .companin-widget-container button { border-radius: 50% !important; box-shadow: 0 0 20px rgba(0, 0, 0, 0.3) !important; } /* Custom message bubble styles */ .companin-widget-container .message-bubble { background: linear-gradient(45deg, #667eea 0%, #764ba2 100%) !important; } /* Hide the default close button */ .companin-widget-container .close-button { display: none !important; }El widget se envía con dos paletas — Claro y Oscuro — configuradas en tu panel. Elige cuál ven los visitantes con el atributo de script data-theme="light|dark|system" (el sistema sigue su dispositivo), o cámbialo en tiempo de ejecución con CompaninWidget.setTheme('dark'). Las variables CSS a continuación aún se aplican además de la paleta activa para sobrescrituras más finas.
Tematización avanzada con propiedades CSS:
:root { /* Override widget theme variables */ --companin-primary: #ff6b6b; --companin-secondary: #4ecdc4; --companin-background: #2d3748; --companin-text: #e2e8f0; --companin-border-radius: 12px; } /* Dark theme variant */ @media (prefers-color-scheme: dark) { :root { --companin-background: #1a202c; --companin-text: #f7fafc; } }Entender cómo los usuarios interactúan con tu widget es crucial para la optimización. Al integrarte con tu plataforma de análisis, puedes rastrear métricas de compromiso, identificar temas populares y medir el impacto del widget en la experiencia del usuario y las tasas de conversión.
Métricas clave a rastrear:
Rastrea interacciones del widget como eventos personalizados en Google Analytics. Esto se integra sin problemas con tu configuración de análisis existente:
// Track widget events window.addEventListener('message', (event) => { if (event.origin !== 'https://widget.companin.tech') return; const { type, data } = event.data; switch (type) { case 'WIDGET_SHOW': gtag('event', 'widget_opened', { event_category: 'engagement', event_label: 'chat_widget' }); break; case 'WIDGET_MESSAGE': gtag('event', 'message_sent', { event_category: 'engagement', event_label: data.messageLength > 50 ? 'long_message' : 'short_message' }); break; case 'WIDGET_RESPONSE': gtag('event', 'conversation_started', { event_category: 'engagement', event_label: 'chat_widget' }); break; } });// Custom analytics tracking const trackWidgetEvent = (eventName, properties = {}) => { fetch('/api/analytics/track', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ event: eventName, properties: { widget: 'companin', ...properties } }) }); }; window.addEventListener('message', (event) => { if (event.origin !== 'https://widget.companin.tech') return; const { type, data } = event.data; switch (type) { case 'WIDGET_SHOW': trackWidgetEvent('widget_opened'); break; case 'WIDGET_MESSAGE': trackWidgetEvent('message_sent', { length: data.message?.length || 0 }); break; } });Nota: Los webhooks salientes están en la hoja de ruta y aún no están disponibles en general — no hay campo de URL de webhook en el panel hoy. Las formas de carga y los nombres de eventos a continuación describen el diseño planeado. Para el manejo de eventos en tiempo real mientras tanto, usa los eventos postMessage en la página (por ejemplo, WIDGET_MESSAGE, WIDGET_RESPONSE) mostrados en la sección de Escucha de eventos anterior, o consulta la API.
Beneficios de Webhook:
Configura URLs de webhook en tu panel de control para recibir solicitudes HTTP POST cuando ocurran eventos específicos. Cada carga útil de webhook incluye datos de eventos y metadatos:
{ "event": "message_received", "timestamp": "2024-01-09T10:30:00Z", "data": { "session_id": "sess_123456", "message": { "id": "msg_789", "content": "Hello, I need help", "sender": "user", "timestamp": "2024-01-09T10:30:00Z" }, "metadata": { "user_agent": "Mozilla/5.0...", "ip_address": "192.168.1.1", "locale": "en" } } }widget_opened - El usuario abrió el widgetwidget_closed - El usuario cerró el widgetconversation_started - Nueva conversación iniciadamessage_received - El usuario envió un mensajemessage_sent - El agente envió un mensajeflow_triggered - El flujo de conversación fue activadosession_ended - La sesión de conversación terminóLa seguridad es primordial al incrustar contenido de terceros en tu sitio web. Mientras que el widget sigue las mejores prácticas de seguridad, hay pasos adicionales que puedes tomar para fortalecer tu integración.
Los encabezados de Política de seguridad de contenido ayudan a prevenir ataques XSS y otras vulnerabilidades de inyección de código. Configura tu CSP para permitir explícitamente el widget mientras mantienes una estricta seguridad en otros lugares:
# nginx.conf add_header Content-Security-Policy " default-src 'self'; script-src 'self' https://widget.companin.tech; style-src 'self' 'unsafe-inline' https://widget.companin.tech; frame-src https://widget.companin.tech; connect-src 'self' https://app.companin.tech; " always;Siempre valida y sanitiza las entradas del usuario:
// Validate message content function validateMessage(message) { if (message.length > 2000) { return { valid: false, error: 'Message too long' }; } const dangerousPatterns = [/<script/i, /javascript:/i, /onw+s*=/i]; for (const pattern of dangerousPatterns) { if (pattern.test(message)) { return { valid: false, error: 'Invalid content' }; } } return { valid: true }; } const validation = validateMessage(userInput); if (!validation.valid) { showError(validation.error); return; }El widget está optimizado para rendimiento desde el primer momento, pero hay estrategias para hacerlo aún más rápido y eficiente, especialmente en sitios de alto tráfico o conexiones más lentas.
En lugar de cargar el widget inmediatamente cuando se carga la página, difiérelo hasta que el usuario lo necesite o después de que se haya cargado el contenido crítico. Esto mejora el tiempo de carga inicial de tu página y las puntuaciones de Core Web Vitals:
// Load widget only when needed function loadWidget() { if (window.CompaninWidget) return; // Already loaded const script = document.createElement('script'); script.src = 'https://widget.companin.tech/widget.js'; script.setAttribute('data-widget-key', 'YOUR_WIDGET_KEY'); document.head.appendChild(script); } // Load on user interaction document.addEventListener('click', () => { loadWidget(); }, { once: true }); // Or load after page load window.addEventListener('load', () => { setTimeout(loadWidget, 2000); });Asegúrate de que tus elecciones de color cumplan con las pautas WCAG: