qwen_2.5_model / dashboard /src /utils /formatPhone.ts
Muhammad Noman
Deploy OpenWA to Hugging Face Spaces
46252cd
Raw
History Blame Contribute Delete
3.16 kB
// Heuristic phone-number formatting for chat display. We deliberately avoid a full
// libphonenumber-js dependency: WhatsApp hands us digits-only user parts (`628123456789`)
// already canonicalised (with the country code prefix in place), so a group-based formatter is
// enough for human-readable display. The raw JID is preserved separately in the UI for the
// technical case where the exact id is needed.
/**
* Extract the local digits from a WhatsApp JID's user part. Returns null for anything that is
* not a digits-only user JID (groups, LID privacy ids, status/broadcast/newsletter).
*
* parsePhoneFromJid('628123456789@c.us') β†’ '628123456789'
* parsePhoneFromJid('120363xxx@g.us') β†’ null (group)
* parsePhoneFromJid('xyz@lid') β†’ null (privacy id, not a phone)
*/
export function parsePhoneFromJid(jid: string): string | null {
if (!jid) return null;
const [local, domain] = jid.split('@');
// Only personal-account domains carry a real phone number. LID privacy ids, groups, and
// status/broadcast/newsletter ids are digit-heavy too but are NOT phones β€” treating them as one
// formats a privacy/group id as a fake number (a LID like 262813461250071@lid displayed as
// "+26 281 346 125 0071").
if (domain && !domain.startsWith('c.us') && domain !== 's.whatsapp.net') return null;
// Group participant ids include a colon + device, e.g. `628xxx@c.us:7`. Strip it for display.
const user = local.split(':')[0];
if (!/^\d+$/.test(user)) return null;
return user;
}
/**
* Format a digits-only phone number (already prefixed with its country code) into a
* human-friendly international form. Uses 3-3-4 grouping after the country code; short codes
* pass through. This is purely cosmetic β€” the raw JID stays authoritative for any technical use.
*
* formatPhoneForDisplay('628123456789') β†’ '+62 812 345 6789'
* formatPhoneForDisplay('14155552671') β†’ '+1 415 555 2671'
* formatPhoneFromJid('120363xxx@g.us') β†’ null
*/
export function formatPhoneForDisplay(phoneOrJid: string): string | null {
const digits = /^\d+$/.test(phoneOrJid) ? phoneOrJid : parsePhoneFromJid(phoneOrJid);
if (!digits) return null;
if (digits.length <= 4) return `+${digits}`;
// Country-code heuristic: WhatsApp country codes are 1–3 digits. Prefer 2 when possible (covers
// the common 62/44/49/91/86… range), fall back to 1 (USA/Canada + a few others) for 11-digit
// numbers starting with 1, and 3 only when the prefix matches a known 3-digit plan.
let ccLen = 2;
if (digits.length === 11 && digits[0] === '1') ccLen = 1;
else if (digits.length <= 6) ccLen = 1;
const cc = digits.slice(0, ccLen);
const rest = digits.slice(ccLen);
if (rest.length <= 4) return `+${cc} ${rest}`;
// Standard display convention: trailing group of 4, then 3-digit groups from the left for the
// remainder. Matches both the Indonesian "812 345 6789" and US "415 555 2671" shapes.
const last4 = rest.slice(-4);
const prefix = rest.slice(0, -4);
const prefixGroups = prefix.match(/.{1,3}/g) ?? [prefix];
return `+${cc} ${[...prefixGroups, last4].join(' ')}`;
}