mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-18 05:27:28 +00:00
fix(feishu): honor wildcard group config for reply policy (#29456)
## Summary - honor Feishu wildcard group policy fallback via `channels.feishu.groups["*"]` when no explicit group entry matches - keep exact and case-insensitive explicit group matches higher precedence than wildcard fallback - add changelog credit and TypeScript-safe test assertions ## Verification - pnpm install --frozen-lockfile - pnpm build - pnpm check - pnpm test:macmini Co-authored-by: Wayne Pika <262095977+WaynePika@users.noreply.github.com> Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
This commit is contained in:
@@ -32,6 +32,7 @@ Docs: https://docs.openclaw.ai
|
||||
- Feishu/Inbound rich-text parsing: preserve `share_chat` payload summaries when available and add explicit parsing for rich-text `code`/`code_block`/`pre` tags so forwarded and code-heavy messages keep useful context in agent input. (#28591) Thanks @kevinWangSheng.
|
||||
- Feishu/Local media sends: propagate `mediaLocalRoots` through Feishu outbound media sending into `loadWebMedia` so local path attachments work with post-CVE local-root enforcement. (#27884) Thanks @joelnishanth.
|
||||
- Feishu/Group sender allowlist fallback: add global `channels.feishu.groupSenderAllowFrom` sender authorization for group chats, with per-group `groups.<id>.allowFrom` precedence and regression coverage for allow/block/precedence behavior. (#29174) Thanks @1MoreBuild.
|
||||
- Feishu/Group wildcard policy fallback: honor `channels.feishu.groups["*"]` when no explicit group match exists so unmatched groups inherit wildcard reply-policy settings instead of falling back to global defaults. (#29456) Thanks @WaynePika.
|
||||
- Feishu/Docx append/write ordering: insert converted Docx blocks sequentially (single-block creates) so Feishu append/write preserves markdown block order instead of returning shuffled sections in asynchronous batch inserts. (#26172, #26022) Thanks @echoVic.
|
||||
- Feishu/Docx convert fallback chunking: recursively split oversized markdown chunks (including long no-heading sections) when `document.convert` hits content limits, while keeping fenced-code-aware split boundaries whenever possible. (#14402) Thanks @lml2468.
|
||||
- Feishu/Inbound media regression coverage: add explicit tests for message resource type mapping (`image` stays `image`, non-image maps to `file`) to prevent reintroducing unsupported Feishu `type=audio` fetches. (#16311, #8746) Thanks @Yaxuan42.
|
||||
|
||||
@@ -1,7 +1,62 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { isFeishuGroupAllowed, resolveFeishuAllowlistMatch } from "./policy.js";
|
||||
import {
|
||||
isFeishuGroupAllowed,
|
||||
resolveFeishuAllowlistMatch,
|
||||
resolveFeishuGroupConfig,
|
||||
} from "./policy.js";
|
||||
import type { FeishuConfig } from "./types.js";
|
||||
|
||||
describe("feishu policy", () => {
|
||||
describe("resolveFeishuGroupConfig", () => {
|
||||
it("falls back to wildcard group config when direct match is missing", () => {
|
||||
const cfg = {
|
||||
groups: {
|
||||
"*": { requireMention: false },
|
||||
"oc-explicit": { requireMention: true },
|
||||
},
|
||||
} as unknown as FeishuConfig;
|
||||
|
||||
const resolved = resolveFeishuGroupConfig({
|
||||
cfg,
|
||||
groupId: "oc-missing",
|
||||
});
|
||||
|
||||
expect(resolved).toEqual({ requireMention: false });
|
||||
});
|
||||
|
||||
it("prefers exact group config over wildcard", () => {
|
||||
const cfg = {
|
||||
groups: {
|
||||
"*": { requireMention: false },
|
||||
"oc-explicit": { requireMention: true },
|
||||
},
|
||||
} as unknown as FeishuConfig;
|
||||
|
||||
const resolved = resolveFeishuGroupConfig({
|
||||
cfg,
|
||||
groupId: "oc-explicit",
|
||||
});
|
||||
|
||||
expect(resolved).toEqual({ requireMention: true });
|
||||
});
|
||||
|
||||
it("keeps case-insensitive matching for explicit group ids", () => {
|
||||
const cfg = {
|
||||
groups: {
|
||||
"*": { requireMention: false },
|
||||
OC_UPPER: { requireMention: true },
|
||||
},
|
||||
} as unknown as FeishuConfig;
|
||||
|
||||
const resolved = resolveFeishuGroupConfig({
|
||||
cfg,
|
||||
groupId: "oc_upper",
|
||||
});
|
||||
|
||||
expect(resolved).toEqual({ requireMention: true });
|
||||
});
|
||||
});
|
||||
|
||||
describe("resolveFeishuAllowlistMatch", () => {
|
||||
it("allows wildcard", () => {
|
||||
expect(
|
||||
|
||||
@@ -56,6 +56,7 @@ export function resolveFeishuGroupConfig(params: {
|
||||
groupId?: string | null;
|
||||
}): FeishuGroupConfig | undefined {
|
||||
const groups = params.cfg?.groups ?? {};
|
||||
const wildcard = groups["*"];
|
||||
const groupId = params.groupId?.trim();
|
||||
if (!groupId) {
|
||||
return undefined;
|
||||
@@ -68,7 +69,10 @@ export function resolveFeishuGroupConfig(params: {
|
||||
|
||||
const lowered = groupId.toLowerCase();
|
||||
const matchKey = Object.keys(groups).find((key) => key.toLowerCase() === lowered);
|
||||
return matchKey ? groups[matchKey] : undefined;
|
||||
if (matchKey) {
|
||||
return groups[matchKey];
|
||||
}
|
||||
return wildcard;
|
||||
}
|
||||
|
||||
export function resolveFeishuGroupToolPolicy(
|
||||
|
||||
Reference in New Issue
Block a user