openclaw/src/channels/targets.ts
2026-02-17 00:32:34 +00:00

101 lines
2.5 KiB
TypeScript

export type { DirectoryConfigParams } from "./plugins/directory-config.js";
export type { ChannelDirectoryEntry } from "./plugins/types.js";
export type MessagingTargetKind = "user" | "channel";
export type MessagingTarget = {
kind: MessagingTargetKind;
id: string;
raw: string;
normalized: string;
};
export type MessagingTargetParseOptions = {
defaultKind?: MessagingTargetKind;
ambiguousMessage?: string;
};
export function normalizeTargetId(kind: MessagingTargetKind, id: string): string {
return `${kind}:${id}`.toLowerCase();
}
export function buildMessagingTarget(
kind: MessagingTargetKind,
id: string,
raw: string,
): MessagingTarget {
return {
kind,
id,
raw,
normalized: normalizeTargetId(kind, id),
};
}
export function ensureTargetId(params: {
candidate: string;
pattern: RegExp;
errorMessage: string;
}): string {
if (!params.pattern.test(params.candidate)) {
throw new Error(params.errorMessage);
}
return params.candidate;
}
export function parseTargetMention(params: {
raw: string;
mentionPattern: RegExp;
kind: MessagingTargetKind;
}): MessagingTarget | undefined {
const match = params.raw.match(params.mentionPattern);
if (!match?.[1]) {
return undefined;
}
return buildMessagingTarget(params.kind, match[1], params.raw);
}
export function parseTargetPrefix(params: {
raw: string;
prefix: string;
kind: MessagingTargetKind;
}): MessagingTarget | undefined {
if (!params.raw.startsWith(params.prefix)) {
return undefined;
}
const id = params.raw.slice(params.prefix.length).trim();
return id ? buildMessagingTarget(params.kind, id, params.raw) : undefined;
}
export function parseTargetPrefixes(params: {
raw: string;
prefixes: Array<{ prefix: string; kind: MessagingTargetKind }>;
}): MessagingTarget | undefined {
for (const entry of params.prefixes) {
const parsed = parseTargetPrefix({
raw: params.raw,
prefix: entry.prefix,
kind: entry.kind,
});
if (parsed) {
return parsed;
}
}
return undefined;
}
export function requireTargetKind(params: {
platform: string;
target: MessagingTarget | undefined;
kind: MessagingTargetKind;
}): string {
const kindLabel = params.kind;
if (!params.target) {
throw new Error(`${params.platform} ${kindLabel} id is required.`);
}
if (params.target.kind !== params.kind) {
throw new Error(`${params.platform} ${kindLabel} id is required (use ${kindLabel}:<id>).`);
}
return params.target.id;
}