woodenfish-bot 4.4.5 → 4.4.6

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.
Files changed (3) hide show
  1. package/es/index.js +180 -103
  2. package/lib/index.js +180 -103
  3. package/package.json +1 -1
package/es/index.js CHANGED
@@ -5,6 +5,7 @@ import _defineProperty from '@babel/runtime/helpers/defineProperty';
5
5
  import _regeneratorRuntime from '@babel/runtime/regenerator';
6
6
  import resty from 'resty-client';
7
7
  import _typeof from '@babel/runtime/helpers/typeof';
8
+ import _slicedToArray from '@babel/runtime/helpers/slicedToArray';
8
9
  import fs from 'fs';
9
10
  import https from 'https';
10
11
  import _possibleConstructorReturn from '@babel/runtime/helpers/possibleConstructorReturn';
@@ -297,7 +298,7 @@ var Guild = /*#__PURE__*/function () {
297
298
  }]);
298
299
  }();
299
300
 
300
- var version = "4.4.5";
301
+ var version = "4.4.6";
301
302
 
302
303
  function getDefaultExportFromCjs (x) {
303
304
  return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
@@ -677,9 +678,45 @@ log.setLevel('info');
677
678
  log.setLevel('trace');
678
679
  var BotLogger = log;
679
680
 
681
+ function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: true } : { done: false, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = true, u = false; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = true, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
682
+ function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
683
+ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
684
+
680
685
  // 全局token刷新锁,避免并发刷新
681
686
  var tokenRefreshPromises = new Map();
682
687
 
688
+ // 定期清理可能遗留的Promise(防止内存泄漏)
689
+ setInterval(function () {
690
+ var now = Date.now();
691
+ var keysToDelete = [];
692
+ var _iterator = _createForOfIteratorHelper(tokenRefreshPromises.entries()),
693
+ _step;
694
+ try {
695
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
696
+ var _step$value = _slicedToArray(_step.value, 2),
697
+ key = _step$value[0],
698
+ _step$value$ = _step$value[1],
699
+ promise = _step$value$.promise,
700
+ timestamp = _step$value$.timestamp;
701
+ // 如果Promise已经存在超过5分钟,可能出现了问题,清理掉
702
+ if (now - timestamp > 5 * 60 * 1000) {
703
+ keysToDelete.push(key);
704
+ console.warn("\u6E05\u7406\u8D85\u65F6\u7684token\u5237\u65B0Promise (key: ".concat(key, ", \u5B58\u5728\u65F6\u95F4: ").concat((now - timestamp) / 1000, "s)"));
705
+ }
706
+ }
707
+ } catch (err) {
708
+ _iterator.e(err);
709
+ } finally {
710
+ _iterator.f();
711
+ }
712
+ keysToDelete.forEach(function (key) {
713
+ return tokenRefreshPromises["delete"](key);
714
+ });
715
+ if (keysToDelete.length > 0) {
716
+ console.log("\u6E05\u7406\u4E86 ".concat(keysToDelete.length, " \u4E2A\u8D85\u65F6\u7684token\u5237\u65B0Promise"));
717
+ }
718
+ }, 60000); // 每分钟清理一次
719
+
683
720
  // 转为对象
684
721
  var toObject = function toObject(data) {
685
722
  if (Buffer.isBuffer(data)) return JSON.parse(data.toString());
@@ -758,150 +795,190 @@ function getAccessToken(access_token_file, url, data, appID) {
758
795
  });
759
796
  }
760
797
 
