fix: treat reply-to-bot as implicit mention across channels
This commit is contained in:
55
src/web/auto-reply/monitor/group-gating.test.ts
Normal file
55
src/web/auto-reply/monitor/group-gating.test.ts
Normal file
@@ -0,0 +1,55 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { applyGroupGating } from "./group-gating.js";
|
||||
|
||||
const baseConfig = {
|
||||
channels: {
|
||||
whatsapp: {
|
||||
groupPolicy: "open",
|
||||
groups: { "*": { requireMention: true } },
|
||||
},
|
||||
},
|
||||
session: { store: "/tmp/clawdbot-sessions.json" },
|
||||
} as const;
|
||||
|
||||
describe("applyGroupGating", () => {
|
||||
it("treats reply-to-bot as implicit mention", () => {
|
||||
const groupHistories = new Map();
|
||||
const result = applyGroupGating({
|
||||
cfg: baseConfig as unknown as ReturnType<typeof import("../../../config/config.js").loadConfig>,
|
||||
msg: {
|
||||
id: "m1",
|
||||
from: "123@g.us",
|
||||
conversationId: "123@g.us",
|
||||
to: "+15550000",
|
||||
accountId: "default",
|
||||
body: "following up",
|
||||
timestamp: Date.now(),
|
||||
chatType: "group",
|
||||
chatId: "123@g.us",
|
||||
selfJid: "15551234567@s.whatsapp.net",
|
||||
selfE164: "+15551234567",
|
||||
replyToId: "m0",
|
||||
replyToBody: "bot said hi",
|
||||
replyToSender: "+15551234567",
|
||||
replyToSenderJid: "15551234567@s.whatsapp.net",
|
||||
replyToSenderE164: "+15551234567",
|
||||
sendComposing: async () => {},
|
||||
reply: async () => {},
|
||||
sendMedia: async () => {},
|
||||
},
|
||||
conversationId: "123@g.us",
|
||||
groupHistoryKey: "group:123@g.us",
|
||||
agentId: "main",
|
||||
sessionKey: "agent:main:whatsapp:group:123@g.us",
|
||||
baseMentionConfig: { mentionRegexes: [] },
|
||||
groupHistories,
|
||||
groupHistoryLimit: 10,
|
||||
groupMemberNames: new Map(),
|
||||
logVerbose: () => {},
|
||||
replyLogger: { debug: () => {} },
|
||||
});
|
||||
|
||||
expect(result.shouldProcess).toBe(true);
|
||||
});
|
||||
});
|
||||
@@ -2,6 +2,7 @@ import { hasControlCommand } from "../../../auto-reply/command-detection.js";
|
||||
import { parseActivationCommand } from "../../../auto-reply/group-activation.js";
|
||||
import type { loadConfig } from "../../../config/config.js";
|
||||
import { normalizeE164 } from "../../../utils.js";
|
||||
import { resolveMentionGating } from "../../../channels/mention-gating.js";
|
||||
import type { MentionConfig } from "../mentions.js";
|
||||
import { buildMentionConfig, debugMention, resolveOwnerList } from "../mentions.js";
|
||||
import type { WebInboundMsg } from "../types.js";
|
||||
@@ -94,7 +95,6 @@ export function applyGroupGating(params: {
|
||||
"group mention debug",
|
||||
);
|
||||
const wasMentioned = mentionDebug.wasMentioned;
|
||||
params.msg.wasMentioned = wasMentioned;
|
||||
const activation = resolveGroupActivationFor({
|
||||
cfg: params.cfg,
|
||||
agentId: params.agentId,
|
||||
@@ -102,7 +102,25 @@ export function applyGroupGating(params: {
|
||||
conversationId: params.conversationId,
|
||||
});
|
||||
const requireMention = activation !== "always";
|
||||
if (!shouldBypassMention && requireMention && !wasMentioned) {
|
||||
const selfJid = params.msg.selfJid?.replace(/:\\d+/, "");
|
||||
const replySenderJid = params.msg.replyToSenderJid?.replace(/:\\d+/, "");
|
||||
const selfE164 = params.msg.selfE164 ? normalizeE164(params.msg.selfE164) : null;
|
||||
const replySenderE164 = params.msg.replyToSenderE164
|
||||
? normalizeE164(params.msg.replyToSenderE164)
|
||||
: null;
|
||||
const implicitMention = Boolean(
|
||||
(selfJid && replySenderJid && selfJid === replySenderJid) ||
|
||||
(selfE164 && replySenderE164 && selfE164 === replySenderE164),
|
||||
);
|
||||
const mentionGate = resolveMentionGating({
|
||||
requireMention,
|
||||
canDetectMention: true,
|
||||
wasMentioned,
|
||||
implicitMention,
|
||||
shouldBypassMention,
|
||||
});
|
||||
params.msg.wasMentioned = mentionGate.effectiveWasMentioned;
|
||||
if (!shouldBypassMention && requireMention && mentionGate.shouldSkip) {
|
||||
params.logVerbose(
|
||||
`Group message stored for context (no mention detected) in ${params.conversationId}: ${params.msg.body}`,
|
||||
);
|
||||
|
||||
@@ -238,6 +238,8 @@ export function describeReplyContext(rawMessage: proto.IMessage | undefined): {
|
||||
id?: string;
|
||||
body: string;
|
||||
sender: string;
|
||||
senderJid?: string;
|
||||
senderE164?: string;
|
||||
} | null {
|
||||
const message = unwrapMessage(rawMessage);
|
||||
if (!message) return null;
|
||||
@@ -265,5 +267,7 @@ export function describeReplyContext(rawMessage: proto.IMessage | undefined): {
|
||||
id: contextInfo?.stanzaId ? String(contextInfo.stanzaId) : undefined,
|
||||
body,
|
||||
sender,
|
||||
senderJid,
|
||||
senderE164,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -284,6 +284,8 @@ export async function monitorWebInbox(options: {
|
||||
replyToId: replyContext?.id,
|
||||
replyToBody: replyContext?.body,
|
||||
replyToSender: replyContext?.sender,
|
||||
replyToSenderJid: replyContext?.senderJid,
|
||||
replyToSenderE164: replyContext?.senderE164,
|
||||
groupSubject,
|
||||
groupParticipants,
|
||||
mentionedJids: mentionedJids ?? undefined,
|
||||
|
||||
@@ -24,6 +24,8 @@ export type WebInboundMessage = {
|
||||
replyToId?: string;
|
||||
replyToBody?: string;
|
||||
replyToSender?: string;
|
||||
replyToSenderJid?: string;
|
||||
replyToSenderE164?: string;
|
||||
groupSubject?: string;
|
||||
groupParticipants?: string[];
|
||||
mentionedJids?: string[];
|
||||
|
||||
Reference in New Issue
Block a user