Zaawansowane funkcje, dostosowania i integracje dla zaawansowanych użytkowników.
Widget udostępnia globalny obiekt CompaninWidget do programistycznej kontroli. Umożliwia to głęboką integrację widgetu z doświadczeniem użytkownika Twojej aplikacji, wyzwalając akcje widgetu na podstawie zachowań użytkownika lub stanu aplikacji.
API jest ładowane asynchronicznie, więc zawsze sprawdzaj, czy istnieje przed wywołaniem metod. Możesz również nasłuchiwać na niestandardowe zdarzenie, gdy będzie gotowe.
Te metody dają pełną programistyczną kontrolę nad widocznością i zachowaniem widgetu.
<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>Nasłuchuj zdarzeń widgetu za pomocą API postMessage. To idealne do śledzenia zaangażowania użytkowników, wyzwalania logiki aplikacji na podstawie interakcji z widgetem lub synchronizacji stanu widgetu z Twoją aplikacją.
Typowe przypadki użycia:
<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>Chociaż interfejs konfiguracji oferuje rozbudowane opcje stylizacji, możesz pójść jeszcze dalej z niestandardowym CSS dla zaawansowanych dostosowań. To przydatne, gdy potrzebujesz unikalnych efektów wizualnych, animacji lub stylów, które nie są dostępne w standardowej konfiguracji.
Ważne uwagi:
!important oszczędnie — tylko wtedy, gdy to konieczne, aby nadpisać izolację iframeCeluj w elementy widgetu za pomocą klasy kontenera. Dodaj swój niestandardowy CSS albo w polu niestandardowego CSS konfiguracji widgetu, albo w globalnym arkuszu stylów Twojej witryny:
/* 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;}Zaawansowane motywowanie z niestandardowymi właściwościami 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; }}Zrozumienie, jak użytkownicy wchodzą w interakcje z Twoim widgetem, jest kluczowe dla optymalizacji. Integrując się z Twoją platformą analityczną, możesz śledzić metryki zaangażowania, identyfikować popularne tematy i mierzyć wpływ widgetu na doświadczenie użytkownika i wskaźniki konwersji.
Kluczowe metryki do śledzenia:
Śledź interakcje widgetu jako niestandardowe zdarzenia w Google Analytics. To integruje się płynnie z twoim istniejącym ustawieniem analityki:
// 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; }});Uwaga: Zewnętrzne webhooki są w planach i jeszcze nie są ogólnie dostępne — obecnie nie ma pola URL webhooka w panelu. Kształty ładunków i nazwy zdarzeń poniżej opisują planowany projekt. W międzyczasie, aby obsługiwać zdarzenia w czasie rzeczywistym, użyj zdarzeń postMessage na stronie (np. WIDGET_MESSAGE, WIDGET_RESPONSE) pokazanych w sekcji Nasłuchiwanie zdarzeń powyżej, lub zapytaj API.
Korzyści z webhooków:
Skonfiguruj adresy URL webhooków w swoim pulpicie, aby otrzymywać żądania HTTP POST, gdy wystąpią określone zdarzenia. Każdy ładunek webhooka zawiera dane zdarzenia i metadane:
{ "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_otwarty - Użytkownik otworzył widgetwidget_zamknięty - Użytkownik zamknął widgetrozmowa_rozpoczęta - Rozpoczęto nową rozmowęwiadomość_odebrana - Użytkownik wysłał wiadomośćwiadomość_wysłana - Agent wysłał wiadomośćprzebieg_uruchomiony - Aktywowano przebieg rozmowysesja_zakończona - Sesja rozmowy zakończonaBezpieczeństwo jest kluczowe przy osadzaniu treści zewnętrznych na Twojej stronie. Chociaż widget przestrzega najlepszych praktyk bezpieczeństwa, istnieją dodatkowe kroki, które możesz podjąć, aby wzmocnić swoją integrację.
Nagłówki polityki bezpieczeństwa treści pomagają zapobiegać atakom XSS i innym podatnościom na wstrzykiwanie kodu. Skonfiguruj swoją CSP, aby wyraźnie zezwolić widgetowi, jednocześnie utrzymując ścisłe bezpieczeństwo w innych miejscach:
# 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;Zawsze waliduj i oczyszczaj dane wejściowe użytkowników:
// 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;}Widget jest zoptymalizowany pod kątem wydajności od razu po wyjęciu z pudełka, ale istnieją strategie, aby uczynić go jeszcze szybszym i bardziej wydajnym, szczególnie na stronach o dużym ruchu lub wolniejszych połączeniach.
Zamiast ładować widget natychmiast po załadowaniu strony, opóźnij go, aż użytkownik go potrzebuje lub po załadowaniu krytycznej treści. To poprawia czas ładowania początkowego Twojej strony i wyniki 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);});Upewnij się, że Twoje wybory kolorów spełniają wytyczne WCAG: