-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
6caa19e
commit af69a1d
Showing
5 changed files
with
105 additions
and
82 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,49 +1,62 @@ | ||
package urns | ||
|
||
import ( | ||
"regexp" | ||
"strconv" | ||
"strings" | ||
|
||
"github.com/nyaruka/gocommon/i18n" | ||
"github.com/nyaruka/phonenumbers" | ||
"github.com/pkg/errors" | ||
) | ||
|
||
// FromLocalPhone returns a validated tel URN | ||
func FromLocalPhone(number string, country string) (URN, error) { | ||
path, err := ParsePhone(number, country) | ||
if err != nil { | ||
return NilURN, err | ||
var nonTelCharsRegex = regexp.MustCompile(`[^0-9A-Za-z]`) | ||
|
||
// ParsePhone returns a validated phone URN. If it can parse a possible number then that is used.. otherwise any value | ||
// that validates as a phone URN is used. | ||
func ParsePhone(raw string, country i18n.Country) (URN, error) { | ||
// strip all non-tel characters.. only preserving an optional leading + | ||
raw = strings.TrimSpace(raw) | ||
hasPlus := strings.HasPrefix(raw, "+") | ||
raw = nonTelCharsRegex.ReplaceAllString(raw, "") | ||
if hasPlus { | ||
raw = "+" + raw | ||
} | ||
|
||
return NewURNFromParts(Phone, path, "", "") | ||
} | ||
|
||
// ToLocalPhone converts a phone URN to a local number in the given country | ||
func ToLocalPhone(u URN, country string) string { | ||
_, path, _, _ := u.ToParts() | ||
number, err := parsePhoneOrShortcode(raw, country) | ||
if err != nil { | ||
if err == phonenumbers.ErrInvalidCountryCode { | ||
return NilURN, errors.New("invalid country code") | ||
} | ||
|
||
parsed, err := phonenumbers.Parse(path, country) | ||
if err == nil { | ||
return strconv.FormatUint(parsed.GetNationalNumber(), 10) | ||
return NewURNFromParts(Phone, raw, "", "") | ||
} | ||
return path | ||
|
||
return NewURNFromParts(Phone, number, "", "") | ||
} | ||
|
||
// ParsePhone tries to parse the given string as a phone number and if successful returns it as E164 | ||
func ParsePhone(s, country string) (string, error) { | ||
parsed, err := phonenumbers.Parse(s, country) | ||
// tries to extract a valid phone number or shortcode from the given string | ||
func parsePhoneOrShortcode(raw string, country i18n.Country) (string, error) { | ||
parsed, err := phonenumbers.Parse(raw, string(country)) | ||
if err != nil { | ||
return "", errors.Wrap(err, "unable to parse number") | ||
return "", err | ||
} | ||
|
||
if phonenumbers.IsPossibleNumberWithReason(parsed) != phonenumbers.IS_POSSIBLE { | ||
// if it's not a possible number, try adding a + and parsing again | ||
if !strings.HasPrefix(s, "+") { | ||
return ParsePhone("+"+s, country) | ||
} | ||
if phonenumbers.IsPossibleNumberWithReason(parsed) == phonenumbers.IS_POSSIBLE { | ||
return phonenumbers.Format(parsed, phonenumbers.E164), nil | ||
} | ||
|
||
return "", errors.New("not a possible number") | ||
if phonenumbers.IsPossibleShortNumberForRegion(parsed, string(country)) { | ||
return phonenumbers.Format(parsed, phonenumbers.NATIONAL), nil | ||
} | ||
|
||
return phonenumbers.Format(parsed, phonenumbers.E164), nil | ||
return "", errors.New("unable to parse phone number or shortcode") | ||
} | ||
|
||
func toLocalPhone(path string, country i18n.Country) string { | ||
parsed, err := phonenumbers.Parse(path, string(country)) | ||
if err == nil { | ||
return strconv.FormatUint(parsed.GetNationalNumber(), 10) | ||
} | ||
return path | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters