# @verba-ai/chat-sdk

A lightweight, TypeScript SDK for embedding the Verba AI chat widget into any web application.

The SDK acts as a secure, high-performance orchestration layer that manages the injection and lifecycle of the Verba chat `iframe`. It supports both floating and inline mounting strategies.

## Usage

### 1. Floating Bubble (Default)

The easiest way to integrate the chat. It creates a fixed-position action button in the bottom corner of your screen that toggles the chat window.

```typescript
import { VerbaChat } from '@verba-ai/chat-sdk'

const chat = new VerbaChat({
    // Required: Your unique Verba tagId
    tagId: 'your-tag-id',

    // Optional
    theme: {
        primaryColor: '#6366f1',
        backgroundColor: '#080b14',
        textColor: '#f1f5f9',
    },

    // You can also our default theme presets
    // theme: 'light' | 'dark',

    // Optional: Configuration for the floating bubble
    bubble: {
        position: 'bottom-right',
        color: '#8b5cf6', // custom background gradient/color
        size: 56, // size in pixels
        icon: '<link>', // src to <img> tag
    },

    // Optional: Overriding the widget source url
    src: '',

    // Optional: Overriding the assistant avatar
    assistantAvatar: 'https://yoursite.com/assistant-icon.svg',
})

// Inject the bubble into the DOM
chat.init()

// Optional programmatic controls
// chat.show();
// chat.hide();
// chat.destroy();
```

### 2. Inline Mounting

If you want to render the chat inside a specific part of your page (like a dashboard panel or a dedicated contact page).

```typescript
import { VerbaChat } from '@verba-ai/chat-sdk'

// Ensure the container exists in your DOM
// <div id="my-chat-container" style="height: 600px;"></div>

const chat = new VerbaChat({
    tagId: 'your-tag-id',

    // Target a CSS selector or pass an HTMLElement directly
    targetElement: '#my-chat-container',

    // Optional: Advanced visual theming
    theme: {
        primaryColor: '#6366f1',
        backgroundColor: '#080b14',
        textColor: '#f1f5f9',
    },

    // Optional: Show a list of previous conversations
    withThreadList: true,

    // Optional: Required for authenticated sessions
    token: 'your-jwt-token',
})

chat.init()
```

### 3. Usage via CDN (UMD)

If you aren't using a bundler (Webpack/Vite/Rollup), you can load the SDK directly via a script tag.

```html
<script src="https://unpkg.com/@verba-ai/chat-sdk@latest/dist/chat-sdk.umd.cjs"></script>
<script>
    const { VerbaChat } = window.VerbaChatSDK

    new VerbaChat({ tagId: 'your-tag-id' }).init()
</script>
```

---

## API Reference

### `VerbaChat` Class

The main entry point for the widget.

#### Methods

| Method      | Description                                                                            |
| :---------- | :------------------------------------------------------------------------------------- |
| `init()`    | Injects the CSS and iframe into the DOM. Returns a `VerbaChat` instance.               |
| `show()`    | Makes the widget visible (animates the iframe open in floating mode).                  |
| `hide()`    | Hides the widget (animates the iframe closed in floating mode).                        |
| `destroy()` | Completely tears down the SDK, removing all injected DOM elements, styles, and events. |

---

## Communication & Security

The SDK communicates with the embedded chat widget via a secure `window.postMessage` bridge.

### Origin Validation

To ensure security, the SDK enforces strict origin validation:

- **Outgoing:** Messages are only sent to the trusted `targetOrigin` (default: `https://embed.verba.chat`).
- **Incoming:** The SDK ignores any messages that do not originate from the allowed widget source.

### Message Protocol

Internally, the SDK uses a namespaced payload structure to avoid collisions with other scripts on the host page:

```typescript
interface PostMessagePayload<T> {
    source: 'verba-chat-sdk'
    type: MessageType
    data: T
}
```

---

### Configuration Types

#### `VerbaChat`

```typescript
interface VerbaChat {
    container: HTMLElement | null
    iframe: HTMLIFrameElement | null
    bubble: HTMLButtonElement | null
}
```

#### `VerbaChatConfig`