761
- // 获取或刷新token(带并发控制)
798
+ // 等待Promise完成,带超时机制
799
+ var waitForPromiseWithTimeout = /*#__PURE__*/function () {
800
+ var _ref = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee(promise) {
801
+ var timeoutMs,
802
+ timeoutPromise,
803
+ _args = arguments;
804
+ return _regeneratorRuntime.wrap(function (_context) {
805
+ while (1) switch (_context.prev = _context.next) {
806
+ case 0:
807
+ timeoutMs = _args.length > 1 && _args[1] !== undefined ? _args[1] : 10000;
808
+ timeoutPromise = new Promise(function (_, reject) {
809
+ setTimeout(function () {
810
+ return reject(new Error("Token refresh timeout after ".concat(timeoutMs, "ms")));
811
+ }, timeoutMs);
812
+ });
813
+ return _context.abrupt("return", Promise.race([promise, timeoutPromise]));
814
+ case 1:
815
+ case "end":
816
+ return _context.stop();
817
+ }
818
+ }, _callee);
819
+ }));
820
+ return function waitForPromiseWithTimeout(_x) {
821
+ return _ref.apply(this, arguments);
822
+ };
823
+ }();
824
+
825
+ // 获取或刷新token(带并发控制和超时保护)
762
826
  var getOrRefreshToken = /*#__PURE__*/function () {
763
- var _ref = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee2(appID, clientSecret) {
764
- var key, existingPromise, refreshPromise;
765
- return _regeneratorRuntime.wrap(function (_context2) {
766
- while (1) switch (_context2.prev = _context2.next) {
827
+ var _ref2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee3(appID, clientSecret) {
828
+ var now_time, url, data, access_token_file, access_token, expires_in, needsRefresh, access_token_json, expiresStr, parsed, default_token_json, key, existingEntry, refreshPromise, _t2;
829
+ return _regeneratorRuntime.wrap(function (_context3) {
830
+ while (1) switch (_context3.prev = _context3.next) {
767
831
  case 0:
832
+ now_time = getTimeStampNumber();
833
+ url = 'https://bots.qq.com/app/getAppAccessToken';
834
+ data = {
835
+ appId: appID,
836
+ clientSecret: clientSecret
837
+ };
838
+ access_token_file = './access_token.json';
839
+ access_token = '';
840
+ expires_in = 0;
841
+ needsRefresh = false; // 首先读取当前token状态
842
+ try {
843
+ if (fs.existsSync(access_token_file)) {
844
+ access_token_json = JSON.parse(fs.readFileSync(access_token_file).toString());
845
+ if (access_token_json.hasOwnProperty('bot') && access_token_json['bot'].hasOwnProperty(appID)) {
846
+ access_token = access_token_json['bot'][appID]['access_token'];
847
+ expiresStr = access_token_json['bot'][appID]['expires_in'];
848
+ if (expiresStr && typeof expiresStr === 'string') {
849
+ parsed = parseInt(expiresStr);
850
+ if (!isNaN(parsed) && parsed > 0) {
851
+ expires_in = parsed;
852
+ } else {
853
+ console.log('expires_in解析失败,重置为0:', expiresStr);
854
+ expires_in = 0;
855
+ }
856
+ } else {
857
+ expires_in = 0;
858
+ }
859
+ }
860
+ } else {
861
+ default_token_json = {
862
+ bot: _defineProperty({}, appID, {
863
+ access_token: "",
864
+ expires_in: ""
865
+ })
866
+ };
867
+ fs.writeFileSync(access_token_file, JSON.stringify(default_token_json, null, 2), 'utf-8');
868
+ needsRefresh = true;
869
+ }
870
+ } catch (err) {
871
+ console.error('读取文件时发生错误:', err);
872
+ expires_in = 0;
873
+ needsRefresh = true;
874
+ }
875
+
876
+ // 如果token有效且不需要刷新,直接返回
877
+ if (!(access_token !== '' && now_time <= expires_in - 50 && !needsRefresh)) {
878
+ _context3.next = 1;
879
+ break;
880
+ }
881
+ return _context3.abrupt("return", access_token);
882
+ case 1:
883
+ // 需要刷新token,进入并发控制逻辑
768
884
  key = "".concat(appID, ":").concat(clientSecret);
769
- existingPromise = tokenRefreshPromises.get(key);
770
- if (!existingPromise) {
771
- _context2.next = 2;
885
+ existingEntry = tokenRefreshPromises.get(key);
886
+ if (!existingEntry) {
887
+ _context3.next = 5;
772
888
  break;
773
889
  }
774
- // 如果已经有刷新在进行,等待它完成
890
+ _context3.prev = 2;
891
+ // 等待已有的刷新完成,但设置超时防止无限等待
775
892
  console.log("\u7B49\u5F85\u5DF2\u6709\u7684token\u5237\u65B0\u5B8C\u6210 (appID: ".concat(appID, ")"));
776
- _context2.next = 1;
777
- return existingPromise;
778
- case 1:
779
- return _context2.abrupt("return", _context2.sent);
780
- case 2:
893
+ _context3.next = 3;
894
+ return waitForPromiseWithTimeout(existingEntry.promise, 10000);
895
+ case 3:
896
+ return _context3.abrupt("return", _context3.sent);
897
+ case 4:
898
+ _context3.prev = 4;
899
+ _t2 = _context3["catch"](2);
900
+ console.warn("\u7B49\u5F85token\u5237\u65B0\u8D85\u65F6\u6216\u5931\u8D25\uFF0C\u91CD\u65B0\u53D1\u8D77\u5237\u65B0 (appID: ".concat(appID, "):"), _t2);
901
+ // 移除失败的Promise,让新的请求可以重新发起刷新
902
+ tokenRefreshPromises["delete"](key);
903
+ case 5:
781
904
  // 创建新的刷新Promise
782
- refreshPromise = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
783
- var now_time, url, data, access_token_file, access_token, expires_in, needsRefresh, access_token_json, expiresStr, parsed, default_token_json;
784
- return _regeneratorRuntime.wrap(function (_context) {
785
- while (1) switch (_context.prev = _context.next) {
905
+ refreshPromise = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee2() {
906
+ var new_token, _t;
907
+ return _regeneratorRuntime.wrap(function (_context2) {
908
+ while (1) switch (_context2.prev = _context2.next) {
786
909
  case 0:
787
- _context.prev = 0;
788
- now_time = getTimeStampNumber();
789
- url = 'https://bots.qq.com/app/getAppAccessToken';
790
- data = {
791
- appId: appID,
792
- clientSecret: clientSecret
793
- };
794
- access_token_file = './access_token.json';
795
- access_token = '';
796
- expires_in = 0;
797
- needsRefresh = false;
798
- try {
799
- // 判断文件是否存在
800
- if (fs.existsSync(access_token_file)) {
801
- // 执行文件存在时的处理逻辑
802
- access_token_json = JSON.parse(fs.readFileSync(access_token_file).toString()); // 判断是否存在appID
803
- if (access_token_json.hasOwnProperty('bot') && access_token_json['bot'].hasOwnProperty(appID)) {
804
- access_token = access_token_json['bot'][appID]['access_token'];
805
- expiresStr = access_token_json['bot'][appID]['expires_in']; // 改进expires_in解析,防止NaN
806
- if (expiresStr && typeof expiresStr === 'string') {
807
- parsed = parseInt(expiresStr);
808
- if (!isNaN(parsed) && parsed > 0) {
809
- expires_in = parsed;
810
- } else {
811
- console.log('expires_in解析失败,重置为0:', expiresStr);
812
- expires_in = 0;
813
- }
814
- } else {
815
- expires_in = 0;
816
- }
817
- }
818
- } else {
819
- // 执行文件不存在时的处理逻辑
820
- default_token_json = {
821
- bot: _defineProperty({}, appID, {
822
- access_token: "",
823
- expires_in: ""
824
- })
825
- };
826
- fs.writeFileSync(access_token_file, JSON.stringify(default_token_json, null, 2), 'utf-8');
827
- needsRefresh = true;
828
- }
829
- } catch (err) {
830
- console.error('读取文件时发生错误:', err);
831
- // 出错时重置expires_in为0,强制重新获取token
832
- expires_in = 0;
833
- needsRefresh = true;
834
- }
835
-
836
- // 判断是否需要刷新token
837
- if (!(access_token === '' || now_time > expires_in - 50 || needsRefresh)) {
838
- _context.next = 2;
839
- break;
840
- }
841
- console.log('检测到access_token需要刷新 - 当前token:', access_token, '过期时间:', expires_in, '当前时间:', now_time);
842
- _context.next = 1;
910
+ _context2.prev = 0;
911
+ console.log('开始刷新access_token - 当前token:', access_token, '过期时间:', expires_in, '当前时间:', now_time);
912
+ _context2.next = 1;
843
913
  return getAccessToken(access_token_file, url, data, appID);
844
914
  case 1:
845
- access_token = _context.sent;
846
- console.log('access_token刷新成功,新token:', access_token);
915
+ new_token = _context2.sent;
916
+ console.log('access_token刷新成功,新token:', new_token);
917
+ return _context2.abrupt("return", new_token);
847
918
  case 2:
848
- return _context.abrupt("return", access_token);
919
+ _context2.prev = 2;
920
+ _t = _context2["catch"](0);
921
+ console.error("Token\u5237\u65B0\u5931\u8D25 (appID: ".concat(appID, "):"), _t);
922
+ throw _t;
849
923
  case 3:
850
- _context.prev = 3;
924
+ _context2.prev = 3;
851
925
  // 刷新完成后移除Promise
852
926
  tokenRefreshPromises["delete"](key);
853
- return _context.finish(3);
927
+ return _context2.finish(3);
854
928
  case 4:
855
929
  case "end":
856
- return _context.stop();
930
+ return _context2.stop();
857
931
  }
858
- }, _callee, null, [[0,, 3, 4]]);
859
- }))(); // 存储Promise以便其他并发请求使用
860
- tokenRefreshPromises.set(key, refreshPromise);
861
- _context2.next = 3;
932
+ }, _callee2, null, [[0, 2, 3, 4]]);
933
+ }))(); // 存储Promise和时间戳以便其他并发请求使用和超时清理
934
+ tokenRefreshPromises.set(key, {
935
+ promise: refreshPromise,
936
+ timestamp: Date.now()
937
+ });
938
+ _context3.next = 6;
862
939
  return refreshPromise;
863
- case 3:
864
- return _context2.abrupt("return", _context2.sent);
865
- case 4:
940
+ case 6:
941
+ return _context3.abrupt("return", _context3.sent);
942
+ case 7:
866
943
  case "end":
867
- return _context2.stop();
944
+ return _context3.stop();
868
945
  }
869
- }, _callee2);
946
+ }, _callee3, null, [[2, 4]]);
870
947
  }));
