customer-chat-sdk 1.3.0 → 1.3.6
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 +503 -293
- package/dist/core/CustomerSDK.d.ts +70 -25
- package/dist/core/CustomerSDK.d.ts.map +1 -1
- package/dist/customer-sdk.cjs.js +292 -892
- package/dist/customer-sdk.esm.js +291 -888
- package/dist/customer-sdk.min.js +4 -4
- package/dist/index.d.ts +10 -47
- package/dist/index.d.ts.map +1 -1
- package/dist/types/index.d.ts +8 -2
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,400 +1,610 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
一个轻量级的客服系统SDK,帮助开发者快速集成客服聊天功能到现有的Web应用中。
|
|
4
|
-
|
|
5
|
-
## 🚀 特性
|
|
6
|
-
|
|
7
|
-
- **轻量级集成**: 一行代码快速接入
|
|
8
|
-
- **悬浮图标**: 页面右下角悬浮聊天图标,支持自定义位置(x, y坐标)
|
|
9
|
-
- **可拖拽图标**: 支持鼠标/触摸拖拽移动图标位置
|
|
10
|
-
- **响应式设计**: PC弹窗模式 / 移动端全屏模式
|
|
11
|
-
- **设备指纹**: 自动获取设备唯一标识
|
|
12
|
-
- **iframe隔离**: 完全隔离的聊天界面,避免样式冲突
|
|
13
|
-
- **通知系统**: 红点徽章、数字提醒功能
|
|
14
|
-
- **页面截图**: 支持自动截图和上传功能,可配置截图引擎和压缩选项
|
|
15
|
-
- **跨平台支持**: 支持UMD、ESM、CJS多种模块格式
|
|
16
|
-
|
|
17
|
-
## 📦 安装
|
|
18
|
-
|
|
19
|
-
### CDN 引入
|
|
20
|
-
|
|
21
|
-
```html
|
|
22
|
-
<script src="https://cdn.jsdelivr.net/npm/customer-chat-sdk@1.0.20/dist/customer-sdk.min.js"></script>
|
|
23
|
-
<script>
|
|
24
|
-
CustomerSDK.init({
|
|
25
|
-
agent: 'your_agent_id',
|
|
26
|
-
token: 'jwt_token',
|
|
27
|
-
iframeUrl: 'https://chat.example.com'
|
|
28
|
-
});
|
|
29
|
-
</script>
|
|
30
|
-
```
|
|
1
|
+
# CustomerSDK 使用文档
|
|
31
2
|
|
|
32
|
-
|
|
33
|
-
```html
|
|
34
|
-
<script src="https://unpkg.com/customer-chat-sdk@1.0.20/dist/customer-sdk.min.js"></script>
|
|
35
|
-
```
|
|
3
|
+
## 简介
|
|
36
4
|
|
|
37
|
-
|
|
5
|
+
CustomerSDK 是一个轻量级的客服 SDK,提供**图标管理**和**截图功能**。适用于需要自行管理弹窗组件的项目场景。
|
|
38
6
|
|
|
39
|
-
|
|
40
|
-
npm install customer-chat-sdk```
|
|
7
|
+
## 特性
|
|
41
8
|
|
|
42
|
-
|
|
43
|
-
|
|
9
|
+
- ✅ **悬浮图标** - 可拖动的悬浮图标,支持侧边吸附和磁性吸附
|
|
10
|
+
- ✅ **截图功能** - 自动截图、压缩、上传
|
|
11
|
+
- ✅ **设备识别** - 自动获取设备指纹 ID
|
|
12
|
+
- ✅ **通知提醒** - 支持数字和文本通知徽章
|
|
13
|
+
- ✅ **无 iframe** - 不包含 iframe 管理,由项目自行实现弹窗
|
|
44
14
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
15
|
+
## 安装
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install customer-chat-sdk
|
|
19
|
+
# 或
|
|
20
|
+
pnpm add customer-chat-sdk
|
|
21
|
+
# 或
|
|
22
|
+
yarn add customer-chat-sdk
|
|
50
23
|
```
|
|
51
24
|
|
|
52
|
-
##
|
|
25
|
+
## 快速开始
|
|
53
26
|
|
|
54
27
|
### 基础用法
|
|
55
28
|
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
//
|
|
65
|
-
iconPosition: {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
//
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
CustomerSDK
|
|
93
|
-
|
|
94
|
-
|
|
29
|
+
```typescript
|
|
30
|
+
import { CustomerSDK } from 'customer-chat-sdk'
|
|
31
|
+
|
|
32
|
+
// 创建 SDK 实例
|
|
33
|
+
const sdk = new CustomerSDK()
|
|
34
|
+
|
|
35
|
+
// 初始化(返回初始化结果,包含设备ID等)
|
|
36
|
+
const initResult = await sdk.init({
|
|
37
|
+
debug: true, // 开发环境开启
|
|
38
|
+
iconPosition: { x: 20, y: 80 },
|
|
39
|
+
target: '#app'
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
console.log('Device ID:', initResult.deviceId)
|
|
43
|
+
|
|
44
|
+
// 设置图标点击回调
|
|
45
|
+
sdk.onIconClick(() => {
|
|
46
|
+
// 打开您的弹窗组件
|
|
47
|
+
openChatPopup()
|
|
48
|
+
})
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### 完整示例(Vue 3)
|
|
52
|
+
|
|
53
|
+
```vue
|
|
54
|
+
<template>
|
|
55
|
+
<div id="app">
|
|
56
|
+
<ChatPopup
|
|
57
|
+
ref="chatPopupRef"
|
|
58
|
+
v-model:visible="chatVisible"
|
|
59
|
+
/>
|
|
60
|
+
</div>
|
|
61
|
+
</template>
|
|
62
|
+
|
|
63
|
+
<script setup lang="ts">
|
|
64
|
+
import { ref, onMounted, onUnmounted } from 'vue'
|
|
65
|
+
import { CustomerSDK } from 'customer-chat-sdk'
|
|
66
|
+
|
|
67
|
+
const chatVisible = ref(false)
|
|
68
|
+
const chatPopupRef = ref()
|
|
69
|
+
let sdk: CustomerSDK | null = null
|
|
70
|
+
|
|
71
|
+
onMounted(async () => {
|
|
72
|
+
sdk = new CustomerSDK()
|
|
73
|
+
|
|
74
|
+
const initResult = await sdk.init({
|
|
75
|
+
debug: true,
|
|
76
|
+
screenshot: {
|
|
77
|
+
engine: 'modern-screenshot',
|
|
78
|
+
quality: 0.15,
|
|
79
|
+
compress: true,
|
|
80
|
+
interval: 5000
|
|
81
|
+
},
|
|
82
|
+
iconPosition: { x: 20, y: 80 },
|
|
83
|
+
target: '#app',
|
|
84
|
+
sideAttach: true,
|
|
85
|
+
magnetic: true
|
|
86
|
+
}, {
|
|
87
|
+
sendData: (data) => {
|
|
88
|
+
// 处理截图数据
|
|
89
|
+
chatPopupRef.value?.handleScreenshotData(data)
|
|
90
|
+
}
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
// 获取设备ID等信息
|
|
94
|
+
console.log('Device ID:', initResult.deviceId)
|
|
95
|
+
console.log('Referrer:', initResult.referrer)
|
|
96
|
+
|
|
97
|
+
// 图标点击打开弹窗
|
|
98
|
+
sdk.onIconClick(async () => {
|
|
99
|
+
chatVisible.value = true
|
|
100
|
+
|
|
101
|
+
// 启用截图
|
|
102
|
+
const config = await fetchScreenshotConfig()
|
|
103
|
+
if (config) {
|
|
104
|
+
sdk?.triggerScreenshotConfig(JSON.stringify(config))
|
|
105
|
+
}
|
|
106
|
+
})
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
onUnmounted(() => {
|
|
110
|
+
sdk?.destroy()
|
|
111
|
+
})
|
|
112
|
+
</script>
|
|
95
113
|
```
|
|
96
114
|
|
|
97
|
-
###
|
|
115
|
+
### React 示例
|
|
116
|
+
|
|
117
|
+
```tsx
|
|
118
|
+
import { useEffect, useRef, useState } from 'react'
|
|
119
|
+
import { CustomerSDK } from 'customer-chat-sdk'
|
|
120
|
+
|
|
121
|
+
function App() {
|
|
122
|
+
const [chatVisible, setChatVisible] = useState(false)
|
|
123
|
+
const sdkRef = useRef<CustomerSDK | null>(null)
|
|
124
|
+
|
|
125
|
+
useEffect(() => {
|
|
126
|
+
const sdk = new CustomerSDK()
|
|
127
|
+
sdkRef.current = sdk
|
|
128
|
+
|
|
129
|
+
sdk.init({
|
|
130
|
+
debug: true,
|
|
131
|
+
screenshot: {
|
|
132
|
+
engine: 'modern-screenshot',
|
|
133
|
+
quality: 0.15,
|
|
134
|
+
compress: true
|
|
135
|
+
},
|
|
136
|
+
iconPosition: { x: 20, y: 80 },
|
|
137
|
+
target: '#app'
|
|
138
|
+
}, {
|
|
139
|
+
sendData: (data) => {
|
|
140
|
+
// 发送截图数据到后端
|
|
141
|
+
fetch('/api/upload-screenshot', {
|
|
142
|
+
method: 'POST',
|
|
143
|
+
headers: { 'Content-Type': 'application/octet-stream' },
|
|
144
|
+
body: data.data
|
|
145
|
+
})
|
|
146
|
+
}
|
|
147
|
+
}).then((initResult) => {
|
|
148
|
+
// 获取设备ID等信息
|
|
149
|
+
console.log('Device ID:', initResult.deviceId)
|
|
150
|
+
|
|
151
|
+
sdk.onIconClick(async () => {
|
|
152
|
+
setChatVisible(true)
|
|
153
|
+
const config = await fetchScreenshotConfig()
|
|
154
|
+
if (config) {
|
|
155
|
+
sdk.triggerScreenshotConfig(JSON.stringify(config))
|
|
156
|
+
}
|
|
157
|
+
})
|
|
158
|
+
})
|
|
159
|
+
|
|
160
|
+
return () => {
|
|
161
|
+
sdk.destroy()
|
|
162
|
+
}
|
|
163
|
+
}, [])
|
|
164
|
+
|
|
165
|
+
return <div id="app">...</div>
|
|
166
|
+
}
|
|
167
|
+
```
|
|
98
168
|
|
|
99
|
-
|
|
100
|
-
// 高级配置
|
|
101
|
-
await CustomerSDK.init({
|
|
102
|
-
agent: 'your_agent_id',
|
|
103
|
-
token: 'your_jwt_token',
|
|
104
|
-
iframeUrl: 'https://chat.example.com',
|
|
105
|
-
debug: true,
|
|
106
|
-
// 截图配置(可选)
|
|
107
|
-
screenshot: {
|
|
108
|
-
interval: 5000, // 截图间隔(毫秒),默认5000
|
|
109
|
-
quality: 0.4, // 图片质量(0-1),默认0.4
|
|
110
|
-
maxWidth: 1600, // 最大宽度,默认1600
|
|
111
|
-
maxHeight: 900, // 最大高度,默认900
|
|
112
|
-
outputFormat: 'webp', // 输出格式:'webp' | 'jpeg' | 'png',默认webp
|
|
113
|
-
engine: 'html2canvas', // 截图引擎(仅支持html2canvas)
|
|
114
|
-
compress: false, // 是否启用前端压缩,默认false
|
|
115
|
-
enableCORS: true, // 是否启用CORS处理,默认true
|
|
116
|
-
corsMode: 'canvas-proxy', // CORS处理模式,默认canvas-proxy
|
|
117
|
-
silentMode: false // 静默模式,减少控制台输出,默认false
|
|
118
|
-
}
|
|
119
|
-
}, {
|
|
120
|
-
// iframe选项(可选)
|
|
121
|
-
width: 400,
|
|
122
|
-
height: 600,
|
|
123
|
-
mode: 'auto', // 'auto' | 'fullscreen' | 'popup'
|
|
124
|
-
draggable: false,
|
|
125
|
-
resizable: false,
|
|
126
|
-
allowClose: true,
|
|
127
|
-
// 图标位置配置(可选)
|
|
128
|
-
iconPosition: {
|
|
129
|
-
x: 20, // 距离左边的距离(像素或CSS值,如'20px'、'10%')
|
|
130
|
-
y: 80 // 距离顶部的距离(像素或CSS值,如'80px'、'10%')
|
|
131
|
-
}
|
|
132
|
-
});
|
|
169
|
+
## API 文档
|
|
133
170
|
|
|
134
|
-
|
|
135
|
-
CustomerSDK.setScreenshotTarget(document.getElementById('my-container'));
|
|
171
|
+
### CustomerSDK 类
|
|
136
172
|
|
|
137
|
-
|
|
138
|
-
await CustomerSDK.captureScreenshot();
|
|
173
|
+
#### 构造函数
|
|
139
174
|
|
|
140
|
-
|
|
141
|
-
const
|
|
142
|
-
console.log('截图状态:', state);
|
|
175
|
+
```typescript
|
|
176
|
+
const sdk = new CustomerSDK()
|
|
143
177
|
```
|
|
144
178
|
|
|
145
|
-
|
|
179
|
+
#### init(config, screenshotCallback?)
|
|
146
180
|
|
|
147
|
-
|
|
181
|
+
初始化 SDK
|
|
182
|
+
|
|
183
|
+
```typescript
|
|
184
|
+
const initResult = await sdk.init(config, screenshotCallback?)
|
|
185
|
+
```
|
|
148
186
|
|
|
149
|
-
|
|
187
|
+
**返回值:**
|
|
150
188
|
|
|
151
|
-
|
|
189
|
+
返回 `InitResult` 对象,包含:
|
|
190
|
+
- `deviceId: string` - 设备ID(md5后的)
|
|
191
|
+
- `referrer: string` - 页面来源
|
|
192
|
+
- `agent?: string` - 代理商ID(如果配置了)
|
|
193
|
+
- `timestamp: number` - 初始化时间戳
|
|
152
194
|
|
|
153
195
|
**参数:**
|
|
154
196
|
|
|
155
|
-
- `config
|
|
156
|
-
- `
|
|
197
|
+
- `config: SDKConfig` - SDK 配置
|
|
198
|
+
- `screenshotCallback?: ScreenshotMessageCallback` - 截图回调(可选)
|
|
199
|
+
|
|
200
|
+
**配置选项:**
|
|
157
201
|
|
|
158
|
-
**SDKConfig:**
|
|
159
202
|
```typescript
|
|
160
203
|
interface SDKConfig {
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
204
|
+
debug?: boolean // 调试模式
|
|
205
|
+
screenshot?: ScreenshotOptions // 截图配置
|
|
206
|
+
iconPosition?: { // 图标位置
|
|
207
|
+
x?: number | string
|
|
208
|
+
y?: number | string
|
|
209
|
+
}
|
|
210
|
+
target?: HTMLElement | string // 图标挂载目标
|
|
211
|
+
sideAttach?: boolean // 侧边吸附(默认 true)
|
|
212
|
+
sideHideRatio?: number // 侧边隐藏比例(默认 0.5)
|
|
213
|
+
magnetic?: boolean // 磁性吸附(默认 true)
|
|
214
|
+
magneticDirection?: 'x' | 'y' | 'both' // 磁性方向(默认 'x')
|
|
215
|
+
margin?: number // 边距(默认 10px)
|
|
216
|
+
autoAttachDelay?: number // 自动吸附延迟(默认 3000ms)
|
|
217
|
+
referrer?: string // 页面来源
|
|
218
|
+
agent?: string // 代理商ID
|
|
219
|
+
token?: string // 认证令牌
|
|
166
220
|
}
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
**截图配置:**
|
|
167
224
|
|
|
225
|
+
```typescript
|
|
168
226
|
interface ScreenshotOptions {
|
|
169
|
-
|
|
170
|
-
quality?: number
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
corsMode?: 'simple' | 'smart' | 'proxy' | 'blob' | 'canvas-proxy' | 'ignore' | 'test-first'; // CORS处理模式,默认canvas-proxy
|
|
181
|
-
silentMode?: boolean; // 静默模式,减少控制台输出,默认false
|
|
182
|
-
maxRetries?: number; // 最大重试次数,默认2
|
|
227
|
+
engine?: 'modern-screenshot' | 'snapdom' | 'html2canvas'
|
|
228
|
+
quality?: number // 0-1,默认 0.15
|
|
229
|
+
compress?: boolean // 是否压缩
|
|
230
|
+
interval?: number // 默认间隔(毫秒)
|
|
231
|
+
maxWidth?: number // 最大宽度
|
|
232
|
+
maxHeight?: number // 最大高度
|
|
233
|
+
outputFormat?: 'webp' | 'jpeg' | 'png'
|
|
234
|
+
enableCORS?: boolean // 启用 CORS
|
|
235
|
+
proxyUrl?: string // 代理 URL
|
|
236
|
+
corsMode?: 'simple' | 'smart' | 'proxy' | 'blob' | 'canvas-proxy'
|
|
237
|
+
debug?: boolean // 截图调试
|
|
183
238
|
}
|
|
184
239
|
```
|
|
185
240
|
|
|
186
|
-
|
|
187
|
-
```typescript
|
|
188
|
-
interface ChatWindowOptions {
|
|
189
|
-
width?: number; // iframe宽度
|
|
190
|
-
height?: number; // iframe高度
|
|
191
|
-
position?: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left';
|
|
192
|
-
draggable?: boolean; // 是否可拖拽
|
|
193
|
-
resizable?: boolean; // 是否可调整大小
|
|
194
|
-
minimizable?: boolean; // 是否可最小化
|
|
195
|
-
iconPosition?: IconPosition; // 图标位置配置
|
|
196
|
-
}
|
|
241
|
+
**截图回调:**
|
|
197
242
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
243
|
+
```typescript
|
|
244
|
+
interface ScreenshotMessageCallback {
|
|
245
|
+
sendData?: (data: {
|
|
246
|
+
type: 'screenshotBinary'
|
|
247
|
+
data: ArrayBuffer
|
|
248
|
+
}) => void
|
|
249
|
+
onConfig?: (config: string) => void
|
|
201
250
|
}
|
|
202
251
|
```
|
|
203
252
|
|
|
204
|
-
|
|
253
|
+
#### onIconClick(callback)
|
|
205
254
|
|
|
206
|
-
|
|
255
|
+
设置图标点击回调(也可以在 init 中配置)
|
|
207
256
|
|
|
208
|
-
|
|
257
|
+
```typescript
|
|
258
|
+
// 方式1: 使用函数式 API(default 导出)- 可以直接调用
|
|
259
|
+
const CustomerSDK = await import('customer-chat-sdk')
|
|
260
|
+
await CustomerSDK.default.init(config)
|
|
261
|
+
CustomerSDK.default.onIconClick(() => {
|
|
262
|
+
openChatPopup()
|
|
263
|
+
})
|
|
264
|
+
|
|
265
|
+
// 方式2: 使用类(命名导出)- 在 init 中配置(推荐)
|
|
266
|
+
const sdk = new CustomerSDK()
|
|
267
|
+
await sdk.init(config, screenshotCallback, {
|
|
268
|
+
onIconClick: () => {
|
|
269
|
+
openChatPopup()
|
|
270
|
+
}
|
|
271
|
+
})
|
|
272
|
+
|
|
273
|
+
// 方式3: 使用类(命名导出)- 单独设置
|
|
274
|
+
const sdk = new CustomerSDK()
|
|
275
|
+
await sdk.init(config)
|
|
276
|
+
sdk.onIconClick(() => {
|
|
277
|
+
openChatPopup()
|
|
278
|
+
})
|
|
279
|
+
```
|
|
209
280
|
|
|
210
|
-
####
|
|
281
|
+
#### updateToken(token, screenshotCallback?, initCallback?)
|
|
211
282
|
|
|
212
|
-
|
|
283
|
+
更新 token(用于用户登录/退出场景)
|
|
213
284
|
|
|
214
|
-
|
|
285
|
+
```typescript
|
|
286
|
+
// 更新 token(会自动重新初始化)
|
|
287
|
+
await sdk.updateToken('new-token')
|
|
215
288
|
|
|
216
|
-
|
|
289
|
+
// 更新 token 并更新回调
|
|
290
|
+
await sdk.updateToken('new-token', {
|
|
291
|
+
sendData: (data) => { /* ... */ }
|
|
292
|
+
}, {
|
|
293
|
+
onIconClick: () => { /* ... */ }
|
|
294
|
+
})
|
|
295
|
+
```
|
|
217
296
|
|
|
218
|
-
|
|
219
|
-
- `position` ('top-left' | 'top-right' | 'bottom-left' | 'bottom-right'): 预设位置
|
|
297
|
+
#### showNotification(badgeCount, options?)
|
|
220
298
|
|
|
221
|
-
|
|
299
|
+
显示通知
|
|
222
300
|
|
|
223
|
-
|
|
301
|
+
```typescript
|
|
302
|
+
sdk.showNotification(5, { pulse: true, autoHide: 5000 })
|
|
303
|
+
sdk.showNotification('新', { pulse: true })
|
|
304
|
+
```
|
|
224
305
|
|
|
225
|
-
|
|
226
|
-
- `position` (IconPosition): 位置配置对象
|
|
227
|
-
```typescript
|
|
228
|
-
{
|
|
229
|
-
x?: number | string; // x坐标(像素值或CSS值)
|
|
230
|
-
y?: number | string; // y坐标(像素值或CSS值)
|
|
231
|
-
}
|
|
232
|
-
```
|
|
306
|
+
#### clearNotification()
|
|
233
307
|
|
|
234
|
-
|
|
235
|
-
```javascript
|
|
236
|
-
// 使用像素值
|
|
237
|
-
CustomerSDK.setIconCoordinates({ x: 50, y: 100 });
|
|
308
|
+
清除通知
|
|
238
309
|
|
|
239
|
-
|
|
240
|
-
|
|
310
|
+
```typescript
|
|
311
|
+
sdk.clearNotification()
|
|
241
312
|
```
|
|
242
313
|
|
|
243
|
-
####
|
|
244
|
-
|
|
245
|
-
设置截图目标元素。默认截图目标为 `document.body`。
|
|
314
|
+
#### triggerScreenshotConfig(configJson)
|
|
246
315
|
|
|
247
|
-
|
|
248
|
-
- `element` (HTMLElement): 要截图的DOM元素
|
|
316
|
+
启用/停止截图
|
|
249
317
|
|
|
250
|
-
|
|
318
|
+
```typescript
|
|
319
|
+
// 启用截图
|
|
320
|
+
const config = {
|
|
321
|
+
agent: 'your-agent-id',
|
|
322
|
+
sign: 'your-sign',
|
|
323
|
+
type: 1,
|
|
324
|
+
topic: 'screenshot',
|
|
325
|
+
routingKey: 'route-key',
|
|
326
|
+
ttl: Date.now() + 3600000, // 1小时后过期
|
|
327
|
+
duration: 5000 // 5秒间隔
|
|
328
|
+
}
|
|
329
|
+
sdk.triggerScreenshotConfig(JSON.stringify(config))
|
|
251
330
|
|
|
252
|
-
|
|
331
|
+
// 停止截图
|
|
332
|
+
sdk.triggerScreenshotConfig(JSON.stringify({
|
|
333
|
+
...config,
|
|
334
|
+
ttl: 0 // 禁用
|
|
335
|
+
}))
|
|
336
|
+
```
|
|
253
337
|
|
|
254
|
-
|
|
338
|
+
#### showIcon() / hideIcon()
|
|
255
339
|
|
|
256
|
-
|
|
340
|
+
显示/隐藏图标
|
|
257
341
|
|
|
258
|
-
|
|
342
|
+
```typescript
|
|
343
|
+
sdk.showIcon()
|
|
344
|
+
sdk.hideIcon()
|
|
345
|
+
```
|
|
259
346
|
|
|
260
|
-
|
|
261
|
-
- `isRunning`: 是否正在运行
|
|
262
|
-
- `screenshotCount`: 截图次数
|
|
263
|
-
- `lastScreenshotTime`: 最后截图时间
|
|
264
|
-
- `error`: 错误信息
|
|
265
|
-
- `isEnabled`: 是否启用
|
|
266
|
-
- `isUploading`: 是否正在上传
|
|
267
|
-
- `uploadError`: 上传错误
|
|
268
|
-
- `uploadProgress`: 上传进度
|
|
269
|
-
- `currentUploadConfig`: 当前上传配置
|
|
347
|
+
#### getDeviceId()
|
|
270
348
|
|
|
271
|
-
|
|
349
|
+
获取设备ID(md5后的)
|
|
272
350
|
|
|
273
|
-
|
|
351
|
+
```typescript
|
|
352
|
+
const deviceId = sdk.getDeviceId()
|
|
353
|
+
console.log('Device ID:', deviceId)
|
|
354
|
+
```
|
|
274
355
|
|
|
275
|
-
|
|
356
|
+
#### getInitResult()
|
|
276
357
|
|
|
277
|
-
|
|
358
|
+
获取初始化结果(包含设备ID等信息)
|
|
278
359
|
|
|
279
|
-
|
|
360
|
+
```typescript
|
|
361
|
+
const initResult = sdk.getInitResult()
|
|
362
|
+
if (initResult) {
|
|
363
|
+
console.log('Device ID:', initResult.deviceId)
|
|
364
|
+
console.log('Referrer:', initResult.referrer)
|
|
365
|
+
console.log('Timestamp:', initResult.timestamp)
|
|
366
|
+
}
|
|
367
|
+
```
|
|
280
368
|
|
|
281
|
-
|
|
282
|
-
- `data` (any): 要发送的数据
|
|
369
|
+
#### getScreenshotManager() / getIconManager()
|
|
283
370
|
|
|
284
|
-
|
|
371
|
+
获取管理器实例(用于高级操作)
|
|
285
372
|
|
|
286
|
-
|
|
373
|
+
```typescript
|
|
374
|
+
const screenshotManager = sdk.getScreenshotManager()
|
|
375
|
+
const iconManager = sdk.getIconManager()
|
|
376
|
+
```
|
|
287
377
|
|
|
288
|
-
|
|
289
|
-
- `badgeCount` (number | string): 徽章内容(数字或文本)
|
|
290
|
-
- `options` (object?, 可选): { pulse?: boolean, autoHide?: number }
|
|
378
|
+
#### destroy()
|
|
291
379
|
|
|
292
|
-
|
|
380
|
+
销毁 SDK
|
|
293
381
|
|
|
294
|
-
|
|
382
|
+
```typescript
|
|
383
|
+
sdk.destroy()
|
|
384
|
+
```
|
|
295
385
|
|
|
296
|
-
##
|
|
386
|
+
## 完整工作流程
|
|
297
387
|
|
|
298
|
-
|
|
388
|
+
### 1. 初始化
|
|
299
389
|
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
390
|
+
```typescript
|
|
391
|
+
const sdk = new CustomerSDK()
|
|
392
|
+
const initResult = await sdk.init({
|
|
393
|
+
debug: true,
|
|
394
|
+
screenshot: { /* ... */ },
|
|
395
|
+
iconPosition: { x: 20, y: 80 },
|
|
396
|
+
target: '#app'
|
|
397
|
+
}, {
|
|
398
|
+
// 截图回调
|
|
399
|
+
sendData: (data) => {
|
|
400
|
+
// 处理截图数据
|
|
401
|
+
}
|
|
402
|
+
}, {
|
|
403
|
+
// 初始化回调(图标点击)
|
|
404
|
+
onIconClick: async () => {
|
|
405
|
+
openChatPopup()
|
|
406
|
+
// 启用截图
|
|
407
|
+
const config = await fetchScreenshotConfig()
|
|
408
|
+
if (config) {
|
|
409
|
+
sdk.triggerScreenshotConfig(JSON.stringify(config))
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
})
|
|
304
413
|
|
|
305
|
-
|
|
414
|
+
// 获取设备ID等信息
|
|
415
|
+
console.log('Device ID:', initResult.deviceId)
|
|
416
|
+
console.log('Referrer:', initResult.referrer)
|
|
306
417
|
```
|
|
307
|
-
|
|
418
|
+
|
|
419
|
+
### 2. 弹窗打开时启用截图
|
|
420
|
+
|
|
421
|
+
```typescript
|
|
422
|
+
// 方式1: 在 init 中配置(推荐)
|
|
423
|
+
await sdk.init(config, screenshotCallback, {
|
|
424
|
+
onIconClick: async () => {
|
|
425
|
+
openChatPopup()
|
|
426
|
+
const config = await fetchScreenshotConfig()
|
|
427
|
+
sdk.triggerScreenshotConfig(JSON.stringify(config))
|
|
428
|
+
}
|
|
429
|
+
})
|
|
430
|
+
|
|
431
|
+
// 方式2: 单独设置
|
|
432
|
+
sdk.onIconClick(async () => {
|
|
433
|
+
openChatPopup()
|
|
434
|
+
const config = await fetchScreenshotConfig()
|
|
435
|
+
sdk.triggerScreenshotConfig(JSON.stringify(config))
|
|
436
|
+
})
|
|
308
437
|
```
|
|
309
438
|
|
|
310
|
-
|
|
439
|
+
### 2.1. 更新 token
|
|
311
440
|
|
|
312
|
-
|
|
441
|
+
```typescript
|
|
442
|
+
// 用户登录后更新 token
|
|
443
|
+
await sdk.updateToken('new-token')
|
|
444
|
+
```
|
|
313
445
|
|
|
314
|
-
|
|
315
|
-
- 悬浮图标:默认右下角,可自定义位置(x, y坐标),支持拖拽移动
|
|
316
|
-
- 聊天窗口:居中弹窗,可通过iframe发送`close`消息关闭
|
|
446
|
+
### 3. 弹窗关闭时停止截图
|
|
317
447
|
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
448
|
+
```typescript
|
|
449
|
+
function closeChatPopup() {
|
|
450
|
+
closePopup()
|
|
451
|
+
sdk.triggerScreenshotConfig(JSON.stringify({
|
|
452
|
+
...config,
|
|
453
|
+
ttl: 0
|
|
454
|
+
}))
|
|
455
|
+
}
|
|
456
|
+
```
|
|
321
457
|
|
|
322
|
-
|
|
458
|
+
### 4. 清理
|
|
323
459
|
|
|
324
|
-
|
|
460
|
+
```typescript
|
|
461
|
+
onUnmounted(() => {
|
|
462
|
+
sdk?.destroy()
|
|
463
|
+
})
|
|
464
|
+
```
|
|
325
465
|
|
|
326
|
-
|
|
327
|
-
- pnpm >= 8 (推荐) 或 npm >= 9
|
|
466
|
+
## 常见场景
|
|
328
467
|
|
|
329
|
-
###
|
|
468
|
+
### 只使用图标功能
|
|
330
469
|
|
|
331
|
-
```
|
|
332
|
-
|
|
333
|
-
|
|
470
|
+
```typescript
|
|
471
|
+
const sdk = new CustomerSDK()
|
|
472
|
+
await sdk.init({
|
|
473
|
+
debug: true,
|
|
474
|
+
iconPosition: { x: 20, y: 80 },
|
|
475
|
+
target: '#app'
|
|
476
|
+
})
|
|
334
477
|
|
|
335
|
-
|
|
336
|
-
|
|
478
|
+
sdk.onIconClick(() => {
|
|
479
|
+
openChatPopup()
|
|
480
|
+
})
|
|
337
481
|
```
|
|
338
482
|
|
|
339
|
-
###
|
|
483
|
+
### 图标 + 截图
|
|
340
484
|
|
|
341
|
-
```
|
|
342
|
-
|
|
343
|
-
|
|
485
|
+
```typescript
|
|
486
|
+
const sdk = new CustomerSDK()
|
|
487
|
+
await sdk.init({
|
|
488
|
+
screenshot: {
|
|
489
|
+
engine: 'modern-screenshot',
|
|
490
|
+
quality: 0.15,
|
|
491
|
+
compress: true
|
|
492
|
+
}
|
|
493
|
+
}, {
|
|
494
|
+
sendData: (data) => {
|
|
495
|
+
sendToBackend(data)
|
|
496
|
+
}
|
|
497
|
+
})
|
|
498
|
+
```
|
|
344
499
|
|
|
345
|
-
|
|
346
|
-
pnpm demo
|
|
500
|
+
## 注意事项
|
|
347
501
|
|
|
348
|
-
|
|
349
|
-
|
|
502
|
+
1. **调试模式**:生产环境请关闭 `debug: true`
|
|
503
|
+
2. **截图性能**:合理设置截图间隔,避免过于频繁
|
|
504
|
+
3. **内存管理**:及时调用 `destroy()` 清理资源
|
|
505
|
+
4. **错误处理**:所有异步操作都应添加错误处理
|
|
506
|
+
5. **CORS 问题**:如果遇到跨域问题,配置 `proxyUrl` 或调整 `corsMode`
|
|
350
507
|
|
|
351
|
-
|
|
352
|
-
pnpm lint
|
|
508
|
+
## 动态导入示例
|
|
353
509
|
|
|
354
|
-
|
|
355
|
-
pnpm format
|
|
510
|
+
### 方式 1: 使用类(推荐)
|
|
356
511
|
|
|
357
|
-
|
|
358
|
-
|
|
512
|
+
```typescript
|
|
513
|
+
const initCustomerSDK = async () => {
|
|
514
|
+
// 动态导入
|
|
515
|
+
const mod = await import('customer-chat-sdk')
|
|
516
|
+
|
|
517
|
+
// 获取 CustomerSDK 类(命名导出)
|
|
518
|
+
const { CustomerSDK } = mod
|
|
519
|
+
|
|
520
|
+
// ✅ 重要:必须先实例化
|
|
521
|
+
const sdk = new CustomerSDK()
|
|
522
|
+
|
|
523
|
+
// 初始化(调用实例方法)
|
|
524
|
+
const initResult = await sdk.init({
|
|
525
|
+
debug: true,
|
|
526
|
+
iconPosition: { x: 20, y: 80 },
|
|
527
|
+
target: '#app'
|
|
528
|
+
}, {
|
|
529
|
+
sendData: (data) => {
|
|
530
|
+
// 处理截图数据
|
|
531
|
+
}
|
|
532
|
+
})
|
|
533
|
+
|
|
534
|
+
// 设置图标点击回调(调用实例方法)
|
|
535
|
+
sdk.onIconClick(() => {
|
|
536
|
+
openChatPopup()
|
|
537
|
+
})
|
|
538
|
+
|
|
539
|
+
return sdk
|
|
540
|
+
}
|
|
359
541
|
```
|
|
360
542
|
|
|
361
|
-
###
|
|
543
|
+
### 方式 2: 使用函数式 API(default 导出)
|
|
362
544
|
|
|
363
|
-
```
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
545
|
+
```typescript
|
|
546
|
+
const initCustomerSDK = async () => {
|
|
547
|
+
// 动态导入
|
|
548
|
+
const mod = await import('customer-chat-sdk')
|
|
549
|
+
|
|
550
|
+
// 获取 default 导出(函数式 API)
|
|
551
|
+
const SDK = mod.default
|
|
552
|
+
|
|
553
|
+
// ✅ 直接调用函数(不需要实例化)
|
|
554
|
+
const initResult = await SDK.init({
|
|
555
|
+
debug: true,
|
|
556
|
+
iconPosition: { x: 20, y: 80 },
|
|
557
|
+
target: '#app'
|
|
558
|
+
})
|
|
559
|
+
|
|
560
|
+
// 使用其他函数式 API
|
|
561
|
+
SDK.showIcon()
|
|
562
|
+
SDK.showNotification(5)
|
|
563
|
+
|
|
564
|
+
return SDK
|
|
565
|
+
}
|
|
371
566
|
```
|
|
372
567
|
|
|
373
|
-
|
|
568
|
+
**注意**:函数式 API 使用全局单例,只能有一个实例。如果需要多个实例或更好的类型支持,推荐使用类的方式。
|
|
374
569
|
|
|
375
|
-
|
|
570
|
+
### 兼容性动态导入(自动检测)
|
|
376
571
|
|
|
377
|
-
```
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
572
|
+
```typescript
|
|
573
|
+
const initCustomerSDK = async () => {
|
|
574
|
+
const mod = await import('customer-chat-sdk')
|
|
575
|
+
|
|
576
|
+
// 优先使用类的方式(推荐)
|
|
577
|
+
if (mod.CustomerSDK && typeof mod.CustomerSDK === 'function') {
|
|
578
|
+
const sdk = new mod.CustomerSDK()
|
|
579
|
+
await sdk.init({ /* ... */ })
|
|
580
|
+
sdk.onIconClick(() => { /* ... */ })
|
|
581
|
+
return sdk
|
|
383
582
|
}
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
583
|
+
|
|
584
|
+
// 回退到函数式 API
|
|
585
|
+
if (mod.default && mod.default.init) {
|
|
586
|
+
const SDK = mod.default
|
|
587
|
+
await SDK.init({ /* ... */ })
|
|
588
|
+
SDK.showIcon()
|
|
589
|
+
return SDK
|
|
390
590
|
}
|
|
391
|
-
|
|
591
|
+
|
|
592
|
+
throw new Error('CustomerSDK 未找到')
|
|
593
|
+
}
|
|
392
594
|
```
|
|
393
595
|
|
|
394
|
-
##
|
|
596
|
+
## 类型定义
|
|
395
597
|
|
|
396
|
-
|
|
598
|
+
```typescript
|
|
599
|
+
import type {
|
|
600
|
+
CustomerSDK,
|
|
601
|
+
ScreenshotMessageCallback,
|
|
602
|
+
SDKConfig,
|
|
603
|
+
ScreenshotOptions,
|
|
604
|
+
InitResult
|
|
605
|
+
} from 'customer-chat-sdk'
|
|
606
|
+
```
|
|
397
607
|
|
|
398
|
-
##
|
|
608
|
+
## 许可证
|
|
399
609
|
|
|
400
|
-
|
|
610
|
+
MIT
|