npm package: @lidakai/ai-chat-bot-sdk
Description: A lightweight SDK to embed an AI chat box via iframe into any web project.
Author: elestyle.jp
Latest version: 0.1.0

[📘 中文](./README.md) | [🇺🇸 English](./README.en.md) | [🇯🇵 日本語](./README.ja.md)

# AI Chat Box SDK 中文文档

一个轻量、框架无关的前端 SDK，帮助你快速集成 AI 聊天对话框。支持以浮窗（popup）、新页面（new-tab）或嵌入式容器（custom）方式呈现聊天窗口，支持上下文注入、鉴权、双向通信、错误监听等现代对话交互需求。

---

## 📦 安装方式

```bash
pnpm add ai-chat-bot-sdk
# 或
npm install ai-chat-bot-sdk
# 或
yarn add ai-chat-bot-sdk
```

---

## 🚀 快速开始示例

### HTML 示例

```html
<div id="chatContainer"></div>
<button id="chatTrigger">打开聊天</button>
<script src="./dist/ai-chat-bot-sdk.umd.js"></script>
<script>
  const chat = new window.AIChatBot({
    url: 'https://chat.example.com',
    mode: 'custom',
    container: '#chatContainer',
    triggerSelector: '#chatTrigger',
    payload: {
      user: { id: 'htmlUser', name: '游客' },
      uuid: 'abc123',
      sessionId: 'sess_001',
      lang: 'zh'
    },
    onAuth: (res) => console.log('✅ 鉴权完成', res),
    onError: (err) => console.error('❌ 错误发生', err)
  });
  chat.init();
</script>
```

### React 示例

```tsx
import { useEffect, useRef } from 'react';
import { AIChatBot } from 'ai-chat-bot-sdk';

export default function App() {
  const containerRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    const chat = new AIChatBot({
      url: 'https://chat.example.com',
      mode: 'custom',
      container: containerRef.current!,
      payload: {
        user: { id: 'reactUser' },
        uuid: 'react123',
        sessionId: 'sess_react',
        lang: 'zh'
      }
    });
    chat.init();
  }, []);

  return (
    <>
      <div ref={containerRef} style={{ width: 400, height: 600 }} />
      <button onClick={() => chat.toggle()}>💬 打开聊天</button>
    </>
  );
}
```

### Vue 3 示例

```vue
<template>
  <div>
    <div ref="containerRef" class="chat-box"></div>
    <button @click="chat.toggle()">打开聊天</button>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted } from 'vue';
import { AIChatBot } from 'ai-chat-bot-sdk';

const containerRef = ref<HTMLElement | null>(null);
let chat: AIChatBot;

onMounted(() => {
  chat = new AIChatBot({
    url: 'https://chat.example.com',
    mode: 'custom',
    container: containerRef.value!,
    payload: {
      user: { id: 'vueUser' },
      uuid: 'vue123',
      sessionId: 'sess_vue'
    }
  });
  chat.init();
});
</script>

<style>
.chat-box {
  width: 420px;
  height: 580px;
  border: 1px solid #ccc;
}
</style>
```

---

## ⚠️ 参数说明 / 互斥项提示

| 配置项                 | 说明                              |
| ------------------- | ------------------------------- |
| `mode: 'popup'`     | ✅ 支持 `position`，忽略 `container`  |
| `mode: 'custom'`    | ✅ 需要 `container`，忽略 `position`  |
| `mode: 'new-tab'`   | ❌ 不插入 iframe，不传 payload/context |
| `triggerSelector`   | 可选，支持自动 toggle 绑定按钮             |
| `onAuth`, `onError` | 用于监听 iframe 中鉴权成功或错误回调          |

---

## 📡 通信事件一览

| 事件类型            | 说明                            |
| --------------- | ----------------------------- |
| `AIChat:init`   | SDK → iframe，首次上下文注入          |
| `AIChat:update` | SDK → iframe，动态更新上下文          |
| `AIChat:close`  | iframe → SDK，用户点击关闭           |
| `AIChat:auth`   | iframe → SDK，返回鉴权结果           |
| `AIChat:error`  | iframe → SDK，报告运行时异常（如 token 过期等） |

---

## 🧱 类型定义说明（TypeScript）

### `ChatPayload` – 聊天上下文与用户身份信息

```ts
export interface ChatPayload {
  /** 页面唯一标识：每次进入页面可本地生成并存入 localStorage，用于区别来源 */
  uuid: string;

  /** 会话 ID：用于多轮上下文跟踪（如对话 session 或客户访问唯一标识） */
  sessionId: string;

  /** 用户语言偏好，用于控制 AI 回答语言（zh: 中文, en: 英文, ja: 日文） */
  lang?: 'zh' | 'en' | 'ja';

  /** 当前所处的功能页面编号（用于 prompt 构造，如 'order.confirm'） */
  feature?: string;

  /** 当前所在菜单（如侧边栏模块 ID 与名称） */
  menu?: {
    id: string;
    name: string;
  };

  /** 当前用户信息（用于 prompt 拼装与身份传递） */
  user?: {
    id: string;      // 用户唯一 ID（例如 userId 或 employeeId）
    name: string;    // 用户姓名（用于 prompt 展示）
  };

  /** 鉴权 token：用于 ChatBot 服务端校验 JWT 或授权身份 */
  token?: string;

  /** 自定义标签数组，例如 ['VIP', '新手', '财务角色'] */
  tags?: string[];

  /** 用户自定义字段，可传任意结构（如部门、平台来源、业务线等） */
  customData?: unknown;
}
```

---

### `AIChatBoxOptions` – SDK 初始化参数

```ts
export interface AIChatBoxOptions {
  /** iframe 页面地址 */
  url: string;

  /** iframe 内联样式，例如宽高、圆角、阴影等 */
  styles?: Partial<CSSStyleDeclaration>;

  /** iframe 外层 class，可用于统一定制 class 名 */
  class?: string;

  /** 展示模式：
   * - 'popup': 默认弹窗（右下角）
   * - 'new-tab': 在新标签页打开
   * - 'custom': 挂载到用户自定义容器中（需设置 container）
   */
  mode?: 'popup' | 'new-tab' | 'custom';

  /** 弹窗模式下的位置控制（仅 popup 生效） */
  position?: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';

  /** 聊天上下文 + 用户身份 + 鉴权配置 */
  payload?: ChatPayload;

  /** 自动绑定触发按钮的选择器（如 '#chatBtn'） */
  triggerSelector?: string;

  /** 自定义挂载容器，仅在 mode 为 'custom' 时有效（可为 DOM 节点或选择器） */
  container?: HTMLElement | string;

  /** 主题设置，可影响 iframe 内部风格（由子页面处理） */
  theme?: 'light' | 'dark';

  /** 打开聊天窗口时触发的回调 */
  onOpen?: (visible: boolean) => void;

  /** 收起聊天窗口时触发的回调 */
  onClose?: (visible: boolean) => void;

  /** iframe 返回鉴权结果时触发 */
  onAuth?: (payload?: unknown) => void;

  /** iframe 内部出错（加载失败、token 失效等）时触发 */
  onError?: (error: unknown) => void;
}
```

---

## 📊 模式能力对比

| 模式        | 是否插入 iframe | 是否支持上下文 | 是否支持通信 |
| --------- | ----------- | ------- | ------ |
| `popup`   | ✅ 是         | ✅ 支持    | ✅ 支持   |
| `custom`  | ✅ 是         | ✅ 支持    | ✅ 支持   |
| `new-tab` | ❌ 否         | ❌ 不支持   | ❌ 不支持  |

---

## 🛡️ 协议与许可

MIT © 2025 ELESTYLE