All projects

SMS forwarding service



External Links


Technology Stack

  • Node.js
  • Cloud Functions for Firebase
  • Firebase Realtime Database

When I got a new phone number, I wanted to share the new number with my contacts as smoothly as possible. I set out with the following goals:

  • Avoid any type of mass announcement
  • Avoid having to manually tell people about the new number
  • When someone calls or texts the old number, guide them to the new number in a straightforward way, while providing enough friction to encourage them to update the number in their address book
  • Keep this guidance in place indefinitely for those who may not try to contact me for years at a time

Handling calls

For incoming calls, I wanted to play a greeting that required the caller to actively respond in some way. I decided to have them press 1 to hear the new phone number, and also have an option to press 2 to connect to the new number on the same call. I was able to set this up with Twimlets, using formed URLs to handle the logic. I hosted the audio files on Google Cloud Storage.

Handling text messages

I decided to use Twilio Programmable SMS to handle incoming text messages. I wanted to forward text messages to my new number, and automatically reply to the sender to let them know that they have contacted an old number. I used Cloud Functions for Firebase to create an endpoint to receive Twilio webhooks.

Conditional replies

The incoming message is forwarded to the new phone number first, and the success status is stored in a variable. The sender receives this message back:

I have a new mobile phone number. Please reply NUMBER to get the new number and update your address book. Your original message has been forwarded.

If the message is not successfully forwarded, the reply indicates as much, so the sender can try again or contact the new phone number directly.

If an incoming message is "NUMBER", the reply contains the new phone number instead of the main reply message.

Preventing infinite reply loops

So far, this works pretty well for messages sent by humans, but what about messages sent by computers? I found that some services reply to every message they receive, so if we are also doing that, the messages will bounce back and forth hundreds or thousands of times before one of the sides fails to reply. I wanted to prevent this loop from starting, so I implemented debouncer functionality so that the function does not send the main reply message if it has already been sent to a particular phone number in the last 10 minutes.

I used Firebase Realtime Database to store a timestamp for each sender phone number, and the cloud function checks that timestamp before replying.

Database tree showing sender phone numbers with timestamps

This leads to a smoother experience for a human sender as well: if they submit a group of messages all at once, they only get one reply back, instead of a reply for each message.