koishi-plugin-booth-get 6.0.0-beta.1 β†’ 6.0.0-beta.2

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.
@@ -8,6 +8,8 @@ class DiscountTracker {
8
8
  this.config = null;
9
9
  this.DISCOUNT_ITEMS_FILE = path.join(__dirname, "discount_items.json");
10
10
  this.DISCOUNT_GROUPS_FILE = path.join(__dirname, "discount_groups.json");
11
+ this.discountCache = new Map();
12
+ this.CACHE_DURATION = 24 * 60 * 60 * 1000;
11
13
  }
12
14
 
13
15
  init(ctx, config) {
@@ -19,6 +21,30 @@ class DiscountTracker {
19
21
  }
20
22
  }
21
23
 
24
+ cleanupExpiredCache() {
25
+ const now = Date.now();
26
+ for (const [id, timestamp] of this.discountCache.entries()) {
27
+ if (now - timestamp > this.CACHE_DURATION) {
28
+ this.discountCache.delete(id);
29
+ }
30
+ }
31
+ }
32
+
33
+ isCached(itemId) {
34
+ const timestamp = this.discountCache.get(itemId);
35
+ if (!timestamp) return false;
36
+
37
+ if (Date.now() - timestamp > this.CACHE_DURATION) {
38
+ this.discountCache.delete(itemId);
39
+ return false;
40
+ }
41
+ return true;
42
+ }
43
+
44
+ addToCache(itemId) {
45
+ this.discountCache.set(itemId, Date.now());
46
+ }
47
+
22
48
  async loadJSON(file, def = {}) {
23
49
  try {
24
50
  const raw = await fs.readFile(file, "utf8");
@@ -123,78 +149,81 @@ class DiscountTracker {
123
149
  }
124
150
  }
125
151
 
126
- async notifyDiscountGroups(discountItems) {
127
- const logger = this.ctx.logger("booth-discount");
128
- const cardGenerator = require('./card-generator');
129
-
130
- for (const groupKey of this.config.targetGroups || []) {
131
- const parts = groupKey.split(':');
132
- if (parts.length < 3) continue;
133
- const platform = parts[1];
134
- const channelId = parts.slice(2).join(':');
152
+ async notifyDiscountGroups(discountItems) {
153
+ const logger = this.ctx.logger("booth-discount");
154
+ const cardGenerator = require('./card-generator');
135
155
 
136
- for (const item of discountItems) {
137
- try {
138
- const html = cardGenerator.generateDiscountCardHTML(item);
139
- const buffer = await cardGenerator.captureCardHTML(html, this.config);
140
- if (!buffer) continue;
141
-
142
- const message = `πŸŽ‰ ε‘ηŽ°ζŠ˜ζ‰£ε•†ε“οΌ\n` +
143
- `商品链ζŽ₯:${item.url}\n` +
144
- `原价:Β₯${item.original_price.toLocaleString()}\n` +
145
- `现价:Β₯${item.price.toLocaleString()}\n` +
146
- `ζŠ˜ζ‰£οΌš${item.discount_rate}% OFF\n` +
147
- `θŠ‚ηœοΌšΒ₯${(item.original_price - item.price).toLocaleString()}`;
148
-
149
- await this.ctx.bots[0].sendMessage(channelId, [message, import_koishi.h.image(buffer, "image/png")]);
150
-
151
- await new Promise(resolve => setTimeout(resolve, 1000));
152
- } catch (e) {
153
- logger.warn(`向羀组 ${channelId} ζŽ¨ι€ζŠ˜ζ‰£δΏ‘ζ―ε€±θ΄₯:`, e);
156
+ const itemsToPush = discountItems.slice(0, this.config.maxDiscountPushCount || 5);
157
+
158
+ for (const groupKey of this.config.targetGroups || []) {
159
+ const parts = groupKey.split(':');
160
+ if (parts.length < 3) continue;
161
+ const platform = parts[1];
162
+ const channelId = parts.slice(2).join(':');
163
+
164
+ for (const item of itemsToPush) {
165
+ try {
166
+ const html = cardGenerator.generateDiscountCardHTML(item);
167
+ const buffer = await cardGenerator.captureCardHTML(html, this.config);
168
+ if (!buffer) continue;
169
+
170
+ const message = `πŸŽ‰ ε‘ηŽ°ζŠ˜ζ‰£ε•†ε“οΌ\n` +
171
+ `商品链ζŽ₯:${item.url}\n` +
172
+ `原价:Β₯${item.original_price.toLocaleString()}\n` +
173
+ `现价:Β₯${item.price.toLocaleString()}\n` +
174
+ `ζŠ˜ζ‰£οΌš${item.discount_rate}% OFF\n` +
175
+ `θŠ‚ηœοΌšΒ₯${(item.original_price - item.price).toLocaleString()}`;
176
+
177
+ await this.ctx.bots[0].sendMessage(channelId, [message, import_koishi.h.image(buffer, "image/png")]);
178
+
179
+ await new Promise(resolve => setTimeout(resolve, 1000));
180
+ } catch (e) {
181
+ logger.warn(`向羀组 ${channelId} ζŽ¨ι€ζŠ˜ζ‰£δΏ‘ζ―ε€±θ΄₯:`, e);
182
+ }
154
183
  }
155
184
  }
156
185
  }
157
- }
158
186
 
159
- startDiscountTracking() {
160
- const logger = this.ctx.logger("booth-discount");
161
- logger.info('ε―εŠ¨ζŠ˜ζ‰£ε•†ε“θΏ½θΈͺ器');
187
+ startDiscountTracking() {
188
+ const logger = this.ctx.logger("booth-discount");
189
+ logger.info('ε―εŠ¨ζŠ˜ζ‰£ε•†ε“θΏ½θΈͺ器');
162
190
 
163
- this.ctx.setInterval(async () => {
164
- try {
165
- this.cleanupExpiredCache();
166
-
167
- logger.info('εΌ€ε§‹ζ£€ζŸ₯ζŠ˜ζ‰£ε•†ε“...');
168
- const discountItems = await this.searchDiscountItems();
169
- const knownItems = await this.loadJSON(this.DISCOUNT_ITEMS_FILE);
170
- const newDiscountItems = [];
171
-
172
- for (const item of discountItems) {
173
- if (!this.isCached(item.id)) {
174
- if (!knownItems[item.id] || knownItems[item.id].discount_rate !== item.discount_rate) {
175
- newDiscountItems.push(item);
176
- this.addToCache(item.id);
177
- knownItems[item.id] = {
178
- ...item,
179
- first_seen: knownItems[item.id]?.first_seen || Date.now(),
180
- last_updated: Date.now()
181
- };
191
+ this.ctx.setInterval(async () => {
192
+ try {
193
+ this.cleanupExpiredCache();
194
+
195
+ logger.info('εΌ€ε§‹ζ£€ζŸ₯ζŠ˜ζ‰£ε•†ε“...');
196
+ const discountItems = await this.searchDiscountItems();
197
+ const knownItems = await this.loadJSON(this.DISCOUNT_ITEMS_FILE);
198
+ const newDiscountItems = [];
199
+
200
+ for (const item of discountItems) {
201
+ if (!this.isCached(item.id)) {
202
+ if (!knownItems[item.id] || knownItems[item.id].discount_rate !== item.discount_rate) {
203
+ newDiscountItems.push(item);
204
+ this.addToCache(item.id);
205
+ knownItems[item.id] = {
206
+ ...item,
207
+ first_seen: knownItems[item.id]?.first_seen || Date.now(),
208
+ last_updated: Date.now()
209
+ };
210
+ }
182
211
  }
183
212
  }
213
+
214
+ if (newDiscountItems.length > 0) {
215
+ logger.info(`ε‘ηŽ° ${newDiscountItems.length} δΈͺζ–°ηš„ζŠ˜ζ‰£ε•†ε“`);
216
+ await this.saveJSON(this.DISCOUNT_ITEMS_FILE, knownItems);
217
+ await this.notifyDiscountGroups(newDiscountItems);
218
+ } else {
219
+ logger.info('ζœͺε‘ηŽ°ζ–°ηš„ζŠ˜ζ‰£ε•†ε“');
220
+ }
221
+ } catch (error) {
222
+ logger.error('ζŠ˜ζ‰£ε•†ε“ζ£€ζŸ₯ε€±θ΄₯:', error);
184
223
  }
185
-
186
- if (newDiscountItems.length > 0) {
187
- logger.info(`ε‘ηŽ° ${newDiscountItems.length} δΈͺζ–°ηš„ζŠ˜ζ‰£ε•†ε“`);
188
- await this.saveJSON(this.DISCOUNT_ITEMS_FILE, knownItems);
189
- await this.notifyDiscountGroups(newDiscountItems);
190
- } else {
191
- logger.info('ζœͺε‘ηŽ°ζ–°ηš„ζŠ˜ζ‰£ε•†ε“');
192
- }
193
- } catch (error) {
194
- logger.error('ζŠ˜ζ‰£ε•†ε“ζ£€ζŸ₯ε€±θ΄₯:', error);
195
- }
196
- }, (this.config.discountCheckInterval || 60) * 60 * 1000);
197
- }
224
+ }, (this.config.discountCheckInterval || 60) * 60 * 1000);
225
+ }
226
+
198
227
  async addDiscountGroupSubscription(platform, channelId) {
199
228
  const groupKey = `group:${platform}:${channelId}`;
200
229
  const discountGroups = await this.loadJSON(this.DISCOUNT_GROUPS_FILE);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-booth-get",
3
3
  "description": "ι€šθΏ‡urlδΈŽεη§°ζ£€ζŸ₯ζ‘Šδ½η‰©ε“εΉΆει¦ˆη”¨ζˆ·ζœη΄’ηš„ε›Ύη‰‡",
4
- "version": "6.0.0-beta.1",
4
+ "version": "6.0.0-beta.2",
5
5
  "contributors": [
6
6
  "rixiang <1148147857@qq.com>"
7
7
  ],