871
- return function getOrRefreshToken(_x, _x2) {
872
- return _ref.apply(this, arguments);
948
+ return function getOrRefreshToken(_x2, _x3) {
949
+ return _ref2.apply(this, arguments);
873
950
  };
874
951
  }();
875
952
 
876
953
  // 添加 User-Agent
877
954
  var addAuthorization = /*#__PURE__*/function () {
878
- var _ref3 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee3(header, appID, token, clientSecret, apiVersion) {
955
+ var _ref4 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee4(header, appID, token, clientSecret, apiVersion) {
879
956
  var access_token;
880
- return _regeneratorRuntime.wrap(function (_context3) {
881
- while (1) switch (_context3.prev = _context3.next) {
957
+ return _regeneratorRuntime.wrap(function (_context4) {
958
+ while (1) switch (_context4.prev = _context4.next) {
882
959
  case 0:
883
960
  if (!(apiVersion == 'v2')) {
884
- _context3.next = 2;
961
+ _context4.next = 2;
885
962
  break;
886
963
  }
887
- _context3.next = 1;
964
+ _context4.next = 1;
888
965
  return getOrRefreshToken(appID, clientSecret);
889
966
  case 1:
890
- access_token = _context3.sent;
967
+ access_token = _context4.sent;
891
968
  // 更新header['Authorization']
892
969
  header['Authorization'] = "QQBot ".concat(access_token);
893
- _context3.next = 3;
970
+ _context4.next = 3;
894
971
  break;
895
972
  case 2:
896
973
  header['Authorization'] = "Bot ".concat(appID, ".").concat(token);
897
974
  case 3:
898
975
  case "end":
899
- return _context3.stop();
976
+ return _context4.stop();
900
977
  }
901
- }, _callee3);
978
+ }, _callee4);
902
979
  }));
903
- return function addAuthorization(_x3, _x4, _x5, _x6, _x7) {
904
- return _ref3.apply(this, arguments);
980
+ return function addAuthorization(_x4, _x5, _x6, _x7, _x8) {
981
+ return _ref4.apply(this, arguments);
905
982
  };
906
983
  }();
907
984
  // 组装完整Url
package/lib/index.js CHANGED
@@ -7,6 +7,7 @@ var _defineProperty = require('@babel/runtime/helpers/defineProperty');
7
7
  var _regeneratorRuntime = require('@babel/runtime/regenerator');
8
8
  var resty = require('resty-client');
9
9
  var _typeof = require('@babel/runtime/helpers/typeof');
10
+ var _slicedToArray = require('@babel/runtime/helpers/slicedToArray');
10
11
  var fs = require('fs');
11
12
  var https = require('https');
12
13
  var _possibleConstructorReturn = require('@babel/runtime/helpers/possibleConstructorReturn');
@@ -299,7 +300,7 @@ var Guild = /*#__PURE__*/function () {
299
300
  }]);
