@gonzih/cc-discord 0.2.23 → 0.2.24
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/notifier.js +22 -15
- package/package.json +1 -1
package/dist/notifier.js
CHANGED
|
@@ -101,6 +101,9 @@ function shortenModelName(model, driver) {
|
|
|
101
101
|
* Appends " cost: $X.XXX" if a numeric cost field is present.
|
|
102
102
|
*/
|
|
103
103
|
export function parseNotification(raw) {
|
|
104
|
+
// Filter cron-fire noise before any parsing — catches plain-text and JSON-wrapped ⏰ cron notifications
|
|
105
|
+
if (raw.startsWith("⏰") || raw.includes('"⏰'))
|
|
106
|
+
return null;
|
|
104
107
|
let text = raw;
|
|
105
108
|
let driver;
|
|
106
109
|
let model;
|
|
@@ -127,10 +130,8 @@ export function parseNotification(raw) {
|
|
|
127
130
|
isCron = parsed.is_cron;
|
|
128
131
|
}
|
|
129
132
|
catch {
|
|
130
|
-
// non-JSON: fall through
|
|
133
|
+
// non-JSON: fall through
|
|
131
134
|
}
|
|
132
|
-
if (text.startsWith("⏰"))
|
|
133
|
-
return null;
|
|
134
135
|
// Parse eval_report if present — this field is non-standard and not in NotificationPayload type
|
|
135
136
|
const evalReport = parseEvalReport(raw);
|
|
136
137
|
if (!driver)
|
|
@@ -356,23 +357,24 @@ export function startNotifier(bot, notifyChannelId, namespace, redis, handleUser
|
|
|
356
357
|
const notification = parseNotification(raw);
|
|
357
358
|
if (notification === null)
|
|
358
359
|
continue; // routing excludes discord
|
|
359
|
-
// Dedup: skip if this notification was already forwarded recently
|
|
360
|
-
//
|
|
360
|
+
// Dedup: skip if this notification was already forwarded recently.
|
|
361
|
+
// Check in-memory first (catches pub/sub-delivered notifications in the same process).
|
|
362
|
+
if (checkAndMarkSentSync(ns, raw)) {
|
|
363
|
+
log("info", `dedup: skipping already-sent notification (ns=${ns})`);
|
|
364
|
+
continue;
|
|
365
|
+
}
|
|
366
|
+
// Also check Redis for cross-restart/cross-process dedup.
|
|
361
367
|
let isDup = false;
|
|
362
368
|
try {
|
|
363
369
|
if (typeof redis.sadd === "function") {
|
|
364
370
|
isDup = await checkAndMarkSent(redis, ns, raw);
|
|
365
371
|
}
|
|
366
|
-
else {
|
|
367
|
-
isDup = checkAndMarkSentSync(ns, raw);
|
|
368
|
-
}
|
|
369
372
|
}
|
|
370
373
|
catch (err) {
|
|
371
|
-
log("warn", `dedup check failed (ns=${ns})
|
|
372
|
-
isDup = checkAndMarkSentSync(ns, raw);
|
|
374
|
+
log("warn", `dedup Redis check failed (ns=${ns}):`, err.message);
|
|
373
375
|
}
|
|
374
376
|
if (isDup) {
|
|
375
|
-
log("info", `dedup: skipping already-sent notification (ns=${ns})`);
|
|
377
|
+
log("info", `dedup: skipping already-sent notification (ns=${ns}) [redis]`);
|
|
376
378
|
continue;
|
|
377
379
|
}
|
|
378
380
|
// Primary namespace: honour chatId-based per-channel routing via reverseSnowflakeLookup,
|
|
@@ -436,6 +438,8 @@ export function startNotifier(bot, notifyChannelId, namespace, redis, handleUser
|
|
|
436
438
|
log("info", `dedup: skipping already-sent pub/sub notification (ns=${ns})`);
|
|
437
439
|
return;
|
|
438
440
|
}
|
|
441
|
+
// Also mark in Redis so list-poller dedup sees it (prevents cross-path duplicates)
|
|
442
|
+
checkAndMarkSent(redis, ns, message).catch(() => { });
|
|
439
443
|
let mainChannelId;
|
|
440
444
|
if (isPrimary) {
|
|
441
445
|
mainChannelId = resolveNotifyChannel(notification.chatId, notifyChannelId, getActiveChannelId, reverseSnowflakeLookup, ns, getChannelIdForNamespace);
|
|
@@ -483,10 +487,13 @@ export function startNotifier(bot, notifyChannelId, namespace, redis, handleUser
|
|
|
483
487
|
? (notifyChannelId ?? getActiveChannelId?.())
|
|
484
488
|
: routedChannelIds.get(ns);
|
|
485
489
|
if (targetChannelId !== undefined) {
|
|
486
|
-
// Echo to Discord so the user sees UI messages
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
+
// Echo to Discord so the user sees UI messages (suppress cron-fire noise)
|
|
491
|
+
const isCronMessage = content.startsWith("⏰") || content.includes("[cron]");
|
|
492
|
+
if (!isCronMessage) {
|
|
493
|
+
bot.sendToChannelById(targetChannelId, `[from UI]: ${content}`).catch((err) => {
|
|
494
|
+
log("warn", `sendToChannelById (UI echo) failed (ns=${ns}):`, err.message);
|
|
495
|
+
});
|
|
496
|
+
}
|
|
490
497
|
// Log the incoming message
|
|
491
498
|
const inMsg = {
|
|
492
499
|
id: crypto.randomUUID(),
|