joytalk 0.0.21 → 0.0.23

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 CHANGED
@@ -29,6 +29,7 @@ pnpm add joytalk
29
29
  ## API 方法
30
30
 
31
31
  ### 初始化
32
+
32
33
  初始化 SDK,传入 token 等配置。**使用前必须调用一次。**
33
34
 
34
35
  **参数说明:**
@@ -39,8 +40,10 @@ pnpm add joytalk
39
40
  | `reconnectInterval` | 重连间隔(毫秒) | 否 | 3000 |
40
41
  | `maxReconnectAttempts` | 最大重连次数 | 否 | 5 |
41
42
  | `responseTimeout` | 响应消息超时时间(毫秒) | 否 | 10000 |
43
+ | `env` | 环境(development, prodtest, production) | 否 | production |
42
44
 
43
45
  **示例:**
46
+
44
47
  ```typescript
45
48
  import JoyTalk, { EventType, ChatType, MessageCode } from 'joytalk';
46
49
 
@@ -48,16 +51,19 @@ import JoyTalk, { EventType, ChatType, MessageCode } from 'joytalk';
48
51
  const JTalk = new JoyTalk();
49
52
 
50
53
  // 初始化:传入 token 等配置(必须在使用前调用)
51
- await JTalk.init({
54
+ JTalk.init({
52
55
  token: 'your-token',
53
56
  });
54
57
  ```
55
58
 
59
+ ---
60
+
56
61
  ### 获取咨询列表
57
- 通过 `getConsultationList` 方法,传入入口ID,获取咨询列表。
58
62
 
63
+ 通过 `getConsultationList` 方法,传入入口 ID,获取咨询列表。
59
64
 
60
65
  **示例:**
66
+
61
67
  ```typescript
62
68
  const entranceId = '123456';
63
69
  // 获取咨询列表
@@ -79,20 +85,22 @@ console.log(result);
79
85
 
80
86
  **ConsultationItem 类型定义:**
81
87
 
82
- | 参数 | 说明 |
83
- |------|------|
84
- | `id` | 咨询类型 ID |
85
- | `customerGroupId` | 客服组 ID |
86
- | `guideText` | 引导文案 |
87
- | `name` | 咨询类型名称 |
88
- | `isDefault` | 是否默认 |
88
+ | 参数 | 说明 |
89
+ | ----------------- | ------------ |
90
+ | `id` | 咨询类型 ID |
91
+ | `customerGroupId` | 客服组 ID |
92
+ | `guideText` | 引导文案 |
93
+ | `name` | 咨询类型名称 |
94
+ | `isDefault` | 是否默认 |
89
95
 
90
96
  ---
91
97
 
92
98
  ### 获取用户信息
99
+
93
100
  通过 `getUserInfo` 方法,获取用户信息。
94
101
 
95
102
  **示例:**
103
+
96
104
  ```typescript
97
105
  // 获取用户信息
98
106
  const userInfo = await JTalk.getUserInfo();
@@ -102,21 +110,23 @@ console.log(userInfo);
102
110
  **返回值说明:**
103
111
  | 参数 | 说明 |
104
112
  |------|------|
105
- | `uuid` | 用户ID |
106
- | `merchantId` | 商户ID |
113
+ | `uuid` | 用户 ID |
114
+ | `merchantId` | 商户 ID |
107
115
  | `nickname` | 用户昵称 |
108
116
  | `avatar` | 用户头像 |
109
117
  | `userSource` | 用户来源 |
110
- | `externalUserId` | 外部用户ID |
111
- | `userIp` | 用户IP |
118
+ | `externalUserId` | 外部用户 ID |
119
+ | `userIp` | 用户 IP |
112
120
  | `isAnonymous` | 是否匿名 |
113
121
 
114
122
  ---
115
123
 
116
124
  ### 连接到服务器
125
+
117
126
  通过 `connect` 方法,连接到服务器。
118
127
 
