GithubHelp home page GithubHelp logo

phonenumbers's Introduction

☎️ phonenumbers

Build Status codecov GoDoc

golang port of Google's libphonenumber forked from libphonenumber from ttacon/libphonenumber. This library is used daily in production for parsing and validation of numbers across the world, so is well maintained. Please open an issue if you encounter any problems, we'll do our best to address them.

Important

The aim of this project is strictly to be a port and match as closely as possible the functionality in libphonenumber. Please don't submit feature requests for functionality that doesn't exist in libphonenumber.

Important

We use the metadata from libphonenumber so if you encounter unexpected parsing results, please first verify if the problem affects libphonenumber and report there if so. You can use their online demo to quickly check parsing results.

Version Numbers

As we don't want to bump our major semantic version number in step with the upstream library, we use independent version numbers than the Google libphonenumber repo. The release notes will mention what version of the metadata a release was built against.

Usage

// parse our phone number
num, err := phonenumbers.Parse("6502530000", "US")

// format it using national format
formattedNum := phonenumbers.Format(num, phonenumbers.NATIONAL)

Updating Metadata

The buildmetadata command will fetch the latest XML file from the official Google repo and rebuild the go source files containing all the territory metadata, timezone and region maps.

It will rebuild the following files:

  • gen/metadata_bin.go - protocol buffer definitions for all the various formats across countries etc..
  • gen/shortnumber_metadata_bin.go - protocol buffer definitions for ShortNumberMetadata.xml
  • gen/countrycode_to_region_bin.go - information needed to map a contry code to a region
  • gen/prefix_to_carrier_bin.go - information needed to map a phone number prefix to a carrier
  • gen/prefix_to_geocoding_bin.go - information needed to map a phone number prefix to a city or region
  • gen/prefix_to_timezone_bin.go - information needed to map a phone number prefix to a city or region
% go install github.com/nyaruka/phonenumbers/cmd/buildmetadata
% $GOPATH/bin/buildmetadata

phonenumbers's People

Contributors

ak-ionos avatar borudar avatar bvisness avatar coreyk avatar cristaloleg avatar dependabot[bot] avatar eugene-gurevich avatar f21 avatar hemachandran-kalaimani avatar iwittkau avatar janh avatar jefftt avatar nicpottier avatar norkans7 avatar ramin0 avatar richard-rance avatar rowanseymour avatar rreuvekamp avatar shaxbee avatar vlastv avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

phonenumbers's Issues

Corner case with French overseas territory ?

Hi Guys,

Could be that I found a corner case that I would like to share with you. I am using your implementation for a telco ticketing system . This telco is exchanging lots of calls from and to the French Overseas territories.

I do have issues with the result of GetGeocodingForNumber.

Here is example which hopefully will make the case clear ...

I have a called number with its national representation like this : 590555008,
Its e164 representation looks like this : +590590555008

When used like this and passing +590590555008 as parameter

func libPhoneNumberEnrichFields(myNumber string) (string, string, string, string) {
	var num *phonenumbers.PhoneNumber
	var err error
	var geo string
	num, err = phonenumbers.Parse(myNumber, "FR")
	if err != nil {
		global.Logger.WithFields(logrus.Fields{
			"error": err,
			"number": myNumber,
		}).Info("unable to parse number")
		return "", "", "", ""
	}

	geo, err = phonenumbers.GetGeocodingForNumber(num, "fr")
	if err != nil {
		global.Logger.WithFields(logrus.Fields{
			"error": err,
			"number": myNumber,
		}).Info("unable to GeoCode this number")
		return "", "", "", ""
	}
	cc := strconv.Itoa(int(num.GetCountryCode()))
	country := phonenumbers.GetRegionCodeForNumber(num)
	numType := descNumTypeFromType[phonenumbers.GetNumberType(num)]
	return cc, country, geo, numType
}

GetGeocodingForNumber is returning me an empty string wo generating any errors.

