If you're sending SMS, MMS — or performing any other form of communication using Twilio's Programmable Messaging API — you'll know that phone numbers must be in E.164 format. The question is, how can you validate them in Go?
Well, in this short tutorial, you're going to learn how, using Twilio's E.164 regular expression (tl;dr, it's ^\+[1-9]\d{1,14}$
).
Actually, you're going to learn a bit more than that. Just showing the core code to validate a phone number would only take about 30 seconds. So, instead, I'll make the tutorial a bit more interesting and fun.
You're going to learn how to create a small Go-powered API that can accept requests with a phone number, and return a small JSON response confirming whether the number is correctly formatted or not.
It's worth mentioning that the E.164 regex is only a simplistic way of catching invalid phone numbers. It doesn't perform more comprehensive searches and validation. Something that does, however, is Twilio's Lookup API, which can, among other things:
- Get confirmation of ownership for a mobile phone number
- Get information on the last SIM change for a mobile phone number
- Get a phone number's line type
Give it a try, if you're looking for a comprehensive solution!
Prerequisites
To follow along with this tutorial, you're going to need the following:
- Go
- curl
- Your favourite text editor or IDE. I recommend Visual Studio Code.
- Some prior experience with Go would be helpful, though not required
Create the project directory structure
Where you keep your Go projects: create a new project directory, change into it, and track modules, by running the following commands.
mkdir e164_validator_api
cd e164_validator_api
go mod init e164_validator_api
Build the Go API
Now, let's write the Go code. Create a new file named main.go, and in that file paste the code below.
package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
"regexp"
"strings"
)
func IsValidPhoneNumber(phone_number string) bool {
e164Regex := `^\+[1-9]\d{1,14}$`
re := regexp.MustCompile(e164Regex)
phone_number = strings.ReplaceAll(phone_number, " ", "")
return re.Find([]byte(phone_number)) != nil
}
type Response struct {
Data string
}
func validate(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
phone_number := r.FormValue("phone_number")
if phone_number == "" {
w.WriteHeader(http.StatusBadRequest)
json.NewEncoder(w).Encode(Response{
Data: "No phone number was provided\n",
})
return
}
if IsValidPhoneNumber(phone_number) {
w.Write([]byte(fmt.Sprintf("[%s] is a valid phone number", phone_number)))
json.NewEncoder(w).Encode(Response{
Data: fmt.Sprintf("[%s] is a valid phone number", phone_number),
})
return
}
w.WriteHeader(http.StatusBadRequest)
json.NewEncoder(w).Encode(Response{
Data: fmt.Sprintf("[%s] is NOT a valid phone number", phone_number),
})
}
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/", validate)
log.Print("Starting server on :4000")
err := http.ListenAndServe(":4000", mux)
log.Fatal(err)
}
The code defines a small function, IsValidPhoneNumber()
. It uses Twilio's E.164 regex and Go's regexp package to determine if the phone number, phone_number
, is formatted correctly. It returns true
if it is or false
otherwise.
Then, it defines another function, validate()
. The function starts by attempting to retrieve the phone_number
parameter from the request. If it was not set or was empty, a response is returned with a message stating this. Otherwise, the retrieved phone number is validated with IsValidPhoneNumber()
. The response's body is then set to a message confirming whether the number was valid or not.
Finally the main()
function is defined. It sets up the application to handle HTTP requests, with the validate()
function handling requests to the application's default route.
It's worth noting that Twilio's E.164 regex doesn't accept valid phone numbers written in other formats. For example, in Germany, you often replace the leading + with 00. And even Twilio APIs accept phone numbers if this part is omitted. However, this regex does not. Please keep that in mind.
Test the code
With the code written, it's now time to test that it works. Start by launching the application with the following command.
go run main.go
Then, run the following command to make a request to the app with curl. Make sure to replace the phone number placeholder with the phone number that you want to test.
curl -i --form "phone_number=<<PHONE NUMBER>>" http://localhost:4000
If the phone number is valid, you should see the following output in the terminal (with the phone number you entered instead of the placeholder).
HTTP/1.1 200 OK
Content-Type: application/json
Date: Thu, 24 Aug 2023 10:20:38 GMT
Content-Length: 55
{"Data":"[<<PHONE NUMBER>>] is a valid phone number"}
That's how to validate that an E.164 phone number in Go
There's not a lot to do. But it's still helpful to know how. I hope that you found the approach that I took to be fun and interesting.
How would you check whether a phone number is in E.164 format? Let me know on LinkedIn?
Matthew Setter is a PHP and Go Editor in the Twilio Voices team and a PHP and Go developer. He’s also the author of Mezzio Essentials and Deploy With Docker Compose. When he's not writing PHP code, he's editing great PHP articles here at Twilio. You can find him at msetter[at]twilio.com, on LinkedIn and GitHub.

In this tutorial, you're going to learn how to build a small S3 file manager in Go that can list files in, upload files to, and download files from the bucket.

In this tutorial, you will learn how to use Cobra to build a CLI application in Go that encrypts and decrypts text based on a specified cipher.

Learn how to build a GitHub desktop client using Wails, React, and Vite which will interact with the Github API.

In this tutorial, you’ll build a Go application that sends inspiring messages via SMS using Twilio Messaging Service to a list of your friends.

In this tutorial, you'll learn how to retrieve your Twilio account usage using Go and Twilio's Go Helper Library, along with a few other classes to make the whole process easier and simpler.

In this article, you'll start learning how to test in Golang by learning how to unit testing a REST API.