Proxy your phone number with Twilio Programmable Voice and Twilio Functions
Time to read: 10 minutes
Using Twilio's Super Network, you can quickly buy phone numbers from around the world. You can even specify a specific area code to buy a phone number that is local to a certain state, territory, or region.
With Twilio Voice, you can quickly integrate voice communication into your applications. For the application in this tutorial, you'll use Twilio phone numbers, Twilio Voice, and Twilio Functions to create a proxy phone number!
What do I mean by a proxy phone number? Before explaining that, I will discuss a similar concept. In web development, there's a concept of "reverse proxies". When you send HTTP requests to a reverse proxy, the reverse proxy forwards the traffic to a web server on a private network. This way the web server still serves a website but isn't exposed directly to the internet adding benefits like security, performance enhancements, and much more.
Similarly, a proxy phone number is a public phone number hiding your real phone number that ideally, you would want to keep private. When the proxy phone number is dialed, the call will be forwarded to your private phone number. After you dial your proxy phone number, you can instruct it to dial another phone number.
The result is that your private phone number is never revealed to the person calling your proxy phone number, or the person you are calling through your proxy phone number.
In addition to proxying phone calls, you can also proxy text messages which you'll also implement in this tutorial.
So why is this useful? Privacy.
- You may not want to hand over your real phone number to marketeers, when signing up for services, etc. Instead, give out your proxy phone number and if you desire, swap to a new proxy phone number as needed.
- Maybe you are a streamer who takes phone calls while on air, but you don't want to share your private phone number with your audience.
- Maybe you enjoy demoing Twilio and you don't want to accidentally dox yourself in the process 😉
So how do you set this up? Start with buying a phone number from Twilio.
Prerequisites
The only things you'll need for this tutorial are:
- A web browser
- A Twilio account
To keep things as approachable as possible, you'll stick to using the Twilio Console exclusively (management web interface).You can switch to the beta console by pressing Try beta Console at the top left of the screen.
You can switch back and forth if necessary, but the experience should be largely the same.
Buy a Twilio phone number
After creating a Twilio account, you will be taken to your account dashboard. If you don't have a Twilio phone number already, click on the Get a Trial Number button.
Accept the phone number suggested by Twilio by clicking the Choose this Number button.
Alternatively, you can navigate to Phone Numbers > Manage > Buy a number. Here you can look for different numbers and quickly buy them:
Now that you have a phone number, you can move on to configuring where Twilio gets instructions when receiving a text message or phone call.
Configure your Twilio phone number as a proxy
To turn your phone number into a proxy, you need to attach some logic to it. You can do this by configuring webhooks on your Twilio phone number.
When your Twilio phone number is rung, Twilio will send an HTTP request to your webhook to ask for instructions. Your webhook responds with TwiML which is essentially Twilio flavored XML. This TwiML will instruct Twilio how to handle the phone call.
Here's a sample TwiML provided by Twilio:
When someone calls your phone number, and Twilio receives this TwiML as a response, the caller will hear the contents of the "Say" node in "Alice's" voice, followed by a 1-second pause, and then followed by the content of the second "Say" node.
There are a lot more capabilities available Voice TwiML, check out the TwiML for Programmable Voice documentation for more information.
In this tutorial, you will use Twilio Functions to implement your webhooks. Twilio Functions is a serverless platform based on NodeJS and provides convenient integrations with Twilio out of the box.
Of course, there are servers involved somewhere, but the servers are owned, managed, and scaled by Twilio so you don't have to worry about that yourself.
Create stub Twilio Functions
You'll need to configure two webhook URLs on your Twilio phone number: one for Voice and one for Messaging. Let's create stubs in Twilio Functions so you can configure the webhook URLs with these stubs before implementing the functionality.
Navigate to Functions > Services and click on the Create Service button. Enter "proxy" for the service name. Twilio will add a random part to the subdomain to ensure the subdomain is unique.
Click the Next button.
Create a function by clicking on the Add button and selecting Add Function in the context menu.
Name your function "/voice".
Create another function, but name it "/message".
Click the Deploy All button at the bottom of the page.
Lastly, click on the three dots next to your function names and copy both URLs somewhere for future use.
Configure webhook URLs
Now that you have the voice and message stub functions, you can configure their URLs on your Twilio phone number. Navigate to Phone Numbers > Manage > Active numbers and click on your phone number.
This will bring you to the configuration page of your Twilio phone number. Scroll down to the Voice & Fax section and paste in the voice function URL in the text field under the A CALL COMES IN label.
Next, scroll down to the Messaging section and paste in the message function URL in the text field under the A MESSAGE COMES IN label.
Finally, hit the Save button.
Now that you have configured the webhook URLs, you can call the Twilio phone number to verify the webhook.
If your account is in trial mode, you'll first hear "You have a trial account, you can remove this message at any time by upgrading to a full account. Press any key to execute your code."
Press any dial key on your phone so that Twilio will execute your webhook. Now you'll hear "Hello world".
You will not get a response when you send an SMS to the phone number, because the message function returns TwiML for Twilio Voice instead of messaging out of the box. You'll update this code later.
Implement voice proxy
Navigate back to your proxy function on Twilio Functions and click on Environment Variables under settings. Here you need to add two variables to store your proxy phone number and your private phone number (be sure to use the E.164 format when you add your numbers):
KEY |
VALUE |
PrivatePhoneNumber |
[YOUR PRIVATE PHONE NUMBER] |
ProxyPhoneNumber |
[YOUR TWILIO PHONE NUMBER] |
After adding these environment variables, they will be available on the context object.
Navigate back to the "/voice" function, update it with the following code and click save:
Here's what the code does:
- Takes the private phone number you configured in the environment variables and stores it in the
privatePhoneNumber
variable. - Creates a new TwiML voice response object. With this object, you can construct the desired TwiML response.
- The
event.From
property will hold the phone number of the person calling your Twilio phone number.
- If the phone call comes from your private phone number, you will construct TwiML to prompt you for the phone number to dial.
When you enter the phone number by pressing the digits on your phone, the pressed digits will be passed to another webhook at the relative URL /dialNumber.
If no response is given, the following message will play: "We didn't receive any input. Goodbye!". - If the phone call comes from any other phone number, the TwiML constructed will instruct Twilio to dial your private phone number.
In addition to the /voice function, you need to create a new function called /dialNumber which will dial the number you pass onto it by pressing the digits on your phone.
After creating the new function, delete the existing code and add the following code, then click Save :
Here's what the /dialNumber function does:
- Grabs your Twilio phone number, aka your proxy phone number, which you have configured in the environment variables and stores it in the
proxyPhoneNumber
variable. - Grabs the digits you entered on your phone when asked which number to call, and stores those digits in the
phoneNumberToCall
variable. - Create a new TwiML voice response object. With this object, you can construct the desired TwiML response.
- Before initiating the call to the desired phone number, the phone number will be repeated to you.
The.split('').join(' ')
is adding a space between every digit. This ensures that Twilio will pronounce the number as "seven one three ..." instead of "seven billion thirty-one million ...". - Lastly, the TwiML will instruct Twilio to dial the
phoneNumberToCall
and specify that the call should be made from the callerId which is set to your Twilio phone number.
Before testing out your new function, you’ll need to redeploy your proxy service with the new code by clicking Deploy All.
To test out the functionality, you will have to call another phone number that you own or someone you know owns. You will have to verify the phone number first if you are using a trial account.
You can follow the steps outlined by Twilio in this article to verify the phone number. Once you have verified the phone number, you can try out your proxy phone number.
Call your proxy phone number from your private phone number, and enter the digits of the phone number you want to call. Listen to a recording of me calling someone whom you can always rely on.
(Audio fragment by Rick Astley)
To test the functionality from the opposite direction, have the second phone number call your Twilio phone number and it will be forwarded to your private phone!
Implement message proxy
You can build a similar proxy functionality for text messaging, but you have two approaches here. Either you use TwiML to instruct Twilio to forward the messages, or you use the Twilio Client to send the message through Twilio's API.
The simplest approach is to use TwiML. Update the '/message' function with the JavaScript below and click Save:
The code does the following:
- Grabs the proxy phone number and the private phone number from the context (env variables) and stores them in the
proxyPhoneNumber
andprivatePhoneNumber
variable. - Creates a new TwiML messaging response object. With this object, you can construct the desired TwiML response.
- Grabs the body of the incoming text message and stores it in the body variable.
- The
event.From
property holds the phone number of the person messaging your Twilio phone number. - If the message originated from your private phone number:
- Verify that the message starts with "to".
The expected body for texts coming from your phone number is "To [phone number]: [Body]".
With this structure, you can easily extract the body you wish to send and which phone number you want to send it to.
If the body doesn't start with "to", respond with information on the expected body structure. Otherwise, move on. - Knowing that the phone number will be between "To " and ":", you can extract the target phone number using
body.substring(3, body.indexOf(':'))
. - Knowing that the target body will be after the colon character ":", you can extract the message using
body.substring(body.indexOf(':') + 1).trim()
. - The first
twiml.message
invocation will construct TwiML to send a message with the target text message to the target phone number. - The second
twiml.message
will respond to your private phone number with "Message sent".
- Verify that the message starts with "to".
- If the message does not originate from your private phone number:
- TwiML is constructed to forward the incoming message to your private phone number.
The alternative using the Twilio Client looks like this:
The logic is very similar, but instead of using TwiML, the Twilio client is used which you can get by calling context.getTwilioClient()
.
Some of the TwiML code has been replaced with client.messages.create({})
.
The benefit of using the client is that you have callbacks for both success and errors when sending the messages.
To test this out, click the Deploy All button at the bottom of the page and send a message from your private phone number to your Twilio phone number in the correct format: "To [target phone number]: [Body]".
You will have to verify the target phone number first if you are using a trial account. You can follow the steps outlined by Twilio in this article to verify the phone number. Once you have verified the phone number, the message will be sent to the target phone number.
To test out receiving texts, have the other phone number text your Twilio phone number and you should receive a text message looking like this: "SMS From: [their phone number], Body: [their text message body]"
Enhancements and security warnings
To determine whether the call originated from your private phone number or someone else's phone number, the webhook checks whether the from
property equals to your private phone number stored in the environment variables. As an additional verification method, you could add your own passcode functionality which you can prompt when dialing or texting your proxy phone.
This solution works to protect a single phone number with a single Twilio proxy phone number. When you want to proxy multiple phone numbers or create proxies as needed by your application, you want a more scalable solution. Twilio has got your back with Twilio Proxy. Using Twilio Proxy you can programmatically create a proxy session between two phone numbers and let participants communicate over a proxy instead of a direct connection.
Summary
In this blog post, you learned how to turn a Twilio phone number into a proxy phone number. You can provide the proxy phone number to prevent leaking your private phone number and thus protecting your privacy. By using Twilio Functions as webhooks for your Twilio phone number, you added logic to proxy phone calls and text messages to your private phone number.
Additional resources
Check out the following resources for more information on the topics and tools presented in this tutorial:
TwiML for Programmable Voice - learn more programmable voice capabilities available for developers in the TwiML language
TwiML Message - learn more programmable voice capabilities available for developers in the TwiML language
Twilio Functions - learn more about Twilio's serverless NodeJS offering
Twilio Proxy – Use this dedicated proxy product by Twilio to enable seamless message and voice proxies for your entire workforce
Niels Swimberghe is a Belgian Full Stack Developer and blogger working in the USA. Get in touch with Niels on Twitter @RealSwimburger and follow Niels’ blog on .NET, Azure, and web development at swimburger.net.
Related Posts
Related Resources
Twilio Docs
From APIs to SDKs to sample apps
API reference documentation, SDKs, helper libraries, quickstarts, and tutorials for your language and platform.
Resource Center
The latest ebooks, industry reports, and webinars
Learn from customer engagement experts to improve your own communication.
Ahoy
Twilio's developer community hub
Best practices, code samples, and inspiration to build communications and digital engagement experiences.