However, when you go to ITU web site and open this page:
https://www.itu.int/oth/T020200004B/en
Then in the pdf format file and click on the link that gives the xls file called MAJNUM.xls:

https://extranet.arcep.fr/portail/LinkClick.aspx?fileticket=PBA1WK-wnOU%3d&tabid=217&portalid=0&mid=850

You search for phone number range 059055, you will find the region/location. It should be the location of "Basse-Terre".

Could you please help me to investigate where is the problem ?

Is it an ITU data base problem or could it be that I don't use you library properly ?

I took this example but it seems to apply to all those territories : Guadeloupe, Martinique, Reunion... It applies to all those country codes +262, +590, +594, +596.

If you could have a look it would be fantastic !

Thanks Matthieu.

export isNumberMatchWithNumbers

Would it be possible to export isNumberMatchWithNumbers(firstNumberIn, secondNumberIn *PhoneNumber) MatchType?

In libphonenumber (Java), the corresponding method is public, while here only IsNumberMatch(firstNumber, secondNumber string) MatchType is exported. This makes it impossible to pass default regions to the function, and thus the result behaves differently from the Java version.

Example:
PhoneNumber "0049 721 12345" compared to "+49 721 12345" results in EXACT_MATCH when default region "DE" is given.
String "0049 721 12345" compared to "+49 721 12345" results in NSN_MATCH.

Get Area Code/Prefix

GetCarrierForNumber tries to guess the name of the carrier of a given number. In its implementation, it calls getValueForNumber which in turn attempts to find the "prefix" (or index) of the provided number that exists in carrierMapData.

My question is, is it possible to alter the function to add this "prefix" as an extra return value? It's a requirement in a project I'm working on where the prefix is needed rather than the carrier name. For example:

