koishi-plugin-aka-60s-api 0.2.9 → 0.2.10

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/lib/index.d.ts CHANGED
@@ -6,6 +6,7 @@ export interface Config {
6
6
  cooldownTime: number;
7
7
  enableLog: boolean;
8
8
  scheduleWhitelist: string[];
9
+ scheduleCooldown: number;
9
10
  enableSchedule: boolean;
10
11
  scheduleTime: string;
11
12
  useForward: boolean;
package/lib/index.js CHANGED
@@ -32,7 +32,8 @@ var inject = ["database"];
32
32
  var Config = import_koishi.Schema.intersect([
33
33
  import_koishi.Schema.object({
34
34
  apiBaseUrl: import_koishi.Schema.string().default("http://172.0.0.1:4399").description("60s 服务 URL(不含 /v2 路径)"),
35
- cooldownTime: import_koishi.Schema.number().default(30).min(5).max(300).description("冷却时间(秒)"),
35
+ cooldownTime: import_koishi.Schema.number().default(30).min(5).max(300).description("命令冷却时间(秒),用户手动触发命令的间隔限制"),
36
+ scheduleCooldown: import_koishi.Schema.number().default(86400).min(0).description("定时任务防重发冷却时间(秒),0表示不限制。默认86400秒=24小时"),
36
37
  enableLog: import_koishi.Schema.boolean().default(true).description("启用日志记录"),
37
38
  scheduleWhitelist: import_koishi.Schema.array(String).default([]).description("定时发送群组白名单频道ID列表(格式: platform:channelId,如 onebot:123456)")
38
39
  }).description("基础设置"),
@@ -70,13 +71,34 @@ function apply(ctx, config) {
70
71
  let moyuScheduleTimeout = null;
71
72
  let goldScheduleTimeout = null;
72
73
  let fuelScheduleTimeout = null;
73
- const sentToday = {
74
- news: "",
75
- aiNews: "",
76
- moyu: "",
77
- gold: "",
78
- fuel: ""
74
+ const lastSentTime = {
75
+ news: 0,
76
+ aiNews: 0,
77
+ moyu: 0,
78
+ gold: 0,
79
+ fuel: 0
79
80
  };
81
+ function isInCooldown(type) {
82
+ if (config.scheduleCooldown <= 0) {
83
+ return false;
84
+ }
85
+ const now = Date.now();
86
+ const lastTime = lastSentTime[type];
87
+ const cooldownMs = config.scheduleCooldown * 1e3;
88
+ return now - lastTime < cooldownMs;
89
+ }
90
+ __name(isInCooldown, "isInCooldown");
91
+ function getRemainingCooldown(type) {
92
+ if (config.scheduleCooldown <= 0) {
93
+ return 0;
94
+ }
95
+ const now = Date.now();
96
+ const lastTime = lastSentTime[type];
97
+ const cooldownMs = config.scheduleCooldown * 1e3;
98
+ const remaining = Math.ceil((lastTime + cooldownMs - now) / 1e3);
99
+ return Math.max(0, remaining);
100
+ }
101
+ __name(getRemainingCooldown, "getRemainingCooldown");
80
102
  function getTodayString() {
81
103
  const now = /* @__PURE__ */ new Date();
82
104
  const year = now.getFullYear();
@@ -580,20 +602,23 @@ ${newsItem.link}`).join("\n\n");
580
602
  }
581
603
  try {
582
604
  const today = getTodayString();
583
- if (sentToday.news === today) {
584
- logInfo("60s API: 今日新闻已发送过,设置为明天任务", { today });
605
+ const remainingCooldown = getRemainingCooldown("news");
606
+ if (isInCooldown("news")) {
607
+ logInfo("60s API: 新闻发送冷却中,跳过本次发送", {
608
+ today,
609
+ remainingCooldownSec: remainingCooldown,
610
+ scheduleCooldown: config.scheduleCooldown
611
+ });
585
612
  const msUntilNext2 = getMsUntilNextTime(config.scheduleTime);
586
613
  if (msUntilNext2 === null) {
587
614
  scheduleTimeout = setTimeout(() => {
588
- sentToday.news = "";
589
615
  setupSchedule();
590
616
  }, 24 * 60 * 60 * 1e3);
591
617
  return;
592
618
  }
593
619
  scheduleTimeout = setTimeout(() => {
594
- sentToday.news = "";
595
620
  setupSchedule();
596
- }, msUntilNext2 + 24 * 60 * 60 * 1e3);
621
+ }, msUntilNext2);
597
622
  return;
598
623
  }
599
624
  const msUntilNext = getMsUntilNextTime(config.scheduleTime);
@@ -609,17 +634,18 @@ ${newsItem.link}`).join("\n\n");
609
634
  msUntilNext,
610
635
  nextRun: new Date(Date.now() + msUntilNext).toLocaleString(),
611
636
  whitelist: config.scheduleWhitelist,
612
- today,
613
- alreadySent: sentToday.news === today
637
+ scheduleCooldown: config.scheduleCooldown
614
638
  });
615
639
  scheduleTimeout = setTimeout(async () => {
616
- if (sentToday.news === getTodayString()) {
617
- logInfo("60s API: 今日新闻已在本次任务等待期间发送,跳过");
640
+ if (isInCooldown("news")) {
641
+ logInfo("60s API: 新闻发送冷却中,跳过本次发送", {
642
+ remainingCooldownSec: getRemainingCooldown("news")
643
+ });
618
644
  setupSchedule();
619
645
  return;
620
646
  }
621
647
  await sendNewsToChannels();
622
- sentToday.news = getTodayString();
648
+ lastSentTime.news = Date.now();
623
649
  setupSchedule();
624
650
  }, msUntilNext);
625
651
  } catch (error) {
@@ -638,20 +664,23 @@ ${newsItem.link}`).join("\n\n");
638
664
  }
639
665
  try {
640
666
  const today = getTodayString();
641
- if (sentToday.aiNews === today) {
642
- logInfo("60s API: 今日AI快报已发送过,设置为明天任务", { today });
667
+ const remainingCooldown = getRemainingCooldown("aiNews");
668
+ if (isInCooldown("aiNews")) {
669
+ logInfo("60s API: AI快报发送冷却中,跳过本次发送", {
670
+ today,
671
+ remainingCooldownSec: remainingCooldown,
672
+ scheduleCooldown: config.scheduleCooldown
673
+ });
643
674
  const msUntilNext2 = getMsUntilNextTime(config.aiNewsScheduleTime);
644
675
  if (msUntilNext2 === null) {
645
676
  aiNewsScheduleTimeout = setTimeout(() => {
646
- sentToday.aiNews = "";
647
677
  setupAiNewsSchedule();
648
678
  }, 24 * 60 * 60 * 1e3);
649
679
  return;
650
680
  }
651
681
  aiNewsScheduleTimeout = setTimeout(() => {
652
- sentToday.aiNews = "";
653
682
  setupAiNewsSchedule();
654
- }, msUntilNext2 + 24 * 60 * 60 * 1e3);
683
+ }, msUntilNext2);
655
684
  return;
656
685
  }
657
686
  const msUntilNext = getMsUntilNextTime(config.aiNewsScheduleTime);
@@ -666,16 +695,19 @@ ${newsItem.link}`).join("\n\n");
666
695
  scheduleTime: config.aiNewsScheduleTime,
667
696
  msUntilNext,
668
697
  nextRun: new Date(Date.now() + msUntilNext).toLocaleString(),
669
- whitelist: config.scheduleWhitelist
698
+ whitelist: config.scheduleWhitelist,
699
+ scheduleCooldown: config.scheduleCooldown
670
700
  });
671
701
  aiNewsScheduleTimeout = setTimeout(async () => {
672
- if (sentToday.aiNews === getTodayString()) {
673
- logInfo("60s API: 今日AI快报已在本次任务等待期间发送,跳过");
702
+ if (isInCooldown("aiNews")) {
703
+ logInfo("60s API: AI快报发送冷却中,跳过本次发送", {
704
+ remainingCooldownSec: getRemainingCooldown("aiNews")
705
+ });
674
706
  setupAiNewsSchedule();
675
707
  return;
676
708
  }
677
709
  await sendAiNewsToChannels();
678
- sentToday.aiNews = getTodayString();
710
+ lastSentTime.aiNews = Date.now();
679
711
  setupAiNewsSchedule();
680
712
  }, msUntilNext);
681
713
  } catch (error) {
@@ -694,20 +726,23 @@ ${newsItem.link}`).join("\n\n");
694
726
  }
695
727
  try {
696
728
  const today = getTodayString();
697
- if (sentToday.moyu === today) {
698
- logInfo("60s API: 今日摸鱼日报已发送过,设置为明天任务", { today });
729
+ const remainingCooldown = getRemainingCooldown("moyu");
730
+ if (isInCooldown("moyu")) {
731
+ logInfo("60s API: 摸鱼日报发送冷却中,跳过本次发送", {
732
+ today,
733
+ remainingCooldownSec: remainingCooldown,
734
+ scheduleCooldown: config.scheduleCooldown
735
+ });
699
736
  const msUntilNext2 = getMsUntilNextTime(config.moyuScheduleTime);
700
737
  if (msUntilNext2 === null) {
701
738
  moyuScheduleTimeout = setTimeout(() => {
702
- sentToday.moyu = "";
703
739
  setupMoyuSchedule();
704
740
  }, 24 * 60 * 60 * 1e3);
705
741
  return;
706
742
  }
707
743
  moyuScheduleTimeout = setTimeout(() => {
708
- sentToday.moyu = "";
709
744
  setupMoyuSchedule();
710
- }, msUntilNext2 + 24 * 60 * 60 * 1e3);
745
+ }, msUntilNext2);
711
746
  return;
712
747
  }
713
748
  const msUntilNext = getMsUntilNextTime(config.moyuScheduleTime);
@@ -722,16 +757,19 @@ ${newsItem.link}`).join("\n\n");
722
757
  scheduleTime: config.moyuScheduleTime,
723
758
  msUntilNext,
724
759
  nextRun: new Date(Date.now() + msUntilNext).toLocaleString(),
725
- whitelist: config.scheduleWhitelist
760
+ whitelist: config.scheduleWhitelist,
761
+ scheduleCooldown: config.scheduleCooldown
726
762
  });
