customer-chat-sdk 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,267 @@
1
+ # Customer SDK
2
+
3
+ 一个轻量级的客服系统SDK,帮助开发者快速集成客服聊天功能到现有的Web应用中。
4
+
5
+ ## 🚀 特性
6
+
7
+ - **轻量级集成**: 一行代码快速接入
8
+ - **悬浮图标**: 页面右下角悬浮聊天图标
9
+ - **响应式设计**: PC弹窗模式 / 移动端全屏模式
10
+ - **设备指纹**: 自动获取设备唯一标识
11
+ - **iframe隔离**: 完全隔离的聊天界面,避免样式冲突
12
+ - **通知系统**: 红点徽章、数字提醒功能
13
+ - **跨平台支持**: 支持UMD、ESM、CJS多种模块格式
14
+
15
+ ## 📦 安装
16
+
17
+ ### CDN 引入
18
+
19
+ ```html
20
+ <script src="https://cdn.example.com/customer-sdk.min.js"></script>
21
+ <script>
22
+ CustomerSDK.init({
23
+ agent: 'your_agent_id',
24
+ userId: 'user_123',
25
+ token: 'jwt_token',
26
+ chatUrl: 'https://chat.example.com'
27
+ });
28
+ </script>
29
+ ```
30
+
31
+ ### NPM 安装
32
+
33
+ ```bash
34
+ npm install customer-chat-sdk```
35
+
36
+ ```javascript
37
+ import CustomerSDK from 'customer-chat-sdk';
38
+
39
+ CustomerSDK.init({
40
+ agent: 'your_agent_id',
41
+ userId: 'user_123',
42
+ token: 'jwt_token',
43
+ chatUrl: 'https://chat.example.com'
44
+ });
45
+ ```
46
+
47
+ ## 🔧 快速开始
48
+
49
+ ### 基础用法
50
+
51
+ ```javascript
52
+ // 初始化SDK
53
+ await CustomerSDK.init({
54
+ agent: 'agent_123',
55
+ userId: 'user_456',
56
+ token: 'jwt_token_here',
57
+ chatUrl: 'https://chat.example.com',
58
+ debug: true
59
+ });
60
+
61
+ // 关闭悬浮图标
62
+ CustomerSDK.hideIcon();
63
+
64
+ // 打开悬浮图标
65
+ CustomerSDK.showIcon();
66
+
67
+ // 打开聊天窗口
68
+ CustomerSDK.openChat();
69
+
70
+ // 检查聊天窗口是否打开
71
+ const isOpen = CustomerSDK.isChatOpen();
72
+
73
+ // 显示通知
74
+ CustomerSDK.showNotification(5); // 数字徽章
75
+ CustomerSDK.showNotification('NEW'); // 文本徽章
76
+ CustomerSDK.clearNotification(); // 清除通知
77
+ ```
78
+
79
+ ### 高级配置
80
+
81
+ ```javascript
82
+ // 完整的配置选项
83
+ await CustomerSDK.init({
84
+ agent: 'your_agent_id',
85
+ userId: 'your_user_id',
86
+ token: 'your_jwt_token',
87
+ chatUrl: 'https://chat.example.com',
88
+ apiBaseUrl: 'https://api.example.com',
89
+ debug: true
90
+ }, {
91
+ // iframe选项(可选)
92
+ width: 400,
93
+ height: 600,
94
+ mode: 'auto', // 'auto' | 'fullscreen' | 'popup'
95
+ draggable: false,
96
+ resizable: false,
97
+ allowClose: true
98
+ });
99
+ ```
100
+
101
+ ## 📖 API 文档
102
+
103
+ ### 初始化方法
104
+
105
+ #### `CustomerSDK.init(config, options?)`
106
+
107
+ 初始化Customer SDK,自动获取设备指纹ID并创建隐藏iframe。
108
+
109
+ **参数:**
110
+
111
+ - `config` (SDKConfig): SDK配置选项
112
+ - `options` (ChatWindowOptions?, 可选): iframe窗口选项
113
+
114
+ **SDKConfig:**
115
+ ```typescript
116
+ interface SDKConfig {
117
+ agent: string; // 代理商ID
118
+ userId: string; // 用户ID
119
+ token: string; // 认证令牌
120
+ chatUrl: string; // 聊天页面URL (必需)
121
+ apiBaseUrl?: string; // API基础地址
122
+ debug?: boolean; // 调试模式
123
+ }
124
+ ```
125
+
126
+ ### 核心方法
127
+
128
+ #### `CustomerSDK.openChat()` / `CustomerSDK.closeChat()`
129
+
130
+ 打开或关闭iframe聊天窗口。
131
+
132
+ #### `CustomerSDK.showIcon()` / `CustomerSDK.hideIcon()`
133
+
134
+ 显示或隐藏悬浮图标。
135
+
136
+ #### `CustomerSDK.isChatOpen()`
137
+
138
+ 检查聊天窗口是否打开。
139
+
140
+ **返回:** boolean
141
+
142
+ #### `CustomerSDK.sendToIframe(data)`
143
+
144
+ 向iframe发送数据消息。
145
+
146
+ **参数:**
147
+ - `data` (any): 要发送的数据
148
+
149
+ #### `CustomerSDK.showNotification(badgeCount, options?)`
150
+
151
+ 显示通知徽章。
152
+
153
+ **参数:**
154
+ - `badgeCount` (number | string): 徽章内容(数字或文本)
155
+ - `options` (object?, 可选): { pulse?: boolean, autoHide?: number }
156
+
157
+ #### `CustomerSDK.clearNotification()`
158
+
159
+ 清除通知徽章。
160
+
161
+ ## 🌐 URL 参数
162
+
163
+ SDK会向iframe URL自动添加以下参数:
164
+
165
+ - `agent`: 代理商ID
166
+ - `userId`: 用户ID
167
+ - `token`: 认证令牌
168
+ - `deviceId`: 设备指纹ID(通过FingerprintJS自动获取)
169
+ - `debug`: 调试模式
170
+
171
+ **最终URL示例:**
172
+ ```
173
+ https://chat.example.com?agent=demo_app&userId=1703123456&token=test_token_1703123456789&deviceId=abc123xyz&debug=true
174
+ ```
175
+
176
+ ## 🔧 响应式设计
177
+
178
+ SDK自动检测设备类型并应用相应样式:
179
+
180
+ **PC模式:**
181
+ - 悬浮图标:右下角圆形图标
182
+ - 聊天窗口:居中弹窗,带关闭按钮
183
+
184
+ **移动端模式:**
185
+ - 悬浮图标:保持不变
186
+ - 聊天窗口:全屏显示,右上角关闭按钮
187
+
188
+ ## 🛠️ 开发
189
+
190
+ ### 环境要求
191
+
192
+ - Node.js >= 18
193
+ - pnpm >= 8 (推荐) 或 npm >= 9
194
+
195
+ ### 安装依赖
196
+
197
+ ```bash
198
+ # 使用pnpm (推荐)
199
+ pnpm install
200
+
201
+ # 或者使用传统npm
202
+ npm install
203
+ ```
204
+
205
+ ### 开发命令
206
+
207
+ ```bash
208
+ # 启动开发服务器
209
+ pnpm dev
210
+
211
+ # 启动Demo页面
212
+ pnpm demo
213
+
214
+ # 构建生产版本
215
+ pnpm build
216
+
217
+ # 代码检查
218
+ pnpm lint
219
+
220
+ # 格式化代码
221
+ pnpm format
222
+
223
+ # 检查依赖更新
224
+ pnpm package-check
225
+ ```
226
+
227
+ ### 项目结构
228
+
229
+ ```
230
+ src/
231
+ ├── core/ # 核心SDK功能
232
+ │ ├── CustomerSDK.ts # SDK主类
233
+ │ ├── IconManager.ts # 悬浮图标管理
234
+ │ └── IframeManager.ts # iframe管理
235
+ ├── types/ # TypeScript类型定义
236
+ └── index.ts # 主入口文件
237
+ ```
238
+
239
+ ## 🔗 iframe 通信
240
+
241
+ SDK通过postMessage与iframe进行通信:
242
+
243
+ ```javascript
244
+ // 向iframe发送数据
245
+ CustomerSDK.sendToIframe({
246
+ type: 'userInfo',
247
+ data: {
248
+ userId: 'user_123',
249
+ profile: { name: 'John', avatar: '...' }
250
+ }
251
+ });
252
+
253
+ // iframe接收示例
254
+ window.addEventListener('message', (event) => {
255
+ if (event.data.type === 'userInfo') {
256
+ console.log('收到用户信息:', event.data.data);
257
+ }
258
+ });
259
+ ```
260
+
261
+ ## 📄 许可证
262
+
263
+ MIT License
264
+
265
+ ## 🤝 贡献
266
+
267
+ 欢迎提交 Issue 和 Pull Request!
@@ -0,0 +1,66 @@
1
+ import { SDKConfig } from '../types';
2
+ export declare class CustomerSDK {
3
+ private config;
4
+ private iconManager;
5
+ private iframeManager;
6
+ private isInitialized;
7
+ constructor();
8
+ /**
9
+ * 初始化SDK
10
+ */
11
+ init(config: SDKConfig): Promise<void>;
12
+ /**
13
+ * 隐藏图标
14
+ */
15
+ hideIcon(): void;
16
+ /**
17
+ * 显示图标
18
+ */
19
+ showIcon(): void;
20
+ /**
21
+ * 打开聊天窗口
22
+ */
23
+ openChat(): void;
24
+ /**
25
+ * 关闭聊天窗口
26
+ */
27
+ closeChat(): void;
28
+ /**
29
+ * 检查聊天窗口是否打开
30
+ */
31
+ isChatOpen(): boolean;
32
+ /**
33
+ * 发送消息给iframe
34
+ */
35
+ sendToIframe(data: any): void;
36
+ /**
37
+ * 获取连接状态
38
+ */
39
+ getConnectionStatus(): {
40
+ connected: boolean;
41
+ };
42
+ /**
43
+ * 显示消息通知
44
+ */
45
+ showNotification(badgeCount?: number | string, options?: {
46
+ pulse?: boolean;
47
+ autoHide?: number;
48
+ }): void;
49
+ /**
50
+ * 清除消息通知
51
+ */
52
+ clearNotification(): void;
53
+ /**
54
+ * 销毁 SDK
55
+ */
56
+ destroy(): void;
57
+ /**
58
+ * 获取设备指纹ID
59
+ */
60
+ private getDeviceId;
61
+ /**
62
+ * 构建iframe URL(带用户参数和设备ID)
63
+ */
64
+ private buildIframeUrl;
65
+ }
66
+ //# sourceMappingURL=CustomerSDK.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CustomerSDK.d.ts","sourceRoot":"","sources":["../../src/core/CustomerSDK.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AAKpC,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAAyB;IACvC,OAAO,CAAC,WAAW,CAA2B;IAC9C,OAAO,CAAC,aAAa,CAA6B;IAClD,OAAO,CAAC,aAAa,CAAQ;;IAI7B;;OAEG;IACG,IAAI,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAwC5C;;OAEG;IACH,QAAQ,IAAI,IAAI;IAIhB;;OAEG;IACH,QAAQ,IAAI,IAAI;IAIhB;;OAEG;IACH,QAAQ,IAAI,IAAI;IAIhB;;OAEG;IACH,SAAS,IAAI,IAAI;IAIjB;;OAEG;IACH,UAAU,IAAI,OAAO;IAIrB;;OAEG;IACH,YAAY,CAAC,IAAI,EAAE,GAAG,GAAG,IAAI;IAM7B;;OAEG;IACH,mBAAmB,IAAI;QAAE,SAAS,EAAE,OAAO,CAAA;KAAE;IAI7C;;OAEG;IACH,gBAAgB,CAAC,UAAU,GAAE,MAAM,GAAG,MAAU,EAAE,OAAO,GAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAO,GAAG,IAAI;IAoB7G;;OAEG;IACH,iBAAiB,IAAI,IAAI;IAIzB;;OAEG;IACH,OAAO,IAAI,IAAI;IAUf;;OAEG;YACW,WAAW;IAkBzB;;OAEG;IACH,OAAO,CAAC,cAAc;CAqBvB"}
@@ -0,0 +1,55 @@
1
+ interface NotificationOptions {
2
+ showBadge?: boolean;
3
+ badgeCount?: number;
4
+ badgeText?: string;
5
+ pulse?: boolean;
6
+ }
7
+ export declare class IconManager {
8
+ private iconElement;
9
+ private badgeElement;
10
+ private onClickCallback;
11
+ private notificationCallback;
12
+ constructor();
13
+ /**
14
+ * 显示悬浮图标
15
+ */
16
+ show(): Promise<void>;
17
+ /**
18
+ * 隐藏悬浮图标
19
+ */
20
+ hide(): void;
21
+ /**
22
+ * setPosition(暂时保留接口兼容性)
23
+ */
24
+ setPosition(position: any): void;
25
+ /**
26
+ * setStyle(暂时保留接口兼容性)
27
+ */
28
+ setStyle(style: any): void;
29
+ /**
30
+ * 设置点击回调
31
+ */
32
+ onClick(callback: () => void): void;
33
+ /**
34
+ * 设置消息通知回调
35
+ */
36
+ onNotification(callback: (data: any) => void): void;
37
+ /**
38
+ * 显示消息订阅(红点、数字等)
39
+ */
40
+ showNotification(options: NotificationOptions): void;
41
+ /**
42
+ * 清除消息订阅
43
+ */
44
+ clearNotification(): void;
45
+ /**
46
+ * 处理点击事件
47
+ */
48
+ private handleClick;
49
+ /**
50
+ * 创建消息徽章(简化版)
51
+ */
52
+ private createBadge;
53
+ }
54
+ export {};
55
+ //# sourceMappingURL=IconManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IconManager.d.ts","sourceRoot":"","sources":["../../src/core/IconManager.ts"],"names":[],"mappings":"AAEA,UAAU,mBAAmB;IAC3B,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,WAAW,CAA2B;IAC9C,OAAO,CAAC,YAAY,CAA2B;IAC/C,OAAO,CAAC,eAAe,CAA4B;IACnD,OAAO,CAAC,oBAAoB,CAAqC;;IAIjE;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IA4C3B;;OAEG;IACH,IAAI,IAAI,IAAI;IASZ;;OAEG;IACH,WAAW,CAAC,QAAQ,EAAE,GAAG,GAAG,IAAI;IAIhC;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,GAAG,GAAG,IAAI;IAI1B;;OAEG;IACH,OAAO,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,IAAI;IAInC;;OAEG;IACH,cAAc,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,IAAI,GAAG,IAAI;IAInD;;OAEG;IACH,gBAAgB,CAAC,OAAO,EAAE,mBAAmB,GAAG,IAAI;IA0BpD;;OAEG;IACH,iBAAiB,IAAI,IAAI;IAQzB;;OAEG;IACH,OAAO,CAAC,WAAW;IAMnB;;OAEG;IACH,OAAO,CAAC,WAAW;CAgDpB"}
@@ -0,0 +1,93 @@
1
+ interface IframeOptions {
2
+ src?: string;
3
+ mode?: 'auto' | 'fullscreen' | 'popup';
4
+ width?: number;
5
+ height?: number;
6
+ draggable?: boolean;
7
+ resizable?: boolean;
8
+ allowClose?: boolean;
9
+ }
10
+ export declare class IframeManager {
11
+ private config;
12
+ private iframeElement;
13
+ private overlayElement;
14
+ private containerElement;
15
+ private isOpen;
16
+ private isCreated;
17
+ constructor(config?: IframeOptions);
18
+ /**
19
+ * 初始化iframe(隐藏状态)
20
+ * 预创建iframe并连接到SSE,但不显示
21
+ */
22
+ init(): Promise<void>;
23
+ /**
24
+ * 显示iframe聊天窗口
25
+ */
26
+ show(): void;
27
+ /**
28
+ * 打开iframe聊天窗口(保持兼容性)
29
+ */
30
+ open(): void;
31
+ /**
32
+ * 隐藏iframe聊天窗口(类似v-show)
33
+ */
34
+ hide(): void;
35
+ /**
36
+ * 关闭iframe聊天窗口(完全销毁,保持兼容性)
37
+ */
38
+ close(): void;
39
+ /**
40
+ * 完全销毁iframe(需要时才调用)
41
+ */
42
+ destroy(): void;
43
+ /**
44
+ * 检查是否已打开
45
+ */
46
+ isIframeOpen(): boolean;
47
+ /**
48
+ * 向iframe发送消息
49
+ */
50
+ sendToIframe(data: any): void;
51
+ /**
52
+ * 创建遮罩层
53
+ */
54
+ private createOverlay;
55
+ /**
56
+ * 创建iframe(默认隐藏状态,用于SSE连接)
57
+ */
58
+ private createIframe;
59
+ /**
60
+ * 向iframe注入移动端优化样式(隐藏滚动条)
61
+ */
62
+ private injectMobileStyles;
63
+ /**
64
+ * 控制页面滚动(移动端全屏模式使用)
65
+ */
66
+ private preventBodyScroll;
67
+ /**
68
+ * 添加关闭按钮(自适应设备)
69
+ */
70
+ private addCloseButton;
71
+ /**
72
+ * 检测设备类型
73
+ */
74
+ private isMobileDevice;
75
+ /**
76
+ * 获取当前显示模式
77
+ */
78
+ private getActualMode;
79
+ /**
80
+ * 设置消息监听
81
+ */
82
+ private setupMessageListener;
83
+ /**
84
+ * 处理来自iframe的消息
85
+ */
86
+ private handleIframeMessage;
87
+ /**
88
+ * 调整iframe大小
89
+ */
90
+ private resizeIframe;
91
+ }
92
+ export {};
93
+ //# sourceMappingURL=IframeManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IframeManager.d.ts","sourceRoot":"","sources":["../../src/core/IframeManager.ts"],"names":[],"mappings":"AAEA,UAAU,aAAa;IACrB,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,MAAM,GAAG,YAAY,GAAG,OAAO,CAAA;IACtC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,UAAU,CAAC,EAAE,OAAO,CAAA;CACrB;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,aAAa,CAAiC;IACtD,OAAO,CAAC,cAAc,CAA2B;IACjD,OAAO,CAAC,gBAAgB,CAA2B;IACnD,OAAO,CAAC,MAAM,CAAQ;IACtB,OAAO,CAAC,SAAS,CAAQ;gBAEb,MAAM,GAAE,aAAkB;IAatC;;;OAGG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAc3B;;OAEG;IACH,IAAI,IAAI,IAAI;IA6DZ;;OAEG;IACH,IAAI,IAAI,IAAI;IAIZ;;OAEG;IACH,IAAI,IAAI,IAAI;IA8BZ;;OAEG;IACH,KAAK,IAAI,IAAI;IAIb;;OAEG;IACH,OAAO,IAAI,IAAI;IAaf;;OAEG;IACH,YAAY,IAAI,OAAO;IAIvB;;OAEG;IACH,YAAY,CAAC,IAAI,EAAE,GAAG,GAAG,IAAI;IAM7B;;OAEG;IACH,OAAO,CAAC,aAAa;IA8BrB;;OAEG;IACH,OAAO,CAAC,YAAY;IAuFpB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IA0D1B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAmCzB;;OAEG;IACH,OAAO,CAAC,cAAc;IAkFtB;;OAEG;IACH,OAAO,CAAC,cAAc;IAKtB;;OAEG;IACH,OAAO,CAAC,aAAa;IAOrB;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAS5B;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAsB3B;;OAEG;IACH,OAAO,CAAC,YAAY;CAMrB"}