feat: release contextual omnichannel customer platform
Add Telegram, WhatsApp and email account management, realtime messaging, contextual multilingual AI, customer intelligence, knowledge workflows, enterprise controls, a unified design system and complete repository documentation.
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
import { parsePhoneNumberFromString } from 'libphonenumber-js'
|
||||
|
||||
const VALID_SOURCE = new Set(['manual', 'account-profile', 'phone-prefix', 'unknown'])
|
||||
|
||||
export function normalizeCountryCode(value) {
|
||||
const code = String(value || '').trim().toUpperCase()
|
||||
return /^[A-Z]{2}$/.test(code) ? code : ''
|
||||
}
|
||||
|
||||
export function inferCountryFromPhone(value) {
|
||||
const raw = String(value || '').trim()
|
||||
if (!raw) return ''
|
||||
const normalized = raw.startsWith('+') ? raw : `+${raw.replace(/[^\d]/g, '')}`
|
||||
try {
|
||||
return normalizeCountryCode(parsePhoneNumberFromString(normalized)?.country)
|
||||
} catch {
|
||||
return ''
|
||||
}
|
||||
}
|
||||
|
||||
export function resolveCustomerCountry(input = {}, existing = {}, options = {}) {
|
||||
const manualCountry = normalizeCountryCode(input.country)
|
||||
if (options.manual === true) {
|
||||
return {
|
||||
country: manualCountry,
|
||||
countrySource: manualCountry ? 'manual' : 'unknown',
|
||||
countryConfidence: manualCountry ? 1 : 0,
|
||||
countryInferredAt: new Date().toISOString(),
|
||||
}
|
||||
}
|
||||
|
||||
const existingSource = VALID_SOURCE.has(existing.countrySource)
|
||||
? existing.countrySource
|
||||
: 'unknown'
|
||||
if (existingSource === 'manual' && normalizeCountryCode(existing.country)) {
|
||||
return {
|
||||
country: normalizeCountryCode(existing.country),
|
||||
countrySource: 'manual',
|
||||
countryConfidence: 1,
|
||||
countryInferredAt: existing.countryInferredAt || existing.updatedAt,
|
||||
}
|
||||
}
|
||||
|
||||
const accountCountry = normalizeCountryCode(
|
||||
input.accountCountry || input.countryCode || input.profileCountry,
|
||||
)
|
||||
if (accountCountry) {
|
||||
return {
|
||||
country: accountCountry,
|
||||
countrySource: 'account-profile',
|
||||
countryConfidence: 0.98,
|
||||
countryInferredAt: new Date().toISOString(),
|
||||
}
|
||||
}
|
||||
|
||||
const phoneCountry = inferCountryFromPhone(input.phone || existing.phone)
|
||||
if (phoneCountry) {
|
||||
return {
|
||||
country: phoneCountry,
|
||||
countrySource: 'phone-prefix',
|
||||
countryConfidence: 0.92,
|
||||
countryInferredAt: new Date().toISOString(),
|
||||
}
|
||||
}
|
||||
|
||||
const preserved = normalizeCountryCode(input.country || existing.country)
|
||||
const preservedSource = VALID_SOURCE.has(input.countrySource)
|
||||
? input.countrySource
|
||||
: existingSource
|
||||
if (preserved && preservedSource !== 'unknown') {
|
||||
return {
|
||||
country: preserved,
|
||||
countrySource: preservedSource,
|
||||
countryConfidence: Number(input.countryConfidence ?? existing.countryConfidence ?? 0.7),
|
||||
countryInferredAt: input.countryInferredAt || existing.countryInferredAt,
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
country: '',
|
||||
countrySource: 'unknown',
|
||||
countryConfidence: 0,
|
||||
countryInferredAt: null,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user