727
763
  moyuScheduleTimeout = setTimeout(async () => {
728
- if (sentToday.moyu === getTodayString()) {
729
- logInfo("60s API: 今日摸鱼日报已在本次任务等待期间发送,跳过");
764
+ if (isInCooldown("moyu")) {
765
+ logInfo("60s API: 摸鱼日报发送冷却中,跳过本次发送", {
766
+ remainingCooldownSec: getRemainingCooldown("moyu")
767
+ });
730
768
  setupMoyuSchedule();
731
769
  return;
732
770
  }
733
771
  await sendMoyuToChannels();
734
- sentToday.moyu = getTodayString();
772
+ lastSentTime.moyu = Date.now();
735
773
  setupMoyuSchedule();
736
774
  }, msUntilNext);
737
775
  } catch (error) {
@@ -750,20 +788,23 @@ ${newsItem.link}`).join("\n\n");
750
788
  }
751
789
  try {
752
790
  const today = getTodayString();
753
- if (sentToday.gold === today) {
754
- logInfo("60s API: 今日金价已发送过,设置为明天任务", { today });
791
+ const remainingCooldown = getRemainingCooldown("gold");
792
+ if (isInCooldown("gold")) {
793
+ logInfo("60s API: 今日金价发送冷却中,跳过本次发送", {
794
+ today,
795
+ remainingCooldownSec: remainingCooldown,
796
+ scheduleCooldown: config.scheduleCooldown
797
+ });
755
798
  const msUntilNext2 = getMsUntilNextTime(config.goldScheduleTime);
756
799
  if (msUntilNext2 === null) {
757
800
  goldScheduleTimeout = setTimeout(() => {
758
- sentToday.gold = "";
759
801
  setupGoldSchedule();
760
802
  }, 24 * 60 * 60 * 1e3);
761
803
  return;
762
804
  }
763
805
  goldScheduleTimeout = setTimeout(() => {
764
- sentToday.gold = "";
765
806
  setupGoldSchedule();
766
- }, msUntilNext2 + 24 * 60 * 60 * 1e3);
807
+ }, msUntilNext2);
767
808
  return;
768
809
  }
769
810
  const msUntilNext = getMsUntilNextTime(config.goldScheduleTime);
@@ -778,16 +819,19 @@ ${newsItem.link}`).join("\n\n");
778
819
  scheduleTime: config.goldScheduleTime,