300
301
  }();
301
302
 
302
- var version = "4.4.5";
303
+ var version = "4.4.6";
303
304
 
304
305
  function getDefaultExportFromCjs (x) {
305
306
  return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
@@ -679,9 +680,45 @@ log.setLevel('info');
679
680
  log.setLevel('trace');
680
681
  var BotLogger = log;
681
682
 
683
+ function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: true } : { done: false, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = true, u = false; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = true, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
684
+ function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
685
+ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
686
+
682
687
  // 全局token刷新锁,避免并发刷新
683
688
  var tokenRefreshPromises = new Map();
684
689
 
690
+ // 定期清理可能遗留的Promise(防止内存泄漏)
691
+ setInterval(function () {
692
+ var now = Date.now();
693
+ var keysToDelete = [];
694
+ var _iterator = _createForOfIteratorHelper(tokenRefreshPromises.entries()),
695
+ _step;
696
+ try {
697
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
698
+ var _step$value = _slicedToArray(_step.value, 2),
699
+ key = _step$value[0],
700
+ _step$value$ = _step$value[1],
701
+ promise = _step$value$.promise,
702
+ timestamp = _step$value$.timestamp;
703
+ // 如果Promise已经存在超过5分钟,可能出现了问题,清理掉
704
+ if (now - timestamp > 5 * 60 * 1000) {
705
+ keysToDelete.push(key);
706
+ console.warn("\u6E05\u7406\u8D85\u65F6\u7684token\u5237\u65B0Promise (key: ".concat(key, ", \u5B58\u5728\u65F6\u95F4: ").concat((now - timestamp) / 1000, "s)"));
707
+ }
708
+ }
709
+ } catch (err) {
710
+ _iterator.e(err);
711
+ } finally {
712
+ _iterator.f();
713
+ }
714
+ keysToDelete.forEach(function (key) {
715
+ return tokenRefreshPromises["delete"](key);
716
+ });
717
+ if (keysToDelete.length > 0) {
718
+ console.log("\u6E05\u7406\u4E86 ".concat(keysToDelete.length, " \u4E2A\u8D85\u65F6\u7684token\u5237\u65B0Promise"));
719
+ }
720
+ }, 60000); // 每分钟清理一次
721
+
685
722
  // 转为对象
