import { normalizeE164 } from "openclaw/plugin-sdk/account-resolution"; const SERVICE_PREFIXES = ["imessage:", "sms:", "auto:"] as const; const CHAT_TARGET_PREFIX_RE = /^(chat_id:|chatid:|chat:|chat_guid:|chatguid:|guid:|chat_identifier:|chatidentifier:|chatident:)/i; function trimMessagingTarget(raw: string): string | undefined { const trimmed = raw.trim(); return trimmed || undefined; } function looksLikeHandleOrPhoneTarget(params: { raw: string; prefixPattern: RegExp; phonePattern?: RegExp; }): boolean { const trimmed = params.raw.trim(); if (!trimmed) { return false; } if (params.prefixPattern.test(trimmed)) { return true; } if (trimmed.includes("@")) { return true; } return (params.phonePattern ?? /^\+?\d{3,}$/).test(trimmed); } export function normalizeIMessageHandle(raw: string): string { const trimmed = raw.trim(); if (!trimmed) { return ""; } const lowered = trimmed.toLowerCase(); if (lowered.startsWith("imessage:")) { return normalizeIMessageHandle(trimmed.slice("imessage:".length)); } if (lowered.startsWith("sms:")) { return normalizeIMessageHandle(trimmed.slice("sms:".length)); } if (lowered.startsWith("auto:")) { return normalizeIMessageHandle(trimmed.slice("auto:".length)); } if (CHAT_TARGET_PREFIX_RE.test(trimmed)) { const prefix = trimmed.match(CHAT_TARGET_PREFIX_RE)?.[0]; if (!prefix) { return ""; } const value = trimmed.slice(prefix.length).trim(); return `${prefix.toLowerCase()}${value}`; } if (trimmed.includes("@")) { return trimmed.toLowerCase(); } const normalized = normalizeE164(trimmed); if (normalized) { return normalized; } return trimmed.replace(/\s+/g, ""); } export function normalizeIMessageMessagingTarget(raw: string): string | undefined { const trimmed = trimMessagingTarget(raw); if (!trimmed) { return undefined; } const lower = trimmed.toLowerCase(); for (const prefix of SERVICE_PREFIXES) { if (lower.startsWith(prefix)) { const remainder = trimmed.slice(prefix.length).trim(); const normalizedHandle = normalizeIMessageHandle(remainder); if (!normalizedHandle) { return undefined; } if (CHAT_TARGET_PREFIX_RE.test(normalizedHandle)) { return normalizedHandle; } return `${prefix}${normalizedHandle}`; } } const normalized = normalizeIMessageHandle(trimmed); return normalized || undefined; } export function looksLikeIMessageTargetId(raw: string): boolean { const trimmed = trimMessagingTarget(raw); if (!trimmed) { return false; } if (CHAT_TARGET_PREFIX_RE.test(trimmed)) { return true; } return looksLikeHandleOrPhoneTarget({ raw: trimmed, prefixPattern: /^(imessage:|sms:|auto:)/i, }); }