```typescript
interface VerbaChatConfig {
    /** Your Verba tag ID (Required) */
    tagId: string

    /**
     * Where to mount the widget iframe.
     * - A CSS selector string (e.g. `'#chat-root'`)
     * - An `HTMLElement` reference
     * - Omit for a floating bubble fixed to the viewport corner.
     */
    targetElement?: string | HTMLElement

    /** Visual theme. String preset or detailed config. */
    theme?: 'light' | 'dark' | ThemeConfig

    /** Configuration for the floating bubble. Has no effect when `targetElement` is provided. */
    bubble?: ChatBubbleConfig

    /** Optional: Custom assistant avatar URL. */
    assistantAvatar?: string

    /**
     * Optional: JWT token for authenticated sessions.
     * Required when the widget is configured to require authentication.
     */
    token?: string

    /**
     * Optional: Token environment passed with the authentication token.
     */
    tokenEnvironment?: string

    /**
     * Optional: Enable the thread list panel.
     * When `true`, users can browse and resume previous conversations.
     * When `false` (default), only a single new chat thread is shown.
     * @default false
     */
    withThreadList?: boolean

    /** Optional: Override the default widget source URL. */
    src?: string
}
```

#### `MessageType`

```typescript
type MessageType =
    | 'INIT_WIDGET'
    | 'READY'
    | 'EXPAND_WIDGET'
    | 'SHRINK_WIDGET'
    | 'CLOSE_WIDGET'
    | 'SHOW_WIDGET_MESSAGE'
```

- `INIT_WIDGET` — SDK → widget. Sent once the widget signals `READY`, carrying the full `VerbaChatConfig`.
- `READY` — widget → SDK. Sent once the widget has mounted and can receive `INIT_WIDGET`.
- `EXPAND_WIDGET` — widget → SDK. Requests the floating iframe panel be enlarged. No-op in inline mode.
- `SHRINK_WIDGET` — widget → SDK. Restores the floating iframe panel to its default size. No-op in inline mode.
- `CLOSE_WIDGET` — widget → SDK. Requests the floating iframe panel be closed (same as clicking the bubble to close it). No-op in inline mode.
- `SHOW_WIDGET_MESSAGE` — widget → SDK. Sends `{ message: string }`; shows a popup near the bubble with a truncated preview of `message` — only while the floating panel is closed. Always supersedes (and permanently dismisses) the first-time greeting popup. No-op in inline mode.

#### `PostMessagePayload`

```typescript
interface PostMessagePayload<T = unknown> {
    /** Namespace guard — prevents collisions with other postMessage users. */
    source: 'verba-chat-sdk'
    type: MessageType
    data: T
}
```

#### `ChatBubbleConfig`

```typescript
interface ChatBubbleConfig {
    /** Corner position of the floating bubble (Default: 'bottom-right') */
    position?: 'bottom-right' | 'bottom-left'

    /** Background color of the bubble (Default: '#ffffff') */
    color?: string

    /** Size of the bubble in pixels (Default: 56) */
    size?: number

    /** SVG string for a custom open (chat) icon */
    icon?: string

    /** Color of the close (X) icon (Default: '#000000') */
    closeIconColor?: string

    /** Color of the chat icon stroke (Default: '#000000') */
    chatIconStrokeColor?: string

    /** Custom CSS color (rgba or hex) for the bubble's box-shadow */
    shadowColor?: string

    /** Configuration for the first-time greeting popup shown near the bubble */
    greeting?: ChatBubbleGreetingConfig

    /** Color of the unread-message badge dot shown on the bubble (Default: '#ef4444') */
    badgeColor?: string
}
```

#### `ChatBubbleGreetingConfig`

```typescript
interface ChatBubbleGreetingConfig {
    /** The message shown the first time a visitor sees the widget (Default: 'Hey, if you need some help, ask me anything!') */
    message?: string

    /** Delay (ms) before the greeting auto-appears after the widget mounts (Default: 2000) */
    delay?: number

    /** Disable the first-time greeting popup entirely (Default: false) */
    disabled?: boolean
}
```

#### `ThemeConfig`

```typescript
interface ThemeConfig {
    primaryColor?: string
    textColor?: string
    backgroundColor?: string
    fontFamily?: string
}
```