686
723
  var toObject = function toObject(data) {
687
724
  if (Buffer.isBuffer(data)) return JSON.parse(data.toString());
@@ -760,150 +797,190 @@ function getAccessToken(access_token_file, url, data, appID) {
760
797
  });
761
798
  }
762
799
 
763
- // 获取或刷新token(带并发控制)
800
+ // 等待Promise完成,带超时机制
801
+ var waitForPromiseWithTimeout = /*#__PURE__*/function () {
802
+ var _ref = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee(promise) {
803
+ var timeoutMs,
804
+ timeoutPromise,
805
+ _args = arguments;
806
+ return _regeneratorRuntime.wrap(function (_context) {
807
+ while (1) switch (_context.prev = _context.next) {
808
+ case 0:
809
+ timeoutMs = _args.length > 1 && _args[1] !== undefined ? _args[1] : 10000;
810
+ timeoutPromise = new Promise(function (_, reject) {
811
+ setTimeout(function () {
812
+ return reject(new Error("Token refresh timeout after ".concat(timeoutMs, "ms")));
813
+ }, timeoutMs);
814
+ });
815
+ return _context.abrupt("return", Promise.race([promise, timeoutPromise]));
816
+ case 1:
817
+ case "end":
818
+ return _context.stop();
819
+ }
820
+ }, _callee);
821
+ }));
822
+ return function waitForPromiseWithTimeout(_x) {
823
+ return _ref.apply(this, arguments);
824
+ };
825
+ }();
826
+
827
+ // 获取或刷新token(带并发控制和超时保护)
764
828
  var getOrRefreshToken = /*#__PURE__*/function () {
765
- var _ref = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee2(appID, clientSecret) {
766
- var key, existingPromise, refreshPromise;
767
- return _regeneratorRuntime.wrap(function (_context2) {
768
- while (1) switch (_context2.prev = _context2.next) {
829
+ var _ref2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee3(appID, clientSecret) {
830
+ var now_time, url, data, access_token_file, access_token, expires_in, needsRefresh, access_token_json, expiresStr, parsed, default_token_json, key, existingEntry, refreshPromise, _t2;
831
+ return _regeneratorRuntime.wrap(function (_context3) {
832
+ while (1) switch (_context3.prev = _context3.next) {
769
833
  case 0:
834
+ now_time = getTimeStampNumber();
835
+ url = 'https://bots.qq.com/app/getAppAccessToken';
836
+ data = {
837
+ appId: appID,
838
+ clientSecret: clientSecret
839
+ };
840
+ access_token_file = './access_token.json';
841
+ access_token = '';
842
+ expires_in = 0;
843
+ needsRefresh = false; // 首先读取当前token状态
844
+ try {
845
+ if (fs.existsSync(access_token_file)) {
846
+ access_token_json = JSON.parse(fs.readFileSync(access_token_file).toString());
847
+ if (access_token_json.hasOwnProperty('bot') && access_token_json['bot'].hasOwnProperty(appID)) {
848
+ access_token = access_token_json['bot'][appID]['access_token'];
849
+ expiresStr = access_token_json['bot'][appID]['expires_in'];
850
+ if (expiresStr && typeof expiresStr === 'string') {
851
+ parsed = parseInt(expiresStr);
852
+ if (!isNaN(parsed) && parsed > 0) {
853
+ expires_in = parsed;
854
+ } else {
855
+ console.log('expires_in解析失败,重置为0:', expiresStr);
856
+ expires_in = 0;
857
+ }
858
+ } else {
859
+ expires_in = 0;
860
+ }
861
+ }
862
+ } else {
863
+ default_token_json = {
864
+ bot: _defineProperty({}, appID, {
865
+ access_token: "",
866
+ expires_in: ""
867
+ })
868
+ };
869
+ fs.writeFileSync(access_token_file, JSON.stringify(default_token_json, null, 2), 'utf-8');
870
+ needsRefresh = true;
871
+ }
872
+ } catch (err) {
873
+ console.error('读取文件时发生错误:', err);
874
+ expires_in = 0;
875
+ needsRefresh = true;
876
+ }
877
+
878
+ // 如果token有效且不需要刷新,直接返回
879
+ if (!(access_token !== '' && now_time <= expires_in - 50 && !needsRefresh)) {
880
+ _context3.next = 1;
881
+ break;
882
+ }
883
+ return _context3.abrupt("return", access_token);
884
+ case 1:
885
+ // 需要刷新token,进入并发控制逻辑
770
886
  key = "".concat(appID, ":").concat(clientSecret);
771
- existingPromise = tokenRefreshPromises.get(key);
772
- if (!existingPromise) {
773
- _context2.next = 2;
887
+ existingEntry = tokenRefreshPromises.get(key);
888
+ if (!existingEntry) {
889
+ _context3.next = 5;
774
890
  break;
775
891
  }
776
- // 如果已经有刷新在进行,等待它完成
892
+ _context3.prev = 2;
893
+ // 等待已有的刷新完成,但设置超时防止无限等待
777
894
  console.log("\u7B49\u5F85\u5DF2\u6709\u7684token\u5237\u65B0\u5B8C\u6210 (appID: ".concat(appID, ")"));
778
- _context2.next = 1;
779
- return existingPromise;
780
- case 1:
781
- return _context2.abrupt("return", _context2.sent);
782
- case 2:
895
+ _context3.next = 3;
896
+ return waitForPromiseWithTimeout(existingEntry.promise, 10000);
897
+ case 3:
898
+ return _context3.abrupt("return", _context3.sent);
899
+ case 4:
900
+ _context3.prev = 4;
901
+ _t2 = _context3["catch"](2);
902
+ console.warn("\u7B49\u5F85token\u5237\u65B0\u8D85\u65F6\u6216\u5931\u8D25\uFF0C\u91CD\u65B0\u53D1\u8D77\u5237\u65B0 (appID: ".concat(appID, "):"), _t2);
903
+ // 移除失败的Promise,让新的请求可以重新发起刷新
904
+ tokenRefreshPromises["delete"](key);
905
+ case 5:
783
906
  // 创建新的刷新Promise
784
- refreshPromise = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
785
- var now_time, url, data, access_token_file, access_token, expires_in, needsRefresh, access_token_json, expiresStr, parsed, default_token_json;
786
- return _regeneratorRuntime.wrap(function (_context) {
787
- while (1) switch (_context.prev = _context.next) {
907
+ refreshPromise = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee2() {
908
+ var new_token, _t;
909
+ return _regeneratorRuntime.wrap(function (_context2) {
910
+ while (1) switch (_context2.prev = _context2.next) {
788
911
  case 0:
789
- _context.prev = 0;
790
- now_time = getTimeStampNumber();
791
- url = 'https://bots.qq.com/app/getAppAccessToken';
792
- data = {
793
- appId: appID,
794
- clientSecret: clientSecret
795
- };
796
- access_token_file = './access_token.json';
797
- access_token = '';
798
- expires_in = 0;
799
- needsRefresh = false;
800
- try {
801
- // 判断文件是否存在
802
- if (fs.existsSync(access_token_file)) {
803
- // 执行文件存在时的处理逻辑
804
- access_token_json = JSON.parse(fs.readFileSync(access_token_file).toString()); // 判断是否存在appID
805
- if (access_token_json.hasOwnProperty('bot') && access_token_json['bot'].hasOwnProperty(appID)) {
806
- access_token = access_token_json['bot'][appID]['access_token'];
807
- expiresStr = access_token_json['bot'][appID]['expires_in']; // 改进expires_in解析,防止NaN
808
- if (expiresStr && typeof expiresStr === 'string') {
809
- parsed = parseInt(expiresStr);
810
- if (!isNaN(parsed) && parsed > 0) {
811
- expires_in = parsed;
812
- } else {
813
- console.log('expires_in解析失败,重置为0:', expiresStr);
814
- expires_in = 0;
815
- }
816
- } else {
817
- expires_in = 0;
818
- }
819
- }
820
- } else {
821
- // 执行文件不存在时的处理逻辑
822
- default_token_json = {
823
- bot: _defineProperty({}, appID, {
824
- access_token: "",
825
- expires_in: ""
826
- })
827
- };
828
- fs.writeFileSync(access_token_file, JSON.stringify(default_token_json, null, 2), 'utf-8');
829
- needsRefresh = true;
830
- }
831
- } catch (err) {
832
- console.error('读取文件时发生错误:', err);
833
- // 出错时重置expires_in为0,强制重新获取token
834
- expires_in = 0;
835
- needsRefresh = true;
836
- }
837
-
838
- // 判断是否需要刷新token
839
- if (!(access_token === '' || now_time > expires_in - 50 || needsRefresh)) {
840
- _context.next = 2;
841
- break;
842
- }
843
- console.log('检测到access_token需要刷新 - 当前token:', access_token, '过期时间:', expires_in, '当前时间:', now_time);
844
- _context.next = 1;
912
+ _context2.prev = 0;
913
+ console.log('开始刷新access_token - 当前token:', access_token, '过期时间:', expires_in, '当前时间:', now_time);
914
+ _context2.next = 1;
845
915
  return getAccessToken(access_token_file, url, data, appID);
846
916
  case 1:
847
- access_token = _context.sent;
848
- console.log('access_token刷新成功,新token:', access_token);
917
+ new_token = _context2.sent;
918
+ console.log('access_token刷新成功,新token:', new_token);
919
+ return _context2.abrupt("return", new_token);
849
920
  case 2:
850
- return _context.abrupt("return", access_token);
921
+ _context2.prev = 2;
922
+ _t = _context2["catch"](0);
923
+ console.error("Token\u5237\u65B0\u5931\u8D25 (appID: ".concat(appID, "):"), _t);
924
+ throw _t;
851
925
  case 3:
852
- _context.prev = 3;
926
+ _context2.prev = 3;
853
927
  // 刷新完成后移除Promise
854
928
  tokenRefreshPromises["delete"](key);
855
- return _context.finish(3);
929
+ return _context2.finish(3);
856
930
  case 4:
857
931
  case "end":
858
- return _context.stop();
932
+ return _context2.stop();
859
933
  }
860
- }, _callee, null, [[0,, 3, 4]]);
861
- }))(); // 存储Promise以便其他并发请求使用
862
- tokenRefreshPromises.set(key, refreshPromise);
863
- _context2.next = 3;
934
+ }, _callee2, null, [[0, 2, 3, 4]]);
935
+ }))(); // 存储Promise和时间戳以便其他并发请求使用和超时清理
936
+ tokenRefreshPromises.set(key, {
937
+ promise: refreshPromise,
938
+ timestamp: Date.now()
939
+ });
940
+ _context3.next = 6;
864
941
  return refreshPromise;
865
- case 3:
866
- return _context2.abrupt("return", _context2.sent);
867
- case 4:
942
+ case 6:
943
+ return _context3.abrupt("return", _context3.sent);
944
+ case 7:
868
945
  case "end":
869
- return _context2.stop();
946
+ return _context3.stop();
870
947
  }
871
- }, _callee2);
948
+ }, _callee3, null, [[2, 4]]);
872
949
  }));
