import {
normalizeAccountId,
resolveMergedAccountConfig,
} from "openclaw/plugin-sdk/account-resolution"; import type { OpenClawConfig } from "openclaw/plugin-sdk/core"; import { evaluateSenderGroupAccessForPolicy } from "openclaw/plugin-sdk/group-access"; import { normalizeOptionalLowercaseString } from "openclaw/plugin-sdk/text-runtime"; import type { AllowlistMatch, ChannelGroupContext } from "../runtime-api.js"; import { detectIdType } from "./targets.js"; import type { FeishuConfig } from "./types.js";
export type FeishuAllowlistMatch = AllowlistMatch<"wildcard" | "id">;
function stripRepeatedFeishuProviderPrefixes(raw: string): string {
let normalized = raw.trim(); while (FEISHU_PROVIDER_PREFIX_RE.test(normalized)) {
normalized = normalized.replace(FEISHU_PROVIDER_PREFIX_RE, "").trim();
} return normalized;
}
function canonicalizeFeishuAllowlistKey(params: { kind: "chat" | "user"; value: string }): string { const value = params.value.trim(); if (!value) { return"";
} // A typed wildcard (`chat:*`, `user:*`, `open_id:*`, `dm:*`, `group:*`, // `channel:*`) collapses to the bare wildcard so it keeps matching across // both kinds, preserving the prior `normalizeFeishuTarget`-based behavior. if (value === "*") { return"*";
} return `${params.kind}:${value}`;
}
function normalizeFeishuAllowEntry(raw: string): string { const trimmed = raw.trim(); if (!trimmed) { return"";
} if (trimmed === "*") { return"*";
}
const withoutProviderPrefix = stripRepeatedFeishuProviderPrefixes(trimmed); if (withoutProviderPrefix === "*") { return"*";
} const lowered = normalizeOptionalLowercaseString(withoutProviderPrefix) ?? ""; if (!lowered) { return"";
} // Lowercase for prefix detection only; preserve the original ID casing in the // canonicalized key. Sender candidates pass through this same path so allowlist // entries and runtime IDs stay normalized symmetrically. if (
lowered.startsWith("chat:") ||
lowered.startsWith("group:") ||
lowered.startsWith("channel:")
) { return canonicalizeFeishuAllowlistKey({
kind: "chat",
value: withoutProviderPrefix.slice(withoutProviderPrefix.indexOf(":") + 1),
});
} if (lowered.startsWith("user:") || lowered.startsWith("dm:")) { return canonicalizeFeishuAllowlistKey({
kind: "user",
value: withoutProviderPrefix.slice(withoutProviderPrefix.indexOf(":") + 1),
});
} if (lowered.startsWith("open_id:")) { return canonicalizeFeishuAllowlistKey({
kind: "user",
value: withoutProviderPrefix.slice(withoutProviderPrefix.indexOf(":") + 1),
});
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.