refactor: reuse ack reaction helper for whatsapp

This commit is contained in:
Peter Steinberger
2026-01-23 22:20:28 +00:00
parent 02bd6e4a24
commit 892197c43e
4 changed files with 141 additions and 23 deletions

View File

@@ -1,6 +1,6 @@
import { describe, expect, it } from "vitest";
import { shouldAckReaction } from "./ack-reactions.js";
import { shouldAckReaction, shouldAckReactionForWhatsApp } from "./ack-reactions.js";
describe("shouldAckReaction", () => {
it("honors direct and group-all scopes", () => {
@@ -132,3 +132,93 @@ describe("shouldAckReaction", () => {
).toBe(true);
});
});
describe("shouldAckReactionForWhatsApp", () => {
it("respects direct and group modes", () => {
expect(
shouldAckReactionForWhatsApp({
emoji: "👀",
isDirect: true,
isGroup: false,
directEnabled: true,
groupMode: "mentions",
wasMentioned: false,
groupActivated: false,
}),
).toBe(true);
expect(
shouldAckReactionForWhatsApp({
emoji: "👀",
isDirect: true,
isGroup: false,
directEnabled: false,
groupMode: "mentions",
wasMentioned: false,
groupActivated: false,
}),
).toBe(false);
expect(
shouldAckReactionForWhatsApp({
emoji: "👀",
isDirect: false,
isGroup: true,
directEnabled: true,
groupMode: "always",
wasMentioned: false,
groupActivated: false,
}),
).toBe(true);
expect(
shouldAckReactionForWhatsApp({
emoji: "👀",
isDirect: false,
isGroup: true,
directEnabled: true,
groupMode: "never",
wasMentioned: true,
groupActivated: true,
}),
).toBe(false);
});
it("honors mentions or activation for group-mentions", () => {
expect(
shouldAckReactionForWhatsApp({
emoji: "👀",
isDirect: false,
isGroup: true,
directEnabled: true,
groupMode: "mentions",
wasMentioned: true,
groupActivated: false,
}),
).toBe(true);
expect(
shouldAckReactionForWhatsApp({
emoji: "👀",
isDirect: false,
isGroup: true,
directEnabled: true,
groupMode: "mentions",
wasMentioned: false,
groupActivated: true,
}),
).toBe(true);
expect(
shouldAckReactionForWhatsApp({
emoji: "👀",
isDirect: false,
isGroup: true,
directEnabled: true,
groupMode: "mentions",
wasMentioned: false,
groupActivated: false,
}),
).toBe(false);
});
});

View File

@@ -1,5 +1,7 @@
export type AckReactionScope = "all" | "direct" | "group-all" | "group-mentions" | "off" | "none";
export type WhatsAppAckReactionMode = "always" | "mentions" | "never";
export type AckReactionGateParams = {
scope: AckReactionScope | undefined;
isDirect: boolean;
@@ -25,3 +27,29 @@ export function shouldAckReaction(params: AckReactionGateParams): boolean {
}
return false;
}
export function shouldAckReactionForWhatsApp(params: {
emoji: string;
isDirect: boolean;
isGroup: boolean;
directEnabled: boolean;
groupMode: WhatsAppAckReactionMode;
wasMentioned: boolean;
groupActivated: boolean;
}): boolean {
if (!params.emoji) return false;
if (params.isDirect) return params.directEnabled;
if (!params.isGroup) return false;
if (params.groupMode === "never") return false;
if (params.groupMode === "always") return true;
return shouldAckReaction({
scope: "group-mentions",
isDirect: false,
isGroup: true,
isMentionableGroup: true,
requireMention: true,
canDetectMention: true,
effectiveWasMentioned: params.wasMentioned,
shouldBypassMention: params.groupActivated,
});
}

View File

@@ -117,8 +117,12 @@ export {
resolveMentionGating,
resolveMentionGatingWithBypass,
} from "../channels/mention-gating.js";
export type { AckReactionGateParams, AckReactionScope } from "../channels/ack-reactions.js";
export { shouldAckReaction } from "../channels/ack-reactions.js";
export type {
AckReactionGateParams,
AckReactionScope,
WhatsAppAckReactionMode,
} from "../channels/ack-reactions.js";
export { shouldAckReaction, shouldAckReactionForWhatsApp } from "../channels/ack-reactions.js";
export { resolveChannelMediaMaxBytes } from "../channels/plugins/media-limits.js";
export type { NormalizedLocation } from "../channels/location.js";
export { formatLocationText, toLocationContext } from "../channels/location.js";

View File

@@ -1,5 +1,6 @@
import type { loadConfig } from "../../../config/config.js";
import { logVerbose } from "../../../globals.js";
import { shouldAckReactionForWhatsApp } from "../../../channels/ack-reactions.js";
import { sendReactionWhatsApp } from "../../outbound.js";
import { formatError } from "../../session.js";
import type { WebInboundMsg } from "../types.js";
@@ -24,30 +25,25 @@ export function maybeSendAckReaction(params: {
const groupMode = ackConfig?.group ?? "mentions";
const conversationIdForCheck = params.msg.conversationId ?? params.msg.from;
const shouldSendReaction = () => {
if (!emoji) return false;
if (params.msg.chatType === "direct") {
return directEnabled;
}
if (params.msg.chatType === "group") {
if (groupMode === "never") return false;
if (groupMode === "always") return true;
if (groupMode === "mentions") {
const activation = resolveGroupActivationFor({
const activation =
params.msg.chatType === "group"
? resolveGroupActivationFor({
cfg: params.cfg,
agentId: params.agentId,
sessionKey: params.sessionKey,
conversationId: conversationIdForCheck,
});
if (activation === "always") return true;
return params.msg.wasMentioned === true;
}
}
return false;
};
})
: null;
const shouldSendReaction = () =>
shouldAckReactionForWhatsApp({
emoji,
isDirect: params.msg.chatType === "direct",
isGroup: params.msg.chatType === "group",
directEnabled,
groupMode,
wasMentioned: params.msg.wasMentioned === true,
groupActivated: activation === "always",
});
if (!shouldSendReaction()) return;