Skip to content

socobox/sbx360-script-guide

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 

Repository files navigation

Bot Events and Integration Guide

Use this guide to integrate the chat bot widget in your site or application. It focuses on the public events the bot emits, the control commands it listens to, and the helper functions you can call. It intentionally avoids internal implementation details.

Overview

  • The bot renders a floating chat widget that connects to your AI agent.
  • It posts lifecycle events to the host page using a CustomEvent named onBotService.
  • The host page can control the bot by dispatching a botEvent CustomEvent to window.

Menu

Events emitted by the bot (listen on the host page)

The widget emits browser events using window.dispatchEvent(new CustomEvent('onBotService', { detail })).

Basic listener example:

window.addEventListener('onBotService', (evt) => {
  const { type, info, agentId, session, sessionKey } = evt.detail || {};
  console.log('[onBotService]', type, info);
});

Common fields included in every evt.detail

  • type: string — the event name (e.g., "botStarted", "openCloseChat").
  • agentId: string — the agent the widget is configured to talk to.
  • session: object | null — the current session object if available; null otherwise.
  • sessionKey: string — the localStorage key the widget uses to persist/restore the session.
  • info: object — always present and includes the universal helper functions below, plus event-specific properties for that event (for example: { open } for openCloseChat, { request } for chatSessionStarted, { message } for newMessageReceived, { error, response } for chatSessionFailed).

Info helpers (always available in evt.detail.info)

  • openCloseChat(open?: boolean)

    • Purpose: open or close the widget programmatically from your code.
    • Behavior:
      • Pass true to open the chat; false to close it.
      • Omit the argument to toggle the current state.
    • Examples:
      • info.openCloseChat(true) // open
      • info.openCloseChat(false) // close
      • info.openCloseChat() // toggle
  • onFinishChat()

    • Purpose: end/finalize the current conversation.
    • Typical effect: the conversation is closed and a chatFinished event is emitted.
  • onAssessorRequest()

    • Purpose: request/notify a human assessor, when that capability is enabled in your setup.
    • Typical effect: sends a standardized notification/message into the conversation flow.

Quick example using the helpers and event-specific fields:

window.addEventListener('onBotService', (evt) => {
  const { type, info } = evt.detail || {};
  if (type === 'openCloseChat') {
    const isOpen = info.open; // event-specific field
    if (isOpen) info.openCloseChat(false);
  }
  if (type === 'chatSessionFailed') {
    console.warn('Session failed:', info.error, info.response);
  }
});

Common event types and payloads:

  • botStarted

    • When the widget has initialized and the UI is rendered.
    • detail includes: type, agentId, session, sessionKey, and info (helpers above).
  • openCloseChat

    • Fired whenever the chat is opened/closed by the user or programmatically.
    • detail.info: { open: boolean }
  • chatSessionStarted

    • A chat session has been created and is ready.
    • detail.info: { request: <payload-used-to-start-session> }
  • chat_session_started (legacy compatibility)

    • Emitted in some flows for older integrations.
    • detail.info: { session: <payload> }
  • chatSessionFailed

    • Session creation failed.
    • detail.info: { error: string, response: any | null }
  • newMessageReceived

    • A new inbound message was received (for example, an agent/bot reply).
    • detail.info: { message: any }
  • chatFinished

    • The chat was finalized.
    • detail.info: {}

Events the bot listens to (control from the host page)

Dispatch a CustomEvent('botEvent') to control the widget from the host page.

// Example: programmatic login (prefill onboarding and jump to Terms)
window.dispatchEvent(new CustomEvent('botEvent', {
  detail: {
    type: 'login',
    name: 'John Doe',
    email: 'john@example.com',
    phone: '3112345678',            // local digits; country code is handled by the widget
    metadata: { plan: 'pro', utm_source: 'ads' }
  }
}));

Supported command types:

  • login

    • Prefills onboarding and advances to the Terms step so the user can accept and immediately start the chat.
    • Accepted fields (in detail or detail.info): name, email, phone, metadata.
  • logout

    • Ends the chat session.
  • sendMessage

    • Programmatically sends a message as if typed by the user.
    • Fields: message (string).
  • toggleChatOpen

    • Opens the chat widget.
  • toggleChatClose

    • Closes the chat widget.

Integration examples

Listen for lifecycle events:

