112 lines
3.5 KiB
TypeScript
112 lines
3.5 KiB
TypeScript
import {
|
|
resolveToolsBySender,
|
|
type GroupToolPolicyBySenderConfig,
|
|
type GroupToolPolicyConfig,
|
|
} from "openclaw/plugin-sdk/channel-policy";
|
|
import { type ChannelGroupContext } from "openclaw/plugin-sdk/channel-runtime";
|
|
import { normalizeAtHashSlug } from "openclaw/plugin-sdk/core";
|
|
import type { DiscordConfig } from "./runtime-api.js";
|
|
|
|
function normalizeDiscordSlug(value?: string | null) {
|
|
return normalizeAtHashSlug(value);
|
|
}
|
|
|
|
type SenderScopedToolsEntry = {
|
|
tools?: GroupToolPolicyConfig;
|
|
toolsBySender?: GroupToolPolicyBySenderConfig;
|
|
requireMention?: boolean;
|
|
};
|
|
|
|
function resolveDiscordGuildEntry(guilds: DiscordConfig["guilds"], groupSpace?: string | null) {
|
|
if (!guilds || Object.keys(guilds).length === 0) {
|
|
return null;
|
|
}
|
|
const space = groupSpace?.trim() ?? "";
|
|
if (space && guilds[space]) {
|
|
return guilds[space];
|
|
}
|
|
const normalized = normalizeDiscordSlug(space);
|
|
if (normalized && guilds[normalized]) {
|
|
return guilds[normalized];
|
|
}
|
|
if (normalized) {
|
|
const match = Object.values(guilds).find(
|
|
(entry) => normalizeDiscordSlug(entry?.slug ?? undefined) === normalized,
|
|
);
|
|
if (match) {
|
|
return match;
|
|
}
|
|
}
|
|
return guilds["*"] ?? null;
|
|
}
|
|
|
|
function resolveDiscordChannelEntry<TEntry extends SenderScopedToolsEntry>(
|
|
channelEntries: Record<string, TEntry> | undefined,
|
|
params: { groupId?: string | null; groupChannel?: string | null },
|
|
): TEntry | undefined {
|
|
if (!channelEntries || Object.keys(channelEntries).length === 0) {
|
|
return undefined;
|
|
}
|
|
const groupChannel = params.groupChannel;
|
|
const channelSlug = normalizeDiscordSlug(groupChannel);
|
|
return (
|
|
(params.groupId ? channelEntries[params.groupId] : undefined) ??
|
|
(channelSlug
|
|
? (channelEntries[channelSlug] ?? channelEntries[`#${channelSlug}`])
|
|
: undefined) ??
|
|
(groupChannel ? channelEntries[normalizeDiscordSlug(groupChannel)] : undefined)
|
|
);
|
|
}
|
|
|
|
function resolveSenderToolsEntry(
|
|
entry: SenderScopedToolsEntry | undefined | null,
|
|
params: ChannelGroupContext,
|
|
): GroupToolPolicyConfig | undefined {
|
|
if (!entry) {
|
|
return undefined;
|
|
}
|
|
const senderPolicy = resolveToolsBySender({
|
|
toolsBySender: entry.toolsBySender,
|
|
senderId: params.senderId,
|
|
senderName: params.senderName,
|
|
senderUsername: params.senderUsername,
|
|
senderE164: params.senderE164,
|
|
});
|
|
return senderPolicy ?? entry.tools;
|
|
}
|
|
|
|
function resolveDiscordPolicyContext(params: ChannelGroupContext) {
|
|
const guildEntry = resolveDiscordGuildEntry(
|
|
params.cfg.channels?.discord?.guilds,
|
|
params.groupSpace,
|
|
);
|
|
const channelEntries = guildEntry?.channels;
|
|
const channelEntry =
|
|
channelEntries && Object.keys(channelEntries).length > 0
|
|
? resolveDiscordChannelEntry(channelEntries, params)
|
|
: undefined;
|
|
return { guildEntry, channelEntry };
|
|
}
|
|
|
|
export function resolveDiscordGroupRequireMention(params: ChannelGroupContext): boolean {
|
|
const context = resolveDiscordPolicyContext(params);
|
|
if (typeof context.channelEntry?.requireMention === "boolean") {
|
|
return context.channelEntry.requireMention;
|
|
}
|
|
if (typeof context.guildEntry?.requireMention === "boolean") {
|
|
return context.guildEntry.requireMention;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
export function resolveDiscordGroupToolPolicy(
|
|
params: ChannelGroupContext,
|
|
): GroupToolPolicyConfig | undefined {
|
|
const context = resolveDiscordPolicyContext(params);
|
|
const channelPolicy = resolveSenderToolsEntry(context.channelEntry, params);
|
|
if (channelPolicy) {
|
|
return channelPolicy;
|
|
}
|
|
return resolveSenderToolsEntry(context.guildEntry, params);
|
|
}
|