> ## Documentation Index
> Fetch the complete documentation index at: https://docs.inploi.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Chatbot Plugin

> Conversational application flows

# Chatbot Plugin

The Chatbot plugin provides conversational flows for job applications and other interactions.

## Installation

<Tabs>
  <Tab title="npm">
    ```bash theme={null}
    npm install @inploi/plugin-chatbot
    ```
  </Tab>

  <Tab title="pnpm">
    ```bash theme={null}
    pnpm add @inploi/plugin-chatbot
    ```
  </Tab>

  <Tab title="CDN">
    ```html theme={null}
    <script defer src="https://sdk.inploi.com/@inploi/sdk/cdn/index.js"></script>
    <script defer src="https://sdk.inploi.com/@inploi/plugin-chatbot/cdn/index.js"></script>
    ```
  </Tab>
</Tabs>

## Basic usage

<Tabs>
  <Tab title="Package">
    ```typescript theme={null}
    import { initialiseSdk } from '@inploi/sdk';
    import { chatbotPlugin } from '@inploi/plugin-chatbot';

    const sdk = initialiseSdk({ publishableKey: 'pk_...', env: 'sandbox' });
    const chatbot = sdk.register(chatbotPlugin({
      theme: { hue: 260, mode: 'light' },
    }));

    // Prepare UI eagerly (optional but recommended)
    await chatbot.prepare();

    // Fetch and open a flow by job ID
    const flow = chatbot.fetchFlowByJobId('12345');
    chatbot.open(flow);
    ```
  </Tab>

  <Tab title="CDN">
    ```html theme={null}
    <script defer src="https://sdk.inploi.com/@inploi/sdk/cdn/index.js"></script>
    <script defer src="https://sdk.inploi.com/@inploi/plugin-chatbot/cdn/index.js"></script>
    <script>
      document.addEventListener('DOMContentLoaded', async () => {
        const sdk = inploi.initialiseSdk({ publishableKey: 'pk_...', env: 'sandbox' });
        const chatbot = sdk.register(inploi.chatbotPlugin({
          theme: { hue: 260, mode: 'light' },
        }));
        await chatbot.prepare();

        // Open chatbot when user clicks apply
        document.querySelector('#apply-btn').addEventListener('click', () => {
          const flow = chatbot.fetchFlowByJobId('12345');
          chatbot.open(flow);
        });
      });
    </script>
    ```
  </Tab>
</Tabs>

## Configuration

### Theme

```typescript theme={null}
type ChatbotTheme = {
  hue: number;            // 0–360 color angle (e.g. 260 for purple, 33 for orange)
  chroma?: number;        // 0–1.5 color intensity multiplier (default 1)
  mode: 'light' | 'dark';
};
```

### Feedback integration

Collect feedback after conversations:

```typescript theme={null}
import { feedbackPlugin } from '@inploi/plugin-feedback';

const chatbot = sdk.register(chatbotPlugin({
  feedback: {
    plugin: feedbackPlugin(),
    params: {
      terms: {
        negative_heading: "We're sorry to hear that. What went wrong?",
      },
    },
  },
}));
```

### Custom terms

Override default UI text. Common keys include `send`, `skip`, `undo`, `maximize`, `minimize`, `close_application`, `upload_file`, `address_search`, and various `validation_*` messages.

```typescript theme={null}
const chatbot = sdk.register(chatbotPlugin({
  terms: {
    send: 'Submit',
    skip: 'Skip this',
    undo: 'Go back',
  },
}));
```

## API

### `prepare()`

Preloads UI assets. Optional but recommended to avoid delays.

```typescript theme={null}
await chatbot.prepare();
```

### `open(flow)`

Opens the chatbot with a flow (or a promise that resolves to a flow).

```typescript theme={null}
chatbot.open(flow);
```

### `close()`

Closes the chatbot UI and clears the in-memory flow state. The widget stays in the DOM and can be reopened with `open()`.

```typescript theme={null}
chatbot.close();
```

### `destroy()`

Fully tears down the chatbot — unmounts the UI, removes the DOM element, and resets all runtime state. Use this when the widget is no longer needed on the current page. After `destroy()`, call `prepare()` to re-initialise.

```typescript theme={null}
chatbot.destroy();
```

<Tip>
  Use `close()` to hide the chatbot temporarily. Use `destroy()` for a full cleanup — for example, during page transitions on sites with client-side navigation.
</Tip>

### `fetchFlowByJobId(jobId, options?)`

Fetches a conversation flow for a specific job. By default, the `jobId` is treated as the external (ATS) ID.

```typescript theme={null}
const flow = chatbot.fetchFlowByJobId('12345');
```

Options:

| Option           | Type                                             | Description                                              |
| ---------------- | ------------------------------------------------ | -------------------------------------------------------- |
| `idType`         | `'inploi'` \| `'ats'`                            | ID type (default `ats`)                                  |
| `context`        | `Record<string, unknown>`                        | Key-value variables available to the flow                |
| `analytics`      | `{ customProperties?: Record<string, unknown> }` | Custom data forwarded to analytics events                |
| `locationOrigin` | `{ lat?: number, lng?: number }`                 | Coordinates for sorting address suggestions by proximity |

### `fetchFlowById(flowId, options?)`

Fetches a conversation flow by its ID. Accepts the same options as `fetchFlowByJobId` (except `idType`).

```typescript theme={null}
const flow = chatbot.fetchFlowById('flow_abc123');
```

## Soft navigation

If your site uses client-side navigation (e.g. Turbo, HTMX, SPA routers), the chatbot's DOM can be removed without it knowing. Use `destroy()` before the page content is replaced, and re-initialise on the new page.

<Tabs>
  <Tab title="Turbo / Turbolinks">
    ```javascript theme={null}
    document.addEventListener('turbo:before-cache', () => chatbot.destroy());
    document.addEventListener('turbo:load', () => chatbot.prepare());
    ```
  </Tab>

  <Tab title="HTMX (hx-boost)">
    ```javascript theme={null}
    document.addEventListener('htmx:beforeSwap', () => chatbot.destroy());
    document.addEventListener('htmx:afterSettle', () => chatbot.prepare());
    ```
  </Tab>

  <Tab title="SPA routers">
    ```javascript theme={null}
    // Call destroy() in your route guard or unmount hook
    router.beforeEach(() => chatbot.destroy());
    router.afterEach(() => chatbot.prepare());
    ```
  </Tab>
</Tabs>

<Note>
  `inploi.ready()` is a DOM-ready helper — it replaces `document.addEventListener('DOMContentLoaded', ...)` for the initial page load. It does **not** replace framework-specific navigation hooks like `turbo:load` or `htmx:afterSettle`.
</Note>

## Full configuration reference

```typescript theme={null}
type ChatbotPluginParams = {
  theme: ChatbotTheme;
  feedback?: {
    plugin: FeedbackPlugin;
    /** When set, `terms` overrides feedback copy for this embed. */
    params?: { terms: Partial<FeedbackTranslationTerms> };
  };
  terms?: Partial<ChatbotTranslationTerms>;
};

type ChatbotTheme = {
  hue: number;              // 0–360 color angle
  chroma?: number;          // 0–1.5 intensity multiplier (default 1)
  mode: 'light' | 'dark';
};

type OpenChatbotParams = {
  flow: Flow;
  flowKeys: string[];
  title: string;
  context?: Record<string, unknown>;
  analytics?: { customProperties?: Record<string, unknown> };
  job?: { id: string; id_type: 'internal' | 'external' };
  locationOrigin?: { lat?: number; lng?: number };
};
```