func getValueForNumber(...) (string, int, error) { // int is for the prefix/index

I'm happy to create a PR for it if this looks like a good addition to this package. I went ahead and created one.

Question - Is Ivory Coast new number format supported?

Ivory Coast (Côte D'Ivoire - CI) will switch from 8 to 10 digits format at the midnight between 30th - 31st of January, 2021. Is the new format supported by this library?

Below the Google translated version of https://www.artci.ci/index.php/foire-aux-questions/470-nouveau-plan-de-national-de-numeroration.html - 6th question.

As of January 31, 2021 at 12:00 a.m. 8-digit numbers will no longer work.
The principle of tilting is very simple.
The general principle of switching is to add a prefix in front of the old 8-digit numbers.
We based ourselves on so-called “characteristic” figures of operators that the population already recognizes.
So for mobile numbers, add:

  • " 07 " in front of the old numbers of ORANGE
  • " 05 " in front of the old ones of MTN
  • " 01 " in front of those of MOOV

For fixed numbers, you must add:

  • " 27 " in front of the old numbers of ORANGE
  • " 25 " in front of the old ones of MTN
  • " 21 " in front of those of MOOV.

Thank you!

Error during rebuilding metadata

Hello!

I moved to the directory with this project and ran the command:
$GOPATH/bin/buildmetadata

This command partially completed the work and then gave an error:

2019/01/24 20:04:54 Fetching PhoneNumberMetadata.xml from Github
2019/01/24 20:04:56 Building new metadata collection
2019/01/24 20:04:56 Writing new metadata_bin.go
Writing new metadata_bin.go
2019/01/24 20:04:56 Building region map
Writing new countrycode_to_region_bin.go
2019/01/24 20:04:56 Building timezone map
Writing new prefix_to_timezone_bin.go
2019/01/24 20:04:56 Fetching https://github.com/googlei18n/libphonenumber/trunk/resources/carrier from Github
2019/01/24 20:04:56 exit status 1

It turns out that the resource requested by the link is not available - error 404.

I think it's worth fixing.

ParseToNumber parses valid numbers as invalid

When trying to parse a few thousands of numbers we are using ParseToNumber. Unfortunately, we hit a bug which causes ParseToNumber to parse valid phone numbers as invalid. Here is a simple test case that can be used to reproduce the issue. I think for some reason ParseToNumber is not reseting ItalianLeadingZero and NumberOfLeadingZeros which probably is causing the number to be treated as invalid?

Code to reproduce the issue: https://play.golang.org/p/jSsK71K6Mdg

IsPossibleNumberWithReason() not working properly

You might want to resync with ttacon/libphonenumber
if you call IsPossibleNumberWithReason()
with a number like +1456723456
It returns IS_POSSIBLE when instead it should be TOO_SHORT
IsPossibleNumberWithReason() at ttacon/libphonenumber is using
GetNationalNumberPattern()
Instead of GetPossibleNumberPattern() for the last test.

recently added number prefix not validate properly.

Hi,

for the "LK", they added a "074" number prefix a few days ago. but it's not recognized by the library. I tried to build the dataset and still not recognized. But in the Java library, it's recognized as expected. even on an online page.

        num, err := phonenumbers.Parse("746557816", "LK")
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(phonenumbers.IsValidNumber(num))

Region detection problem

Hi, today I got error with country detection on phonenumbers library.

This is a working example of my Python code:

In [1]: from phonenumbers import parse, region_code_for_number, carrier, is_valid_number

In [2]: number = parse("+77015321922")

In [3]: region_code_for_number(number)
Out[3]: 'KZ'

In [4]: carrier.name_for_number(number, "en")
Out[4]: 'Kcell/Activ'

In [5]: is_valid_number(number)
Out[5]: True

and on Go version:

package main

import (
	"fmt"

	"github.com/nyaruka/phonenumbers"
)


func main() {
	phone := "+77015321922"
	number, _ := phonenumbers.Parse(phone, "US")
	carrier, _ := phonenumbers.GetCarrierForNumber(number, "en")
	country := phonenumbers.GetRegionCodeForCountryCode(int(number.GetCountryCode()))

	fmt.Printf("CountryCode:    %s\n", country)
	fmt.Printf("Carrier:        %s\n", carrier)
	fmt.Printf("IsValid:        %+v\n", phonenumbers.IsValidNumber(number))
}

I'm getting this result

CountryCode:    RU
Carrier:        Kcell/Activ
IsValid:        true

But country result is wrong.

PhoneNumberOfflineGeocoder

Hello, do not find this function, how to get country name, do you plane to add PhoneNumberOfflineGeocoder?

Subversion dependency not stated in README for building metadata

Tried to rebuild meta and got the following results:

2019/03/07 12:41:05 Fetching PhoneNumberMetadata.xml from Github
2019/03/07 12:41:06 Building new metadata collection
2019/03/07 12:41:06 Writing new metadata_bin.go
Writing new metadata_bin.go
2019/03/07 12:41:06 Building region map
Writing new countrycode_to_region_bin.go
2019/03/07 12:41:06 Building timezone map
Writing new prefix_to_timezone_bin.go
2019/03/07 12:41:06 Fetching https://github.com/googlei18n/libphonenumber/trunk/resources/carrier from Github
2019/03/07 12:41:06 exit status 127

Fortunately, I knew what 127 meant and looked in the code to see it was making an svn call (of which I didn't have installed on my laptop). Installing subversion resolved the problem.

Anyway, it'd prob be good to note in the README that building the metadata requires subversion installed :)

Find Mobile Number Carrier Gateway Address

Hi,

Can you tell me how i can find Mobile number carrier gateway address likewise ... ACS Wireless <10-digit-number>@paging.acswireless.com , thorugh this library

Regards,
Shubham Agarwal

panic: proto: nil destination -- when using phonenumbers.FormatByPattern(..)

Hello,

Thanks for this great port of libphonenumber.

I'm getting a panic error when I'm trying to use the following function:
https://godoc.org/github.com/nyaruka/phonenumbers#FormatByPattern

panic: proto: nil destination

goroutine 1 [running]:
github.com/golang/protobuf/proto.Merge(0x131ae60, 0x0, 0x131ae60, 0x13efd00)
	/Users/mdouchement/workspaces/golang/src/github.com/golang/protobuf/proto/clone.go:86 +0x45b
github.com/nyaruka/phonenumbers.FormatByPattern(0xc4202a4c00, 0x0, 0xc4200e1f10, 0x1, 0x1, 0x0, 0x0)
	/Users/mdouchement/workspaces/golang/src/github.com/nyaruka/phonenumbers/phonenumbers.go:1148 +0x196
main.main()
	/Users/mdouchement/workspaces/golang/src/github.com/mdouchementent/testouille/phonenumber.go:28 +0x1da
exit status 2


According to the stacktrace, the error is raised by the statement proto.Merge(numFormatCopy, formattingPattern) because numFormatCopy is nil.

phonenumbers/phonenumbers.go

Lines 1143 to 1148 in 06e7b8a

var numFormatCopy *NumberFormat
// Before we do a replacement of the national prefix pattern
// $NP with the national prefix, we need to copy the rule so
// that subsequent replacements for different numbers have the
// appropriate national prefix.
proto.Merge(numFormatCopy, formattingPattern)



I'm also wondering if github.com/golang/protobuf v1.0.0 defined in the go.mod is the right version because proto.InternalMessageInfo was introduced in the v.1.1.0 release according to Githubs' history.

add manual update mechanism

When the mobile phone number verification rule xml is updated, my running service needs to run the external cmd program and then recompile and restart before it takes effect. could you add the Update method to concurrently and securely update?

phonenumbers/phonenumbers.go

Lines 3226 to 3276 in 70effd0

func init() {
// load our regions
regionMap, err := loadIntStringArrayMap(regionMapData)
if err != nil {
panic(err)
}
countryCodeToRegion = regionMap.Map
// then our metadata
err = loadMetadataFromFile("US", 1)
if err != nil {
panic(err)
}
for eKey, regionCodes := range countryCodeToRegion {
// We can assume that if the county calling code maps to the
// non-geo entity region code then that's the only region code
// it maps to.
if len(regionCodes) == 1 && REGION_CODE_FOR_NON_GEO_ENTITY == regionCodes[0] {
// This is the subset of all country codes that map to the
// non-geo entity region code.
countryCodesForNonGeographicalRegion[eKey] = true
} else {
// The supported regions set does not include the "001"
// non-geo entity region code.
for _, val := range regionCodes {
supportedRegions[val] = true
}
}
supportedCallingCodes[eKey] = true
}
// If the non-geo entity still got added to the set of supported
// regions it must be because there are entries that list the non-geo
// entity alongside normal regions (which is wrong). If we discover
// this, remove the non-geo entity from the set of supported regions
// and log (or not log).
delete(supportedRegions, REGION_CODE_FOR_NON_GEO_ENTITY)
for _, val := range countryCodeToRegion[NANPA_COUNTRY_CODE] {
writeToNanpaRegions(val, struct{}{})
}
// Create our sync.Onces for each of our languages for carriers
for lang := range carrierMapData {
carrierOnces[lang] = &sync.Once{}
}
for lang := range geocodingMapData {
geocodingOnces[lang] = &sync.Once{}
}
}

Region code support

Hi, in examples I see Parse supports taking in a two letter region code as default region. Does it only supports two letter region code, not the other formats (3 letter, etc.)?
Thanks!

OffLine Geocoder support

Nice golang port of libphonenumber : thanks to make it available as open source.

I was wondering if you ever investigated the support of PhoneNumberOfflineGeocoder in order to get phone number location ?

Thanks Matthieu.

: undefined: proto.InternalMessageInfo

go run *.go
# github.com/gomagicbox/vendor/github.com/nyaruka/phonenumbers
vendor/github.com/nyaruka/phonenumbers/phonemetadata.pb.go:108:34: undefined: proto.InternalMessageInfo
vendor/github.com/nyaruka/phonenumbers/phonemetadata.pb.go:214:37: undefined: proto.InternalMessageInfo
vendor/github.com/nyaruka/phonenumbers/phonemetadata.pb.go:416:35: undefined: proto.InternalMessageInfo
vendor/github.com/nyaruka/phonenumbers/phonemetadata.pb.go:676:45: undefined: proto.InternalMessageInfo
vendor/github.com/nyaruka/phonenumbers/phonenumber.pb.go:173:33: undefined: proto.InternalMessageInfo

getSupportedCallingCodes method not found

Hey, thank you for the great library!

In the software I am trying to build I was looking for getSupportedCallingCodes that I found in both Java and python versions.

I tried to get them like this:

var supportedCallingCodes []int
for region := range phonenumbers.GetSupportedRegions() {		
	supportedCallingCodes.append(supportedCallingCodes, phonenumbers.GetCountryCodeForRegion(region))
}

but in this way I don't get a few codes (e.g. 800,808,883,870,878,881,882,888,979

Did I missed the method or is there another workaround to get all supported calling codes?

Regards,
-rif

panic: proto: nil destination in phonenumbers.FormatInOriginalFormat

FormatInOriginalFormat panics in some cases:

panic: proto: nil destination

goroutine 1 [running]:
github.com/golang/protobuf/proto.Merge(0x757080, 0x0, 0x757080, 0xc000231920)
	/home/jan/Entwicklung/go/src/github.com/golang/protobuf/proto/clone.go:86 +0x71b
github.com/nyaruka/phonenumbers.FormatInOriginalFormat(0xc0002efef0, 0x5e6766, 0x2, 0x2, 0x101)
	/home/jan/Entwicklung/go/src/github.com/nyaruka/phonenumbers/phonenumbers.go:1527 +0x4bb
main.main()
	/home/jan/test/main.go:13 +0xe0
exit status 2

This can be reproduced with the following sample code:

package main

import (
	"fmt"
	"github.com/nyaruka/phonenumbers"
)

func main() {
	number, err := phonenumbers.ParseAndKeepRawInput("0987654321", "DE")
	if err != nil {
		panic(err)
	}
	formatted := phonenumbers.FormatInOriginalFormat(number, "DE")
	fmt.Println(formatted)
}

Similar to #16, this is because proto.Merge is called with a nil dst here:

phonenumbers/phonenumbers.go

Lines 1526 to 1527 in ce4687a

var numFormatCopy *NumberFormat
proto.Merge(numFormatCopy, formatRule)

The same also occurs at two other places:

phonenumbers/phonenumbers.go

Lines 1648 to 1649 in ce4687a

var newFormat *NumberFormat
proto.Merge(newFormat, formattingPattern)

phonenumbers/phonenumbers.go

Lines 2472 to 2473 in ce4687a

var numberCopy *PhoneNumber
proto.Merge(numberCopy, number)

Allocates a large chunk of memory at run time

This library seems to statically allocate a LOT of data at run time. Nearly 3MB of it. On some devices that have severe memory limitations, this can be an issue.

I've put together a small python script that can demonstrate the memory footprint that the library can bring with it.

The python script
import psutil
import os
import subprocess
import time

GO_SCRIPT_WITH_PHONENUMBERS = """
package main

import (
    "github.com/nyaruka/phonenumbers"
    "time"
)

func main() {
    // We have to USE the library if we import it, so here is what
    // should be a simple invocation.
    phonenumbers.NormalizeDigitsOnly("1234567890")

    // Keep the process alive
    for true {
        time.Sleep(1)
    }
}
"""

GO_SCRIPT_WITHOUT_PHONENUMBERS = """
package main

import (
    "time"
)

func main() {
    // Keep the process alive
    for true {
        time.Sleep(1)
    }
}
"""

def run_go_process(with_phonenumbers):
    with open("tmp_go_script.go", 'w') as f:
        if with_phonenumbers:
            f.write(GO_SCRIPT_WITH_PHONENUMBERS)
        else:
            f.write(GO_SCRIPT_WITHOUT_PHONENUMBERS)
    os.system("go build -o tmp_go_binary tmp_go_script.go")
    process = subprocess.Popen("./tmp_go_binary", shell=False)
    time.sleep(1)
    psproc = psutil.Process(process.pid)
    return psproc.memory_full_info().uss

def sizeof_fmt(num, suffix='', kunit=1024.0):
    for unit in ['','K','M','G','T','P','E','Z']:
        if abs(num) < kunit:
            return "%3.2f%s%s" % (num, unit, suffix)
        num /= kunit
    return "%.1f%s%s" % (num, 'Y', suffix)

def main():
    with_phonenumbers = run_go_process(with_phonenumbers=True)
    without_phonenumbers = run_go_process(with_phonenumbers=False)
    print(f"With Phonenumbers:    {sizeof_fmt(with_phonenumbers)}")
    print(f"Without Phonenumbers: {sizeof_fmt(without_phonenumbers)}")

if __name__ == "__main__":
    main()

This script will create two Go binaries, one that includes the phonenumbers library and one that does not. Once each process is spun up, it will use the psutil python library to retrieve the current memory footprint of the binary. The process will have 1s to settle before this sample is taken. The value displayed is the amount of memory that would be freed up if the process were to be terminated immediately.

It's important that the script is run as root as it uses the .memory_full_info() function of the psutil Python library.

When I run this script on my macOS 10.15.5 system running go 1.13, this is the output I see:

$ python3 phonenumbers_memory.py
With Phonenumbers:    3.02M
Without Phonenumbers: 716.00K

That's quite a drastic increase when including the library. Now, it's not clear at this time if this is due to deeper dependencies of the phonenumbers library or if it's due to the number of static allocations in the library ( I would assume for mapping phone number formats / ISO codes / etc.) However, it seems pretty excessive.

Support a Parse method that uses a default country code

When using the Parse(numberToParse, defaultRegion), I realised a potential need for having the default region be expressed more like a defaultCode.

In the example, I want to allow users to select which country code they suspect most of their numbers will use. The reason for displaying to them these values is that it supports:

  • non-geo (As I was previously using the GetSupportedRegions() to provide a list for them to choose from and this doesn't seem to allow non-geo codes)
  • I suspect a user can identify the +44 over the "GB" code. I know I tried "UK" a few times when starting out.

The result would look something like:

stringToParse := "01234567890"
// 800 as an example of non-geo code
num, err := phonenumbers.ParseWithCode(stringToParse, 800)

Problems with FR phone numbers validation

Hello,
I noticed the following problem with French phones validation in v1.0.60:

func Normalize(nm string) (string, error) {
        n, err := phonenumbers.Parse(nm, "")
	if err != nil {
		return "", err
	}

	if !phonenumbers.IsValidNumber(n) {
		cc := phonenumbers.GetRegionCodeForCountryCode(int(num.GetCountryCode()))
		return "", fmt.Errorf("%v is an invalid number for region %v", number, cc)
	}
}

In v1.0.59 my test works fine. Since the last release, for numbers like +33691111111 it returns XXX is an invalid number for region FR

Did you change validation rules? I see some changes in diff, is it related?

Panic with .IsNumberMatch

I am trying to compare UK numbers without country code and end up with panic.

package main

import (
	"fmt"

	"github.com/nyaruka/phonenumbers"
)

func main() {
	res := phonenumbers.IsNumberMatch("07598765432", "07598765432")
	fmt.Println(res)
}

This results in following panic

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x117d130]

goroutine 1 [running]:
github.com/nyaruka/phonenumbers.maybeExtractCountryCode(0xc00015de38, 0xb, 0x0, 0xc00017a1c0, 0xc00015de00, 0x0, 0x10138f7, 0x1594638, 0x203000)
        /Users/myuser/go/pkg/mod/github.com/nyaruka/[email protected]/phonenumbers.go:2597 +0x800
github.com/nyaruka/phonenumbers.parseHelper(0x11dd979, 0xb, 0x0, 0x0, 0xc000320000, 0x0, 0xc000010ab0, 0xffffffffffffffff)
        /Users/myuser/go/pkg/mod/github.com/nyaruka/[email protected]/phonenumbers.go:2890 +0x317
github.com/nyaruka/phonenumbers.IsNumberMatch(0x11dd979, 0xb, 0x11dd979, 0xb, 0xc0000200b8)
        /Users/myuser/go/pkg/mod/github.com/nyaruka/[email protected]/phonenumbers.go:3142 +0x155
main.main()
        /Users/myuser/Projects/go/phone-numbers/main.go:10 +0x48
exit status 2

go version go1.14.4 darwin/amd64

Error while installing package

Hi,

when I try to install your package I get errors:
Projects/Golang/src/github.com/nyaruka/phonenumbers/phonemetadata.pb.go:108: undefined: proto.InternalMessageInfo
Projects/Golang/src/github.com/nyaruka/phonenumbers/phonemetadata.pb.go:214: undefined: proto.InternalMessageInfo
Projects/Golang/src/github.com/nyaruka/phonenumbers/phonemetadata.pb.go:416: undefined: proto.InternalMessageInfo
Projects/Golang/src/github.com/nyaruka/phonenumbers/phonemetadata.pb.go:676: undefined: proto.InternalMessageInfo
Projects/Golang/src/github.com/nyaruka/phonenumbers/phonenumber.pb.go:173: undefined: proto.InternalMessageInfo

Area Code not evaluated

func GetLengthOfNationalDestinationCode(number *PhoneNumber) int ...
https://github.com/nyaruka/phonenumbers/blob/master/phonenumbers.go
Line 944

if len(numberGroups) <= 3 {
return 0
}

... but numberGroups evalueates to e.g.: []string {"49", "30", "1234567"} with len == 3

so GetLengthOfNationalDestinationCode(..) returns always 0.

The comment states:

// The pattern will start with "+COUNTRY_CODE " so the first group
// will always be the empty string (before the + symbol)
and the
// second group will be the country calling code. The third group
// will be area code if it is not the last group.

which seems to be wrong in this case. Comparison should be written as follows:

if len(numberGroups) <= 2 {
return 0
}

A small test program shows how it should work (as i understand):

package main

import (
	"fmt"
	"log"

	"github.com/nyaruka/phonenumbers"
)


func main() {
	phone := "+14061234567"
	country := "US"
	metadata, err := phonenumbers.Parse(phone, country)
	if err != nil {
		log.Printf("error parsing phone: %s", err)
	}

	nationalSignificantNumber := phonenumbers.GetNationalSignificantNumber(metadata)
	var areaCode string
	var subscriberNumber string

	areaCodeLength := phonenumbers.GetLengthOfGeographicalAreaCode(metadata)
	if areaCodeLength > 0 {
		areaCode = nationalSignificantNumber[0:areaCodeLength]
		subscriberNumber = nationalSignificantNumber[areaCodeLength:]
	} else {
		areaCode = ""
		subscriberNumber = nationalSignificantNumber
	}

	fmt.Printf("%+v\n", metadata)

	fmt.Printf("NationalNumber:            %+v\n", *metadata.NationalNumber)
	fmt.Printf("NationalSignificantNumber: %+v\n", nationalSignificantNumber)
	fmt.Printf("AreaCode:                  %+v\n", areaCode)
	fmt.Printf("SubscriberNumber:          %+v\n", subscriberNumber)
	fmt.Printf("CountryCode:               %+v\n", *metadata.CountryCode)
	fmt.Printf("IsPossible:                %+v\n", phonenumbers.IsPossibleNumber(metadata))
	fmt.Printf("IsValid:                   %+v\n", phonenumbers.IsValidNumber(metadata))
	fmt.Printf("NationalFormatted:         %+v\n", phonenumbers.Format(metadata, phonenumbers.NATIONAL))
	fmt.Printf("InternationalFormatted:    %+v\n", phonenumbers.Format(metadata, phonenumbers.INTERNATIONAL))
}

without change the result shows an empty AreaCode.

with best regards
Hans S, Kula


Partial number formatting

Is there a way to format a number that is not complete?

For example, the following COMPLETE number works fine

    iso := "US"
    phone := "2345678901"
    num, _ := phonenumbers.Parse(phone, iso)
    formatted := phonenumbers.Format(num, phonenumbers.NATIONAL)
    fmt.Printf("%s\n", formatted)
(234) 567-8901

However, if I instead pass a PARTIAL number, it loses all formatting.

    iso := "US"
    phone := "23456789"
    num, _ := phonenumbers.Parse(phone, iso)
    formatted := phonenumbers.Format(num, phonenumbers.NATIONAL)
    fmt.Printf("%s\n", formatted)
23456789

I would like it if that would spit out:

(234) 567-89

Since I want to use this for as the user types their phone number in, displaying it in a proper format.

Is this doable with this library?

Cannot pass Null to prefix while parsing a number

For the numbers starting with plus +, I am not being be able to pass null or nothing for the 2nd parameter of Parse method as in:

num, err := phonenumbers.Parse("6502530000", "US")

This would be invalid

But
I can't do something like this:

num, err := phonenumbers.Parse("+6502530000")

This should be valid enough, How can I pass Null value or nothing for prefix when there's plus symbol or 00

broken countrycode detection in v1.0.60

Hi,

thanks for the useful library!

I got a number which gets parsed correctly in v1.0.59, but not anymore in v1.0.60.

The call is to Parse("6282240080000", "ID"), which returns +626282240080000, but it should detect that the 62 is already present and make it +6282240080000.
The original number is possible and valid according to https://rawgit.com/googlei18n/libphonenumber/master/javascript/i18n/phonenumbers/demo-compiled.html but the new number (+6262822...) is possible but not(!) valid.

A shorter version of the number (62822400800) does get parsed and formatted correctly.

This shows the problem:

diff --git a/phonenumbers_test.go b/phonenumbers_test.go
index a7e16bd..dc58af3 100644
--- a/phonenumbers_test.go
+++ b/phonenumbers_test.go
@@ -1308,6 +1308,9 @@ func TestParsing(t *testing.T) {
                {"+2203693200", "", "+2203693200"},
                {"0877747666", "ID", "+62877747666"},
                {"62816640000", "ID", "+62816640000"},
+
+               {"62822400800", "ID", "+62822400800"},
+               {"6282240080000", "ID", "+6282240080000"},
        }
 
        for _, tc := range tests {

Unparsing phone number and country code

I am trying to use this library as follows:

  1. get user input for phone number (string) and country code (2-char string)
  2. use Parse(phoneNumber, countryCode) to get a PhoneNumber

However from this point I don't have a clue how to handle it, save to database and use it again later on.

I could store PhoneNumber.CountryCode and PhoneNumber.NationalNumber to database, but this library contains no means of unparsing that back to phone number and country code as input. I could use only number country code IDs as returned by Parse but then again this library can't parse using id (int) instead of code (2-char), as far as I could understand.

So how would I parsing a phone number + country code to a "storable" format and then unparse back? I don't care about formatting but I feel uint64 is a horrible choice for storage as it would gobble leading zeros.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.