@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/README.md +0 -366
- package/dist/index.cjs +291 -27
- package/dist/index.d.cts +86 -6
- package/dist/index.d.ts +86 -6
- package/dist/index.js +290 -28
- package/package.json +1 -1
- package/dist/index.cjs.map +0 -1
- package/dist/index.js.map +0 -1
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
|
-
|
|
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
|
-
|
|
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(
|
|
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 {
|
|
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
|
-
|
|
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(
|
|
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
|