koishi-plugin-rocom 1.0.1

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 (157) hide show
  1. package/lib/client.d.ts +53 -0
  2. package/lib/client.js +473 -0
  3. package/lib/commands/account.d.ts +5 -0
  4. package/lib/commands/account.js +205 -0
  5. package/lib/commands/admin.d.ts +2 -0
  6. package/lib/commands/admin.js +117 -0
  7. package/lib/commands/egg.d.ts +2 -0
  8. package/lib/commands/egg.js +196 -0
  9. package/lib/commands/merchant.d.ts +2 -0
  10. package/lib/commands/merchant.js +242 -0
  11. package/lib/commands/query.d.ts +2 -0
  12. package/lib/commands/query.js +1264 -0
  13. package/lib/commands/wiki.d.ts +2 -0
  14. package/lib/commands/wiki.js +11 -0
  15. package/lib/egg-service.d.ts +229 -0
  16. package/lib/egg-service.js +705 -0
  17. package/lib/index.d.ts +24 -0
  18. package/lib/index.js +3746 -0
  19. package/lib/render-templates/bind-list/index.html +51 -0
  20. package/lib/render-templates/bind-list/style.css +178 -0
  21. package/lib/render-templates/exchange-hall/css/_@astro-renderers.0KDkAyVb.css +1 -0
  22. package/lib/render-templates/exchange-hall/css/index.B3tv56V6.css +1 -0
  23. package/lib/render-templates/exchange-hall/css/index.D2LGPudy.css +1 -0
  24. package/lib/render-templates/exchange-hall/extracted.css +393 -0
  25. package/lib/render-templates/exchange-hall/index.html +99 -0
  26. package/lib/render-templates/exchange-hall/style.css +267 -0
  27. package/lib/render-templates/friendship/index.html +58 -0
  28. package/lib/render-templates/friendship/style.css +182 -0
  29. package/lib/render-templates/home/data/home_item_list.json +122 -0
  30. package/lib/render-templates/home/img/home_icon/100604.png +0 -0
  31. package/lib/render-templates/home/img/home_icon/100604_1.png +0 -0
  32. package/lib/render-templates/home/img/home_icon/100604_2.png +0 -0
  33. package/lib/render-templates/home/img/home_icon/100605.png +0 -0
  34. package/lib/render-templates/home/img/home_icon/100605_1.png +0 -0
  35. package/lib/render-templates/home/img/home_icon/100605_2.png +0 -0
  36. package/lib/render-templates/home/img/home_icon/100606.png +0 -0
  37. package/lib/render-templates/home/img/home_icon/100606_1.png +0 -0
  38. package/lib/render-templates/home/img/home_icon/100606_2.png +0 -0
  39. package/lib/render-templates/home/img/home_icon/100607.png +0 -0
  40. package/lib/render-templates/home/img/home_icon/100607_1.png +0 -0
  41. package/lib/render-templates/home/img/home_icon/100607_2.png +0 -0
  42. package/lib/render-templates/home/img/home_icon/100608.png +0 -0
  43. package/lib/render-templates/home/img/home_icon/100608_1.png +0 -0
  44. package/lib/render-templates/home/img/home_icon/100608_2.png +0 -0
  45. package/lib/render-templates/home/img/home_icon/100622.png +0 -0
  46. package/lib/render-templates/home/img/home_icon/100622_1.png +0 -0
  47. package/lib/render-templates/home/img/home_icon/100622_2.png +0 -0
  48. package/lib/render-templates/home/img/home_icon/100623.png +0 -0
  49. package/lib/render-templates/home/img/home_icon/100623_1.png +0 -0
  50. package/lib/render-templates/home/img/home_icon/100623_2.png +0 -0
  51. package/lib/render-templates/home/img/home_icon/100624.png +0 -0
  52. package/lib/render-templates/home/img/home_icon/100624_1.png +0 -0
  53. package/lib/render-templates/home/img/home_icon/100624_2.png +0 -0
  54. package/lib/render-templates/home/img/home_icon/100627.png +0 -0
  55. package/lib/render-templates/home/img/home_icon/100627_1.png +0 -0
  56. package/lib/render-templates/home/img/home_icon/100627_2.png +0 -0
  57. package/lib/render-templates/home/img/home_icon/100684.png +0 -0
  58. package/lib/render-templates/home/img/home_icon/100684_1.png +0 -0
  59. package/lib/render-templates/home/img/home_icon/100684_2.png +0 -0
  60. package/lib/render-templates/home/img/home_icon/100686.png +0 -0
  61. package/lib/render-templates/home/img/home_icon/100686_1.png +0 -0
  62. package/lib/render-templates/home/img/home_icon/100686_2.png +0 -0
  63. package/lib/render-templates/home/img/home_icon/100687.png +0 -0
  64. package/lib/render-templates/home/img/home_icon/100687_1.png +0 -0
  65. package/lib/render-templates/home/img/home_icon/100687_2.png +0 -0
  66. package/lib/render-templates/home/img/home_icon/100689.png +0 -0
  67. package/lib/render-templates/home/img/home_icon/100689_1.png +0 -0
  68. package/lib/render-templates/home/img/home_icon/100689_2.png +0 -0
  69. package/lib/render-templates/home/img/home_icon/100690.png +0 -0
  70. package/lib/render-templates/home/img/home_icon/100690_1.png +0 -0
  71. package/lib/render-templates/home/img/home_icon/100690_2.png +0 -0
  72. package/lib/render-templates/home/img/home_icon/100691.png +0 -0
  73. package/lib/render-templates/home/img/home_icon/100691_1.png +0 -0
  74. package/lib/render-templates/home/img/home_icon/100691_2.png +0 -0
  75. package/lib/render-templates/home/img/home_icon/100692.png +0 -0
  76. package/lib/render-templates/home/img/home_icon/100692_1.png +0 -0
  77. package/lib/render-templates/home/img/home_icon/100692_2.png +0 -0
  78. package/lib/render-templates/home/img/home_icon/100693.png +0 -0
  79. package/lib/render-templates/home/img/home_icon/100693_1.png +0 -0
  80. package/lib/render-templates/home/img/home_icon/100693_2.png +0 -0
  81. package/lib/render-templates/home/img/home_icon/100694.png +0 -0
  82. package/lib/render-templates/home/img/home_icon/100694_1.png +0 -0
  83. package/lib/render-templates/home/img/home_icon/100694_2.png +0 -0
  84. package/lib/render-templates/home/img/home_icon/100706.png +0 -0
  85. package/lib/render-templates/home/img/home_icon/100706_1.png +0 -0
  86. package/lib/render-templates/home/img/home_icon/100706_2.png +0 -0
  87. package/lib/render-templates/home/img/home_icon/100751.png +0 -0
  88. package/lib/render-templates/home/img/home_icon/100751_1.png +0 -0
  89. package/lib/render-templates/home/img/home_icon/100751_2.png +0 -0
  90. package/lib/render-templates/home/img/home_icon/100755.png +0 -0
  91. package/lib/render-templates/home/img/home_icon/100755_1.png +0 -0
  92. package/lib/render-templates/home/img/home_icon/100755_2.png +0 -0
  93. package/lib/render-templates/home/img/home_icon/100762.png +0 -0
  94. package/lib/render-templates/home/img/home_icon/100762_1.png +0 -0
  95. package/lib/render-templates/home/img/home_icon/100762_2.png +0 -0
  96. package/lib/render-templates/home/img/home_icon/100764.png +0 -0
  97. package/lib/render-templates/home/img/home_icon/100764_1.png +0 -0
  98. package/lib/render-templates/home/img/home_icon/100764_2.png +0 -0
  99. package/lib/render-templates/home/img/home_icon/100869.png +0 -0
  100. package/lib/render-templates/home/img/home_icon/100869_1.png +0 -0
  101. package/lib/render-templates/home/img/home_icon/100869_2.png +0 -0
  102. package/lib/render-templates/home/img/img_HomeVisit_Icon1.png +0 -0
  103. package/lib/render-templates/home/img/img_LevelReward_Bg2.png +0 -0
  104. package/lib/render-templates/home/index.html +139 -0
  105. package/lib/render-templates/home/style.css +537 -0
  106. package/lib/render-templates/ingame-shop/index.html +87 -0
  107. package/lib/render-templates/ingame-shop/style.css +220 -0
  108. package/lib/render-templates/inspect/index.html +47 -0
  109. package/lib/render-templates/inspect/style.css +149 -0
  110. package/lib/render-templates/lineup/index.html +77 -0
  111. package/lib/render-templates/lineup/style.css +255 -0
  112. package/lib/render-templates/lineup-detail/index.html +63 -0
  113. package/lib/render-templates/lineup-detail/style.css +218 -0
  114. package/lib/render-templates/menu/index.html +36 -0
  115. package/lib/render-templates/menu/style.css +126 -0
  116. package/lib/render-templates/package/index.html +115 -0
  117. package/lib/render-templates/package/style.css +352 -0
  118. package/lib/render-templates/personal-card/index.html +292 -0
  119. package/lib/render-templates/personal-card/style.css +2114 -0
  120. package/lib/render-templates/pet-wiki/index.html +118 -0
  121. package/lib/render-templates/pet-wiki/style.css +382 -0
  122. package/lib/render-templates/player-search/index.html +60 -0
  123. package/lib/render-templates/player-search/style.css +192 -0
  124. package/lib/render-templates/record/index.html +86 -0
  125. package/lib/render-templates/record/style.css +322 -0
  126. package/lib/render-templates/searcheggs/Pets.json +104328 -0
  127. package/lib/render-templates/searcheggs/candidates.html +52 -0
  128. package/lib/render-templates/searcheggs/eggs.py +599 -0
  129. package/lib/render-templates/searcheggs/index.html +198 -0
  130. package/lib/render-templates/searcheggs/pair.html +81 -0
  131. package/lib/render-templates/searcheggs/size.html +82 -0
  132. package/lib/render-templates/searcheggs/style.css +586 -0
  133. package/lib/render-templates/searcheggs/want.html +63 -0
  134. package/lib/render-templates/skill-wiki/index.html +68 -0
  135. package/lib/render-templates/skill-wiki/style.css +182 -0
  136. package/lib/render-templates/student/index.html +95 -0
  137. package/lib/render-templates/student/style.css +255 -0
  138. package/lib/render-templates/student-perks/index.html +78 -0
  139. package/lib/render-templates/student-perks/style.css +238 -0
  140. package/lib/render-templates/student-state/index.html +52 -0
  141. package/lib/render-templates/student-state/style.css +157 -0
  142. package/lib/render-templates/yuanxing-shangren/index.html +371 -0
  143. package/lib/render-templates/yuanxing-shangren/style.css +371 -0
  144. package/lib/render.d.ts +11 -0
  145. package/lib/render.js +226 -0
  146. package/lib/role-token.d.ts +27 -0
  147. package/lib/role-token.js +137 -0
  148. package/lib/send-image.d.ts +3 -0
  149. package/lib/send-image.js +135 -0
  150. package/lib/subscription-send.d.ts +8 -0
  151. package/lib/subscription-send.js +48 -0
  152. package/lib/types.d.ts +32 -0
  153. package/lib/types.js +2 -0
  154. package/lib/user.d.ts +67 -0
  155. package/lib/user.js +176 -0
  156. package/package.json +58 -0
  157. package/readme.md +575 -0