119
128
  **示例:**
129
+
120
130
  ```typescript
121
131
  const consultationTypeId = '123456';
122
132
  // 连接到服务器
@@ -130,10 +140,12 @@ JTalk.connect(consultationTypeId);
130
140
 
131
141
  ---
132
142
 
133
- ### 监听消息事件
143
+ ### 监听WebSocket事件
144
+
134
145
  通过 `on` 方法,监听消息事件。
135
146
 
136
147
  **示例:**
148
+
137
149
  ```typescript
138
150
  // 监听连接事件
139
151
  JTalk.on(EventType.CONNECTED, () => {
@@ -143,7 +155,7 @@ JTalk.on(EventType.CONNECTED, () => {
143
155
  // 监听消息事件
144
156
  JTalk.on(EventType.MESSAGE, (message) => {
145
157
  console.log('收到消息:', message);
146
-
158
+
147
159
  // 根据消息类型处理
148
160
  switch (message.code) {
149
161
  case MessageCode.SEND_SUCCESS:
@@ -166,6 +178,16 @@ JTalk.on(EventType.STATUS_CHANGE, (status) => {
166
178
  console.log('连接状态变化:', status);
167
179
  });
168
180
 
181
+ // 监听心跳超时事件
182
+ JTalk.on(EventType.HEARTBEAT_TIMEOUT, () => {
183
+ console.log('心跳超时');
184
+ });
185
+
186
+ // 监听连接断开事件
187
+ JTalk.on(EventType.DISCONNECTED, () => {
188
+ console.log('连接断开');
189
+ });
190
+
169
191
  ```
170
192
 
171
193
  **参数说明:**
@@ -175,6 +197,7 @@ JTalk.on(EventType.STATUS_CHANGE, (status) => {
175
197
  | `callback` | 回调函数 | 是 | - |
176
198
 
177
199
  **EventType 枚举:**
200
+
178
201
  - `EventType.CONNECTED` - 连接成功
179
202
  - `EventType.DISCONNECTED` - 连接断开
180
203
  - `EventType.ERROR` - 发生错误
@@ -182,27 +205,123 @@ JTalk.on(EventType.STATUS_CHANGE, (status) => {
182
205
  - `EventType.STATUS_CHANGE` - 连接状态变化
183
206
  - `EventType.HEARTBEAT_TIMEOUT` - 心跳超时
184
207
 
208
+ ---
209
+ ### 消息处理示例
210
+
211
+ 通过监听 `EventType.MESSAGE`,根据 `message.code` 区分消息类型并处理。
212
+
213
+ **示例:**
214
+
215
+ ```typescript
216
+ JTalk.on(EventType.MESSAGE, (message) => {
217
+ const msgData = message.data
218
+ // 根据消息类型处理
219
+ switch (message.code) {
220
+ case MessageCode.MATCH_INFO:
221
+ case MessageCode.MATCH_SUCCESS:
222
+ case MessageCode.TRANSFER_USER_SUCCESS:
223
+ case MessageCode.REMATCH:
224
+ // 匹配成功/分配成功/转接成功/重新匹配,msgData 为 SessionData 类型
225
+ sessionData.value = msgData
226
+ if (message.code === MessageCode.MATCH_INFO || message.code === MessageCode.MATCH_SUCCESS) {
227
+ // 匹配成功/分配成功,获取聊天记录
228
+ getHistoryMessages()
229
+ }
230
+ break
231
+ case MessageCode.MATCH_FAIL:
232
+ console.error(message.msg || '匹配失败')
233
+ break
234
+ case MessageCode.SEND_SUCCESS:
235
+ case MessageCode.REPLY_SUCCESS:
236
+ // 发送成功/回复成功,msgData 为 MessageData 类型
237
+ console.log('收到回复消息', msgData)
238
+ break
239
+ case MessageCode.RETRACT:
240
+ // 撤回消息,msgData 为 MessageData 类型
241
+ console.log('收到撤回消息', msgData)
242
+ console.log('撤回消息的 messageId', messageId)
243
+ break
244
+ case MessageCode.EDIT:
245
+ // 编辑消息,msgData 为 MessageData 类型
246
+ console.log('收到编辑消息', msgData)
247
+ console.log('编辑消息的 messageId', messageId)
248
+ console.log('编辑后消息的内容', msgData.content)
249
+ break
250
+ default:
251
+ console.log('收到其他消息', msgData)
252
+ break
253
+ }
254
+ });
255
+ ```
256
+
185
257
  **MessageCode 枚举:**
258
+
186
259
  - `MessageCode.CONNECT_SUCCESS` - 连接成功
187
260
  - `MessageCode.CONNECT_FAILED` - 连接失败
188
- - `MessageCode.MATCH_INFO` / `MessageCode.MATCH_SUCCESS` - 匹配成功
261
+ - `MessageCode.TRANSFER_CUSTOMER_SUCCESS` - 转接成功通知原客服
262
+ - `MessageCode.TRANSFER_TO_CUSTOMER_SUCCESS` - 转接成功通知转接客服
263
+ - `MessageCode.TRANSFER_USER_SUCCESS` - 转接成功通知用户
264
+ - `MessageCode.TRANSFER_FAIL` - 转接失败
189
265
  - `MessageCode.MATCH_FAIL` - 匹配失败
190
- - `MessageCode.SEND_SUCCESS` - 发送成功
191
- - `MessageCode.SEND_CALLBACK` - 发送回调
266
+ - `MessageCode.MATCH_INFO` - 匹配成功,返回信息
267
+ - `MessageCode.MATCH_SUCCESS` - 分配成功
192
268
  - `MessageCode.RETRACT` - 撤回
269
+ - `MessageCode.RETRACT_FAIL` - 撤回失败
193
270
  - `MessageCode.EDIT` - 编辑
194
- - `MessageCode.TRANSFER_*` - 转接相关
271
+ - `MessageCode.EDIT_FAIL` - 编辑失败
195
272
  - `MessageCode.COMMON_FAIL` - 通用错误
273
+ - `MessageCode.SEND_SUCCESS` - 发送成功
274
+ - `MessageCode.SEND_CALLBACK` - 发送回调
275
+ - `MessageCode.CHANGE_CHAT_STATUS` - 变更会话状态
276
+ - `MessageCode.REPLY_FAIL` - 回复消息失败
277
+ - `MessageCode.REPLY_SUCCESS` - 回复消息成功
278
+ - `MessageCode.UNBIND_SUCCESS` - 解绑成功
279
+ - `MessageCode.REMATCH` - 重新匹配
280
+
281
+
282
+ ---
283
+
284
+ ### 获取聊天记录
285
+
286
+ 通过 `getHistoryMessages` 方法,获取聊天记录。
287
+ **注意:该方法需在已匹配客服后调用。**
288
+
289
+ **示例:**
290
+
291
+ ```typescript
292
+ const getHistoryMessages = async (lastMsgId?: string) => {
293
+ const { list, hasMore } = await JTalk.getHistoryMessages({ lastMsgId, size: 50 });
294
+ console.log(list, hasMore);
295
+ return { list, hasMore };
296
+ };
297
+ ```
298
+
299
+ **参数说明:**
300
+
301
+ | 参数 | 说明 | 是否必填 | 默认值 |
302
+ | ----------- | --------------------- | -------- | ------ |
303
+ | `lastMsgId` | 上一页最后一条消息 ID | 否 | - |
304
+ | `size` | 每页条数 | 否 | 50 |
305
+
306
+ **返回值说明:**
307
+
308
+ | 返回值 | 说明 |
309
+ | --------- | -------------- |
310
+ | `list` | 消息列表 |
311
+ | `hasMore` | 是否有更多数据 |
196
312
 
197
313
  ---
198
314
 
199
315
  ### 发送文本消息
316
+
200
317
  通过 `sendText` 方法,发送文本消息。
201
318
 
202
319
  **示例:**
320
+
203
321
  ```typescript
204
- const content = '你好,我需要帮助';
205
- JTalk.sendText(content);
322
+ const content = '你好!';
323
+ const { messageId } = await JTalk.sendText(content);
324
+ console.log(messageId);
206
325
  ```
207
326
 
208
327
  **参数说明:**
@@ -210,77 +329,101 @@ JTalk.sendText(content);
210
329
  |------|------|----------|--------|
211
330
  | `content` | 消息内容 | 是 | - |
212
331
 
213
- ### 发送文件消息(图片 / 文件)
214
- 通过 `sendFile` 方法,发送图片或普通文件消息(视频见下方「发送视频消息」)。
332
+ **返回值说明:**
333
+
334
+ | 返回值 | 说明 |
335
+ | ----------- | ------- |
336
+ | `messageId` | 消息 ID |
337
+
338
+ ---
339
+
340
+ ### 发送文件消息(图片 / 视频 / 文件)
341
+
342
+ 通过 `sendFile` 方法,发送图片、视频或普通文件消息。
215
343
 
216
344
  **示例:**
345
+
217
346
  ```typescript
218
347
  // 发送图片
219
348
  const file = document.querySelector('input[type="file"]').files?.[0];
220
349
  if (file) {
221
- await JTalk.sendFile({ file, chatType: ChatType.IMAGE });
350
+ const { messageId } = await JTalk.sendFile({ file, chatType: ChatType.IMAGE });
351
+ console.log(messageId);
222
352
  }
223
- // 发送文件
224
- await JTalk.sendFile({ file: docFile, chatType: ChatType.FILE });
225
- ```
226
353
 
227
- **参数说明:**
228
-
229
- | 参数 | 说明 | 是否必填 | 默认值 |
230
- |------|------|----------|--------|
231
- | `file` | 文件对象 | 是 | - |
232
- | `chatType` | 聊天类型:`ChatType.IMAGE` 或 `ChatType.FILE` | 是 | - |
233
-
234
- ### 发送视频消息
235
- 通过 `sendFile` 方法并传入 `ChatType.VIDEO`,发送视频消息。建议先用 `getVideoThumbnail` 生成缩略图再发送。
236
-
237
- **示例:**
238
- ```typescript
354
+ // 发送视频
239
355
  const videoFile = document.querySelector('input[type="file"]').files?.[0];
240
356
  if (videoFile) {
357
+ // 获取视频缩略图
241
358
  const thumbnailFile = await JTalk.getVideoThumbnail(videoFile);
242
- await JTalk.sendFile({
243
- file: videoFile,
244
- thumbnailFile,
245
- chatType: ChatType.VIDEO,
246
- });
359
+ const { messageId } = await JTalk.sendFile({ file: videoFile, thumbnailFile, chatType: ChatType.VIDEO });
360
+ console.log(messageId);
361
+ }
362
+
363
+ // 发送文件
364
+ const file = document.querySelector('input[type="file"]').files?.[0];
365
+ if (file) {
366
+ const { messageId } = await JTalk.sendFile({ file, chatType: ChatType.FILE });
367
+ console.log(messageId);
247
368
  }
248
369
  ```
249
370
 
250
371
  **参数说明:**
251
372
 
252
- | 参数 | 说明 | 是否必填 | 默认值 |
253
- |------|------|----------|--------|
254
- | `file` | 视频文件对象 | 是 | - |
255
- | `thumbnailFile` | 缩略图文件(可选,建议使用 getVideoThumbnail 生成) | 否 | - |
256
- | `chatType` | 固定为 `ChatType.VIDEO` | 是 | - |
373
+ | 参数 | 说明 | 是否必填 | 默认值 |
374
+ | --------------- | ----------------------------------------------------------------- | -------- | ------ |
375
+ | `file` | 文件对象 | 是 | - |
376
+ | `thumbnailFile` | 缩略图文件(可选,建议使用 getVideoThumbnail 生成) | 否 | - |
377
+ | `chatType` | 聊天类型:`ChatType.IMAGE` `ChatType.VIDEO` 或 `ChatType.FILE` | 是 | - |
257
378
 
258
- ### 获取聊天记录
259
- 通过 `getHistoryMessages` 方法,获取聊天记录。需在已匹配客服后调用。
379
+ **返回值说明:**
380
+
381
+ | 返回值 | 说明 |
382
+ | ----------- | ------- |
383
+ | `messageId` | 消息 ID |
384
+
385
+ ---
386
+
387
+ ### 发送 FAQ 消息
388
+
389
+ 点击 FAQ 问题时,通过 `sendFaq` 方法,将该 FAQ 问题对象作为参数传入,SDK 会自动返回该 FAQ 问题的答案。
260
390
 
261
391
  **示例:**
392
+
262
393
  ```typescript
263
- const { list, hasMore } = await JTalk.getHistoryMessages({ size: 50 });
264
- // 加载更多
265
- const next = await JTalk.getHistoryMessages({
266
- lastMsgId: list[0]?.messageId,
267
- size: 50,
268
- });
394
+ const faqItem = {
395
+ faqId: 1,
396
+ faqItemId: 1,
397
+ id: 1,
398
+ imageUrl: ['https://example.com/image.jpg'],
399
+ question: '问题',
400
+ answer: '答案',
401
+ sortOrder: 1,
402
+ isMulti: false,
403
+ item: [],
404
+ };
405
+ await JTalk.sendFaq(faqItem);
269
406
  ```
270
407
 
271
408
  **参数说明:**
272
409
 
273
- | 参数 | 说明 | 是否必填 | 默认值 |
274
- |------|------|----------|--------|
275
- | `lastMsgId` | 上一页最后一条消息 ID | | - |
276
- | `size` | 每页条数 | 否 | 50 |
410
+ | 参数 | 说明 | 是否必填 | 默认值 |
411
+ | --------- | ------------ | -------- | ------ |
412
+ | `faqItem` | FAQ 问题对象 | | - |
277
413
 
278
- **返回值说明:**
414
+ **FaqItem 类型定义:**
279
415
 
280
- | 返回值 | 说明 |
281
- |--------|------|
282
- | `list` | 消息列表 |
283
- | `hasMore` | 是否有更多数据 |
416
+ | 参数 | 说明 |
417
+ | ----------- | ------------- |
418
+ | `faqId` | FAQ ID |
419
+ | `faqItemId` | FAQ 项 ID |
420
+ | `id` | ID |
421
+ | `imageUrl` | 图片 URL 列表 |
422
+ | `question` | 问题 |
423
+ | `answer` | 答案 |
424
+ | `sortOrder` | 排序 |
425
+ | `isMulti` | 是否多选 |
426
+ | `item` | 子项 |
284
427
 
285
428
  ---
286
429
 
@@ -290,7 +433,6 @@ const next = await JTalk.getHistoryMessages({
290
433
  - **`getStatus(): ConnectionStatus`** — 获取当前连接状态。
291
434
  - **`isConnected(): boolean`** — 是否已连接。
292
435
  - **`getVideoThumbnail(videoFile: File): Promise<File>`** — 获取视频首帧缩略图,发送视频时建议使用。
293
- - **`sendFaq(faqItem: FaqItem): void`** — 发送 FAQ 消息。
294
436
  - **`off(event, callback): void`** — 取消监听事件,需传入与 `on` 时相同的回调引用。
295
437
  - **公共属性:** `OBS_URL`(OBS 存储地址)、`userInfo`(当前用户信息,只读)。
296
438
 
@@ -366,252 +508,59 @@ const handleFileChange = async (e: Event) => {
366
508
  </html>
367
509
  ```
368
510
 
369
- #### 完整示例
370
-
371
- ```html
372
- <!DOCTYPE html>
373
- <html lang="zh-CN">
374
- <head>
375
- <meta charset="UTF-8">
376
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
377
- <title>客服 SDK 示例</title>
378
- <!-- 引入 SDK -->
379
- <script src="https://your-cdn.com/joytalk/dist/index.umd.js"></script>
380
- </head>
381
- <body>
382
- <div id="app">
383
- <button id="connectBtn">连接</button>
384
- <button id="sendBtn">发送消息</button>
385
- <input type="file" id="fileInput" accept="image/*,video/*" />
386
- </div>
387
-
388
- <script>
389
- (async function () {
390
- const JoyTalk = window.JoyTalk.default;
391
- const { EventType, ChatType, MessageCode, ConnectionStatus, MessageType } = window.JoyTalk;
392
-
393
- const sdk = new JoyTalk();
394
-
395
- await sdk.init({
396
- token: 'your-token',
397
- autoReconnect: true,
398
- reconnectInterval: 3000,
399
- maxReconnectAttempts: 5,
400
- responseTimeout: 10000,
401
- });
402
-
403
- sdk.on(EventType.CONNECTED, () => {
404
- console.log('已连接到服务器');
405
- });
406
-
407
- // 监听消息事件
408
- sdk.on(EventType.MESSAGE, (message) => {
409
- console.log('收到消息:', message);
410
-
411
- // 根据消息类型处理
412
- switch (message.code) {
413
- case MessageCode.SEND_SUCCESS:
414
- console.log('消息发送成功:', message.data);
415
- break;
416
- case MessageCode.MATCH_SUCCESS:
417
- console.log('匹配成功:', message.data);
418
- break;
419
- // ... 其他消息类型
420
- }
421
- });
422
-
423
- // 监听错误事件
424
- sdk.on(EventType.ERROR, (error) => {
425
- console.error('发生错误:', error);
426
- });
427
-
428
- // 监听状态变化
429
- sdk.on(EventType.STATUS_CHANGE, (status) => {
430
- console.log('连接状态变化:', status);
431
- });
432
-
433
- // 连接按钮
434
- document.getElementById('connectBtn').addEventListener('click', async () => {
435
- try {
436
- await sdk.connect('customer-group-id');
437
- console.log('连接成功');
438
- } catch (error) {
439
- console.error('连接失败:', error);
440
- }
441
- });
442
-
443
- // 发送消息按钮
444
- document.getElementById('sendBtn').addEventListener('click', async () => {
445
- try {
446
- await sdk.sendText('你好,我需要帮助');
447
- } catch (error) {
448
- console.error('发送失败:', error);
449
- }
450
- });
451
-
452
- // 文件上传
453
- document.getElementById('fileInput').addEventListener('change', async (e) => {
454
- const file = e.target.files[0];
455
- if (!file) return;
456
-
457
- try {
458
- if (file.type.startsWith('image/')) {
459
- // 发送图片
460
- await sdk.sendFile({
461
- file: file,
462
- chatType: ChatType.IMAGE,
463
- });
464
- } else if (file.type.startsWith('video/')) {
465
- // 发送视频(自动生成缩略图)
466
- const thumbnailFile = await sdk.getVideoThumbnail(file);
467
- await sdk.sendFile({
468
- file: file,
469
- thumbnailFile: thumbnailFile,
470
- chatType: ChatType.VIDEO,
471
- });
472
- } else {
473
- // 发送文件
474
- await sdk.sendFile({
475
- file: file,
476
- chatType: ChatType.FILE,
477
- });
478
- }
479
- console.log('文件发送成功');
480
- } catch (error) {
481
- console.error('文件发送失败:', error);
482
- }
483
- });
484
-
485
- // 获取用户信息示例
486
- async function loadUserInfo() {
487
- try {
488
- const userInfo = await sdk.getUserInfo();
489
- console.log('用户信息:', userInfo);
490
- // 可以在页面上显示用户信息
491
- // document.getElementById('userName').textContent = userInfo.nickname;
492
- } catch (error) {
493
- console.error('获取用户信息失败:', error);
494
- }
495
- }
496
-
497
- // 获取咨询列表示例
498
- async function loadConsultationList(entranceId) {
499
- try {
500
- const result = await sdk.getConsultationList(entranceId);
501
- console.log('咨询列表:', result.data.list);
502
- // 可以在页面上显示咨询列表
503
- } catch (error) {
504
- console.error('获取咨询列表失败:', error);
505
- }
506
- }
507
-
508
- // 页面加载完成后可以调用
509
- // loadUserInfo();
510
- // loadConsultationList(123);
511
- })();
512
- </script>
513
- </body>
514
- </html>
515
- ```
516
-
517
511
  **CDN 地址说明:**
512
+
518
513
  - 将 `https://your-cdn.com/joytalk/dist/index.umd.js` 替换为实际的 CDN 地址
519
514
  - 如果使用本地构建文件,可以使用相对路径:`<script src="./dist/index.umd.js"></script>`
520
515
  - 建议使用版本号锁定,如:`https://cdn.example.com/joytalk@0.0.1/dist/index.umd.js`
521
516
 
522
517
  **注意事项:**
518
+
523
519
  - CDN 引入后,SDK 会挂载到 `window.JoyTalk` 全局对象上
524
520
  - 默认导出(`default`)是 `JoyTalk` 类,通过 `window.JoyTalk.default` 访问
525
521
  - 所有枚举和类型都可以从 `window.JoyTalk` 中获取,如 `EventType`、`ChatType`、`MessageCode`、`ConnectionStatus`、`MessageType` 等
526
522
  - 确保 CDN 地址可访问,并且版本正确
527
523
  - 如果页面中已经使用了模块化构建工具(如 Webpack、Vite),建议使用 NPM 安装方式而不是 CDN
528
524
 
529
- ### 配置选项(SDKConfig)
530
525
 
531
- 初始化时通过 `init(config)` 传入的配置项。参数说明见上方「初始化」表格。
532
526
 
533
- **事件类型(EventType):**
534
- - `EventType.CONNECTED` - 连接成功
535
- - `EventType.DISCONNECTED` - 连接断开
536
- - `EventType.ERROR` - 发生错误
537
- - `EventType.MESSAGE` - 收到消息
538
- - `EventType.STATUS_CHANGE` - 连接状态变化
539
- - `EventType.HEARTBEAT_TIMEOUT` - 心跳超时
527
+
528
+
529
+ ## 类型定义
530
+
531
+ SDK 提供完整的 TypeScript 类型定义,可从 `joytalk` 按需导入。
532
+
533
+ | 类型名 | 说明 |
534
+ | ----------------------- | -------------------- |
535
+ | `MessageData` | 消息数据(联合类型) |
536
+ | `TextMessageData` | 文本消息数据 |
537
+ | `FileMessageData` | 文件消息数据 |
538
+ | `FaqMessageData` | FAQ 消息数据 |
539
+ | `SessionData` | 会话数据 |
540
+ | `UserInfo` | 用户信息 |
541
+ | `ChatType` | 聊天类型枚举 |
542
+ | `MessageType` | 消息类型枚举 |
543
+ | `EventType` | 事件类型枚举 |
544
+ | `ConnectionStatus` | 连接状态枚举 |
545
+ | `MessageCode` | 消息代码枚举 |
546
+ | `MatchStatus` | 匹配状态枚举 |
547
+ | `HistoryMessagesParams` | 聊天记录查询参数 |
548
+ | `RequestResponse<T>` | 接口响应包装 |
540
549
 
541
550
  **消息类型(ChatType):**
551
+
542
552
  - `ChatType.TEXT` - 文本消息
543
553
  - `ChatType.IMAGE` - 图片消息
544
554
  - `ChatType.VIDEO` - 视频消息
545
555
  - `ChatType.FILE` - 文件消息
546
556
  - `ChatType.FAQ` - FAQ 消息
547
557
 
548
- **连接状态(ConnectionStatus):**
549
- - `ConnectionStatus.DISCONNECTED` - 未连接
550
- - `ConnectionStatus.CONNECTING` - 连接中
551
- - `ConnectionStatus.CONNECTED` - 已连接
552
- - `ConnectionStatus.RECONNECTING` - 重连中
553
- - `ConnectionStatus.ERROR` - 错误
558
+
554
559
 
555
560
  **匹配状态(MatchStatus):**
561
+
556
562
  - `MatchStatus.UNMATCHED` - 未匹配
557
563
  - `MatchStatus.MATCHING` - 匹配中
558
564
  - `MatchStatus.MATCHED` - 已匹配
559
565
  - `MatchStatus.UNBIND` - 已解绑
560
566
 
561
- **线路测速与 Base URL:** 首次发起 API 请求时,SDK 会调用 `ListLines` 获取线路列表,并对 API 线路请求 `TestLineLatency`、对下载线路请求 `/pub/logo.png`,取最先成功的地址作为后续请求的 baseURL。
562
-
563
- **环境变量(构建时):** `VITE_BASE_API_URL` 拉取 ListLines 的初始 API 地址(必填);`VITE_OBS_URL` 下载线路测速失败时的下载地址兜底(可选)。
564
-
565
- ## 类型定义
566
-
567
- SDK 提供完整的 TypeScript 类型定义,可从 `joytalk` 按需导入。
568
-
569
- | 类型名 | 说明 |
570
- |--------|------|
571
- | `MessageData` | 消息数据(联合类型) |
572
- | `TextMessageData` | 文本消息数据 |
573
- | `FileMessageData` | 文件消息数据 |
574
- | `FaqMessageData` | FAQ 消息数据 |
575
- | `SessionData` | 会话数据 |
576
- | `UserInfo` | 用户信息 |
577
- | `ChatType` | 聊天类型枚举 |
578
- | `MessageType` | 消息类型枚举 |
579
- | `EventType` | 事件类型枚举 |
580
- | `ConnectionStatus` | 连接状态枚举 |
581
- | `MessageCode` | 消息代码枚举 |
582
- | `MatchStatus` | 匹配状态枚举 |
583
- | `HistoryMessagesParams` | 聊天记录查询参数 |
584
- | `RequestResponse<T>` | 接口响应包装 |
585
-
586
- ## 消息处理示例
587
-
588
- 通过监听 `EventType.MESSAGE`,根据 `message.code` 区分消息类型并处理。
589
-
590
- **示例:**
591
- ```typescript
592
- import JoyTalk, { EventType, MessageCode, ChatType } from 'joytalk';
593
-
594
- const JTalk = new JoyTalk();
595
- await JTalk.init({ token: 'your-token' });
596
-
597
- JTalk.on(EventType.MESSAGE, (message) => {
598
- switch (message.code) {
599
- case MessageCode.SEND_SUCCESS:
600
- const messageData = message.data;
601
- if (messageData.contentType === ChatType.TEXT) {
602
- console.log('文本消息:', messageData.content);
603
- } else if (messageData.contentType === ChatType.IMAGE) {
604
- console.log('图片消息:', messageData.content.fileUrl);
605
- }
606
- break;
607
- case MessageCode.MATCH_SUCCESS:
608
- const sessionData = message.data;
609
- console.log('会话ID:', sessionData.sessionId);
610
- break;
611
- case MessageCode.CONNECT_SUCCESS:
612
- console.log('连接成功');
613
- break;
614
- // ... 其他消息类型
615
- }
616
- });
617
- ```