@meet-im/meet-bot-jssdk 1.0.0 → 1.2.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/dist/index.cjs CHANGED
@@ -50,16 +50,34 @@ var init_error = __esm({
50
50
  };
51
51
  exports.NetworkError = class extends exports.MeetBotError {
52
52
  cause;
53
- constructor(message, cause) {
53
+ /**
54
+ * HTTP 状态码(如果有的话)
55
+ * 例如:504 表示网关超时,0 表示无 HTTP 响应
56
+ */
57
+ httpStatus;
58
+ /**
59
+ * 响应内容片段(用于调试)
60
+ */
61
+ responseSnippet;
62
+ constructor(message, cause, httpStatus, responseSnippet) {
54
63
  super(message, "NETWORK_ERROR");
55
64
  this.name = "NetworkError";
56
65
  this.cause = cause;
66
+ this.httpStatus = httpStatus;
67
+ this.responseSnippet = responseSnippet;
57
68
  }
58
69
  };
59
70
  exports.TimeoutError = class extends exports.MeetBotError {
60
- constructor(message) {
71
+ /**
72
+ * 是否为本地客户端超时(AbortController 触发)
73
+ * true: 本地 HTTP 请求超时
74
+ * false: 服务端/网关返回的超时(如 504 Gateway Timeout)
75
+ */
76
+ isLocal;
77
+ constructor(message, isLocal = true) {
61
78
  super(message, "TIMEOUT_ERROR");
62
79
  this.name = "TimeoutError";
80
+ this.isLocal = isLocal;
63
81
  }
64
82
  };
65
83
  exports.ValidationError = class extends exports.MeetBotError {
@@ -202,8 +220,8 @@ function extractBotToken(token) {
202
220
  const parts = token.split(":");
203
221
  return parts.length >= 2 ? parts.slice(1).join(":") : token;
204
222
  }
205
- function buildUrl(baseUrl, path, params) {
206
- const url = new URL(`/im/bot/${path}`, baseUrl);
223
+ function buildUrl(baseUrl, path, pathPrefix, params) {
224
+ const url = new URL(`${pathPrefix}${path}`, baseUrl);
207
225
  if (params) {
208
226
  for (const [key, value] of Object.entries(params)) {
209
227
  if (value !== void 0) {
@@ -213,10 +231,27 @@ function buildUrl(baseUrl, path, params) {
213
231
  }
214
232
  return url.toString();
215
233
  }
234
+ function sanitizeHeaders(headers) {
235
+ return {
236
+ ...headers,
237
+ Authorization: headers.Authorization ? "Bot ***" : ""
238
+ };
239
+ }
216
240
  async function request(options) {
217
- const { token, baseUrl, method = "GET", path, params, body, timeout = HTTP.DEFAULT_TIMEOUT } = options;
241
+ const {
242
+ token,
243
+ baseUrl,
244
+ method = "GET",
245
+ path,
246
+ pathPrefix = "/im/bot/",
247
+ params,
248
+ body,
249
+ timeout = HTTP.DEFAULT_TIMEOUT,
250
+ userAgent,
251
+ raw = false
252
+ } = options;
218
253
  validateToken(token);
219
- const url = buildUrl(baseUrl || DEFAULT_BASE_URL, path, method === "GET" ? params : void 0);
254
+ const url = buildUrl(baseUrl || DEFAULT_BASE_URL, path, pathPrefix, method === "GET" ? params : void 0);
220
255
  const controller = new AbortController();
221
256
  const timeoutId = setTimeout(() => controller.abort(), timeout);
222
257
  const headers = {
@@ -224,7 +259,11 @@ async function request(options) {
224
259
  Accept: "application/json",
225
260
  Authorization: `Bot ${extractBotToken(token)}`
226
261
  };
262
+ if (userAgent) {
263
+ headers["User-Agent"] = userAgent;
264
+ }
227
265
  logger.info("[Request]", method, url);
266
+ logger.info("[Headers]", sanitizeHeaders(headers));
228
267
  if (body) {
229
268
  logger.info("[Body]", JSON.stringify(body));
230
269
  }
@@ -245,18 +284,40 @@ async function request(options) {
245
284
  const responseText = await response.text();
246
285
  if (!contentType.includes("application/json")) {
247
286
  logger.error("[Response] Non-JSON response:", responseText.substring(0, 500));
248
- throw new exports.NetworkError(`Server returned non-JSON response (status ${response.status})`, void 0);
287
+ if (response.status === 504) {
288
+ throw new exports.TimeoutError(`Gateway timeout (status ${response.status})`, false);
289
+ }
290
+ throw new exports.NetworkError(
291
+ `Server returned non-JSON response (status ${response.status})`,
292
+ void 0,
293
+ response.status,
294
+ responseText.substring(0, 200)
295
+ );
249
296
  }
250
297
  let data;
251
298
  try {
252
299
  data = JSON.parse(responseText);
253
300
  } catch {
254
301
  logger.error("[Response] Failed to parse JSON:", responseText.substring(0, 500));
255
- throw new exports.NetworkError("Failed to parse server response", void 0);
302
+ throw new exports.NetworkError(
303
+ "Failed to parse server response",
304
+ void 0,
305
+ response.status,
306
+ responseText.substring(0, 200)
307
+ );
256
308
  }
257
309
  logger.info("[Response Body]", JSON.stringify(data));
310
+ if (raw) {
311
+ return data;
312
+ }
258
313
  if (!response.ok || !data.ok) {
259
314
  const errorData = data;
315
+ if (response.status === 504) {
316
+ throw new exports.TimeoutError(
317
+ errorData.description || `Gateway timeout (status ${response.status})`,
318
+ false
319
+ );
320
+ }
260
321
  throw new exports.ApiError(
261
322
  errorData.description || `HTTP ${response.status}`,
262
323
  response.status,
@@ -272,7 +333,7 @@ async function request(options) {
272
333
  }
273
334
  if (error instanceof Error) {
274
335
  if (error.name === "AbortError") {
275
- throw new exports.TimeoutError(`Request timeout after ${timeout}ms`);
336
+ throw new exports.TimeoutError(`Request timeout after ${timeout}ms`, true);
276
337
  }
277
338
  throw new exports.NetworkError(`Network error: ${error.message}`, error);
278
339
  }
@@ -300,10 +361,11 @@ function mapStatusCodeToErrorCode(status) {
300
361
 
301
362
  // src/api/file.ts
302
363
  async function getUploadURL(params) {
303
- const { token, baseUrl, ...body } = params;
364
+ const { token, baseUrl, userAgent, ...body } = params;
304
365
  return request({
305
366
  token,
306
367
  baseUrl,
368
+ userAgent,
307
369
  method: "POST",
308
370
  path: "getUploadURL",
309
371
  body: {
@@ -321,10 +383,11 @@ async function getUploadURL(params) {
321
383
  });
322
384
  }
323
385
  async function getMultiPartUploadURL(params) {
324
- const { token, baseUrl, ...body } = params;
386
+ const { token, baseUrl, userAgent, ...body } = params;
325
387
  return request({
326
388
  token,
327
389
  baseUrl,
390
+ userAgent,
328
391
  method: "POST",
329
392
  path: "getMultiPartUploadURL",
330
393
  body: {
@@ -340,10 +403,11 @@ async function getMultiPartUploadURL(params) {
340
403
  });
341
404
  }
342
405
  async function completeMultipartUpload(params) {
343
- const { token, baseUrl, ...body } = params;
406
+ const { token, baseUrl, userAgent, ...body } = params;
344
407
  return request({
345
408
  token,
346
409
  baseUrl,
410
+ userAgent,
347
411
  method: "POST",
348
412
  path: "completeMultipartUpload",
349
413
  body: {
@@ -355,10 +419,11 @@ async function completeMultipartUpload(params) {
355
419
  });
356
420
  }
357
421
  async function getAccessURL(params) {
358
- const { token, baseUrl, ...queryParams } = params;
422
+ const { token, baseUrl, userAgent, ...queryParams } = params;
359
423
  return request({
360
424
  token,
361
425
  baseUrl,
426
+ userAgent,
362
427
  method: "GET",
363
428
  path: "getAccessURL",
364
429
  params: {
@@ -436,21 +501,22 @@ function formatSpeed(bytesPerSecond) {
436
501
  return `${(bytesPerSecond / 1024 / 1024).toFixed(2)}MB/s`;
437
502
  }
438
503
  }
439
- async function uploadFile(token, buffer, options, baseUrl) {
504
+ async function uploadFile(token, buffer, options, baseUrl, userAgent) {
440
505
  const { fileName, contentType, onProgress } = options;
441
506
  const size = buffer.length;
442
507
  const md5 = await computeMD5(buffer);
443
508
  logger.info(`[uploadFile] Starting upload: ${fileName}, size: ${size}, md5: ${md5}`);
444
509
  if (size < UPLOAD.MULTIPART_THRESHOLD) {
445
- return uploadSingleFile(token, buffer, fileName, contentType, md5, baseUrl, onProgress);
510
+ return uploadSingleFile(token, buffer, fileName, contentType, md5, baseUrl, userAgent, onProgress);
446
511
  } else {
447
- return uploadMultipartFile(token, buffer, fileName, contentType, md5, baseUrl, onProgress);
512
+ return uploadMultipartFile(token, buffer, fileName, contentType, md5, baseUrl, userAgent, onProgress);
448
513
  }
449
514
  }
450
- async function uploadSingleFile(token, buffer, fileName, contentType, md5, baseUrl, onProgress) {
515
+ async function uploadSingleFile(token, buffer, fileName, contentType, md5, baseUrl, userAgent, onProgress) {
451
516
  const result = await getUploadURL({
452
517
  token,
453
518
  baseUrl,
519
+ userAgent,
454
520
  originFileName: fileName,
455
521
  contentType,
456
522
  md5,
@@ -463,13 +529,14 @@ async function uploadSingleFile(token, buffer, fileName, contentType, md5, baseU
463
529
  const ossResult = await uploadToOSS(result.signedUrl, buffer, contentType, result.callback || "", onProgress);
464
530
  return { fileID: ossResult.id, path: ossResult.path, size: ossResult.size };
465
531
  }
466
- async function uploadMultipartFile(token, buffer, fileName, contentType, md5, baseUrl, onProgress) {
532
+ async function uploadMultipartFile(token, buffer, fileName, contentType, md5, baseUrl, userAgent, onProgress) {
467
533
  const size = buffer.length;
468
534
  const chunkNum = getChunkNum(size);
469
535
  logger.info(`[uploadMultipartFile] Starting multipart upload: ${chunkNum} chunks`);
470
536
  const result = await getMultiPartUploadURL({
471
537
  token,
472
538
  baseUrl,
539
+ userAgent,
473
540
  originFileName: fileName,
474
541
  contentType,
475
542
  md5,
@@ -517,6 +584,7 @@ async function uploadMultipartFile(token, buffer, fileName, contentType, md5, ba
517
584
  const complete = await completeMultipartUpload({
518
585
  token,
519
586
  baseUrl,
587
+ userAgent,
520
588
  originFileName: fileName,
521
589
  md5,
522
590
  UploadParts: uploadParts
@@ -524,13 +592,14 @@ async function uploadMultipartFile(token, buffer, fileName, contentType, md5, ba
524
592
  logger.info(`[uploadMultipartFile] Upload complete: ${complete.ID}`);
525
593
  return { fileID: complete.ID, path: complete.path, size };
526
594
  }
527
- async function sendMediaMessage(token, sessionInfo, options, baseUrl) {
595
+ async function sendMediaMessage(token, sessionInfo, options, baseUrl, userAgent) {
528
596
  const { buffer, fileName, contentType, content, onProgress } = options;
529
- const { fileID, path } = await uploadFile(token, buffer, { fileName, contentType, onProgress }, baseUrl);
597
+ const { fileID, path } = await uploadFile(token, buffer, { fileName, contentType, onProgress }, baseUrl, userAgent);
530
598
  logger.info(`[sendMediaMessage] fileID=${fileID}, path=${path}`);
531
599
  return sendMessage({
532
600
  token,
533
601
  baseUrl,
602
+ userAgent,
534
603
  sessionInfo,
535
604
  msgContent: {
536
605
  content: content || "",
@@ -547,12 +616,33 @@ async function sendMediaMessage(token, sessionInfo, options, baseUrl) {
547
616
  });
548
617
  }
549
618
 
619
+ // src/api/user.ts
620
+ async function getUsers(params) {
621
+ const { token, baseUrl, userAgent } = params;
622
+ const result = await request({
623
+ token,
624
+ baseUrl,
625
+ userAgent,
626
+ method: "POST",
627
+ path: "general/SyncCompanyUser",
628
+ pathPrefix: "/",
629
+ body: { syncAt: 0 },
630
+ timeout: HTTP.DEFAULT_TIMEOUT,
631
+ raw: true
632
+ });
633
+ return Object.values(result.users).map((user) => ({
634
+ userID: user.userID,
635
+ nickName: user.nickName
636
+ }));
637
+ }
638
+
550
639
  // src/api/index.ts
551
640
  async function getUpdates(params) {
552
- const { token, baseUrl, timeout = API.DEFAULT_TIMEOUT, offset, limit = API.DEFAULT_LIMIT } = params;
641
+ const { token, baseUrl, userAgent, timeout = API.DEFAULT_TIMEOUT, offset, limit = API.DEFAULT_LIMIT } = params;
553
642
  return request({
554
643
  token,
555
644
  baseUrl,
645
+ userAgent,
556
646
  method: "POST",
557
647
  path: "getUpdates",
558
648
  body: {
@@ -564,10 +654,11 @@ async function getUpdates(params) {
564
654
  });
565
655
  }
566
656
  async function getUpdatesV2(params) {
567
- const { token, baseUrl, timeout = API.DEFAULT_TIMEOUT, limit = API.DEFAULT_LIMIT } = params;
657
+ const { token, baseUrl, userAgent, timeout = API.DEFAULT_TIMEOUT, limit = API.DEFAULT_LIMIT } = params;
568
658
  return request({
569
659
  token,
570
660
  baseUrl,
661
+ userAgent,
571
662
  method: "POST",
572
663
  path: "getUpdatesV2",
573
664
  body: {
@@ -578,7 +669,7 @@ async function getUpdatesV2(params) {
578
669
  });
579
670
  }
580
671
  async function sendMessage(params) {
581
- const { token, baseUrl, sessionInfo, msgContent } = params;
672
+ const { token, baseUrl, userAgent, sessionInfo, msgContent } = params;
582
673
  const hasContent = msgContent.content && msgContent.content.trim() !== "";
583
674
  const hasAttachment = msgContent.extraInfo?.attechmentInfo || msgContent.extraInfo?.attechmentInfos && msgContent.extraInfo.attechmentInfos.length > 0;
584
675
  if (!hasContent && !hasAttachment) {
@@ -588,6 +679,7 @@ async function sendMessage(params) {
588
679
  return request({
589
680
  token,
590
681
  baseUrl,
682
+ userAgent,
591
683
  method: "POST",
592
684
  path: "sendMessage",
593
685
  body: {
@@ -599,16 +691,127 @@ async function sendMessage(params) {
599
691
 
600
692
  // src/client.ts
601
693
  init_error();
694
+
695
+ // src/user-cache.ts
696
+ var UserCache = class {
697
+ byId = /* @__PURE__ */ new Map();
698
+ byNickName = /* @__PURE__ */ new Map();
699
+ byAliasName = /* @__PURE__ */ new Map();
700
+ loadedAt = 0;
701
+ ttl;
702
+ loading = null;
703
+ constructor(options) {
704
+ this.ttl = options?.ttl ?? 60 * 60 * 1e3;
705
+ }
706
+ isExpired() {
707
+ return this.byId.size === 0 || this.ttl > 0 && Date.now() - this.loadedAt > this.ttl;
708
+ }
709
+ async load(fetchAll) {
710
+ if (this.loading) {
711
+ return this.loading;
712
+ }
713
+ this.loading = (async () => {
714
+ try {
715
+ const users = await fetchAll();
716
+ this.rebuild(users);
717
+ logger.info(`\u7528\u6237\u7F13\u5B58\u5DF2\u52A0\u8F7D\uFF0C\u5171 ${users.length} \u4E2A\u7528\u6237`);
718
+ } finally {
719
+ this.loading = null;
720
+ }
721
+ })();
722
+ return this.loading;
723
+ }
724
+ rebuild(users) {
725
+ this.byId.clear();
726
+ this.byNickName.clear();
727
+ this.byAliasName.clear();
728
+ for (const user of users) {
729
+ this.byId.set(user.userID, user);
730
+ const nickKey = user.nickName.toLowerCase();
731
+ let nickList = this.byNickName.get(nickKey);
732
+ if (!nickList) {
733
+ nickList = [];
734
+ this.byNickName.set(nickKey, nickList);
735
+ }
736
+ nickList.push(user);
737
+ if (user.aliasName) {
738
+ const aliasKey = user.aliasName.toLowerCase();
739
+ let aliasList = this.byAliasName.get(aliasKey);
740
+ if (!aliasList) {
741
+ aliasList = [];
742
+ this.byAliasName.set(aliasKey, aliasList);
743
+ }
744
+ aliasList.push(user);
745
+ }
746
+ }
747
+ this.loadedAt = Date.now();
748
+ }
749
+ async ensureLoaded(fetchAll) {
750
+ if (!this.isExpired()) return;
751
+ await this.load(fetchAll);
752
+ }
753
+ getById(userId) {
754
+ return this.byId.get(userId);
755
+ }
756
+ getByIds(userIds) {
757
+ const result = /* @__PURE__ */ new Map();
758
+ for (const id of userIds) {
759
+ const user = this.byId.get(id);
760
+ if (user) {
761
+ result.set(id, user);
762
+ }
763
+ }
764
+ return result;
765
+ }
766
+ getByName(name) {
767
+ const key = name.toLowerCase();
768
+ const byNick = this.byNickName.get(key);
769
+ const byAlias = this.byAliasName.get(key);
770
+ if (!byNick && !byAlias) return [];
771
+ if (!byNick) return [...byAlias];
772
+ if (!byAlias) return [...byNick];
773
+ const seen = /* @__PURE__ */ new Set();
774
+ const result = [];
775
+ for (const u of [...byNick, ...byAlias]) {
776
+ if (!seen.has(u.userID)) {
777
+ seen.add(u.userID);
778
+ result.push(u);
779
+ }
780
+ }
781
+ return result;
782
+ }
783
+ searchByName(query) {
784
+ const q = query.toLowerCase();
785
+ const result = [];
786
+ const seen = /* @__PURE__ */ new Set();
787
+ for (const user of this.byId.values()) {
788
+ if (user.nickName.toLowerCase().includes(q) || user.aliasName && user.aliasName.toLowerCase().includes(q) || user.nickNamePinyin && user.nickNamePinyin.toLowerCase().includes(q) || user.aliasNamePinyin && user.aliasNamePinyin.toLowerCase().includes(q)) {
789
+ if (!seen.has(user.userID)) {
790
+ seen.add(user.userID);
791
+ result.push(user);
792
+ }
793
+ }
794
+ }
795
+ return result;
796
+ }
797
+ get size() {
798
+ return this.byId.size;
799
+ }
800
+ };
801
+
802
+ // src/client.ts
602
803
  var MeetBot = class {
603
804
  token;
604
805
  baseUrl;
605
806
  pollingLimit;
606
807
  longPollingTimeout;
607
808
  useV2;
809
+ userAgent;
608
810
  eventHandlers = /* @__PURE__ */ new Map();
609
811
  polling = false;
610
812
  offset = 0;
611
813
  abortController = null;
814
+ userCache;
612
815
  constructor(config) {
613
816
  if (config.token) {
614
817
  if (!config.token.includes(":")) {
@@ -624,6 +827,8 @@ var MeetBot = class {
624
827
  this.pollingLimit = config.pollingLimit ?? POLLING.DEFAULT_LIMIT;
625
828
  this.longPollingTimeout = config.longPollingTimeout ?? POLLING.DEFAULT_TIMEOUT;
626
829
  this.useV2 = config.useV2 ?? false;
830
+ this.userAgent = config.userAgent;
831
+ this.userCache = new UserCache(config.userCacheOptions);
627
832
  logger.setLevel(config.logLevel ?? "silent");
628
833
  }
629
834
  on(event, handler) {
@@ -675,6 +880,7 @@ var MeetBot = class {
675
880
  const result = await getUpdatesV2({
676
881
  token: this.token,
677
882
  baseUrl: this.baseUrl,
883
+ userAgent: this.userAgent,
678
884
  timeout,
679
885
  limit
680
886
  });
@@ -688,6 +894,7 @@ var MeetBot = class {
688
894
  const updates = await getUpdates({
689
895
  token: this.token,
690
896
  baseUrl: this.baseUrl,
897
+ userAgent: this.userAgent,
691
898
  timeout,
692
899
  offset: this.offset,
693
900
  limit
@@ -727,6 +934,7 @@ var MeetBot = class {
727
934
  return getUpdates({
728
935
  token: this.token,
729
936
  baseUrl: this.baseUrl,
937
+ userAgent: this.userAgent,
730
938
  ...options
731
939
  });
732
940
  }
@@ -734,6 +942,7 @@ var MeetBot = class {
734
942
  return getUpdatesV2({
735
943
  token: this.token,
736
944
  baseUrl: this.baseUrl,
945
+ userAgent: this.userAgent,
737
946
  ...options
738
947
  });
739
948
  }
@@ -741,6 +950,7 @@ var MeetBot = class {
741
950
  return sendMessage({
742
951
  token: this.token,
743
952
  baseUrl: this.baseUrl,
953
+ userAgent: this.userAgent,
744
954
  sessionInfo,
745
955
  msgContent
746
956
  });
@@ -752,6 +962,7 @@ var MeetBot = class {
752
962
  return getUploadURL({
753
963
  token: this.token,
754
964
  baseUrl: this.baseUrl,
965
+ userAgent: this.userAgent,
755
966
  ...params
756
967
  });
757
968
  }
@@ -762,6 +973,7 @@ var MeetBot = class {
762
973
  return getMultiPartUploadURL({
763
974
  token: this.token,
764
975
  baseUrl: this.baseUrl,
976
+ userAgent: this.userAgent,
765
977
  ...params
766
978
  });
767
979
  }
@@ -772,6 +984,7 @@ var MeetBot = class {
772
984
  return completeMultipartUpload({
773
985
  token: this.token,
774
986
  baseUrl: this.baseUrl,
987
+ userAgent: this.userAgent,
775
988
  ...params
776
989
  });
777
990
  }
@@ -790,6 +1003,7 @@ var MeetBot = class {
790
1003
  return getAccessURL({
791
1004
  token: this.token,
792
1005
  baseUrl: this.baseUrl,
1006
+ userAgent: this.userAgent,
793
1007
  ...apiParams
794
1008
  });
795
1009
  }
@@ -797,13 +1011,63 @@ var MeetBot = class {
797
1011
  * 上传文件(自动选择单文件或分片上传)
798
1012
  */
799
1013
  async uploadFile(buffer, options) {
800
- return uploadFile(this.token, buffer, options, this.baseUrl);
1014
+ return uploadFile(this.token, buffer, options, this.baseUrl, this.userAgent);
801
1015
  }
802
1016
  /**
803
1017
  * 发送媒体消息(上传并发送)
804
1018
  */
805
1019
  async sendMedia(sessionInfo, options) {
806
- return sendMediaMessage(this.token, sessionInfo, options, this.baseUrl);
1020
+ return sendMediaMessage(this.token, sessionInfo, options, this.baseUrl, this.userAgent);
1021
+ }
1022
+ /**
1023
+ * 刷新用户缓存
1024
+ */
1025
+ async refreshUserCache() {
1026
+ await this.userCache.load(async () => {
1027
+ return getUsers({ token: this.token, baseUrl: this.baseUrl, userAgent: this.userAgent });
1028
+ });
1029
+ }
1030
+ /**
1031
+ * 根据用户 ID 获取用户信息
1032
+ */
1033
+ async getUserById(userId) {
1034
+ await this.userCache.ensureLoaded(async () => {
1035
+ return getUsers({ token: this.token, baseUrl: this.baseUrl, userAgent: this.userAgent });
1036
+ });
1037
+ return this.userCache.getById(userId);
1038
+ }
1039
+ /**
1040
+ * 批量根据用户 ID 获取用户信息
1041
+ */
1042
+ async getUserByIds(userIds) {
1043
+ await this.userCache.ensureLoaded(async () => {
1044
+ return getUsers({ token: this.token, baseUrl: this.baseUrl, userAgent: this.userAgent });
1045
+ });
1046
+ return this.userCache.getByIds(userIds);
1047
+ }
1048
+ /**
1049
+ * 根据昵称或别名精确查找用户
1050
+ */
1051
+ async getUserByName(name) {
1052
+ await this.userCache.ensureLoaded(async () => {
1053
+ return getUsers({ token: this.token, baseUrl: this.baseUrl, userAgent: this.userAgent });
1054
+ });
1055
+ return this.userCache.getByName(name);
1056
+ }
1057
+ /**
1058
+ * 根据昵称或别名模糊搜索用户
1059
+ */
1060
+ async searchUserByName(query) {
1061
+ await this.userCache.ensureLoaded(async () => {
1062
+ return getUsers({ token: this.token, baseUrl: this.baseUrl, userAgent: this.userAgent });
1063
+ });
1064
+ return this.userCache.searchByName(query);
1065
+ }
1066
+ /**
1067
+ * 获取缓存用户数
1068
+ */
1069
+ get userCacheSize() {
1070
+ return this.userCache.size;
807
1071
  }
808
1072
  sleep(ms) {
809
1073
  return new Promise((resolve) => setTimeout(resolve, ms));
@@ -821,6 +1085,7 @@ exports.MeetBot = MeetBot;
821
1085
  exports.POLLING = POLLING;
822
1086
  exports.SESSION_TYPE = SESSION_TYPE;
823
1087
  exports.UPLOAD = UPLOAD;
1088
+ exports.UserCache = UserCache;
824
1089
  exports.completeMultipartUpload = completeMultipartUpload;
825
1090
  exports.computeMD5 = computeMD5;
826
1091
  exports.getAccessURL = getAccessURL;
@@ -831,8 +1096,7 @@ exports.getQuoteMsgKey = getQuoteMsgKey;
831
1096
  exports.getUpdates = getUpdates;
832
1097
  exports.getUpdatesV2 = getUpdatesV2;
833
1098
  exports.getUploadURL = getUploadURL;
1099
+ exports.getUsers = getUsers;
834
1100
  exports.sendMediaMessage = sendMediaMessage;
835
1101
  exports.sendMessage = sendMessage;
836
1102
  exports.uploadFile = uploadFile;
837
- //# sourceMappingURL=index.cjs.map
838
- //# sourceMappingURL=index.cjs.map