window.addEventListener('onBotService', (evt) => {
  const { type, info, session } = evt.detail || {};
  if (type === 'chatSessionStarted') {
    console.log('Session started with request:', info?.request);
  }
  if (type === 'newMessageReceived') {
    console.log('New message:', info?.message);
  }
  if (type === 'chatFinished') {
    console.log('Chat ended');
  }
});

Programmatic open/close:

// Open
window.dispatchEvent(new CustomEvent('botEvent', { detail: { type: 'toggleChatOpen' } }));

// Close
window.dispatchEvent(new CustomEvent('botEvent', { detail: { type: 'toggleChatClose' } }));

Send a message programmatically:

window.dispatchEvent(new CustomEvent('botEvent', {
  detail: { type: 'sendMessage', message: 'Hello from host page!' }
}));

Data used and why (high level)

  • Name, phone, and optional email are used to identify and contact the user for the conversation.
  • Agent ID routes the session to the correct agent.
  • Optional metadata can include page context (e.g., UTM parameters) to help attribute and debug sessions.
  • The active session is stored in localStorage under a known key (sessionKey) so the widget can restore state after reloads.

Notes on legacy compatibility

  • The widget keeps compatibility with older integrations by:
    • Emitting onBotService with a consistent detail shape.
    • Handling botEvent commands with both detail.field and detail.info.field patterns (older versions).
    • Emitting some legacy event names in specific flows (e.g., chat_session_started).
  • For new integrations, prefer the event names and payloads listed above.

Include the widget via a script tag (.js link)

Use your provided script URL (referred below as SCRIPT_URL). The widget will load on any page that includes this script. You can then listen to events and control it via the same event API described above.

General pattern (works everywhere):

  • Add the <script> tag that points to SCRIPT_URL.
  • Optionally, wait for the onBotService "botStarted" event to confirm the widget is ready.
  • To programmatically show the widget, dispatch a botEvent of type "toggleChatOpen" after it starts.

Example ready-check + open:

window.addEventListener('onBotService', (evt) => {
  if (evt?.detail?.type === 'botStarted') {
    // Open the widget right away (optional)
    window.dispatchEvent(new CustomEvent('botEvent', {
      detail: { type: 'toggleChatOpen' }
    }));
  }
});

If your integration requires an agent ID or other configuration, follow the instructions you received with SCRIPT_URL (for example, some deployments accept a data-agent-id attribute or read a global config object). If unsure, contact your SBX representative.

Static sites (plain HTML)

Add the script tag to your HTML (e.g., in with defer or at the end of ):

<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
    <title>My Site</title>
    <!-- Option A: simple include -->
    <script defer src="https://example.cdn.com/path/to/SCRIPT_URL.js"></script>

    <!-- Option B: include with a data attribute (only if your SCRIPT_URL supports it) -->
    <!-- <script defer src="https://example.cdn.com/path/to/SCRIPT_URL.js" data-agent-id="YOUR_AGENT_ID"></script> -->
  </head>
  <body>
    <!-- Your content -->

    <script>
      // Optional: open the bot when it is ready
      window.addEventListener('onBotService', (evt) => {
        if (evt?.detail?.type === 'botStarted') {
          window.dispatchEvent(new CustomEvent('botEvent', { detail: { type: 'toggleChatOpen' } }));
        }
      });
    </script>
  </body>
</html>

Next.js

You can load the script with next/script or dynamically on the client.

  • App Router (app/): place in app/layout.tsx (or a client component) using next/script
// app/layout.tsx
import Script from 'next/script';

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>
        {children}
        <Script
          src="https://example.cdn.com/path/to/SCRIPT_URL.js"
          strategy="afterInteractive"
        />
        <Script id="sbx-bot-open" strategy="afterInteractive">
          {`
            window.addEventListener('onBotService', (evt) => {
              if (evt?.detail?.type === 'botStarted') {
                window.dispatchEvent(new CustomEvent('botEvent', { detail: { type: 'toggleChatOpen' } }));
              }
            });
          `}
        </Script>
      </body>
    </html>
  );
}
  • Pages Router (pages/): place in pages/_app.tsx (or _document) with next/script
// pages/_app.tsx
import type { AppProps } from 'next/app';
import Script from 'next/script';

export default function MyApp({ Component, pageProps }: AppProps) {
  return (
    <>
      <Component {...pageProps} />
      <Script src="https://example.cdn.com/path/to/SCRIPT_URL.js" strategy="afterInteractive" />
      <Script id="sbx-bot-open" strategy="afterInteractive">
        {`
          window.addEventListener('onBotService', (evt) => {
            if (evt?.detail?.type === 'botStarted') {
              window.dispatchEvent(new CustomEvent('botEvent', { detail: { type: 'toggleChatOpen' } }));
            }
          });
        `}
      </Script>
    </>
  );
}

