fix: dedupe inbound messages across providers
This commit is contained in:
52
src/auto-reply/reply/inbound-dedupe.ts
Normal file
52
src/auto-reply/reply/inbound-dedupe.ts
Normal file
@@ -0,0 +1,52 @@
|
||||
import { logVerbose, shouldLogVerbose } from "../../globals.js";
|
||||
import { createDedupeCache, type DedupeCache } from "../../infra/dedupe.js";
|
||||
import type { MsgContext } from "../templating.js";
|
||||
|
||||
const DEFAULT_INBOUND_DEDUPE_TTL_MS = 20 * 60_000;
|
||||
const DEFAULT_INBOUND_DEDUPE_MAX = 5000;
|
||||
|
||||
const inboundDedupeCache = createDedupeCache({
|
||||
ttlMs: DEFAULT_INBOUND_DEDUPE_TTL_MS,
|
||||
maxSize: DEFAULT_INBOUND_DEDUPE_MAX,
|
||||
});
|
||||
|
||||
const normalizeProvider = (value?: string | null) =>
|
||||
value?.trim().toLowerCase() || "";
|
||||
|
||||
const resolveInboundPeerId = (ctx: MsgContext) =>
|
||||
ctx.OriginatingTo ?? ctx.To ?? ctx.From ?? ctx.SessionKey;
|
||||
|
||||
export function buildInboundDedupeKey(ctx: MsgContext): string | null {
|
||||
const provider = normalizeProvider(
|
||||
ctx.OriginatingChannel ?? ctx.Provider ?? ctx.Surface,
|
||||
);
|
||||
const messageId = ctx.MessageSid?.trim();
|
||||
if (!provider || !messageId) return null;
|
||||
const peerId = resolveInboundPeerId(ctx);
|
||||
if (!peerId) return null;
|
||||
const sessionKey = ctx.SessionKey?.trim() ?? "";
|
||||
const accountId = ctx.AccountId?.trim() ?? "";
|
||||
const threadId =
|
||||
typeof ctx.MessageThreadId === "number" ? String(ctx.MessageThreadId) : "";
|
||||
return [provider, accountId, sessionKey, peerId, threadId, messageId]
|
||||
.filter(Boolean)
|
||||
.join("|");
|
||||
}
|
||||
|
||||
export function shouldSkipDuplicateInbound(
|
||||
ctx: MsgContext,
|
||||
opts?: { cache?: DedupeCache; now?: number },
|
||||
): boolean {
|
||||
const key = buildInboundDedupeKey(ctx);
|
||||
if (!key) return false;
|
||||
const cache = opts?.cache ?? inboundDedupeCache;
|
||||
const skipped = cache.check(key, opts?.now);
|
||||
if (skipped && shouldLogVerbose()) {
|
||||
logVerbose(`inbound dedupe: skipped ${key}`);
|
||||
}
|
||||
return skipped;
|
||||
}
|
||||
|
||||
export function resetInboundDedupe(): void {
|
||||
inboundDedupeCache.clear();
|
||||
}
|
||||
Reference in New Issue
Block a user