From 61618bc7f823ab1c1b530ede4b53f54dfd0f2da5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A0=D1=83=D1=81=D0=BB=D0=B0=D0=BD?= Date: Mon, 23 Dec 2024 15:49:05 +0300 Subject: [PATCH] fix parsing --- core/util/phone.go | 57 ++++++++++++++++++++++++++--------------- core/util/phone_test.go | 43 ++++++++++++++++++++++++++++--- 2 files changed, 75 insertions(+), 25 deletions(-) diff --git a/core/util/phone.go b/core/util/phone.go index c303147..105993a 100644 --- a/core/util/phone.go +++ b/core/util/phone.go @@ -17,24 +17,24 @@ const ( CountryPhoneCodeDE = 49 CountryPhoneCodeAG = 54 CountryPhoneCodeMX = 52 - // CountryPhoneCodeMXWA For Whatsapp. - CountryPhoneCodeMXWA = 521 - CountryPhoneCodeUS = "1443" - CountryPhoneCodePS = 970 - CountryPhoneCodeUZ = 998 - PalestineRegion = "PS" - BangladeshRegion = "BD" + CountryPhoneCodeUS = "1443" + CountryPhoneCodePS = 970 + CountryPhoneCodeUZ = 998 + PalestineRegion = "PS" + BangladeshRegion = "BD" ) var ( ErrPhoneTooShort = errors.New("phone is too short - must be at least 5 symbols") ErrCannotDetermineCountry = errors.New("cannot determine phone country code") ErrCannotParsePhone = errors.New("cannot parse phone number") - undefinedUSCodes = []string{"1445", "1945", "1840", "1448", "1279", "1839"} + + TrimmedPhoneRegexp = regexp.MustCompile(`\D+`) + UndefinedUSCodes = []string{"1445", "1945", "1840", "1448", "1279", "1839"} ) -// FormatNumberForWA forms in the specified format according to the rules https://faq.whatsapp.com/1294841057948784 -func FormatNumberForWA(number string, format pn.PhoneNumberFormat) (string, error) { +// FormatNumberForWA forms in the format according to the rules https://faq.whatsapp.com/1294841057948784 +func FormatNumberForWA(number string) (string, error) { parsedPhone, err := ParsePhone(number) if err != nil { @@ -46,7 +46,7 @@ func FormatNumberForWA(number string, format pn.PhoneNumberFormat) (string, erro case CountryPhoneCodeAG: formattedPhoneNumber = Add9AGIFNeed(parsedPhone) default: - formattedPhoneNumber = pn.Format(parsedPhone, format) + formattedPhoneNumber = pn.Format(parsedPhone, pn.E164) } return formattedPhoneNumber, nil @@ -56,7 +56,7 @@ func FormatNumberForWA(number string, format pn.PhoneNumberFormat) (string, erro // For mexican numbers automatic add 1 after to the country code (521). // But for argentine numbers there is no automatic addition 9 to the country code. func ParsePhone(phoneNumber string) (*pn.PhoneNumber, error) { - trimmedPhone := regexp.MustCompile(`\D+`).ReplaceAllString(phoneNumber, "") + trimmedPhone := TrimmedPhoneRegexp.ReplaceAllString(phoneNumber, "") if len(trimmedPhone) < MinPhoneSymbolCount { return nil, ErrPhoneTooShort } @@ -89,9 +89,13 @@ func ParsePhone(phoneNumber string) (*pn.PhoneNumber, error) { parsedPhone.NationalNumber = &number } - if IsMexicoNumber(trimmedPhone, parsedPhone) { - c := int32(CountryPhoneCodeMXWA) - parsedPhone.CountryCode = &c + if IsMexicoNumber(parsedPhone) { + number, err := getMexicanNationalNumber(parsedPhone) + if err != nil { + return nil, err + } + + parsedPhone.NationalNumber = &number } return parsedPhone, err @@ -101,15 +105,12 @@ func IsRussianNumberWith8Prefix(phone string) bool { return strings.HasPrefix(phone, "8") && len(phone) == 11 && phoneiso3166.E164.LookupString("7"+phone[1:]) == "RU" } -func IsMexicoNumber(phone string, parsed *pn.PhoneNumber) bool { - phoneNumber := regexp.MustCompile(`\D+`).ReplaceAllString(phone, "") - return len(phoneNumber) == 13 && - parsed.GetCountryCode() == CountryPhoneCodeMX && - strings.HasPrefix(phoneNumber, "521") +func IsMexicoNumber(parsed *pn.PhoneNumber) bool { + return parsed.GetCountryCode() == CountryPhoneCodeMX } func IsUSNumber(phone string) bool { - return slices.Contains(undefinedUSCodes, phone[:4]) && + return slices.Contains(UndefinedUSCodes, phone[:4]) && phoneiso3166.E164.LookupString(CountryPhoneCodeUS+phone[4:]) == "US" } @@ -177,6 +178,20 @@ func getUzbekistanNationalNumber(phone string, parsedPhone *pn.PhoneNumber) (uin return result, nil } +func getMexicanNationalNumber(parsedPhone *pn.PhoneNumber) (uint64, error) { + result := parsedPhone.GetNationalNumber() + phoneWithDigit := fmt.Sprintf("1%d", parsedPhone.GetNationalNumber()) + + num, err := strconv.Atoi(phoneWithDigit) + + if err != nil { + return 0, err + } + + result = uint64(num) + return result, nil +} + func getCountryCode(phone string) string { countryCode := phoneiso3166.E164.LookupString(phone) diff --git a/core/util/phone_test.go b/core/util/phone_test.go index c4532e0..e9d13b4 100644 --- a/core/util/phone_test.go +++ b/core/util/phone_test.go @@ -54,14 +54,20 @@ func TestParsePhone(t *testing.T) { n := "5219982418333" pn, err := ParsePhone(n) require.NoError(t, err) - assert.Equal(t, uint64(9982418333), pn.GetNationalNumber()) - assert.Equal(t, int32(CountryPhoneCodeMXWA), pn.GetCountryCode()) + assert.Equal(t, uint64(19982418333), pn.GetNationalNumber()) + assert.Equal(t, int32(CountryPhoneCodeMX), pn.GetCountryCode()) n = "+521 (998) 241 83 33" pn, err = ParsePhone(n) require.NoError(t, err) - assert.Equal(t, uint64(9982418333), pn.GetNationalNumber()) - assert.Equal(t, int32(CountryPhoneCodeMXWA), pn.GetCountryCode()) + assert.Equal(t, uint64(19982418333), pn.GetNationalNumber()) + assert.Equal(t, int32(CountryPhoneCodeMX), pn.GetCountryCode()) + + n = "529982418333" + pn, err = ParsePhone(n) + require.NoError(t, err) + assert.Equal(t, uint64(19982418333), pn.GetNationalNumber()) + assert.Equal(t, int32(CountryPhoneCodeMX), pn.GetCountryCode()) }) t.Run("palestine number", func(t *testing.T) { @@ -88,3 +94,32 @@ func TestParsePhone(t *testing.T) { assert.Equal(t, int32(CountryPhoneCodeUZ), pn.GetCountryCode()) }) } + +func TestFormatNumberForWA(t *testing.T) { + numbers := map[string]string{ + "79040000000": "+79040000000", + "491736276098": "+491736276098", + "89185553535": "+79185553535", + "4915229457499": "+4915229457499", + "5491131157821": "+5491131157821", + "541131157821": "+5491131157821", + "5219982418333": "+5219982418333", + "529982418333": "+5219982418333", + "14452385043": "+14452385043", + "19452090748": "+19452090748", + "19453003681": "+19453003681", + "19452141217": "+19452141217", + "18407778097": "+18407778097", + "14482074337": "+14482074337", + "18406665259": "+18406665259", + "19455009160": "+19455009160", + "19452381431": "+19452381431", + "12793006305": "+12793006305", + } + + for orig, expected := range numbers { + actual, err := FormatNumberForWA(orig) + assert.NoError(t, err) + assert.Equal(t, expected, actual) + } +}