Alternative (client-only dynamic injection with useEffect):

// Any client component
import { useEffect } from 'react';

export default function BotLoader() {
  useEffect(() => {
    const s = document.createElement('script');
    s.src = 'https://example.cdn.com/path/to/SCRIPT_URL.js';
    s.async = true;
    document.body.appendChild(s);
    const handler = (evt) => {
      if (evt?.detail?.type === 'botStarted') {
        window.dispatchEvent(new CustomEvent('botEvent', { detail: { type: 'toggleChatOpen' } }));
      }
    };
    window.addEventListener('onBotService', handler);
    return () => {
      window.removeEventListener('onBotService', handler);
      document.body.removeChild(s);
    };
  }, []);
  return null;
}

Angular

Option A: add to index.html

<!-- src/index.html -->
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Angular App</title>
    <base href="/">
    <script defer src="https://example.cdn.com/path/to/SCRIPT_URL.js"></script>
  </head>
  <body>
    <app-root></app-root>
    <script>
      window.addEventListener('onBotService', (evt) => {
        if (evt?.detail?.type === 'botStarted') {
          window.dispatchEvent(new CustomEvent('botEvent', { detail: { type: 'toggleChatOpen' } }));
        }
      });
    </script>
  </body>
</html>

Option B: add from a component with Renderer2

// any.component.ts
import { Component, OnInit, OnDestroy, Renderer2 } from '@angular/core';

@Component({ selector: 'app-bot-loader', template: '' })
export class BotLoaderComponent implements OnInit, OnDestroy {
  private removeListener?: () => void;
  constructor(private renderer: Renderer2) {}
  ngOnInit(): void {
    const script = this.renderer.createElement('script');
    script.src = 'https://example.cdn.com/path/to/SCRIPT_URL.js';
    script.defer = true;
    this.renderer.appendChild(document.body, script);
    const handler = (evt: any) => {
      if (evt?.detail?.type === 'botStarted') {
        window.dispatchEvent(new CustomEvent('botEvent', { detail: { type: 'toggleChatOpen' } }));
      }
    };
    window.addEventListener('onBotService', handler);
    this.removeListener = () => window.removeEventListener('onBotService', handler);
  }
  ngOnDestroy(): void {
    this.removeListener?.();
  }
}

Vue.js

Option A: add to public/index.html (Vue CLI) or root HTML (Vite)

<!-- public/index.html or index.html -->
<!doctype html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>Vue App</title>
    <script defer src="https://example.cdn.com/path/to/SCRIPT_URL.js"></script>
  </head>
  <body>
    <div id="app"></div>
    <script>
      window.addEventListener('onBotService', (evt) => {
        if (evt?.detail?.type === 'botStarted') {
          window.dispatchEvent(new CustomEvent('botEvent', { detail: { type: 'toggleChatOpen' } }));
        }
      });
    </script>
  </body>
</html>

Option B: add from a component (Vue 3)

<script setup>
import { onMounted, onBeforeUnmount } from 'vue';

onMounted(() => {
  const s = document.createElement('script');
  s.src = 'https://example.cdn.com/path/to/SCRIPT_URL.js';
  s.defer = true;
  document.body.appendChild(s);
  const handler = (evt) => {
    if (evt?.detail?.type === 'botStarted') {
      window.dispatchEvent(new CustomEvent('botEvent', { detail: { type: 'toggleChatOpen' } }));
    }
  };
  window.addEventListener('onBotService', handler);
  onBeforeUnmount(() => {
    window.removeEventListener('onBotService', handler);
    document.body.removeChild(s);
  });
});
</script>

<template>
  <div />
</template>

Notes:

  • Replace https://example.cdn.com/path/to/SCRIPT_URL.js with your actual provided URL.
  • If your deployment requires configuration (agent ID, language, color, etc.), apply it by the method documented with your SCRIPT_URL (e.g., data attributes on the <script> tag or a global configuration object). If not specified, the default configuration for your link will be used.
  • You can always verify the widget is ready by listening for onBotService with type === 'botStarted'. After that, use botEvent commands (e.g., toggleChatOpen, sendMessage, login) as described earlier.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published