779
820
  msUntilNext,
780
821
  nextRun: new Date(Date.now() + msUntilNext).toLocaleString(),
781
- whitelist: config.scheduleWhitelist
822
+ whitelist: config.scheduleWhitelist,
823
+ scheduleCooldown: config.scheduleCooldown
782
824
  });
783
825
  goldScheduleTimeout = setTimeout(async () => {
784
- if (sentToday.gold === getTodayString()) {
785
- logInfo("60s API: 今日金价已在本次任务等待期间发送,跳过");
826
+ if (isInCooldown("gold")) {
827
+ logInfo("60s API: 今日金价发送冷却中,跳过本次发送", {
828
+ remainingCooldownSec: getRemainingCooldown("gold")
829
+ });
786
830
  setupGoldSchedule();
787
831
  return;
788
832
  }
789
833
  await sendGoldToChannels();
790
- sentToday.gold = getTodayString();
834
+ lastSentTime.gold = Date.now();
791
835
  setupGoldSchedule();
792
836
  }, msUntilNext);
793
837
  } catch (error) {
@@ -806,20 +850,23 @@ ${newsItem.link}`).join("\n\n");
806
850
  }
807
851
  try {
808
852
  const today = getTodayString();
809
- if (sentToday.fuel === today) {
810
- logInfo("60s API: 今日油价已发送过,设置为明天任务", { today });
853
+ const remainingCooldown = getRemainingCooldown("fuel");
854
+ if (isInCooldown("fuel")) {
855
+ logInfo("60s API: 今日油价发送冷却中,跳过本次发送", {
856
+ today,
857
+ remainingCooldownSec: remainingCooldown,
858
+ scheduleCooldown: config.scheduleCooldown
859
+ });
811
860
  const msUntilNext2 = getMsUntilNextTime(config.fuelScheduleTime);
812
861
  if (msUntilNext2 === null) {
813
862
  fuelScheduleTimeout = setTimeout(() => {
814
- sentToday.fuel = "";
815
863
  setupFuelSchedule();
816
864
  }, 24 * 60 * 60 * 1e3);
817
865
  return;
818
866
  }
819
867
  fuelScheduleTimeout = setTimeout(() => {
820
- sentToday.fuel = "";
821
868
  setupFuelSchedule();
822
- }, msUntilNext2 + 24 * 60 * 60 * 1e3);
869
+ }, msUntilNext2);
823
870
  return;
824
871
  }
825
872
  const msUntilNext = getMsUntilNextTime(config.fuelScheduleTime);
@@ -834,16 +881,19 @@ ${newsItem.link}`).join("\n\n");
834
881
  scheduleTime: config.fuelScheduleTime,
