refactor: unify group allowlist policy
This commit is contained in:
@@ -1045,6 +1045,57 @@ describe("web auto-reply", () => {
|
||||
resetLoadConfigMock();
|
||||
});
|
||||
|
||||
it("blocks group messages when whatsapp groups is set without a wildcard", async () => {
|
||||
const sendMedia = vi.fn();
|
||||
const reply = vi.fn().mockResolvedValue(undefined);
|
||||
const sendComposing = vi.fn();
|
||||
const resolver = vi.fn().mockResolvedValue({ text: "ok" });
|
||||
|
||||
setLoadConfigMock(() => ({
|
||||
whatsapp: {
|
||||
allowFrom: ["*"],
|
||||
groups: { "999@g.us": { requireMention: false } },
|
||||
},
|
||||
routing: { groupChat: { mentionPatterns: ["@clawd"] } },
|
||||
}));
|
||||
|
||||
let capturedOnMessage:
|
||||
| ((msg: import("./inbound.js").WebInboundMessage) => Promise<void>)
|
||||
| undefined;
|
||||
const listenerFactory = async (opts: {
|
||||
onMessage: (
|
||||
msg: import("./inbound.js").WebInboundMessage,
|
||||
) => Promise<void>;
|
||||
}) => {
|
||||
capturedOnMessage = opts.onMessage;
|
||||
return { close: vi.fn() };
|
||||
};
|
||||
|
||||
await monitorWebProvider(false, listenerFactory, false, resolver);
|
||||
expect(capturedOnMessage).toBeDefined();
|
||||
|
||||
await capturedOnMessage?.({
|
||||
body: "@clawd hello",
|
||||
from: "123@g.us",
|
||||
conversationId: "123@g.us",
|
||||
chatId: "123@g.us",
|
||||
chatType: "group",
|
||||
to: "+2",
|
||||
id: "g-allowlist-block",
|
||||
senderE164: "+111",
|
||||
senderName: "Alice",
|
||||
mentionedJids: ["999@s.whatsapp.net"],
|
||||
selfE164: "+999",
|
||||
selfJid: "999@s.whatsapp.net",
|
||||
sendComposing,
|
||||
reply,
|
||||
sendMedia,
|
||||
});
|
||||
|
||||
expect(resolver).not.toHaveBeenCalled();
|
||||
resetLoadConfigMock();
|
||||
});
|
||||
|
||||
it("honors per-group mention overrides when conversationId uses session key", async () => {
|
||||
const sendMedia = vi.fn();
|
||||
const reply = vi.fn().mockResolvedValue(undefined);
|
||||
|
||||
@@ -20,6 +20,10 @@ import { HEARTBEAT_TOKEN, SILENT_REPLY_TOKEN } from "../auto-reply/tokens.js";
|
||||
import type { ReplyPayload } from "../auto-reply/types.js";
|
||||
import { waitForever } from "../cli/wait.js";
|
||||
import { loadConfig } from "../config/config.js";
|
||||
import {
|
||||
resolveProviderGroupPolicy,
|
||||
resolveProviderGroupRequireMention,
|
||||
} from "../config/group-policy.js";
|
||||
import {
|
||||
DEFAULT_IDLE_MINUTES,
|
||||
loadSessionStore,
|
||||
@@ -850,16 +854,24 @@ export async function monitorWebProvider(
|
||||
Surface: "whatsapp",
|
||||
});
|
||||
|
||||
const resolveGroupPolicyFor = (conversationId: string) => {
|
||||
const groupId =
|
||||
resolveGroupResolution(conversationId)?.id ?? conversationId;
|
||||
return resolveProviderGroupPolicy({
|
||||
cfg,
|
||||
surface: "whatsapp",
|
||||
groupId,
|
||||
});
|
||||
};
|
||||
|
||||
const resolveGroupRequireMentionFor = (conversationId: string) => {
|
||||
const groupId =
|
||||
resolveGroupResolution(conversationId)?.id ?? conversationId;
|
||||
const groupConfig = cfg.whatsapp?.groups?.[groupId];
|
||||
if (typeof groupConfig?.requireMention === "boolean") {
|
||||
return groupConfig.requireMention;
|
||||
}
|
||||
const groupDefault = cfg.whatsapp?.groups?.["*"]?.requireMention;
|
||||
if (typeof groupDefault === "boolean") return groupDefault;
|
||||
return true;
|
||||
return resolveProviderGroupRequireMention({
|
||||
cfg,
|
||||
surface: "whatsapp",
|
||||
groupId,
|
||||
});
|
||||
};
|
||||
|
||||
const resolveGroupActivationFor = (conversationId: string) => {
|
||||
@@ -1275,6 +1287,13 @@ export async function monitorWebProvider(
|
||||
}
|
||||
|
||||
if (msg.chatType === "group") {
|
||||
const groupPolicy = resolveGroupPolicyFor(conversationId);
|
||||
if (groupPolicy.allowlistEnabled && !groupPolicy.allowed) {
|
||||
logVerbose(
|
||||
`Skipping group message ${conversationId} (not in allowlist)`,
|
||||
);
|
||||
return;
|
||||
}
|
||||
noteGroupMember(conversationId, msg.senderE164, msg.senderName);
|
||||
const commandBody = stripMentionsForCommand(msg.body, msg.selfE164);
|
||||
const activationCommand = parseActivationCommand(commandBody);
|
||||
|
||||
Reference in New Issue
Block a user