LINE: remove shared group mentions helper

This commit is contained in:
Gustavo Madeira Santana 2026-03-18 03:42:41 +00:00
parent f253f14b0b
commit 1aae93b1fa
No known key found for this signature in database
6 changed files with 82 additions and 239 deletions

View File

@ -19,6 +19,7 @@ import {
type LineChannelData,
type ResolvedLineAccount,
} from "../api.js";
import { resolveLineGroupRequireMention } from "./group-policy.js";
import { getLineRuntime } from "./runtime.js";
import { lineSetupAdapter } from "./setup-core.js";
import { lineSetupWizard } from "./setup-surface.js";
@ -127,18 +128,7 @@ export const linePlugin: ChannelPlugin<ResolvedLineAccount> = {
},
},
groups: {
resolveRequireMention: ({ cfg, accountId, groupId }) => {
const account = getLineRuntime().channel.line.resolveLineAccount({
cfg,
accountId: accountId ?? undefined,
});
const groups = account.config.groups;
if (!groups || !groupId) {
return false;
}
const groupConfig = groups[groupId] ?? groups["*"];
return groupConfig?.requireMention ?? false;
},
resolveRequireMention: resolveLineGroupRequireMention,
},
messaging: {
normalizeTarget: (target) => {

View File

@ -0,0 +1,57 @@
import { describe, expect, it } from "vitest";
import { resolveLineGroupRequireMention } from "./group-policy.js";
describe("line group policy", () => {
it("matches raw and prefixed LINE group keys for requireMention", () => {
const cfg = {
channels: {
line: {
groups: {
"room:r123": {
requireMention: false,
},
"group:g123": {
requireMention: false,
},
"*": {
requireMention: true,
},
},
},
},
// oxlint-disable-next-line typescript/no-explicit-any
} as any;
expect(resolveLineGroupRequireMention({ cfg, groupId: "r123" })).toBe(false);
expect(resolveLineGroupRequireMention({ cfg, groupId: "room:r123" })).toBe(false);
expect(resolveLineGroupRequireMention({ cfg, groupId: "g123" })).toBe(false);
expect(resolveLineGroupRequireMention({ cfg, groupId: "group:g123" })).toBe(false);
expect(resolveLineGroupRequireMention({ cfg, groupId: "other" })).toBe(true);
});
it("uses account-scoped prefixed LINE group config for requireMention", () => {
const cfg = {
channels: {
line: {
groups: {
"*": {
requireMention: true,
},
},
accounts: {
work: {
groups: {
"group:g123": {
requireMention: false,
},
},
},
},
},
},
// oxlint-disable-next-line typescript/no-explicit-any
} as any;
expect(resolveLineGroupRequireMention({ cfg, groupId: "g123", accountId: "work" })).toBe(false);
});
});

View File

@ -0,0 +1,22 @@
import { resolveChannelGroupRequireMention } from "openclaw/plugin-sdk/channel-policy";
import { resolveExactLineGroupConfigKey, type OpenClawConfig } from "openclaw/plugin-sdk/line-core";
type LineGroupContext = {
cfg: OpenClawConfig;
accountId?: string | null;
groupId?: string | null;
};
export function resolveLineGroupRequireMention(params: LineGroupContext): boolean {
const exactGroupId = resolveExactLineGroupConfigKey({
cfg: params.cfg,
accountId: params.accountId,
groupId: params.groupId,
});
return resolveChannelGroupRequireMention({
cfg: params.cfg,
channel: "line",
groupId: exactGroupId ?? params.groupId,
accountId: params.accountId,
});
}

View File

@ -1,109 +0,0 @@
import { describe, expect, it } from "vitest";
import {
resolveBlueBubblesGroupRequireMention,
resolveBlueBubblesGroupToolPolicy,
resolveLineGroupRequireMention,
resolveLineGroupToolPolicy,
} from "./group-mentions.js";
describe("group mentions (bluebubbles)", () => {
it("uses generic channel group policy helpers", () => {
const blueBubblesCfg = {
channels: {
bluebubbles: {
groups: {
"chat:primary": {
requireMention: false,
tools: { deny: ["exec"] },
},
"*": {
requireMention: true,
tools: { allow: ["message.send"] },
},
},
},
},
// oxlint-disable-next-line typescript/no-explicit-any
} as any;
expect(
resolveBlueBubblesGroupRequireMention({ cfg: blueBubblesCfg, groupId: "chat:primary" }),
).toBe(false);
expect(
resolveBlueBubblesGroupRequireMention({ cfg: blueBubblesCfg, groupId: "chat:other" }),
).toBe(true);
expect(
resolveBlueBubblesGroupToolPolicy({ cfg: blueBubblesCfg, groupId: "chat:primary" }),
).toEqual({ deny: ["exec"] });
expect(
resolveBlueBubblesGroupToolPolicy({ cfg: blueBubblesCfg, groupId: "chat:other" }),
).toEqual({
allow: ["message.send"],
});
});
});
describe("group mentions (line)", () => {
it("matches raw and prefixed LINE group keys for requireMention and tools", () => {
const lineCfg = {
channels: {
line: {
groups: {
"room:r123": {
requireMention: false,
tools: { allow: ["message.send"] },
},
"group:g123": {
requireMention: false,
tools: { deny: ["exec"] },
},
"*": {
requireMention: true,
},
},
},
},
// oxlint-disable-next-line typescript/no-explicit-any
} as any;
expect(resolveLineGroupRequireMention({ cfg: lineCfg, groupId: "r123" })).toBe(false);
expect(resolveLineGroupRequireMention({ cfg: lineCfg, groupId: "room:r123" })).toBe(false);
expect(resolveLineGroupRequireMention({ cfg: lineCfg, groupId: "g123" })).toBe(false);
expect(resolveLineGroupRequireMention({ cfg: lineCfg, groupId: "group:g123" })).toBe(false);
expect(resolveLineGroupRequireMention({ cfg: lineCfg, groupId: "other" })).toBe(true);
expect(resolveLineGroupToolPolicy({ cfg: lineCfg, groupId: "r123" })).toEqual({
allow: ["message.send"],
});
expect(resolveLineGroupToolPolicy({ cfg: lineCfg, groupId: "g123" })).toEqual({
deny: ["exec"],
});
});
it("uses account-scoped prefixed LINE group config for requireMention", () => {
const lineCfg = {
channels: {
line: {
groups: {
"*": {
requireMention: true,
},
},
accounts: {
work: {
groups: {
"group:g123": {
requireMention: false,
},
},
},
},
},
},
// oxlint-disable-next-line typescript/no-explicit-any
} as any;
expect(
resolveLineGroupRequireMention({ cfg: lineCfg, groupId: "g123", accountId: "work" }),
).toBe(false);
});
});

View File

@ -1,118 +0,0 @@
import {
resolveChannelGroupRequireMention,
resolveChannelGroupToolsPolicy,
} from "../../config/group-policy.js";
import type { GroupToolPolicyConfig } from "../../config/types.tools.js";
import { resolveExactLineGroupConfigKey } from "../../line/group-keys.js";
import type { ChannelGroupContext } from "./types.js";
type GroupMentionParams = ChannelGroupContext;
type ChannelGroupPolicyChannel =
| "telegram"
| "whatsapp"
| "imessage"
| "googlechat"
| "bluebubbles"
| "line";
function resolveChannelRequireMention(
params: GroupMentionParams,
channel: ChannelGroupPolicyChannel,
groupId: string | null | undefined = params.groupId,
): boolean {
return resolveChannelGroupRequireMention({
cfg: params.cfg,
channel,
groupId,
accountId: params.accountId,
});
}
function resolveChannelToolPolicyForSender(
params: GroupMentionParams,
channel: ChannelGroupPolicyChannel,
groupId: string | null | undefined = params.groupId,
): GroupToolPolicyConfig | undefined {
return resolveChannelGroupToolsPolicy({
cfg: params.cfg,
channel,
groupId,
accountId: params.accountId,
senderId: params.senderId,
senderName: params.senderName,
senderUsername: params.senderUsername,
senderE164: params.senderE164,
});
}
export function resolveWhatsAppGroupRequireMention(params: GroupMentionParams): boolean {
return resolveChannelRequireMention(params, "whatsapp");
}
export function resolveIMessageGroupRequireMention(params: GroupMentionParams): boolean {
return resolveChannelRequireMention(params, "imessage");
}
export function resolveGoogleChatGroupRequireMention(params: GroupMentionParams): boolean {
return resolveChannelRequireMention(params, "googlechat");
}
export function resolveGoogleChatGroupToolPolicy(
params: GroupMentionParams,
): GroupToolPolicyConfig | undefined {
return resolveChannelToolPolicyForSender(params, "googlechat");
}
export function resolveBlueBubblesGroupRequireMention(params: GroupMentionParams): boolean {
return resolveChannelRequireMention(params, "bluebubbles");
}
export function resolveWhatsAppGroupToolPolicy(
params: GroupMentionParams,
): GroupToolPolicyConfig | undefined {
return resolveChannelToolPolicyForSender(params, "whatsapp");
}
export function resolveIMessageGroupToolPolicy(
params: GroupMentionParams,
): GroupToolPolicyConfig | undefined {
return resolveChannelToolPolicyForSender(params, "imessage");
}
export function resolveBlueBubblesGroupToolPolicy(
params: GroupMentionParams,
): GroupToolPolicyConfig | undefined {
return resolveChannelToolPolicyForSender(params, "bluebubbles");
}
export function resolveLineGroupRequireMention(params: GroupMentionParams): boolean {
const exactGroupId = resolveExactLineGroupConfigKey({
cfg: params.cfg,
accountId: params.accountId,
groupId: params.groupId,
});
if (exactGroupId) {
return resolveChannelGroupRequireMention({
cfg: params.cfg,
channel: "line",
groupId: exactGroupId,
accountId: params.accountId,
});
}
return resolveChannelRequireMention(params, "line");
}
export function resolveLineGroupToolPolicy(
params: GroupMentionParams,
): GroupToolPolicyConfig | undefined {
const exactGroupId = resolveExactLineGroupConfigKey({
cfg: params.cfg,
accountId: params.accountId,
groupId: params.groupId,
});
if (exactGroupId) {
return resolveChannelToolPolicyForSender(params, "line", exactGroupId);
}
return resolveChannelToolPolicyForSender(params, "line");
}

View File

@ -15,5 +15,6 @@ export {
resolveDefaultLineAccountId,
resolveLineAccount,
} from "../line/accounts.js";
export { resolveExactLineGroupConfigKey } from "../line/group-keys.js";
export type { ResolvedLineAccount } from "../line/types.js";
export { LineConfigSchema } from "../line/config-schema.js";