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 del 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 la participación del usuario, activar lógica de 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 del 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 estilos 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;}Tematización avanzada con propiedades CSS personalizadas:
: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 participación, 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 eventswindow.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 trackingconst 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 de forma 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 arriba, o consulta la API.
Beneficios de Webhook:
Configura las URL de webhook en tu panel 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_abierto - El usuario abrió el widgetwidget_cerrado - El usuario cerró el widgetconversación_iniciada - Nueva conversación iniciadamensaje_recibido - El usuario envió un mensajemensaje_enviado - El agente envió un mensajeflujo_activado - El flujo de conversación fue activadosesión_terminada - 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.confadd_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 contentfunction 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 principio, 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 neededfunction 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 interactiondocument.addEventListener('click', () => { loadWidget();}, { once: true });// Or load after page loadwindow.addEventListener('load', () => { setTimeout(loadWidget, 2000);});Asegúrate de que tus elecciones de color cumplan con las pautas WCAG: