@meet-im/meet-bot-jssdk 1.0.0 → 1.1.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 +241 -11
- package/dist/index.d.cts +74 -4
- package/dist/index.d.ts +74 -4
- package/dist/index.js +240 -12
- package/package.json +1 -1
- package/dist/index.cjs.map +0 -1
- package/dist/index.js.map +0 -1
package/dist/index.d.cts
CHANGED
|
@@ -216,6 +216,37 @@ interface ReceivedAttachmentInfo {
|
|
|
216
216
|
mimeType?: string;
|
|
217
217
|
}
|
|
218
218
|
|
|
219
|
+
interface MeetUser {
|
|
220
|
+
userID: number;
|
|
221
|
+
nickName: string;
|
|
222
|
+
nickNamePinyin?: string;
|
|
223
|
+
aliasName?: string;
|
|
224
|
+
aliasNamePinyin?: string;
|
|
225
|
+
gender?: number;
|
|
226
|
+
birthday?: string;
|
|
227
|
+
avatar?: string;
|
|
228
|
+
avatarUrl?: string;
|
|
229
|
+
email?: string;
|
|
230
|
+
mobile?: string;
|
|
231
|
+
jobNumber?: string;
|
|
232
|
+
tag?: string;
|
|
233
|
+
tags?: string[];
|
|
234
|
+
companyId?: number;
|
|
235
|
+
status?: number;
|
|
236
|
+
statusMsg?: string[];
|
|
237
|
+
sourceType?: number;
|
|
238
|
+
employeeStatus?: number;
|
|
239
|
+
cleanStatus?: number;
|
|
240
|
+
deletedAt?: number;
|
|
241
|
+
isDepartmentAdmin?: boolean;
|
|
242
|
+
isHide?: boolean;
|
|
243
|
+
sort?: number;
|
|
244
|
+
oaUID?: number;
|
|
245
|
+
msgDelTimeStamp?: number;
|
|
246
|
+
userType?: number;
|
|
247
|
+
updatedAt?: number;
|
|
248
|
+
}
|
|
249
|
+
|
|
219
250
|
declare class MeetBotError extends Error {
|
|
220
251
|
readonly code: ErrorCode;
|
|
221
252
|
constructor(message: string, code: ErrorCode);
|
|
@@ -227,10 +258,13 @@ declare class ApiError extends MeetBotError {
|
|
|
227
258
|
}
|
|
228
259
|
declare class NetworkError extends MeetBotError {
|
|
229
260
|
readonly cause?: Error;
|
|
230
|
-
|
|
261
|
+
readonly httpStatus?: number;
|
|
262
|
+
readonly responseSnippet?: string;
|
|
263
|
+
constructor(message: string, cause?: Error, httpStatus?: number, responseSnippet?: string);
|
|
231
264
|
}
|
|
232
265
|
declare class TimeoutError extends MeetBotError {
|
|
233
|
-
|
|
266
|
+
readonly isLocal: boolean;
|
|
267
|
+
constructor(message: string, isLocal?: boolean);
|
|
234
268
|
}
|
|
235
269
|
declare class ValidationError extends MeetBotError {
|
|
236
270
|
readonly field: string;
|
|
@@ -238,6 +272,28 @@ declare class ValidationError extends MeetBotError {
|
|
|
238
272
|
constructor(message: string, field: string, value: unknown);
|
|
239
273
|
}
|
|
240
274
|
|
|
275
|
+
interface UserCacheOptions {
|
|
276
|
+
ttl?: number;
|
|
277
|
+
}
|
|
278
|
+
declare class UserCache {
|
|
279
|
+
private byId;
|
|
280
|
+
private byNickName;
|
|
281
|
+
private byAliasName;
|
|
282
|
+
private loadedAt;
|
|
283
|
+
private readonly ttl;
|
|
284
|
+
private loading;
|
|
285
|
+
constructor(options?: UserCacheOptions);
|
|
286
|
+
isExpired(): boolean;
|
|
287
|
+
load(fetchAll: () => Promise<MeetUser[]>): Promise<void>;
|
|
288
|
+
private rebuild;
|
|
289
|
+
ensureLoaded(fetchAll: () => Promise<MeetUser[]>): Promise<void>;
|
|
290
|
+
getById(userId: number): MeetUser | undefined;
|
|
291
|
+
getByIds(userIds: number[]): Map<number, MeetUser>;
|
|
292
|
+
getByName(name: string): MeetUser[];
|
|
293
|
+
searchByName(query: string): MeetUser[];
|
|
294
|
+
get size(): number;
|
|
295
|
+
}
|
|
296
|
+
|
|
241
297
|
type EventHandler<T = unknown> = (data: T) => void;
|
|
242
298
|
interface Events {
|
|
243
299
|
message: {
|
|
@@ -258,7 +314,10 @@ declare class MeetBot {
|
|
|
258
314
|
private polling;
|
|
259
315
|
private offset;
|
|
260
316
|
private abortController;
|
|
261
|
-
|
|
317
|
+
private readonly userCache;
|
|
318
|
+
constructor(config: MeetBotConfig & {
|
|
319
|
+
userCacheOptions?: UserCacheOptions;
|
|
320
|
+
});
|
|
262
321
|
on<K extends keyof Events>(event: K, handler: EventHandler<Events[K]>): this;
|
|
263
322
|
off<K extends keyof Events>(event: K, handler: EventHandler<Events[K]>): this;
|
|
264
323
|
private emit;
|
|
@@ -281,6 +340,12 @@ declare class MeetBot {
|
|
|
281
340
|
getAccessURL(params: GetAccessURLParams | GetAccessURLBySessionParams): Promise<AccessURLResult>;
|
|
282
341
|
uploadFile(buffer: Buffer, options: UploadFileOptions): Promise<UploadFileResult>;
|
|
283
342
|
sendMedia(sessionInfo: SessionInfo, options: SendMediaOptions): Promise<SendMessageResult>;
|
|
343
|
+
refreshUserCache(): Promise<void>;
|
|
344
|
+
getUserById(userId: number): Promise<MeetUser | undefined>;
|
|
345
|
+
getUserByIds(userIds: number[]): Promise<Map<number, MeetUser>>;
|
|
346
|
+
getUserByName(name: string): Promise<MeetUser[]>;
|
|
347
|
+
searchUserByName(query: string): Promise<MeetUser[]>;
|
|
348
|
+
get userCacheSize(): number;
|
|
284
349
|
private sleep;
|
|
285
350
|
}
|
|
286
351
|
|
|
@@ -309,6 +374,11 @@ declare function computeMD5(buffer: Buffer): Promise<string>;
|
|
|
309
374
|
declare function uploadFile(token: string, buffer: Buffer, options: UploadFileOptions, baseUrl?: string): Promise<UploadFileResult>;
|
|
310
375
|
declare function sendMediaMessage(token: string, sessionInfo: SessionInfo, options: SendMediaOptions, baseUrl?: string): Promise<SendMessageResult>;
|
|
311
376
|
|
|
377
|
+
declare function getUsers(params: {
|
|
378
|
+
token: string;
|
|
379
|
+
baseUrl?: string;
|
|
380
|
+
}): Promise<MeetUser[]>;
|
|
381
|
+
|
|
312
382
|
interface GetUpdatesParams {
|
|
313
383
|
token: string;
|
|
314
384
|
baseUrl?: string;
|
|
@@ -378,4 +448,4 @@ declare function getChunkNum(size: number): number;
|
|
|
378
448
|
declare function getConvID(firstID: number, secondID: number, sessionType: number, companyID?: number): string;
|
|
379
449
|
declare function getQuoteMsgKey(convID: string, seqID: number): string;
|
|
380
450
|
|
|
381
|
-
export { API, type AccessURLResult, ApiError, type ApiErrorResponse, type ApiResponse, type AttachmentInfo, type BotChat, type BotFile, type BotMsg, type BotMsgUpdate, type BotUpdate, type BotUser, CHUNK_RULES, type ChatType, type CompleteMultipartUploadParams, type CompleteMultipartUploadResult, DEFAULT_BASE_URL, type ErrorCode, type ExtraInfo, type GetAccessURLBySessionParams, type GetAccessURLParams, type GetMultiPartUploadURLParams, type GetUpdatesOptions, type GetUpdatesV2Result, type GetUploadURLParams, HTTP, type LogLevel, MeetBot, type MeetBotConfig, MeetBotError, type MsgContent, type MsgType, type MultiPartUploadURLResult, NetworkError, POLLING, type PollingOptions, type QuoteMsgMap, type ReceivedAttachmentInfo, SESSION_TYPE, type SendMediaOptions, type SendMessageOptions, type SendMessageResult, type SessionInfo, type SessionType, TimeoutError, UPLOAD, type UploadFileOptions, type UploadFileResult, type UploadPart, type UploadProgress, type UploadURLResult, ValidationError, completeMultipartUpload, computeMD5, getAccessURL, getChunkNum, getConvID, getMultiPartUploadURL, getQuoteMsgKey, getUpdates, getUpdatesV2, getUploadURL, sendMediaMessage, sendMessage, uploadFile };
|
|
451
|
+
export { API, type AccessURLResult, ApiError, type ApiErrorResponse, type ApiResponse, type AttachmentInfo, type BotChat, type BotFile, type BotMsg, type BotMsgUpdate, type BotUpdate, type BotUser, CHUNK_RULES, type ChatType, type CompleteMultipartUploadParams, type CompleteMultipartUploadResult, DEFAULT_BASE_URL, type ErrorCode, type ExtraInfo, type GetAccessURLBySessionParams, type GetAccessURLParams, type GetMultiPartUploadURLParams, type GetUpdatesOptions, type GetUpdatesV2Result, type GetUploadURLParams, HTTP, type LogLevel, MeetBot, type MeetBotConfig, MeetBotError, type MeetUser, type MsgContent, type MsgType, type MultiPartUploadURLResult, NetworkError, POLLING, type PollingOptions, type QuoteMsgMap, type ReceivedAttachmentInfo, SESSION_TYPE, type SendMediaOptions, type SendMessageOptions, type SendMessageResult, type SessionInfo, type SessionType, TimeoutError, UPLOAD, type UploadFileOptions, type UploadFileResult, type UploadPart, type UploadProgress, type UploadURLResult, UserCache, type UserCacheOptions, ValidationError, completeMultipartUpload, computeMD5, getAccessURL, getChunkNum, getConvID, getMultiPartUploadURL, getQuoteMsgKey, getUpdates, getUpdatesV2, getUploadURL, getUsers, sendMediaMessage, sendMessage, uploadFile };
|
package/dist/index.d.ts
CHANGED
|
@@ -216,6 +216,37 @@ interface ReceivedAttachmentInfo {
|
|
|
216
216
|
mimeType?: string;
|
|
217
217
|
}
|
|
218
218
|
|
|
219
|
+
interface MeetUser {
|
|
220
|
+
userID: number;
|
|
221
|
+
nickName: string;
|
|
222
|
+
nickNamePinyin?: string;
|
|
223
|
+
aliasName?: string;
|
|
224
|
+
aliasNamePinyin?: string;
|
|
225
|
+
gender?: number;
|
|
226
|
+
birthday?: string;
|
|
227
|
+
avatar?: string;
|
|
228
|
+
avatarUrl?: string;
|
|
229
|
+
email?: string;
|
|
230
|
+
mobile?: string;
|
|
231
|
+
jobNumber?: string;
|
|
232
|
+
tag?: string;
|
|
233
|
+
tags?: string[];
|
|
234
|
+
companyId?: number;
|
|
235
|
+
status?: number;
|
|
236
|
+
statusMsg?: string[];
|
|
237
|
+
sourceType?: number;
|
|
238
|
+
employeeStatus?: number;
|
|
239
|
+
cleanStatus?: number;
|
|
240
|
+
deletedAt?: number;
|
|
241
|
+
isDepartmentAdmin?: boolean;
|
|
242
|
+
isHide?: boolean;
|
|
243
|
+
sort?: number;
|
|
244
|
+
oaUID?: number;
|
|
245
|
+
msgDelTimeStamp?: number;
|
|
246
|
+
userType?: number;
|
|
247
|
+
updatedAt?: number;
|
|
248
|
+
}
|
|
249
|
+
|
|
219
250
|
declare class MeetBotError extends Error {
|
|
220
251
|
readonly code: ErrorCode;
|
|
221
252
|
constructor(message: string, code: ErrorCode);
|
|
@@ -227,10 +258,13 @@ declare class ApiError extends MeetBotError {
|
|
|
227
258
|
}
|
|
228
259
|
declare class NetworkError extends MeetBotError {
|
|
229
260
|
readonly cause?: Error;
|
|
230
|
-
|
|
261
|
+
readonly httpStatus?: number;
|
|
262
|
+
readonly responseSnippet?: string;
|
|
263
|
+
constructor(message: string, cause?: Error, httpStatus?: number, responseSnippet?: string);
|
|
231
264
|
}
|
|
232
265
|
declare class TimeoutError extends MeetBotError {
|
|
233
|
-
|
|
266
|
+
readonly isLocal: boolean;
|
|
267
|
+
constructor(message: string, isLocal?: boolean);
|
|
234
268
|
}
|
|
235
269
|
declare class ValidationError extends MeetBotError {
|
|
236
270
|
readonly field: string;
|
|
@@ -238,6 +272,28 @@ declare class ValidationError extends MeetBotError {
|
|
|
238
272
|
constructor(message: string, field: string, value: unknown);
|
|
239
273
|
}
|
|
240
274
|
|
|
275
|
+
interface UserCacheOptions {
|
|
276
|
+
ttl?: number;
|
|
277
|
+
}
|
|
278
|
+
declare class UserCache {
|
|
279
|
+
private byId;
|
|
280
|
+
private byNickName;
|
|
281
|
+
private byAliasName;
|
|
282
|
+
private loadedAt;
|
|
283
|
+
private readonly ttl;
|
|
284
|
+
private loading;
|
|
285
|
+
constructor(options?: UserCacheOptions);
|
|
286
|
+
isExpired(): boolean;
|
|
287
|
+
load(fetchAll: () => Promise<MeetUser[]>): Promise<void>;
|
|
288
|
+
private rebuild;
|
|
289
|
+
ensureLoaded(fetchAll: () => Promise<MeetUser[]>): Promise<void>;
|
|
290
|
+
getById(userId: number): MeetUser | undefined;
|
|
291
|
+
getByIds(userIds: number[]): Map<number, MeetUser>;
|
|
292
|
+
getByName(name: string): MeetUser[];
|
|
293
|
+
searchByName(query: string): MeetUser[];
|
|
294
|
+
get size(): number;
|
|
295
|
+
}
|
|
296
|
+
|
|
241
297
|
type EventHandler<T = unknown> = (data: T) => void;
|
|
242
298
|
interface Events {
|
|
243
299
|
message: {
|
|
@@ -258,7 +314,10 @@ declare class MeetBot {
|
|
|
258
314
|
private polling;
|
|
259
315
|
private offset;
|
|
260
316
|
private abortController;
|
|
261
|
-
|
|
317
|
+
private readonly userCache;
|
|
318
|
+
constructor(config: MeetBotConfig & {
|
|
319
|
+
userCacheOptions?: UserCacheOptions;
|
|
320
|
+
});
|
|
262
321
|
on<K extends keyof Events>(event: K, handler: EventHandler<Events[K]>): this;
|
|
263
322
|
off<K extends keyof Events>(event: K, handler: EventHandler<Events[K]>): this;
|
|
264
323
|
private emit;
|
|
@@ -281,6 +340,12 @@ declare class MeetBot {
|
|
|
281
340
|
getAccessURL(params: GetAccessURLParams | GetAccessURLBySessionParams): Promise<AccessURLResult>;
|
|
282
341
|
uploadFile(buffer: Buffer, options: UploadFileOptions): Promise<UploadFileResult>;
|
|
283
342
|
sendMedia(sessionInfo: SessionInfo, options: SendMediaOptions): Promise<SendMessageResult>;
|
|
343
|
+
refreshUserCache(): Promise<void>;
|
|
344
|
+
getUserById(userId: number): Promise<MeetUser | undefined>;
|
|
345
|
+
getUserByIds(userIds: number[]): Promise<Map<number, MeetUser>>;
|
|
346
|
+
getUserByName(name: string): Promise<MeetUser[]>;
|
|
347
|
+
searchUserByName(query: string): Promise<MeetUser[]>;
|
|
348
|
+
get userCacheSize(): number;
|
|
284
349
|
private sleep;
|
|
285
350
|
}
|
|
286
351
|
|
|
@@ -309,6 +374,11 @@ declare function computeMD5(buffer: Buffer): Promise<string>;
|
|
|
309
374
|
declare function uploadFile(token: string, buffer: Buffer, options: UploadFileOptions, baseUrl?: string): Promise<UploadFileResult>;
|
|
310
375
|
declare function sendMediaMessage(token: string, sessionInfo: SessionInfo, options: SendMediaOptions, baseUrl?: string): Promise<SendMessageResult>;
|
|
311
376
|
|
|
377
|
+
declare function getUsers(params: {
|
|
378
|
+
token: string;
|
|
379
|
+
baseUrl?: string;
|
|
380
|
+
}): Promise<MeetUser[]>;
|
|
381
|
+
|
|
312
382
|
interface GetUpdatesParams {
|
|
313
383
|
token: string;
|
|
314
384
|
baseUrl?: string;
|
|
@@ -378,4 +448,4 @@ declare function getChunkNum(size: number): number;
|
|
|
378
448
|
declare function getConvID(firstID: number, secondID: number, sessionType: number, companyID?: number): string;
|
|
379
449
|
declare function getQuoteMsgKey(convID: string, seqID: number): string;
|
|
380
450
|
|
|
381
|
-
export { API, type AccessURLResult, ApiError, type ApiErrorResponse, type ApiResponse, type AttachmentInfo, type BotChat, type BotFile, type BotMsg, type BotMsgUpdate, type BotUpdate, type BotUser, CHUNK_RULES, type ChatType, type CompleteMultipartUploadParams, type CompleteMultipartUploadResult, DEFAULT_BASE_URL, type ErrorCode, type ExtraInfo, type GetAccessURLBySessionParams, type GetAccessURLParams, type GetMultiPartUploadURLParams, type GetUpdatesOptions, type GetUpdatesV2Result, type GetUploadURLParams, HTTP, type LogLevel, MeetBot, type MeetBotConfig, MeetBotError, type MsgContent, type MsgType, type MultiPartUploadURLResult, NetworkError, POLLING, type PollingOptions, type QuoteMsgMap, type ReceivedAttachmentInfo, SESSION_TYPE, type SendMediaOptions, type SendMessageOptions, type SendMessageResult, type SessionInfo, type SessionType, TimeoutError, UPLOAD, type UploadFileOptions, type UploadFileResult, type UploadPart, type UploadProgress, type UploadURLResult, ValidationError, completeMultipartUpload, computeMD5, getAccessURL, getChunkNum, getConvID, getMultiPartUploadURL, getQuoteMsgKey, getUpdates, getUpdatesV2, getUploadURL, sendMediaMessage, sendMessage, uploadFile };
|
|
451
|
+
export { API, type AccessURLResult, ApiError, type ApiErrorResponse, type ApiResponse, type AttachmentInfo, type BotChat, type BotFile, type BotMsg, type BotMsgUpdate, type BotUpdate, type BotUser, CHUNK_RULES, type ChatType, type CompleteMultipartUploadParams, type CompleteMultipartUploadResult, DEFAULT_BASE_URL, type ErrorCode, type ExtraInfo, type GetAccessURLBySessionParams, type GetAccessURLParams, type GetMultiPartUploadURLParams, type GetUpdatesOptions, type GetUpdatesV2Result, type GetUploadURLParams, HTTP, type LogLevel, MeetBot, type MeetBotConfig, MeetBotError, type MeetUser, type MsgContent, type MsgType, type MultiPartUploadURLResult, NetworkError, POLLING, type PollingOptions, type QuoteMsgMap, type ReceivedAttachmentInfo, SESSION_TYPE, type SendMediaOptions, type SendMessageOptions, type SendMessageResult, type SessionInfo, type SessionType, TimeoutError, UPLOAD, type UploadFileOptions, type UploadFileResult, type UploadPart, type UploadProgress, type UploadURLResult, UserCache, type UserCacheOptions, ValidationError, completeMultipartUpload, computeMD5, getAccessURL, getChunkNum, getConvID, getMultiPartUploadURL, getQuoteMsgKey, getUpdates, getUpdatesV2, getUploadURL, getUsers, sendMediaMessage, sendMessage, uploadFile };
|
package/dist/index.js
CHANGED
|
@@ -44,16 +44,34 @@ var init_error = __esm({
|
|
|
44
44
|
};
|
|
45
45
|
NetworkError = class extends MeetBotError {
|
|
46
46
|
cause;
|
|
47
|
-
|
|
47
|
+
/**
|
|
48
|
+
* HTTP 状态码(如果有的话)
|
|
49
|
+
* 例如:504 表示网关超时,0 表示无 HTTP 响应
|
|
50
|
+
*/
|
|
51
|
+
httpStatus;
|
|
52
|
+
/**
|
|
53
|
+
* 响应内容片段(用于调试)
|
|
54
|
+
*/
|
|
55
|
+
responseSnippet;
|
|
56
|
+
constructor(message, cause, httpStatus, responseSnippet) {
|
|
48
57
|
super(message, "NETWORK_ERROR");
|
|
49
58
|
this.name = "NetworkError";
|
|
50
59
|
this.cause = cause;
|
|
60
|
+
this.httpStatus = httpStatus;
|
|
61
|
+
this.responseSnippet = responseSnippet;
|
|
51
62
|
}
|
|
52
63
|
};
|
|
53
64
|
TimeoutError = class extends MeetBotError {
|
|
54
|
-
|
|
65
|
+
/**
|
|
66
|
+
* 是否为本地客户端超时(AbortController 触发)
|
|
67
|
+
* true: 本地 HTTP 请求超时
|
|
68
|
+
* false: 服务端/网关返回的超时(如 504 Gateway Timeout)
|
|
69
|
+
*/
|
|
70
|
+
isLocal;
|
|
71
|
+
constructor(message, isLocal = true) {
|
|
55
72
|
super(message, "TIMEOUT_ERROR");
|
|
56
73
|
this.name = "TimeoutError";
|
|
74
|
+
this.isLocal = isLocal;
|
|
57
75
|
}
|
|
58
76
|
};
|
|
59
77
|
ValidationError = class extends MeetBotError {
|
|
@@ -196,8 +214,8 @@ function extractBotToken(token) {
|
|
|
196
214
|
const parts = token.split(":");
|
|
197
215
|
return parts.length >= 2 ? parts.slice(1).join(":") : token;
|
|
198
216
|
}
|
|
199
|
-
function buildUrl(baseUrl, path, params) {
|
|
200
|
-
const url = new URL(
|
|
217
|
+
function buildUrl(baseUrl, path, pathPrefix, params) {
|
|
218
|
+
const url = new URL(`${pathPrefix}${path}`, baseUrl);
|
|
201
219
|
if (params) {
|
|
202
220
|
for (const [key, value] of Object.entries(params)) {
|
|
203
221
|
if (value !== void 0) {
|
|
@@ -208,9 +226,19 @@ function buildUrl(baseUrl, path, params) {
|
|
|
208
226
|
return url.toString();
|
|
209
227
|
}
|
|
210
228
|
async function request(options) {
|
|
211
|
-
const {
|
|
229
|
+
const {
|
|
230
|
+
token,
|
|
231
|
+
baseUrl,
|
|
232
|
+
method = "GET",
|
|
233
|
+
path,
|
|
234
|
+
pathPrefix = "/im/bot/",
|
|
235
|
+
params,
|
|
236
|
+
body,
|
|
237
|
+
timeout = HTTP.DEFAULT_TIMEOUT,
|
|
238
|
+
raw = false
|
|
239
|
+
} = options;
|
|
212
240
|
validateToken(token);
|
|
213
|
-
const url = buildUrl(baseUrl || DEFAULT_BASE_URL, path, method === "GET" ? params : void 0);
|
|
241
|
+
const url = buildUrl(baseUrl || DEFAULT_BASE_URL, path, pathPrefix, method === "GET" ? params : void 0);
|
|
214
242
|
const controller = new AbortController();
|
|
215
243
|
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
216
244
|
const headers = {
|
|
@@ -239,18 +267,40 @@ async function request(options) {
|
|
|
239
267
|
const responseText = await response.text();
|
|
240
268
|
if (!contentType.includes("application/json")) {
|
|
241
269
|
logger.error("[Response] Non-JSON response:", responseText.substring(0, 500));
|
|
242
|
-
|
|
270
|
+
if (response.status === 504) {
|
|
271
|
+
throw new TimeoutError(`Gateway timeout (status ${response.status})`, false);
|
|
272
|
+
}
|
|
273
|
+
throw new NetworkError(
|
|
274
|
+
`Server returned non-JSON response (status ${response.status})`,
|
|
275
|
+
void 0,
|
|
276
|
+
response.status,
|
|
277
|
+
responseText.substring(0, 200)
|
|
278
|
+
);
|
|
243
279
|
}
|
|
244
280
|
let data;
|
|
245
281
|
try {
|
|
246
282
|
data = JSON.parse(responseText);
|
|
247
283
|
} catch {
|
|
248
284
|
logger.error("[Response] Failed to parse JSON:", responseText.substring(0, 500));
|
|
249
|
-
throw new NetworkError(
|
|
285
|
+
throw new NetworkError(
|
|
286
|
+
"Failed to parse server response",
|
|
287
|
+
void 0,
|
|
288
|
+
response.status,
|
|
289
|
+
responseText.substring(0, 200)
|
|
290
|
+
);
|
|
250
291
|
}
|
|
251
292
|
logger.info("[Response Body]", JSON.stringify(data));
|
|
293
|
+
if (raw) {
|
|
294
|
+
return data;
|
|
295
|
+
}
|
|
252
296
|
if (!response.ok || !data.ok) {
|
|
253
297
|
const errorData = data;
|
|
298
|
+
if (response.status === 504) {
|
|
299
|
+
throw new TimeoutError(
|
|
300
|
+
errorData.description || `Gateway timeout (status ${response.status})`,
|
|
301
|
+
false
|
|
302
|
+
);
|
|
303
|
+
}
|
|
254
304
|
throw new ApiError(
|
|
255
305
|
errorData.description || `HTTP ${response.status}`,
|
|
256
306
|
response.status,
|
|
@@ -266,7 +316,7 @@ async function request(options) {
|
|
|
266
316
|
}
|
|
267
317
|
if (error instanceof Error) {
|
|
268
318
|
if (error.name === "AbortError") {
|
|
269
|
-
throw new TimeoutError(`Request timeout after ${timeout}ms
|
|
319
|
+
throw new TimeoutError(`Request timeout after ${timeout}ms`, true);
|
|
270
320
|
}
|
|
271
321
|
throw new NetworkError(`Network error: ${error.message}`, error);
|
|
272
322
|
}
|
|
@@ -541,6 +591,25 @@ async function sendMediaMessage(token, sessionInfo, options, baseUrl) {
|
|
|
541
591
|
});
|
|
542
592
|
}
|
|
543
593
|
|
|
594
|
+
// src/api/user.ts
|
|
595
|
+
async function getUsers(params) {
|
|
596
|
+
const { token, baseUrl } = params;
|
|
597
|
+
const result = await request({
|
|
598
|
+
token,
|
|
599
|
+
baseUrl,
|
|
600
|
+
method: "POST",
|
|
601
|
+
path: "general/SyncCompanyUser",
|
|
602
|
+
pathPrefix: "/",
|
|
603
|
+
body: { syncAt: 0 },
|
|
604
|
+
timeout: HTTP.DEFAULT_TIMEOUT,
|
|
605
|
+
raw: true
|
|
606
|
+
});
|
|
607
|
+
return Object.values(result.users).map((user) => ({
|
|
608
|
+
userID: user.userID,
|
|
609
|
+
nickName: user.nickName
|
|
610
|
+
}));
|
|
611
|
+
}
|
|
612
|
+
|
|
544
613
|
// src/api/index.ts
|
|
545
614
|
async function getUpdates(params) {
|
|
546
615
|
const { token, baseUrl, timeout = API.DEFAULT_TIMEOUT, offset, limit = API.DEFAULT_LIMIT } = params;
|
|
@@ -593,6 +662,115 @@ async function sendMessage(params) {
|
|
|
593
662
|
|
|
594
663
|
// src/client.ts
|
|
595
664
|
init_error();
|
|
665
|
+
|
|
666
|
+
// src/user-cache.ts
|
|
667
|
+
var UserCache = class {
|
|
668
|
+
byId = /* @__PURE__ */ new Map();
|
|
669
|
+
byNickName = /* @__PURE__ */ new Map();
|
|
670
|
+
byAliasName = /* @__PURE__ */ new Map();
|
|
671
|
+
loadedAt = 0;
|
|
672
|
+
ttl;
|
|
673
|
+
loading = null;
|
|
674
|
+
constructor(options) {
|
|
675
|
+
this.ttl = options?.ttl ?? 60 * 60 * 1e3;
|
|
676
|
+
}
|
|
677
|
+
isExpired() {
|
|
678
|
+
return this.byId.size === 0 || this.ttl > 0 && Date.now() - this.loadedAt > this.ttl;
|
|
679
|
+
}
|
|
680
|
+
async load(fetchAll) {
|
|
681
|
+
if (this.loading) {
|
|
682
|
+
return this.loading;
|
|
683
|
+
}
|
|
684
|
+
this.loading = (async () => {
|
|
685
|
+
try {
|
|
686
|
+
const users = await fetchAll();
|
|
687
|
+
this.rebuild(users);
|
|
688
|
+
logger.info(`\u7528\u6237\u7F13\u5B58\u5DF2\u52A0\u8F7D\uFF0C\u5171 ${users.length} \u4E2A\u7528\u6237`);
|
|
689
|
+
} finally {
|
|
690
|
+
this.loading = null;
|
|
691
|
+
}
|
|
692
|
+
})();
|
|
693
|
+
return this.loading;
|
|
694
|
+
}
|
|
695
|
+
rebuild(users) {
|
|
696
|
+
this.byId.clear();
|
|
697
|
+
this.byNickName.clear();
|
|
698
|
+
this.byAliasName.clear();
|
|
699
|
+
for (const user of users) {
|
|
700
|
+
this.byId.set(user.userID, user);
|
|
701
|
+
const nickKey = user.nickName.toLowerCase();
|
|
702
|
+
let nickList = this.byNickName.get(nickKey);
|
|
703
|
+
if (!nickList) {
|
|
704
|
+
nickList = [];
|
|
705
|
+
this.byNickName.set(nickKey, nickList);
|
|
706
|
+
}
|
|
707
|
+
nickList.push(user);
|
|
708
|
+
if (user.aliasName) {
|
|
709
|
+
const aliasKey = user.aliasName.toLowerCase();
|
|
710
|
+
let aliasList = this.byAliasName.get(aliasKey);
|
|
711
|
+
if (!aliasList) {
|
|
712
|
+
aliasList = [];
|
|
713
|
+
this.byAliasName.set(aliasKey, aliasList);
|
|
714
|
+
}
|
|
715
|
+
aliasList.push(user);
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
this.loadedAt = Date.now();
|
|
719
|
+
}
|
|
720
|
+
async ensureLoaded(fetchAll) {
|
|
721
|
+
if (!this.isExpired()) return;
|
|
722
|
+
await this.load(fetchAll);
|
|
723
|
+
}
|
|
724
|
+
getById(userId) {
|
|
725
|
+
return this.byId.get(userId);
|
|
726
|
+
}
|
|
727
|
+
getByIds(userIds) {
|
|
728
|
+
const result = /* @__PURE__ */ new Map();
|
|
729
|
+
for (const id of userIds) {
|
|
730
|
+
const user = this.byId.get(id);
|
|
731
|
+
if (user) {
|
|
732
|
+
result.set(id, user);
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
return result;
|
|
736
|
+
}
|
|
737
|
+
getByName(name) {
|
|
738
|
+
const key = name.toLowerCase();
|
|
739
|
+
const byNick = this.byNickName.get(key);
|
|
740
|
+
const byAlias = this.byAliasName.get(key);
|
|
741
|
+
if (!byNick && !byAlias) return [];
|
|
742
|
+
if (!byNick) return [...byAlias];
|
|
743
|
+
if (!byAlias) return [...byNick];
|
|
744
|
+
const seen = /* @__PURE__ */ new Set();
|
|
745
|
+
const result = [];
|
|
746
|
+
for (const u of [...byNick, ...byAlias]) {
|
|
747
|
+
if (!seen.has(u.userID)) {
|
|
748
|
+
seen.add(u.userID);
|
|
749
|
+
result.push(u);
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
return result;
|
|
753
|
+
}
|
|
754
|
+
searchByName(query) {
|
|
755
|
+
const q = query.toLowerCase();
|
|
756
|
+
const result = [];
|
|
757
|
+
const seen = /* @__PURE__ */ new Set();
|
|
758
|
+
for (const user of this.byId.values()) {
|
|
759
|
+
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)) {
|
|
760
|
+
if (!seen.has(user.userID)) {
|
|
761
|
+
seen.add(user.userID);
|
|
762
|
+
result.push(user);
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
}
|
|
766
|
+
return result;
|
|
767
|
+
}
|
|
768
|
+
get size() {
|
|
769
|
+
return this.byId.size;
|
|
770
|
+
}
|
|
771
|
+
};
|
|
772
|
+
|
|
773
|
+
// src/client.ts
|
|
596
774
|
var MeetBot = class {
|
|
597
775
|
token;
|
|
598
776
|
baseUrl;
|
|
@@ -603,6 +781,7 @@ var MeetBot = class {
|
|
|
603
781
|
polling = false;
|
|
604
782
|
offset = 0;
|
|
605
783
|
abortController = null;
|
|
784
|
+
userCache;
|
|
606
785
|
constructor(config) {
|
|
607
786
|
if (config.token) {
|
|
608
787
|
if (!config.token.includes(":")) {
|
|
@@ -618,6 +797,7 @@ var MeetBot = class {
|
|
|
618
797
|
this.pollingLimit = config.pollingLimit ?? POLLING.DEFAULT_LIMIT;
|
|
619
798
|
this.longPollingTimeout = config.longPollingTimeout ?? POLLING.DEFAULT_TIMEOUT;
|
|
620
799
|
this.useV2 = config.useV2 ?? false;
|
|
800
|
+
this.userCache = new UserCache(config.userCacheOptions);
|
|
621
801
|
logger.setLevel(config.logLevel ?? "silent");
|
|
622
802
|
}
|
|
623
803
|
on(event, handler) {
|
|
@@ -799,6 +979,56 @@ var MeetBot = class {
|
|
|
799
979
|
async sendMedia(sessionInfo, options) {
|
|
800
980
|
return sendMediaMessage(this.token, sessionInfo, options, this.baseUrl);
|
|
801
981
|
}
|
|
982
|
+
/**
|
|
983
|
+
* 刷新用户缓存
|
|
984
|
+
*/
|
|
985
|
+
async refreshUserCache() {
|
|
986
|
+
await this.userCache.load(async () => {
|
|
987
|
+
return getUsers({ token: this.token, baseUrl: this.baseUrl });
|
|
988
|
+
});
|
|
989
|
+
}
|
|
990
|
+
/**
|
|
991
|
+
* 根据用户 ID 获取用户信息
|
|
992
|
+
*/
|
|
993
|
+
async getUserById(userId) {
|
|
994
|
+
await this.userCache.ensureLoaded(async () => {
|
|
995
|
+
return getUsers({ token: this.token, baseUrl: this.baseUrl });
|
|
996
|
+
});
|
|
997
|
+
return this.userCache.getById(userId);
|
|
998
|
+
}
|
|
999
|
+
/**
|
|
1000
|
+
* 批量根据用户 ID 获取用户信息
|
|
1001
|
+
*/
|
|
1002
|
+
async getUserByIds(userIds) {
|
|
1003
|
+
await this.userCache.ensureLoaded(async () => {
|
|
1004
|
+
return getUsers({ token: this.token, baseUrl: this.baseUrl });
|
|
1005
|
+
});
|
|
1006
|
+
return this.userCache.getByIds(userIds);
|
|
1007
|
+
}
|
|
1008
|
+
/**
|
|
1009
|
+
* 根据昵称或别名精确查找用户
|
|
1010
|
+
*/
|
|
1011
|
+
async getUserByName(name) {
|
|
1012
|
+
await this.userCache.ensureLoaded(async () => {
|
|
1013
|
+
return getUsers({ token: this.token, baseUrl: this.baseUrl });
|
|
1014
|
+
});
|
|
1015
|
+
return this.userCache.getByName(name);
|
|
1016
|
+
}
|
|
1017
|
+
/**
|
|
1018
|
+
* 根据昵称或别名模糊搜索用户
|
|
1019
|
+
*/
|
|
1020
|
+
async searchUserByName(query) {
|
|
1021
|
+
await this.userCache.ensureLoaded(async () => {
|
|
1022
|
+
return getUsers({ token: this.token, baseUrl: this.baseUrl });
|
|
1023
|
+
});
|
|
1024
|
+
return this.userCache.searchByName(query);
|
|
1025
|
+
}
|
|
1026
|
+
/**
|
|
1027
|
+
* 获取缓存用户数
|
|
1028
|
+
*/
|
|
1029
|
+
get userCacheSize() {
|
|
1030
|
+
return this.userCache.size;
|
|
1031
|
+
}
|
|
802
1032
|
sleep(ms) {
|
|
803
1033
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
804
1034
|
}
|
|
@@ -807,6 +1037,4 @@ var MeetBot = class {
|
|
|
807
1037
|
// src/index.ts
|
|
808
1038
|
init_error();
|
|
809
1039
|
|
|
810
|
-
export { API, ApiError, CHUNK_RULES, DEFAULT_BASE_URL, HTTP, MeetBot, MeetBotError, NetworkError, POLLING, SESSION_TYPE, TimeoutError, UPLOAD, ValidationError, completeMultipartUpload, computeMD5, getAccessURL, getChunkNum, getConvID, getMultiPartUploadURL, getQuoteMsgKey, getUpdates, getUpdatesV2, getUploadURL, sendMediaMessage, sendMessage, uploadFile };
|
|
811
|
-
//# sourceMappingURL=index.js.map
|
|
812
|
-
//# sourceMappingURL=index.js.map
|
|
1040
|
+
export { API, ApiError, CHUNK_RULES, DEFAULT_BASE_URL, HTTP, MeetBot, MeetBotError, NetworkError, POLLING, SESSION_TYPE, TimeoutError, UPLOAD, UserCache, ValidationError, completeMultipartUpload, computeMD5, getAccessURL, getChunkNum, getConvID, getMultiPartUploadURL, getQuoteMsgKey, getUpdates, getUpdatesV2, getUploadURL, getUsers, sendMediaMessage, sendMessage, uploadFile };
|