당신의 페이지에서 위젯을 제어하세요: 열고 닫고, 메시지를 보내고, 로그인한 사용자를 식별하고, 전환을 추적하며, 생애 주기 이벤트에 반응하세요.
위젯 스크립트가 로드되면 window.CompaninWidget에 글로벌을 등록합니다. 이를 통해 페이지에 위젯을 열고 닫고, 메시지를 보내고, 현재 사용자를 식별하고, 라이프사이클 이벤트에 구독할 수 있는 작고 의존성 없는 API를 제공합니다 — 코드가 위젯의 내부에 결합되지 않도록 합니다.
스크립트는 비동기적으로 로드되므로, 전역 객체는 페이지가 로드된 후 잠시 후에 나타납니다. 첫 번째 호출을 보호하세요 (window.CompaninWidget?.open()), 또는 widget.ready 이벤트에 구독하세요. 페이지에 위젯을 하나 이상 포함할 때, 각 인스턴스는 window.CompaninWidgets 아래의 data-instance-id로 등록됩니다 — 특정 인스턴스를 타겟팅하려면 CompaninWidgets.get(‘id’)를 사용하세요; window.CompaninWidget는 가장 최근에 생성된 인스턴스를 가리킵니다.
위젯이 로드된 후 window.CompaninWidget에서 이러한 호출을 하세요. iframe이 준비되기 전에 효과가 없는 메서드는 조용히 실패하고 콘솔에 로그를 남기며, 예외를 발생시키지 않으므로 잘못된 타이밍의 호출이 페이지를 깨뜨리지 않습니다.
open() / close() / toggle() — 채팅 패널을 확장, 축소 또는 뒤집으세요.show() / hide() — 전체 위젯 컨테이너를 표시하거나 숨깁니다. 발사기도 포함됩니다.isOpen() / isVisible() / isReady() — 현재 패널, 컨테이너 및 부트스트랩 상태를 읽습니다.sendMessage(text) — 방문자로 메시지를 보내고 답장을 받으세요.prefill(text) — 죄송하지만, 요청하신 내용을 처리할 수 없습니다.identify(user) — 세션에 사용자 ID를 연결하세요 — { userId, email, name, metadata, token }. 아래를 참조하세요.setContext(data) — 페이지 수준 컨텍스트를 푸시합니다; 위젯은 이를 다음 요청의 page_context에 병합합니다.setTheme(theme) — 런타임에 팔레트를 전환하세요 — 'light', 'dark', 또는 'system'. 대시보드 테마와 data-theme을 재정의합니다.trackConversion(goal, value, opts) — 채팅 후 도달한 목표를 기록하세요. 예: trackConversion('checkout', 79.00, { currency: 'EUR' }).beforeSend(fn) / afterReceive(fn) — 메시지를 발송하거나 수신하는 과정에서 검사, 수정 또는 취소하세요. 취소하려면 null을 반환하세요.on(event, handler) — 라이프사이클 이벤트에 구독합니다; 구독 취소 함수가 반환됩니다. off(event, handler)도 작동합니다.update(config) — 페이지를 새로 고치지 않고 부분 위젯 구성을 실시간으로 적용합니다.reset() — 현재 대화를 지우고 새 세션을 시작합니다.enableDebug() / disableDebug() — 라이브 페이지에서 자세한 콘솔 로깅을 켜거나 끕니다.grantConsent() / revokeConsent() — 위젯이 브라우저 저장소를 사용할 수 있는지 여부를 알려주세요. 동의 기반 배포에 필요합니다.getVersion() / destroy() — 로더 버전을 읽거나 위젯을 제거하고 페이지에서 삭제하세요.<script> // The embed loads asynchronously — wait for it before calling in. window.CompaninWidget?.on('widget.ready', function () { var w = window.CompaninWidget; w.open(); w.prefill('I have a question about pricing.'); console.log('version', w.getVersion(), 'open?', w.isOpen()); });</script>위젯이 로그인한 사용자를 인식하여 대화가 개인화되고 장치 간에 복원될 수 있도록 하세요. 귀하의 서버는 위젯이 Companin에 전달하는 단기 토큰을 서명합니다; Companin은 이를 검증하고 세션을 해당 사용자에 연결합니다.
대시보드에서 서명 비밀을 가져와서 서버의 환경에 복사하세요. 브라우저 코드에 노출하지 마세요.
서버에서 토큰에 서명하세요 — 사용자의 id (sub), 이메일 및 이름을 포함하는 단기 HS256 JWT.
const jwt = require('jsonwebtoken'); // npm i jsonwebtokenfunction signUserToken(user) { return jwt.sign( { sub: String(user.id), email: user.email, name: user.name }, process.env.COMPANIN_EMBED_SECRET, { algorithm: 'HS256', expiresIn: '5m' } );}3. 토큰을 위젯에 전달하세요. 서버 렌더링된 페이지에서는 script 태그에 data-user-token으로 추가하고, 싱글 페이지 앱에서는 사용자가 로그인한 후 identify()를 호출하세요:
<!-- Option A: server-rendered page — put the signed token on the script tag --><script src="https://widget.companin.tech/widget.js" data-widget-key="wgt_your_key" data-user-token="SERVER_SIGNED_JWT"></script><!-- Option B: after login — fetch a fresh token and call identify() --><script> fetch('/api/widget-user-token') .then(function (r) { return r.json(); }) .then(function (data) { if (data.token) window.CompaninWidget.identify({ token: data.token }); });</script>잘못되었거나 만료된 토큰은 무시됩니다 — 위젯은 단순히 익명으로 유지되므로 항상 식별을 시도하는 것이 안전합니다.
beforeSend(fn)은 API에 도달하기 전에 모든 나가는 방문자 메시지에서 귀하의 함수를 실행합니다; afterReceive(fn)은 렌더링되기 전에 모든 에이전트 응답에서 실행됩니다. 변경하려면 수정된 문자열을 반환하거나 취소하려면 null을 반환하십시오. 두 함수 모두 Promise를 수용하므로 먼저 귀하의 서비스를 호출할 수 있으며, 여러 인터셉터가 등록 순서대로 실행됩니다.
// Redact email addresses before a message leaves the browser.window.CompaninWidget.beforeSend(function (message) { if (!message.trim()) return null; // return null to cancel the send return message.replace(/[\w.+-]+@[\w-]+\.[\w.-]+/g, '[email]');});// Post-process the agent's reply before it renders.window.CompaninWidget.afterReceive(function (reply) { return reply.replace(/support@example\.com/g, 'our support team');});방문자가 목표에 도달하면 trackConversion()을 호출하여 대시보드가 해당 대화에 기여한 것으로 귀속할 수 있도록 합니다. 목표 슬러그와, 있을 경우 금액 및 통화를 전달합니다. 일반적인 슬러그는 add_to_cart, checkout, signup, lead 및 booking이지만, 선택한 슬러그는 모두 허용됩니다. dedupKey(또는 metadata.order_id)를 전달하여 새로 고침 시 동일한 주문을 두 번 계산할 수 없도록 합니다.
// On your order-confirmation page:window.CompaninWidget?.trackConversion('checkout', 79.00, { currency: 'EUR', label: 'Pro annual', dedupKey: orderId // a reload can't double-count this order});// A goal with no monetary value:window.CompaninWidget?.trackConversion('signup');CompaninWidget.on(name, handler)로 구독하면 구독 취소 함수가 반환됩니다. 핸들러는 봉투를 수신합니다: { event, timestamp, data, context } — 페이로드는 envelope.data에 있습니다. 늦게 구독한 사용자들은 해당 이벤트에 대한 마지막 봉투를 즉시 수신하므로, 로드 후에 연결하더라도 하나를 놓치지 않습니다.
widget.ready — iframe이 부트스트랩 핸드셰이크를 완료했으며 API가 활성화되었습니다.open / close — 채팅 패널이 확장되거나 축소되었습니다. 별칭: widget.opened, widget.closed.message — 방문자가 메시지를 보냈습니다. 별칭: message.sent.response — 에이전트가 응답했습니다. 별칭: message.received.conversation.created / conversation.closed — 대화가 시작되었거나 종료되었습니다.user.updated — identify()가 호출되었거나 확인된 사용자 신원이 변경되었습니다.file.uploaded — 방문자가 파일을 첨부했습니다.conversion.tracked — trackConversion()은 목표를 기록했습니다.theme.change — 활성화된 라이트/다크 팔레트가 변경되었습니다.authFailure — 백엔드와의 인증에 실패했습니다. 별칭: auth.failed.error — 위젯에서 오류가 발생했습니다.var widget = window.CompaninWidget;widget.on('message', function (e) { console.log('Visitor sent:', e.data);});widget.on('response', function (e) { console.log('Agent replied:', e.data);});var stopWatching = widget.on('authFailure', function (e) { console.warn('Widget auth failed:', e.data);});// on() returns an unsubscribe function.stopWatching();모든 생애 주기 이벤트는 또한 window에서 companin-widget:<event>라는 이름의 CustomEvent로 전송됩니다 — 예를 들어 companin-widget:response. 동일한 envelope는 event.detail에 있습니다. 위젯에 대한 참조를 보유할 수 없는 경우, 예를 들어 분석 태그나 태그 관리자 스니펫과 같은 경우에 이를 사용하십시오.
// Note the hyphen: companin-widget:<event>, not companin:widget:<event>.window.addEventListener('companin-widget:response', function (e) { // e.detail is { event, timestamp, data, context } console.log('Agent replied:', e.detail.data); console.log('on page:', e.detail.context.pagePath);});window.addEventListener('companin-widget:open', function () { window.dataLayer?.push({ event: 'widget_open' });});