873
- return function getOrRefreshToken(_x, _x2) {
874
- return _ref.apply(this, arguments);
950
+ return function getOrRefreshToken(_x2, _x3) {
951
+ return _ref2.apply(this, arguments);
875
952
  };
876
953
  }();
877
954
 
878
955
  // 添加 User-Agent
879
956
  var addAuthorization = /*#__PURE__*/function () {
880
- var _ref3 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee3(header, appID, token, clientSecret, apiVersion) {
957
+ var _ref4 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee4(header, appID, token, clientSecret, apiVersion) {
881
958
  var access_token;
882
- return _regeneratorRuntime.wrap(function (_context3) {
883
- while (1) switch (_context3.prev = _context3.next) {
959
+ return _regeneratorRuntime.wrap(function (_context4) {
960
+ while (1) switch (_context4.prev = _context4.next) {
884
961
  case 0:
885
962
  if (!(apiVersion == 'v2')) {
886
- _context3.next = 2;
963
+ _context4.next = 2;
887
964
  break;
888
965
  }
889
- _context3.next = 1;
966
+ _context4.next = 1;
890
967
  return getOrRefreshToken(appID, clientSecret);
891
968
  case 1:
892
- access_token = _context3.sent;
969
+ access_token = _context4.sent;
893
970
  // 更新header['Authorization']
894
971
  header['Authorization'] = "QQBot ".concat(access_token);
895
- _context3.next = 3;
972
+ _context4.next = 3;
896
973
  break;
897
974
  case 2:
898
975
  header['Authorization'] = "Bot ".concat(appID, ".").concat(token);
899
976
  case 3:
900
977
  case "end":
901
- return _context3.stop();
978
+ return _context4.stop();
902
979
  }
903
- }, _callee3);
980
+ }, _callee4);
904
981
  }));
905
- return function addAuthorization(_x3, _x4, _x5, _x6, _x7) {
906
- return _ref3.apply(this, arguments);
982
+ return function addAuthorization(_x4, _x5, _x6, _x7, _x8) {
983
+ return _ref4.apply(this, arguments);
907
984
  };
908
985
  }();
909
986
  // 组装完整Url
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "woodenfish-bot",
3
- "version": "4.4.5",
3
+ "version": "4.4.6",
4
4
  "description": "woodenfish-bot",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org/"