@naplink/naplink 0.0.1 → 0.0.3

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.js CHANGED
@@ -328,11 +328,14 @@ function startHeartbeat(deps) {
328
328
 
329
329
  // src/core/connection/retry-handler.ts
330
330
  function handleReconnect(deps) {
331
- const { config, logger, reconnectService, setState, connect } = deps;
331
+ const { config, logger, reconnectService, setState, connect, onMaxAttemptsReached } = deps;
332
332
  if (!reconnectService.hasRemainingAttempts()) {
333
333
  setState("disconnected" /* DISCONNECTED */);
334
334
  const err = new MaxReconnectAttemptsError(reconnectService.getMaxAttempts());
335
335
  logger.error("\u81EA\u52A8\u91CD\u8FDE\u5DF2\u8FBE\u4E0A\u9650\uFF0C\u505C\u6B62\u91CD\u8FDE", err);
336
+ if (onMaxAttemptsReached) {
337
+ onMaxAttemptsReached();
338
+ }
336
339
  return false;
337
340
  }
338
341
  setState("reconnecting" /* RECONNECTING */);
@@ -341,6 +344,9 @@ function handleReconnect(deps) {
341
344
  setState("disconnected" /* DISCONNECTED */);
342
345
  const err = new MaxReconnectAttemptsError(config.reconnect.maxAttempts);
343
346
  logger.error("\u81EA\u52A8\u91CD\u8FDE\u5DF2\u8FBE\u4E0A\u9650\uFF0C\u505C\u6B62\u91CD\u8FDE", err);
347
+ if (onMaxAttemptsReached) {
348
+ onMaxAttemptsReached();
349
+ }
344
350
  return false;
345
351
  }
346
352
  return true;
@@ -348,7 +354,7 @@ function handleReconnect(deps) {
348
354
 
349
355
  // src/core/connection/close-handler.ts
350
356
  function handleCloseEvent(deps, event) {
351
- const { getState, setState, stopHeartbeat, logger, config, reconnectService, reconnect } = deps;
357
+ const { getState, setState, stopHeartbeat, logger, config, reconnectService, reconnect, onMaxAttemptsReached } = deps;
352
358
  stopHeartbeat();
353
359
  logger.info(`\u8FDE\u63A5\u5173\u95ED (code: ${event.code}, reason: ${event.reason})`);
354
360
  if (event.code === 1e3) {
@@ -362,7 +368,9 @@ function handleCloseEvent(deps, event) {
362
368
  logger,
363
369
  reconnectService,
364
370
  setState,
365
- connect: reconnect
371
+ connect: reconnect,
372
+ onMaxAttemptsReached
373
+ // 传递回调
366
374
  });
367
375
  } else {
368
376
  setState("disconnected" /* DISCONNECTED */);
@@ -412,11 +420,13 @@ function attachWebSocketHandlers(ws, deps, resolve, reject) {
412
420
 
413
421
  // src/core/connection/manager.ts
414
422
  var ConnectionManager = class {
415
- constructor(config, logger, onMessage, onStateChange) {
423
+ // 跟踪是否处于重连状态
424
+ constructor(config, logger, onMessage, onStateChange, emitter) {
416
425
  this.config = config;
417
426
  this.logger = logger;
418
427
  this.onMessage = onMessage;
419
428
  this.onStateChange = onStateChange;
429
+ this.emitter = emitter;
420
430
  this.reconnectService = new ReconnectService(config.reconnect, logger);
421
431
  }
422
432
  ws;
@@ -425,6 +435,7 @@ var ConnectionManager = class {
425
435
  heartbeatService;
426
436
  connectPromise;
427
437
  connectTimeout;
438
+ wasReconnecting = false;
428
439
  /**
429
440
  * 连接到WebSocket服务器
430
441
  */
@@ -480,7 +491,15 @@ var ConnectionManager = class {
480
491
  logger: this.logger,
481
492
  config: this.config,
482
493
  reconnectService: this.reconnectService,
483
- reconnect: () => this.connect()
494
+ reconnect: () => this.connect(),
495
+ onMaxAttemptsReached: () => {
496
+ if (this.emitter) {
497
+ this.emitter.emit("connection:lost", {
498
+ timestamp: Date.now(),
499
+ attempts: this.reconnectService.getMaxAttempts()
500
+ });
501
+ }
502
+ }
484
503
  }, event),
485
504
  clearConnectTimeout: () => this.clearConnectTimeout()
486
505
  },
@@ -540,7 +559,14 @@ var ConnectionManager = class {
540
559
  if (this.state !== state) {
541
560
  this.state = state;
542
561
  this.logger.debug(`\u72B6\u6001\u53D8\u66F4: ${state}`);
543
- this.onStateChange(state);
562
+ if (state === "reconnecting" /* RECONNECTING */) {
563
+ this.wasReconnecting = true;
564
+ } else if (state === "connected" /* CONNECTED */) {
565
+ this.onStateChange(state, this.wasReconnecting);
566
+ this.wasReconnecting = false;
567
+ return;
568
+ }
569
+ this.onStateChange(state, false);
544
570
  }
545
571
  }
546
572
  /**
@@ -594,6 +620,20 @@ var ResponseRegistry = class {
594
620
  this.pending.set(echo, entry);
595
621
  return entry;
596
622
  }
623
+ get(echo) {
624
+ return this.pending.get(echo);
625
+ }
626
+ refresh(echo) {
627
+ const req = this.pending.get(echo);
628
+ if (!req) return false;
629
+ clearTimeout(req.timer);
630
+ req.createdAt = Date.now();
631
+ req.timer = setTimeout(() => {
632
+ this.pending.delete(echo);
633
+ req.reject(new ApiTimeoutError(req.method, req.timeoutMs));
634
+ }, req.timeoutMs);
635
+ return true;
636
+ }
597
637
  resolve(echo, data) {
598
638
  const req = this.pending.get(echo);
599
639
  if (!req) return false;
@@ -661,6 +701,52 @@ async function withRetry(fn, retries, method, logger, delayFn) {
661
701
  }
662
702
 
663
703
  // src/core/api-client.ts
704
+ var AsyncQueue = class {
705
+ values = [];
706
+ waiters = [];
707
+ closed = false;
708
+ push(value) {
709
+ if (this.closed) return;
710
+ const waiter = this.waiters.shift();
711
+ if (waiter) {
712
+ waiter.resolve({ value, done: false });
713
+ } else {
714
+ this.values.push(value);
715
+ }
716
+ }
717
+ close() {
718
+ if (this.closed) return;
719
+ this.closed = true;
720
+ while (this.waiters.length) {
721
+ this.waiters.shift().resolve({ value: void 0, done: true });
722
+ }
723
+ }
724
+ fail(error) {
725
+ if (this.closed) return;
726
+ this.closed = true;
727
+ while (this.waiters.length) {
728
+ this.waiters.shift().reject(error);
729
+ }
730
+ this.values = [];
731
+ }
732
+ async next() {
733
+ if (this.values.length) {
734
+ return { value: this.values.shift(), done: false };
735
+ }
736
+ if (this.closed) {
737
+ return { value: void 0, done: true };
738
+ }
739
+ return await new Promise((resolve, reject) => {
740
+ this.waiters.push({
741
+ resolve,
742
+ reject: (err) => reject(err)
743
+ });
744
+ });
745
+ }
746
+ [Symbol.asyncIterator]() {
747
+ return this;
748
+ }
749
+ };
664
750
  var ApiClient = class {
665
751
  constructor(connection, config, logger) {
666
752
  this.connection = connection;
@@ -688,32 +774,68 @@ var ApiClient = class {
688
774
  this.delay.bind(this)
689
775
  );
690
776
  }
777
+ /**
778
+ * 调用流式 API(NapCat stream-action)
779
+ * 会持续产出 data.type=stream 的分片包,并在 data.type=response 时结束。
780
+ */
781
+ callStream(method, params = {}, options) {
782
+ const timeout = options?.timeout ?? this.config.api.timeout;
783
+ const queue = new AsyncQueue();
784
+ const result = this.sendRequest(method, params, timeout, {
785
+ onPacket: (packet) => queue.push(packet),
786
+ onEnd: () => queue.close(),
787
+ onError: (error) => queue.fail(error)
788
+ });
789
+ return { packets: queue, result };
790
+ }
691
791
  /**
692
792
  * 处理API响应
693
793
  * 由连接管理器调用
694
794
  */
695
795
  handleResponse(echo, response) {
696
- const request = this.registry.take(echo);
796
+ const request = this.registry.get(echo);
697
797
  if (!request) {
698
- this.logger.warn(`\u6536\u5230\u672A\u77E5\u8BF7\u6C42\u7684\u54CD\u5E94: ${echo}`);
798
+ if (response?.stream === "stream-action") {
799
+ this.logger.debug(`\u6536\u5230\u672A\u77E5\u6D41\u5F0F\u54CD\u5E94: ${echo}`);
800
+ } else {
801
+ this.logger.warn(`\u6536\u5230\u672A\u77E5\u8BF7\u6C42\u7684\u54CD\u5E94: ${echo}`);
802
+ }
699
803
  return;
700
804
  }
805
+ const isStreamAction = response?.stream === "stream-action" || typeof response?.data?.type === "string" && ["stream", "response", "reset", "error"].includes(response.data.type);
701
806
  if (response.status === "ok" || response.retcode === 0) {
807
+ if (isStreamAction) {
808
+ const packet = response.data;
809
+ const packetType = packet?.type;
810
+ if (request.onPacket) {
811
+ this.registry.refresh(echo);
812
+ request.onPacket(packet);
813
+ if (packetType === "response") {
814
+ this.logger.debug(`API\u6D41\u5F0F\u5B8C\u6210: ${request.method}`);
815
+ this.registry.resolve(echo, packet);
816
+ request.onEnd?.();
817
+ }
818
+ return;
819
+ }
820
+ this.logger.debug(`API\u6210\u529F(stream): ${request.method}`);
821
+ this.registry.resolve(echo, packet);
822
+ return;
823
+ }
702
824
  this.logger.debug(`API\u6210\u529F: ${request.method}`);
703
- request.resolve(response.data);
825
+ this.registry.resolve(echo, response.data);
704
826
  } else {
705
827
  this.logger.warn(`API\u5931\u8D25: ${request.method}`, {
706
828
  retcode: response.retcode,
707
829
  message: response.message
708
830
  });
709
- request.reject(
710
- new ApiError(
711
- request.method,
712
- response.retcode,
713
- response.message,
714
- response.wording
715
- )
831
+ const error = new ApiError(
832
+ request.method,
833
+ response.retcode,
834
+ response.message,
835
+ response.wording
716
836
  );
837
+ request.onError?.(error);
838
+ this.registry.reject(echo, error);
717
839
  }
718
840
  }
719
841
  /**
@@ -729,17 +851,19 @@ var ApiClient = class {
729
851
  /**
730
852
  * 发送API请求
731
853
  */
732
- sendRequest(method, params, timeout) {
854
+ sendRequest(method, params, timeout, hooks) {
733
855
  return new Promise((resolve, reject) => {
734
856
  const echo = this.generateRequestId();
735
857
  this.logger.debug(`\u53D1\u9001API\u8BF7\u6C42: ${method}`, { echo, params });
736
858
  this.registry.add(
737
859
  echo,
738
860
  {
739
- resolve,
740
- reject,
861
+ resolve: (data) => resolve(data),
862
+ reject: (error) => reject(error),
741
863
  createdAt: Date.now(),
742
- method
864
+ method,
865
+ timeoutMs: timeout,
866
+ ...hooks ?? {}
743
867
  },
744
868
  timeout
745
869
  );
@@ -751,6 +875,7 @@ var ApiClient = class {
751
875
  this.connection.send(payload);
752
876
  } catch (error) {
753
877
  this.registry.reject(echo, error);
878
+ hooks?.onError?.(error);
754
879
  reject(error);
755
880
  }
756
881
  });
@@ -951,11 +1076,14 @@ var MessageDispatcher = class {
951
1076
  };
952
1077
 
953
1078
  // src/core/connection/state-handler.ts
954
- function handleConnectionStateChange(emitter, state) {
1079
+ function handleConnectionStateChange(emitter, state, wasReconnecting = false) {
955
1080
  emitter.emit("state_change", state);
956
1081
  switch (state) {
957
1082
  case "connected" /* CONNECTED */:
958
1083
  emitter.emit("connect");
1084
+ if (wasReconnecting) {
1085
+ emitter.emit("connection:restored", { timestamp: Date.now() });
1086
+ }
959
1087
  break;
960
1088
  case "disconnected" /* DISCONNECTED */:
961
1089
  emitter.emit("disconnect");
@@ -1002,6 +1130,15 @@ function createMessageApi(client) {
1002
1130
  markMessageAsRead(messageId) {
1003
1131
  return client.call("mark_msg_as_read", { message_id: messageId });
1004
1132
  },
1133
+ markGroupMsgAsRead(groupId) {
1134
+ return client.call("mark_group_msg_as_read", { group_id: groupId });
1135
+ },
1136
+ markPrivateMsgAsRead(userId) {
1137
+ return client.call("mark_private_msg_as_read", { user_id: userId });
1138
+ },
1139
+ markAllMsgAsRead() {
1140
+ return client.call("_mark_all_as_read");
1141
+ },
1005
1142
  getGroupAtAllRemain(groupId) {
1006
1143
  return client.call("get_group_at_all_remain", { group_id: groupId });
1007
1144
  },
@@ -1010,6 +1147,30 @@ function createMessageApi(client) {
1010
1147
  },
1011
1148
  getGroupHonorInfo(groupId, type) {
1012
1149
  return client.call("get_group_honor_info", { group_id: groupId, type });
1150
+ },
1151
+ getGroupMsgHistory(params) {
1152
+ return client.call("get_group_msg_history", params);
1153
+ },
1154
+ getFriendMsgHistory(params) {
1155
+ return client.call("get_friend_msg_history", params);
1156
+ },
1157
+ getRecentContact(count) {
1158
+ return client.call("get_recent_contact", { count });
1159
+ },
1160
+ setMsgEmojiLike(messageId, emojiId, set) {
1161
+ return client.call("set_msg_emoji_like", { message_id: messageId, emoji_id: emojiId, set });
1162
+ },
1163
+ fetchEmojiLike(params) {
1164
+ return client.call("fetch_emoji_like", params);
1165
+ },
1166
+ sendGroupPoke(groupId, userId) {
1167
+ return client.call("group_poke", { group_id: groupId, user_id: userId });
1168
+ },
1169
+ sendFriendPoke(userId) {
1170
+ return client.call("friend_poke", { user_id: userId });
1171
+ },
1172
+ sendPoke(targetId, groupId) {
1173
+ return client.call("send_poke", groupId ? { group_id: groupId, target_id: targetId } : { user_id: targetId });
1013
1174
  }
1014
1175
  };
1015
1176
  }
@@ -1033,26 +1194,29 @@ function createMediaApi(client, logger) {
1033
1194
  const data = segment?.data;
1034
1195
  if (!type || !data) return;
1035
1196
  if (["image", "video", "record", "audio", "file"].includes(type)) {
1036
- const fileId = data.file;
1197
+ const fileId = data.file ?? data.file_id;
1037
1198
  if (typeof fileId === "string" && !/^https?:\/\//.test(fileId) && !fileId.startsWith("file://")) {
1038
1199
  try {
1039
1200
  const res = await api.getFile(fileId);
1040
- if (res?.file) {
1041
- data.url = res.file;
1042
- data.file = res.file;
1201
+ const hydratedUrl = res?.file ?? res?.url;
1202
+ if (hydratedUrl) {
1203
+ data.url = hydratedUrl;
1204
+ data.file = hydratedUrl;
1043
1205
  return;
1044
1206
  }
1045
1207
  if (type === "record" || type === "audio") {
1046
1208
  const rec = await api.getRecord(fileId, "mp3");
1047
- if (rec?.file) {
1048
- data.url = rec.file;
1049
- data.file = rec.file;
1209
+ const recUrl = rec?.file ?? rec?.url;
1210
+ if (recUrl) {
1211
+ data.url = recUrl;
1212
+ data.file = recUrl;
1050
1213
  }
1051
1214
  } else if (type === "image") {
1052
1215
  const img = await api.getImage(fileId);
1053
- if (img?.file) {
1054
- data.url = img.file;
1055
- data.file = img.file;
1216
+ const imgUrl = img?.file ?? img?.url;
1217
+ if (imgUrl) {
1218
+ data.url = imgUrl;
1219
+ data.file = imgUrl;
1056
1220
  }
1057
1221
  }
1058
1222
  } catch (e) {
@@ -1272,7 +1436,39 @@ async function computeSha256(source) {
1272
1436
  }
1273
1437
 
1274
1438
  // src/api/onebot/stream.ts
1439
+ import { createWriteStream as createWriteStream3 } from "fs";
1440
+ import { promises as fs3 } from "fs";
1441
+ import { tmpdir as tmpdir3 } from "os";
1442
+ import { join as join3 } from "path";
1275
1443
  function createStreamApi(client) {
1444
+ const downloadToFile = async (action, params, filenameHint) => {
1445
+ const { packets } = client.callStream(action, params);
1446
+ let fileInfo;
1447
+ const tempPath = join3(tmpdir3(), `${randomUUID3()}-${filenameHint || "naplink.download"}`);
1448
+ const writeStream = createWriteStream3(tempPath);
1449
+ try {
1450
+ for await (const packet of packets) {
1451
+ if (packet?.data_type === "file_info") {
1452
+ fileInfo = packet;
1453
+ }
1454
+ if (packet?.data_type === "file_chunk" && typeof packet.data === "string") {
1455
+ writeStream.write(Buffer.from(packet.data, "base64"));
1456
+ }
1457
+ }
1458
+ await new Promise((resolve, reject) => {
1459
+ writeStream.once("error", reject);
1460
+ writeStream.end(() => resolve());
1461
+ });
1462
+ return { path: tempPath, info: fileInfo };
1463
+ } catch (error) {
1464
+ try {
1465
+ writeStream.destroy();
1466
+ } catch {
1467
+ }
1468
+ await fs3.unlink(tempPath).catch(() => void 0);
1469
+ throw error;
1470
+ }
1471
+ };
1276
1472
  return {
1277
1473
  async uploadFileStream(file, options) {
1278
1474
  const chunkSize = options?.chunkSize ?? 256 * 1024;
@@ -1311,7 +1507,48 @@ function createStreamApi(client) {
1311
1507
  return completion;
1312
1508
  },
1313
1509
  getUploadStreamStatus(streamId) {
1314
- return client.call("upload_file_stream", { stream_id: streamId });
1510
+ return client.call("upload_file_stream", { stream_id: streamId, verify_only: true });
1511
+ },
1512
+ downloadFileStream(fileId, options) {
1513
+ const chunkSize = options?.chunkSize ?? 64 * 1024;
1514
+ return client.callStream("download_file_stream", {
1515
+ file: fileId,
1516
+ chunk_size: chunkSize
1517
+ });
1518
+ },
1519
+ async downloadFileStreamToFile(fileId, options) {
1520
+ const chunkSize = options?.chunkSize ?? 64 * 1024;
1521
+ return downloadToFile("download_file_stream", { file: fileId, chunk_size: chunkSize }, options?.filename);
1522
+ },
1523
+ downloadFileImageStream(fileId, options) {
1524
+ const chunkSize = options?.chunkSize ?? 64 * 1024;
1525
+ return client.callStream("download_file_image_stream", {
1526
+ file: fileId,
1527
+ chunk_size: chunkSize
1528
+ });
1529
+ },
1530
+ async downloadFileImageStreamToFile(fileId, options) {
1531
+ const chunkSize = options?.chunkSize ?? 64 * 1024;
1532
+ return downloadToFile("download_file_image_stream", { file: fileId, chunk_size: chunkSize }, options?.filename);
1533
+ },
1534
+ downloadFileRecordStream(fileId, outFormat, options) {
1535
+ const chunkSize = options?.chunkSize ?? 64 * 1024;
1536
+ return client.callStream("download_file_record_stream", {
1537
+ file: fileId,
1538
+ chunk_size: chunkSize,
1539
+ out_format: outFormat
1540
+ });
1541
+ },
1542
+ async downloadFileRecordStreamToFile(fileId, outFormat, options) {
1543
+ const chunkSize = options?.chunkSize ?? 64 * 1024;
1544
+ return downloadToFile(
1545
+ "download_file_record_stream",
1546
+ { file: fileId, chunk_size: chunkSize, out_format: outFormat },
1547
+ options?.filename
1548
+ );
1549
+ },
1550
+ cleanStreamTempFile() {
1551
+ return client.call("clean_stream_temp_file");
1315
1552
  }
1316
1553
  };
1317
1554
  }
@@ -1328,6 +1565,328 @@ function createRequestApi(client) {
1328
1565
  };
1329
1566
  }
1330
1567
 
1568
+ // src/api/onebot/system.ts
1569
+ function createSystemApi(client) {
1570
+ return {
1571
+ getOnlineClients(noCache = false) {
1572
+ return client.call("get_online_clients", { no_cache: noCache });
1573
+ },
1574
+ getRobotUinRange() {
1575
+ return client.call("get_robot_uin_range");
1576
+ },
1577
+ canSendImage() {
1578
+ return client.call("can_send_image");
1579
+ },
1580
+ canSendRecord() {
1581
+ return client.call("can_send_record");
1582
+ },
1583
+ getCookies(domain) {
1584
+ return client.call("get_cookies", { domain });
1585
+ },
1586
+ getCsrfToken() {
1587
+ return client.call("get_csrf_token");
1588
+ },
1589
+ getCredentials(domain) {
1590
+ return client.call("get_credentials", { domain });
1591
+ },
1592
+ setInputStatus(userId, eventType) {
1593
+ return client.call("set_input_status", { user_id: userId, event_type: eventType, eventType });
1594
+ },
1595
+ ocrImage(image, dot = false) {
1596
+ return client.call(dot ? ".ocr_image" : "ocr_image", { image });
1597
+ },
1598
+ translateEn2zh(words) {
1599
+ return client.call("translate_en2zh", { words });
1600
+ },
1601
+ checkUrlSafely(url) {
1602
+ return client.call("check_url_safely", { url });
1603
+ },
1604
+ handleQuickOperation(context, operation) {
1605
+ return client.call(".handle_quick_operation", { context, operation });
1606
+ },
1607
+ getModelShow(model) {
1608
+ return client.call("_get_model_show", { model });
1609
+ },
1610
+ setModelShow(model, modelShow) {
1611
+ return client.call("_set_model_show", { model, model_show: modelShow });
1612
+ },
1613
+ getPacketStatus() {
1614
+ return client.call("nc_get_packet_status");
1615
+ }
1616
+ };
1617
+ }
1618
+
1619
+ // src/api/onebot/napcat.ts
1620
+ function createNapCatApi(client) {
1621
+ return {
1622
+ getRkeyEx() {
1623
+ return client.call("get_rkey");
1624
+ },
1625
+ getRkeyServer() {
1626
+ return client.call("get_rkey_server");
1627
+ },
1628
+ getRkey() {
1629
+ return client.call("nc_get_rkey");
1630
+ },
1631
+ setFriendRemark(userId, remark) {
1632
+ return client.call("set_friend_remark", { user_id: userId, remark });
1633
+ },
1634
+ deleteFriend(userId) {
1635
+ return client.call("delete_friend", { user_id: userId });
1636
+ },
1637
+ getUnidirectionalFriendList() {
1638
+ return client.call("get_unidirectional_friend_list");
1639
+ },
1640
+ setGroupRemark(groupId, remark) {
1641
+ return client.call("set_group_remark", { group_id: String(groupId), remark });
1642
+ },
1643
+ getGroupInfoEx(groupId) {
1644
+ return client.call("get_group_info_ex", { group_id: groupId });
1645
+ },
1646
+ getGroupDetailInfo(groupId) {
1647
+ return client.call("get_group_detail_info", { group_id: groupId });
1648
+ },
1649
+ getGroupIgnoredNotifies() {
1650
+ return client.call("get_group_ignored_notifies");
1651
+ },
1652
+ getGroupShutList(groupId) {
1653
+ return client.call("get_group_shut_list", { group_id: groupId });
1654
+ },
1655
+ sendPrivateForwardMessage(params) {
1656
+ return client.call("send_private_forward_msg", params);
1657
+ },
1658
+ forwardFriendSingleMsg(userId, messageId) {
1659
+ return client.call("forward_friend_single_msg", { user_id: userId, message_id: messageId });
1660
+ },
1661
+ forwardGroupSingleMsg(groupId, messageId) {
1662
+ return client.call("forward_group_single_msg", { group_id: groupId, message_id: messageId });
1663
+ },
1664
+ sendForwardMsg(params) {
1665
+ return client.call("send_forward_msg", params);
1666
+ },
1667
+ sendGroupNotice(params) {
1668
+ return client.call("_send_group_notice", params);
1669
+ },
1670
+ getGroupNotice(groupId) {
1671
+ return client.call("_get_group_notice", { group_id: groupId });
1672
+ },
1673
+ delGroupNotice(groupId, noticeId) {
1674
+ return client.call("_del_group_notice", { group_id: groupId, notice_id: +noticeId });
1675
+ },
1676
+ setOnlineStatus(status, extStatus, batteryStatus) {
1677
+ return client.call("set_online_status", { status, ext_status: extStatus, battery_status: batteryStatus });
1678
+ },
1679
+ setDiyOnlineStatus(faceId, wording = " ", faceType = 1) {
1680
+ return client.call("set_diy_online_status", { face_id: faceId, wording, face_type: faceType });
1681
+ },
1682
+ sendArkShare(params) {
1683
+ return client.call("send_ark_share", params);
1684
+ },
1685
+ sendGroupArkShare(groupId) {
1686
+ return client.call("send_group_ark_share", { group_id: groupId });
1687
+ },
1688
+ getMiniAppArk(payload) {
1689
+ return client.call("get_mini_app_ark", payload);
1690
+ },
1691
+ getAiCharacters(groupId, chatType = 1) {
1692
+ return client.call("get_ai_characters", { group_id: groupId, chat_type: chatType });
1693
+ },
1694
+ getAiRecord(groupId, character, text) {
1695
+ return client.call("get_ai_record", { group_id: groupId, character, text });
1696
+ },
1697
+ sendGroupAiRecord(groupId, character, text) {
1698
+ return client.call("send_group_ai_record", { group_id: groupId, character, text });
1699
+ },
1700
+ setGroupSign(groupId) {
1701
+ return client.call("set_group_sign", { group_id: groupId });
1702
+ },
1703
+ sendGroupSign(groupId) {
1704
+ return client.call("send_group_sign", { group_id: groupId });
1705
+ },
1706
+ fetchCustomFace(params) {
1707
+ return client.call("fetch_custom_face", params ?? {});
1708
+ },
1709
+ getClientkey() {
1710
+ return client.call("get_clientkey");
1711
+ },
1712
+ clickInlineKeyboardButton(params) {
1713
+ return client.call("click_inline_keyboard_button", {
1714
+ ...params,
1715
+ button_id: params.button_id ?? "",
1716
+ callback_data: params.callback_data ?? "",
1717
+ msg_seq: params.msg_seq ?? "10086"
1718
+ });
1719
+ }
1720
+ };
1721
+ }
1722
+
1723
+ // src/api/onebot/raw.ts
1724
+ var NAPCAT_ACTIONS = [
1725
+ ".get_word_slices",
1726
+ ".handle_quick_operation",
1727
+ ".ocr_image",
1728
+ "ArkShareGroup",
1729
+ "ArkSharePeer",
1730
+ "_del_group_notice",
1731
+ "_get_group_notice",
1732
+ "_get_model_show",
1733
+ "_mark_all_as_read",
1734
+ "_send_group_notice",
1735
+ "_set_model_show",
1736
+ "bot_exit",
1737
+ "can_send_image",
1738
+ "can_send_record",
1739
+ "check_url_safely",
1740
+ "clean_cache",
1741
+ "clean_stream_temp_file",
1742
+ "click_inline_keyboard_button",
1743
+ "create_collection",
1744
+ "create_group_file_folder",
1745
+ "del_group_album_media",
1746
+ "delete_essence_msg",
1747
+ "delete_friend",
1748
+ "delete_group_file",
1749
+ "delete_group_folder",
1750
+ "delete_msg",
1751
+ "delete_unidirectional_friend",
1752
+ "do_group_album_comment",
1753
+ "download_file",
1754
+ "download_file_image_stream",
1755
+ "download_file_record_stream",
1756
+ "download_file_stream",
1757
+ "fetch_custom_face",
1758
+ "fetch_emoji_like",
1759
+ "forward_friend_single_msg",
1760
+ "forward_group_single_msg",
1761
+ "friend_poke",
1762
+ "get_ai_characters",
1763
+ "get_ai_record",
1764
+ "get_clientkey",
1765
+ "get_collection_list",
1766
+ "get_cookies",
1767
+ "get_credentials",
1768
+ "get_csrf_token",
1769
+ "get_doubt_friends_add_request",
1770
+ "get_essence_msg_list",
1771
+ "get_file",
1772
+ "get_forward_msg",
1773
+ "get_friend_list",
1774
+ "get_friend_msg_history",
1775
+ "get_friends_with_category",
1776
+ "get_group_album_media_list",
1777
+ "get_group_at_all_remain",
1778
+ "get_group_detail_info",
1779
+ "get_group_file_system_info",
1780
+ "get_group_file_url",
1781
+ "get_group_files_by_folder",
1782
+ "get_group_honor_info",
1783
+ "get_group_ignore_add_request",
1784
+ "get_group_ignored_notifies",
1785
+ "get_group_info",
1786
+ "get_group_info_ex",
1787
+ "get_group_list",
1788
+ "get_group_member_info",
1789
+ "get_group_member_list",
1790
+ "get_group_msg_history",
1791
+ "get_group_root_files",
1792
+ "get_group_shut_list",
1793
+ "get_group_system_msg",
1794
+ "get_guild_list",
1795
+ "get_guild_service_profile",
1796
+ "get_image",
1797
+ "get_login_info",
1798
+ "get_mini_app_ark",
1799
+ "get_msg",
1800
+ "get_online_clients",
1801
+ "get_private_file_url",
1802
+ "get_profile_like",
1803
+ "get_qun_album_list",
1804
+ "get_recent_contact",
1805
+ "get_record",
1806
+ "get_rkey",
1807
+ "get_rkey_server",
1808
+ "get_robot_uin_range",
1809
+ "get_status",
1810
+ "get_stranger_info",
1811
+ "get_unidirectional_friend_list",
1812
+ "get_version_info",
1813
+ "group_poke",
1814
+ "mark_group_msg_as_read",
1815
+ "mark_msg_as_read",
1816
+ "mark_private_msg_as_read",
1817
+ "move_group_file",
1818
+ "nc_get_packet_status",
1819
+ "nc_get_rkey",
1820
+ "nc_get_user_status",
1821
+ "ocr_image",
1822
+ "qidian_get_account_info",
1823
+ "reboot_normal",
1824
+ "reload_event_filter",
1825
+ "rename_group_file",
1826
+ "send_ark_share",
1827
+ "send_forward_msg",
1828
+ "send_group_ai_record",
1829
+ "send_group_ark_share",
1830
+ "send_group_forward_msg",
1831
+ "send_group_msg",
1832
+ "send_group_sign",
1833
+ "send_like",
1834
+ "send_msg",
1835
+ "send_packet",
1836
+ "send_poke",
1837
+ "send_private_forward_msg",
1838
+ "send_private_msg",
1839
+ "set_diy_online_status",
1840
+ "set_doubt_friends_add_request",
1841
+ "set_essence_msg",
1842
+ "set_friend_add_request",
1843
+ "set_friend_remark",
1844
+ "set_group_add_option",
1845
+ "set_group_add_request",
1846
+ "set_group_admin",
1847
+ "set_group_album_media_like",
1848
+ "set_group_anonymous",
1849
+ "set_group_anonymous_ban",
1850
+ "set_group_ban",
1851
+ "set_group_card",
1852
+ "set_group_kick",
1853
+ "set_group_kick_members",
1854
+ "set_group_leave",
1855
+ "set_group_name",
1856
+ "set_group_portrait",
1857
+ "set_group_remark",
1858
+ "set_group_robot_add_option",
1859
+ "set_group_search",
1860
+ "set_group_sign",
1861
+ "set_group_special_title",
1862
+ "set_group_todo",
1863
+ "set_group_whole_ban",
1864
+ "set_input_status",
1865
+ "set_msg_emoji_like",
1866
+ "set_online_status",
1867
+ "set_qq_avatar",
1868
+ "set_qq_profile",
1869
+ "set_restart",
1870
+ "set_self_longnick",
1871
+ "test_auto_register_01",
1872
+ "test_auto_register_02",
1873
+ "test_download_stream",
1874
+ "trans_group_file",
1875
+ "translate_en2zh",
1876
+ "unknown",
1877
+ "upload_file_stream",
1878
+ "upload_group_file",
1879
+ "upload_image_to_qun_album",
1880
+ "upload_private_file"
1881
+ ];
1882
+ function createRawActionApi(client) {
1883
+ const entries = NAPCAT_ACTIONS.map((action) => [
1884
+ action,
1885
+ (params) => client.call(action, params ?? {})
1886
+ ]);
1887
+ return Object.fromEntries(entries);
1888
+ }
1889
+
1331
1890
  // src/api/onebot/index.ts
1332
1891
  var OneBotApi = class {
1333
1892
  messageApi;
@@ -1337,6 +1896,9 @@ var OneBotApi = class {
1337
1896
  fileApi;
1338
1897
  streamApi;
1339
1898
  requestApi;
1899
+ systemApi;
1900
+ napcatApi;
1901
+ raw;
1340
1902
  constructor(client, logger) {
1341
1903
  this.messageApi = createMessageApi(client);
1342
1904
  this.mediaApi = createMediaApi(client, logger);
@@ -1345,6 +1907,9 @@ var OneBotApi = class {
1345
1907
  this.fileApi = createFileApi(client);
1346
1908
  this.streamApi = createStreamApi(client);
1347
1909
  this.requestApi = createRequestApi(client);
1910
+ this.systemApi = createSystemApi(client);
1911
+ this.napcatApi = createNapCatApi(client);
1912
+ this.raw = createRawActionApi(client);
1348
1913
  Object.assign(
1349
1914
  this,
1350
1915
  this.messageApi,
@@ -1353,7 +1918,9 @@ var OneBotApi = class {
1353
1918
  this.groupApi,
1354
1919
  this.fileApi,
1355
1920
  this.streamApi,
1356
- this.requestApi
1921
+ this.requestApi,
1922
+ this.systemApi,
1923
+ this.napcatApi
1357
1924
  );
1358
1925
  }
1359
1926
  };
@@ -1371,6 +1938,9 @@ function bindOneBotApiMethods(api, target) {
1371
1938
  getForwardMessage: (id) => api.getForwardMessage(id),
1372
1939
  getEssenceMessageList: (groupId) => api.getEssenceMessageList(groupId),
1373
1940
  markMessageAsRead: (messageId) => api.markMessageAsRead(messageId),
1941
+ markGroupMsgAsRead: (groupId) => api.markGroupMsgAsRead(groupId),
1942
+ markPrivateMsgAsRead: (userId) => api.markPrivateMsgAsRead(userId),
1943
+ markAllMsgAsRead: () => api.markAllMsgAsRead(),
1374
1944
  getGroupAtAllRemain: (groupId) => api.getGroupAtAllRemain(groupId),
1375
1945
  getGroupSystemMsg: () => api.getGroupSystemMsg(),
1376
1946
  getGroupHonorInfo: (groupId, type) => api.getGroupHonorInfo(groupId, type),
@@ -1384,7 +1954,22 @@ function bindOneBotApiMethods(api, target) {
1384
1954
  downloadFile: (url, threadCount, headers) => api.downloadFile(url, threadCount, headers),
1385
1955
  uploadFileStream: (file, options) => api.uploadFileStream(file, options),
1386
1956
  getUploadStreamStatus: (streamId) => api.getUploadStreamStatus(streamId),
1957
+ downloadFileStream: (fileId, options) => api.downloadFileStream(fileId, options),
1958
+ downloadFileStreamToFile: (fileId, options) => api.downloadFileStreamToFile(fileId, options),
1959
+ downloadFileImageStream: (fileId, options) => api.downloadFileImageStream(fileId, options),
1960
+ downloadFileImageStreamToFile: (fileId, options) => api.downloadFileImageStreamToFile(fileId, options),
1961
+ downloadFileRecordStream: (fileId, outFormat, options) => api.downloadFileRecordStream(fileId, outFormat, options),
1962
+ downloadFileRecordStreamToFile: (fileId, outFormat, options) => api.downloadFileRecordStreamToFile(fileId, outFormat, options),
1963
+ cleanStreamTempFile: () => api.cleanStreamTempFile(),
1387
1964
  sendGroupForwardMessage: (groupId, messages) => api.sendGroupForwardMessage(groupId, messages),
1965
+ getGroupMsgHistory: (params) => api.getGroupMsgHistory(params),
1966
+ getFriendMsgHistory: (params) => api.getFriendMsgHistory(params),
1967
+ getRecentContact: (count) => api.getRecentContact(count),
1968
+ setMsgEmojiLike: (messageId, emojiId, set) => api.setMsgEmojiLike(messageId, emojiId, set),
1969
+ fetchEmojiLike: (params) => api.fetchEmojiLike(params),
1970
+ sendGroupPoke: (groupId, userId) => api.sendGroupPoke(groupId, userId),
1971
+ sendFriendPoke: (userId) => api.sendFriendPoke(userId),
1972
+ sendPoke: (targetId, groupId) => api.sendPoke(targetId, groupId),
1388
1973
  getImage: (file) => api.getImage(file),
1389
1974
  getRecord: (file, outFormat) => api.getRecord(file, outFormat),
1390
1975
  getFile: (file) => api.getFile(file),
@@ -1412,7 +1997,56 @@ function bindOneBotApiMethods(api, target) {
1412
1997
  getStrangerInfo: (userId, noCache = false) => api.getStrangerInfo(userId, noCache),
1413
1998
  getVersionInfo: () => api.getVersionInfo(),
1414
1999
  handleFriendRequest: (flag, approve = true, remark) => api.handleFriendRequest(flag, approve, remark),
1415
- handleGroupRequest: (flag, subType, approve = true, reason) => api.handleGroupRequest(flag, subType, approve, reason)
2000
+ handleGroupRequest: (flag, subType, approve = true, reason) => api.handleGroupRequest(flag, subType, approve, reason),
2001
+ // SystemApi
2002
+ getOnlineClients: (noCache = false) => api.getOnlineClients(noCache),
2003
+ getRobotUinRange: () => api.getRobotUinRange(),
2004
+ canSendImage: () => api.canSendImage(),
2005
+ canSendRecord: () => api.canSendRecord(),
2006
+ getCookies: (domain) => api.getCookies(domain),
2007
+ getCsrfToken: () => api.getCsrfToken(),
2008
+ getCredentials: (domain) => api.getCredentials(domain),
2009
+ setInputStatus: (userId, eventType) => api.setInputStatus(userId, eventType),
2010
+ ocrImage: (image, dot) => api.ocrImage(image, dot),
2011
+ translateEn2zh: (words) => api.translateEn2zh(words),
2012
+ checkUrlSafely: (url) => api.checkUrlSafely(url),
2013
+ handleQuickOperation: (context, operation) => api.handleQuickOperation(context, operation),
2014
+ getModelShow: (model) => api.getModelShow(model),
2015
+ setModelShow: (model, modelShow) => api.setModelShow(model, modelShow),
2016
+ getPacketStatus: () => api.getPacketStatus(),
2017
+ // NapCatApi
2018
+ getRkeyEx: () => api.getRkeyEx(),
2019
+ getRkeyServer: () => api.getRkeyServer(),
2020
+ getRkey: () => api.getRkey(),
2021
+ setFriendRemark: (userId, remark) => api.setFriendRemark(userId, remark),
2022
+ deleteFriend: (userId) => api.deleteFriend(userId),
2023
+ getUnidirectionalFriendList: () => api.getUnidirectionalFriendList(),
2024
+ setGroupRemark: (groupId, remark) => api.setGroupRemark(groupId, remark),
2025
+ getGroupInfoEx: (groupId) => api.getGroupInfoEx(groupId),
2026
+ getGroupDetailInfo: (groupId) => api.getGroupDetailInfo(groupId),
2027
+ getGroupIgnoredNotifies: () => api.getGroupIgnoredNotifies(),
2028
+ getGroupShutList: (groupId) => api.getGroupShutList(groupId),
2029
+ sendPrivateForwardMessage: (params) => api.sendPrivateForwardMessage(params),
2030
+ forwardFriendSingleMsg: (userId, messageId) => api.forwardFriendSingleMsg(userId, messageId),
2031
+ forwardGroupSingleMsg: (groupId, messageId) => api.forwardGroupSingleMsg(groupId, messageId),
2032
+ sendForwardMsg: (params) => api.sendForwardMsg(params),
2033
+ sendGroupNotice: (params) => api.sendGroupNotice(params),
2034
+ getGroupNotice: (groupId) => api.getGroupNotice(groupId),
2035
+ delGroupNotice: (groupId, noticeId) => api.delGroupNotice(groupId, noticeId),
2036
+ setOnlineStatus: (status, extStatus, batteryStatus) => api.setOnlineStatus(status, extStatus, batteryStatus),
2037
+ setDiyOnlineStatus: (faceId, wording, faceType) => api.setDiyOnlineStatus(faceId, wording, faceType),
2038
+ sendArkShare: (params) => api.sendArkShare(params),
2039
+ sendGroupArkShare: (groupId) => api.sendGroupArkShare(groupId),
2040
+ getMiniAppArk: (payload) => api.getMiniAppArk(payload),
2041
+ getAiCharacters: (groupId, chatType) => api.getAiCharacters(groupId, chatType),
2042
+ getAiRecord: (groupId, character, text) => api.getAiRecord(groupId, character, text),
2043
+ sendGroupAiRecord: (groupId, character, text) => api.sendGroupAiRecord(groupId, character, text),
2044
+ setGroupSign: (groupId) => api.setGroupSign(groupId),
2045
+ sendGroupSign: (groupId) => api.sendGroupSign(groupId),
2046
+ fetchCustomFace: (params) => api.fetchCustomFace(params),
2047
+ getClientkey: () => api.getClientkey(),
2048
+ clickInlineKeyboardButton: (params) => api.clickInlineKeyboardButton(params),
2049
+ raw: api.raw
1416
2050
  };
1417
2051
  Object.assign(target, bindings);
1418
2052
  }
@@ -1492,7 +2126,9 @@ var NapLink = class extends EventEmitter2 {
1492
2126
  this.config,
1493
2127
  this.logger,
1494
2128
  (message) => this.dispatcher.dispatch(message),
1495
- (state) => handleConnectionStateChange(this, state)
2129
+ (state, wasReconnecting) => handleConnectionStateChange(this, state, wasReconnecting || false),
2130
+ this
2131
+ // 传递 emitter 用于发送 connection:lost 事件
1496
2132
  );
1497
2133
  this.apiClient = new ApiClient(this.connection, this.config, this.logger);
1498
2134
  this.dispatcher = new MessageDispatcher(this.apiClient, this.eventRouter, this.logger);