835
882
  msUntilNext,
836
883
  nextRun: new Date(Date.now() + msUntilNext).toLocaleString(),
837
- whitelist: config.scheduleWhitelist
884
+ whitelist: config.scheduleWhitelist,
885
+ scheduleCooldown: config.scheduleCooldown
838
886
  });
839
887
  fuelScheduleTimeout = setTimeout(async () => {
840
- if (sentToday.fuel === getTodayString()) {
841
- logInfo("60s API: 今日油价已在本次任务等待期间发送,跳过");
888
+ if (isInCooldown("fuel")) {
889
+ logInfo("60s API: 今日油价发送冷却中,跳过本次发送", {
890
+ remainingCooldownSec: getRemainingCooldown("fuel")
891
+ });
842
892
  setupFuelSchedule();
843
893
  return;
844
894
  }
845
895
  await sendFuelToChannels();
846
- sentToday.fuel = getTodayString();
896
+ lastSentTime.fuel = Date.now();
847
897
  setupFuelSchedule();
848
898
  }, msUntilNext);
849
899
  } catch (error) {
@@ -1237,11 +1287,11 @@ ${shortDetail}
1237
1287
  clearTimeout(fuelScheduleTimeout);
1238
1288
  fuelScheduleTimeout = null;
1239
1289
  }
1240
- sentToday.news = "";
1241
- sentToday.aiNews = "";
1242
- sentToday.moyu = "";
1243
- sentToday.gold = "";
1244
- sentToday.fuel = "";
1290
+ lastSentTime.news = 0;
1291
+ lastSentTime.aiNews = 0;
1292
+ lastSentTime.moyu = 0;
1293
+ lastSentTime.gold = 0;
1294
+ lastSentTime.fuel = 0;
1245
1295
  });
1246
1296
  }
1247
1297
  __name(apply, "apply");
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-aka-60s-api",
3
3
  "description": "调用60s API转发信息的工具 - 个人用",
4
- "version": "0.2.9",
4
+ "version": "0.2.10",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
7
7
  "files": [