@@ -0,0 +1,242 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.register = register;
4
+ const koishi_1 = require("koishi");
5
+ const send_image_1 = require("../send-image");
6
+ const subscription_send_1 = require("../subscription-send");
7
+ const logger = new koishi_1.Logger('rocom-merchant');
8
+ const TEXT = {
9
+ merchant: '\u8fdc\u884c\u5546\u4eba',
10
+ subscribe: '\u8ba2\u9605\u8fdc\u884c\u5546\u4eba',
11
+ unsubscribe: '\u53d6\u6d88\u8ba2\u9605\u8fdc\u884c\u5546\u4eba',
12
+ viewSubscribe: '\u67e5\u770b\u8fdc\u884c\u5546\u4eba\u8ba2\u9605',
13
+ unknown: '\u672a\u77e5',
14
+ notOpen: '\u672a\u5f00\u653e',
15
+ defaultSource: '\u9ed8\u8ba4',
16
+ customSource: '\u81ea\u5b9a\u4e49',
17
+ };
18
+ function normalizeTimestamp(value) {
19
+ if (value === null || value === undefined || value === '')
20
+ return null;
21
+ const timestamp = Number(value);
22
+ if (!Number.isFinite(timestamp))
23
+ return null;
24
+ return timestamp < 100000000000 ? timestamp * 1000 : timestamp;
25
+ }
26
+ function formatProductWindow(product) {
27
+ const start = normalizeTimestamp(product?.start_time);
28
+ const end = normalizeTimestamp(product?.end_time);
29
+ if (!start && !end)
30
+ return '';
31
+ const formatTime = (timestamp) => {
32
+ const date = new Date(timestamp);
33
+ const hour = String(date.getHours()).padStart(2, '0');
34
+ const minute = String(date.getMinutes()).padStart(2, '0');
35
+ return `${hour}:${minute}`;
36
+ };
37
+ if (start && end)
38
+ return `${formatTime(start)}-${formatTime(end)}`;
39
+ if (start)
40
+ return `${formatTime(start)}+`;
41
+ return `${formatTime(end)}-`;
42
+ }
43
+ function getMerchantActivity(res) {
44
+ const activities = res?.merchantActivities || res?.merchant_activities || [];
45
+ return activities[0] || {};
46
+ }
47
+ function getActiveProducts(res) {
48
+ const activity = getMerchantActivity(res);
49
+ const products = activity?.products || activity?.product_list || activity?.get_props || [];
50
+ return products.filter((p) => {
51
+ const now = Date.now();
52
+ const start = normalizeTimestamp(p.start_time) ?? 0;
53
+ const end = normalizeTimestamp(p.end_time) ?? Infinity;
54
+ return now >= start && now < end;
55
+ });
56
+ }
57
+ function getCurrentMerchantRound() {
58
+ const now = new Date();
59
+ const hour = now.getHours();
60
+ const rounds = [8, 12, 16, 20];
61
+ let currentRound = null;
62
+ let nextRound = null;
63
+ for (let i = 0; i < rounds.length; i++) {
64
+ if (hour >= rounds[i] && (i === rounds.length - 1 || hour < rounds[i + 1])) {
65
+ currentRound = i + 1;
66
+ nextRound = i < rounds.length - 1 ? rounds[i + 1] : rounds[0];
67
+ break;
68
+ }
69
+ }
70
+ if (currentRound === null)
71
+ nextRound = rounds[0];
72
+ const nextTime = new Date(now);
73
+ if (nextRound <= hour)
74
+ nextTime.setDate(nextTime.getDate() + 1);
75
+ nextTime.setHours(nextRound, 0, 0, 0);
76
+ const diff = nextTime.getTime() - now.getTime();
77
+ const hours = Math.floor(diff / 3600000);
78
+ const mins = Math.floor((diff % 3600000) / 60000);
79
+ const datePart = [
80
+ now.getFullYear(),
81
+ String(now.getMonth() + 1).padStart(2, '0'),
82
+ String(now.getDate()).padStart(2, '0'),
83
+ ].join('-');
84
+ return {
85
+ current: currentRound,
86
+ countdown: `${hours}\u5c0f\u65f6${mins}\u5206\u949f`,
87
+ is_open: currentRound !== null,
88
+ round_id: `${datePart}-${currentRound || 'closed'}`,
89
+ };
90
+ }
91
+ function parseMerchantSubscriptionArgs(args, defaultItems) {
92
+ const parts = (args || '').split(/\s+/).filter(Boolean);
93
+ let mentionAll = false;
94
+ if (parts[0] === '1' || parts[0] === '0') {
95
+ mentionAll = parts.shift() === '1';
96
+ }
97
+ const items = parts.length ? parts : defaultItems;
98
+ return {
99
+ mention_all: mentionAll,
100
+ items,
101
+ source: parts.length ? TEXT.customSource : TEXT.defaultSource,
102
+ };
103
+ }
104
+ function getSubscriptionTarget(session) {
105
+ const platform = session.platform || session.bot?.platform || '';
106
+ const privateChat = !session.guildId;
107
+ const channelId = session.channelId || session.guildId || session.userId || '';
108
+ const key = privateChat ? `private_${session.userId}` : session.guildId;
109
+ return { key, platform, channelId, privateChat };
110
+ }
111
+ function isBotAdmin(session, adminUserIds) {
112
+ return adminUserIds.includes(session?.userId || '');
113
+ }
114
+ function sameStringArray(left, right) {
115
+ return JSON.stringify(left) === JSON.stringify(right);
116
+ }
117
+ async function checkMerchantSubscriptions(deps) {
118
+ const { ctx, client, merchantSubMgr } = deps;
119
+ const res = await client.getMerchantInfo(ctx, true);
120
+ if (!res)
121
+ return { subscriptions: 0, matched: 0, pushed: 0 };
122
+ const products = getActiveProducts(res);
123
+ const productNames = products.map((p) => p.name || '').filter(Boolean);
124
+ const roundInfo = getCurrentMerchantRound();
125
+ const subs = merchantSubMgr.getAll();
126
+ let matchedCount = 0;
127
+ let pushedCount = 0;
128
+ for (const [key, sub] of Object.entries(subs)) {
129
+ const matched = sub.items.filter((item) => productNames.some(n => n.includes(item)));
130
+ if (!matched.length)
131
+ continue;
132
+ matchedCount++;
133
+ if (sub.last_push_round === roundInfo.round_id && sameStringArray(matched, sub.last_matched_items || []))
134
+ continue;
135
+ const msg = `\ud83d\udd14 \u8fdc\u884c\u5546\u4eba\u5237\u65b0\u63d0\u9192\n\u5f53\u524d\u5546\u54c1\uff1a${productNames.join('\u3001')}\n\u5339\u914d\u8ba2\u9605\uff1a${matched.join('\u3001')}`;
136
+ const platform = sub.platform || ctx.bots[0]?.platform;
137
+ const channelId = sub.channel_id || sub.group_id || sub.user_id || key;
138
+ if (!platform || !channelId) {
139
+ logger.warn(`\u63a8\u9001\u5931\u8d25 ${key}: \u65e0\u6cd5\u786e\u5b9a\u5e73\u53f0\u6216\u9891\u9053`);
140
+ continue;
141
+ }
142
+ const sent = await (0, subscription_send_1.sendScheduledMessage)(ctx, {
143
+ platform,
144
+ channelId,
145
+ guildId: sub.group_id || '',
146
+ userId: sub.user_id || '',
147
+ }, sub.mention_all ? `@\u5168\u4f53\n${msg}` : msg);
148
+ if (!sent)
149
+ continue;
150
+ pushedCount++;
151
+ merchantSubMgr.upsert(key, {
152
+ ...sub,
153
+ last_push_round: roundInfo.round_id,
154
+ last_matched_items: matched,
155
+ });
156
+ }
157
+ return { subscriptions: Object.keys(subs).length, matched: matchedCount, pushed: pushedCount };
158
+ }
159
+ function register(deps) {
160
+ const { ctx, config, client, merchantSubMgr } = deps;
161
+ ctx.command(TEXT.merchant, '\u67e5\u770b\u8fdc\u884c\u5546\u4eba\u5546\u54c1')
162
+ .action(async ({ session }) => {
163
+ const res = await client.getMerchantInfo(ctx, true);
164
+ if (!res)
165
+ return '\u83b7\u53d6\u8fdc\u884c\u5546\u4eba\u6570\u636e\u5931\u8d25\u3002';
166
+ const products = getActiveProducts(res);
167
+ const roundInfo = getCurrentMerchantRound();
168
+ const activity = getMerchantActivity(res);
169
+ const data = {
170
+ background: '',
171
+ title: activity.name || TEXT.merchant,
172
+ subtitle: activity.start_date || '\u6bcf\u65e5 08:00 / 12:00 / 16:00 / 20:00 \u5237\u65b0',
173
+ titleIcon: '',
174
+ product_count: products.length,
175
+ round_info: roundInfo,
176
+ products: products.map((p) => ({
177
+ name: p.name || TEXT.unknown,
178
+ image: p.icon_url || '',
179
+ time_label: formatProductWindow(p),
180
+ })),
181
+ };
182
+ const fallback = products.length
183
+ ? `\u8fdc\u884c\u5546\u4eba\u5f53\u524d\u5546\u54c1\uff1a${products.map((p) => p.name || TEXT.unknown).join('\u3001')}\n\u8f6e\u6b21\uff1a${roundInfo.current || TEXT.notOpen}\n\u5269\u4f59\uff1a${roundInfo.countdown}`
184
+ : '\u5f53\u524d\u8fdc\u884c\u5546\u4eba\u6682\u65e0\u5546\u54c1\u3002';
185
+ const png = await deps.renderer.renderHtml(ctx, 'yuanxing-shangren', data);
186
+ await (0, send_image_1.sendImageWithFallback)(session, png, fallback, 'merchant:yuanxing-shangren', deps.config);
187
+ });
188
+ ctx.command(`${TEXT.subscribe} [args:text]`, '\u8ba2\u9605\u8fdc\u884c\u5546\u4eba\u5546\u54c1\u63d0\u9192')
189
+ .action(async ({ session }, args) => {
190
+ const target = getSubscriptionTarget(session);
191
+ if (!target.privateChat && !isBotAdmin(session, config.adminUserIds))
192
+ return '此指令仅限管理员使用。';
193
+ if (target.privateChat && !config.merchantPrivateSubscriptionEnabled)
194
+ return '个人私聊订阅功能已被禁用,请联系机器人管理员。';
195
+ const parsed = parseMerchantSubscriptionArgs(args, config.merchantSubscriptionItems);
196
+ const existing = merchantSubMgr.get(target.key);
197
+ merchantSubMgr.upsert(target.key, {
198
+ group_id: session.guildId || '',
199
+ user_id: target.privateChat ? session.userId : '',
200
+ type: target.privateChat ? '个人订阅' : '群订阅',
201
+ channel_id: target.channelId,
202
+ platform: target.platform,
203
+ items: parsed.items,
204
+ mention_all: target.privateChat ? false : parsed.mention_all,
205
+ last_push_round: existing?.last_push_round ?? null,
206
+ last_matched_items: existing?.last_matched_items ?? [],
207
+ updated_by: session.userId,
208
+ });
209
+ return `\u2705 \u5df2\u8ba2\u9605\u8fdc\u884c\u5546\u4eba\u5546\u54c1\uff1a${parsed.items.join('\u3001')}\uff08${parsed.source}\uff09\uff1b${target.privateChat ? '个人订阅' : (parsed.mention_all ? '\u547d\u4e2d\u540e\u4f1a @\u5168\u4f53' : '\u547d\u4e2d\u540e\u4e0d @\u5168\u4f53')}`;
210
+ });
211
+ ctx.command(TEXT.viewSubscribe, '\u67e5\u770b\u5f53\u524d\u4f1a\u8bdd\u7684\u8fdc\u884c\u5546\u4eba\u8ba2\u9605')
212
+ .action(async ({ session }) => {
213
+ const target = getSubscriptionTarget(session);
214
+ if (!target.privateChat && !isBotAdmin(session, config.adminUserIds))
215
+ return '此指令仅限管理员使用。';
216
+ const sub = merchantSubMgr.get(target.key);
217
+ const scopeName = target.privateChat ? '你' : '当前群组';
218
+ if (!sub)
219
+ return `${scopeName}未订阅远行商人。\n用法:${TEXT.subscribe} [1/0] [商品名1] [商品名2] ...`;
220
+ return `${scopeName}订阅商品:${sub.items.join('、')}\n提醒方式:${target.privateChat ? '私聊提醒' : (sub.mention_all ? '@全体' : '普通提醒')}`;
221
+ });
222
+ ctx.command(TEXT.unsubscribe, '\u53d6\u6d88\u8fdc\u884c\u5546\u4eba\u8ba2\u9605')
223
+ .action(async ({ session }) => {
224
+ const target = getSubscriptionTarget(session);
225
+ if (!target.privateChat && !isBotAdmin(session, config.adminUserIds))
226
+ return '此指令仅限管理员使用。';
227
+ merchantSubMgr.delete(target.key);
228
+ return '\u2705 \u5df2\u53d6\u6d88\u8fdc\u884c\u5546\u4eba\u8ba2\u9605\u3002';
229
+ });
230
+ ctx.command('洛克').subcommand('.调试远行商人订阅', '立即执行一次远行商人订阅检查')
231
+ .action(async ({ session }) => {
232
+ if (!isBotAdmin(session, config.adminUserIds))
233
+ return '此指令仅限管理员使用。';
234
+ const result = await checkMerchantSubscriptions(deps);
235
+ return `远行商人订阅检查完成:订阅 ${result.subscriptions} 条,命中 ${result.matched} 条,推送 ${result.pushed} 条。`;
236
+ });
237
+ if (config.merchantSubscriptionEnabled) {
238
+ ctx.setInterval(async () => {
239
+ await checkMerchantSubscriptions(deps);
240
+ }, config.merchantCheckInterval);
241
+ }
242
+ }
@@ -0,0 +1,2 @@
1
+ import { PluginDeps } from '../types';
2
+ export declare function register(deps: PluginDeps): void;