Files
openclaw/extensions/mattermost/src/normalize.ts
Tony Dehnke 970b62b676 fix(mattermost): restore normalize.ts fixes, add button click dispatch, show button name
- normalize.ts: Restore #channel-name → undefined (directory lookup) fix
  that was lost during PR consolidation. Also restore strict ID matching
  in looksLikeMattermostTargetId (26-char alnum only, not loose 3+ regex).
- interactions.ts: Add dispatchButtonClick callback so the agent responds
  immediately to button clicks. Show the clicked button's display name
  (not raw action ID) in the "selected by" confirmation message.
- monitor.ts: Wire up dispatchButtonClick with full reply pipeline
  (routing, typing indicator, chunking, dispatchReplyFromConfig).
- interactions.test.ts: Update test to expect sanitized action IDs.
2026-03-05 14:33:35 +00:00

51 lines
1.7 KiB
TypeScript

export function normalizeMattermostMessagingTarget(raw: string): string | undefined {
const trimmed = raw.trim();
if (!trimmed) {
return undefined;
}
const lower = trimmed.toLowerCase();
if (lower.startsWith("channel:")) {
const id = trimmed.slice("channel:".length).trim();
return id ? `channel:${id}` : undefined;
}
if (lower.startsWith("group:")) {
const id = trimmed.slice("group:".length).trim();
return id ? `channel:${id}` : undefined;
}
if (lower.startsWith("user:")) {
const id = trimmed.slice("user:".length).trim();
return id ? `user:${id}` : undefined;
}
if (lower.startsWith("mattermost:")) {
const id = trimmed.slice("mattermost:".length).trim();
return id ? `user:${id}` : undefined;
}
if (trimmed.startsWith("@")) {
const id = trimmed.slice(1).trim();
return id ? `@${id}` : undefined;
}
if (trimmed.startsWith("#")) {
// Strip # prefix and fall through to directory lookup (same as bare names).
// The core's resolveMessagingTarget will use the directory adapter to
// resolve the channel name to its Mattermost ID.
return undefined;
}
// Bare name without prefix — return undefined to allow directory lookup
return undefined;
}
export function looksLikeMattermostTargetId(raw: string, normalized?: string): boolean {
const trimmed = raw.trim();
if (!trimmed) {
return false;
}
if (/^(user|channel|group|mattermost):/i.test(trimmed)) {
return true;
}
if (trimmed.startsWith("@")) {
return true;
}
// Mattermost IDs: 26-char alnum, or DM channels like "abc123__xyz789" (53 chars)
return /^[a-z0-9]{26}$/i.test(trimmed) || /^[a-z0-9]{26}__[a-z0-9]{26}$/i.test(trimmed);
}