Twilio for Vacation Rentals
It's been a busy summer and a full rental season since I first automated my vacation rental and it worked beautifully! All season I simply forwarded new reservation emails and it took care of everything else. But there is still one sticking point...
I don't want to have to login to VRBO
I had to login to VRBO and look up every renter's email address, as it's not included in any emails VRBO sends. This finally got on my nerves enough and I really don't want to forward the reservation emails at all. Since VRBO does provide phone numbers in their reservation emails, I wanted to use SMS texts instead.
Requirements
- Cheap. My guests don't call or text me much at all. I've received two phone calls and a handful of text messages over the past two years.
- Programmable. I want to be able to call it from Zapier or SmartThings to have it do stuff.
- Flexible. If I want to add another number later or change how it works, I don't want it to be a huge undertaking.
Options
There's a ton of VOIP and telephony offerings. Here's the shortlist of what I like and considered using.
Google Voice
I was using Google Voice at first. I already had the number and simply started using it. I figured it was better than giving out my number directly and it's well integrated with Android. It's also free!
However, it's not programmable and not very flexible. You can't have more than one number on your device and it's hard to change numbers (and not free). The biggest issue is there is no way to write code to use it. Plus, any chance I get to de-Google my life is always a win.
Burner.app
Burner.app is nearly perfect for my use case. It's cheap at $48/year, programmable with their own API, and easy to use and change numbers. The only reason I didn't use it is it's not quite cheap enough for my very small usage. If my usage increases even a tiny bit or practically anything else happens, I'll probably switch to them. They use Twilio on the backend and have Zapier integration.
MySudo
MySudo.com is a complete alternate identity management app. It integrates alternate names, emails, and phone numbers. Unfortunately, it's only on iOS at the moment, and it's not programmable.
Twilio
Twilio lets you hack all things related to telephony. You can write code to handle SMS, voice, MMS, fax, and more. They've been around since 2008 and are now a publicly traded company in the US. I first used them years ago for a restaurant SMS waitlisting app. It's cheap, at $1/mo per number, plus usage.
My Choice: Twilio
The choice really came down to ~$15/year for Twilio with some coding to make it work exactly how I want, or $48 a year for Burner to do the basics. Since I'm a developer, Twilio is it.
I first created an account and added some funds. Since Twilio bills in small increments and nobody has solved the microtransaction problem yet, they take larger sums and maintain a balance.
Next, I bought an easy to remember number in the area code I wanted. Now, we code how we want our number to work.
Twilio Functions
Nowadays, Twilio has functions built-in (in beta), so they basically will host snippets of code for you. It used to be you had to provide callback URLs that return TWIML documents, which are a form of XML that told Twilio what to do.
Call Forward
Our first function will handle any voice calls to our number. Navigate to the Functions tab and click the red +. Give it a name and assign a path, I used /callForward.
Next is the code, copy and paste this in:
/**
* Call Forward Template
*
* This Function will forward a call to another phone number. If the call isn't answered or the line is busy,
* the call is optionally forwarded to a specified URL. You can optionally restrict which calling phones
* will be forwarded.
*/
exports.handler = function(context, event, callback) {
// set-up the variables that this Function will use to forward a phone call using TwiML
const MY_NUMBER = '+1XXXYYYZZZZ'; // Your real number
// REQUIRED - you must set this
let phoneNumber = event.PhoneNumber || MY_NUMBER;
// OPTIONAL
let callerId = event.CallerId || null;
// OPTIONAL
let timeout = event.Timeout || null;
// generate the TwiML to tell Twilio how to forward this call
let twiml = new Twilio.twiml.VoiceResponse();
let dialParams = {};
if (callerId) {
dialParams.callerId = callerId
}
if (timeout) {
dialParams.timeout = timeout
}
var ltz = new Date().toLocaleString("en-US", {timeZone: "America/New_York"});
let hour = new Date(ltz).getHours();
if (hour > 7 && hour < 18) {
twiml.say({voice: 'alice'}, 'Connecting you to the owner');
} else {
twiml.say({voice: 'alice'}, 'Connecting you to the after hours line');
}
twiml.dial(dialParams, phoneNumber);
// return the TwiML
callback(null, twiml);
};
When a guest calls our number, they will first hear a "Connecting you to..." prompt, and then it will call my phone and connect us. This is essentially a copy of the Twilio callForward template. I do some checks on time to present a different message if it's outside my normal awake hours. The idea is I can take most calls, but anything important enough to call overnight, I could make go directly to my local crew. Or I could have a prompt confirming it's a real emergency. I also use a different voice, this took me awhile to figure out how to do, documentation is still a bit sparce on how to use things in functions, versus TWiML.
One thing to note about this scenario, is when you do get calls, you're getting double charged. You're getting the base rate per minute for the guest talking to Twilio PLUS the base rate for Twilio talking to you. It can add up quickly!
Another downside of this scenario is there is no way to place calls from your Twilio number to your guest. You could have it check, and if you call from your phone, then prompt you for number to call. However, for now, I just block my caller id and call from my normal phone. It's seldom that I need to place calls from this number. This is where something like Burner would be handy.
SMS Forward
SMS is the real bread and butter of my usage. Navigate to the Functions tab and click the red +. Give it a name and assign a path, I used /smsForward.
Next is the code, copy and paste this in:
exports.handler = function(context, event, callback) {
const MY_NUMBER = '+1XXXYYYZZZZ';
var msg;
let twiml = new Twilio.twiml.MessagingResponse();
if (event.From === MY_NUMBER) {
const separatorPosition = event.Body.indexOf(':');
if (separatorPosition < 1) {
msg = twiml.message('You need to specify a recipient number and a ":" before the message.');
} else {
const recipientNumber = event.Body.substr(0, separatorPosition).trim();
const messageBody = event.Body.substr(separatorPosition + 1).trim();
msg = twiml.message({to: recipientNumber});
msg.body(messageBody);
}
} else {
msg = twiml.message({to: MY_NUMBER});
msg.body(`${event.From}: ${event.Body}`);
}
for (i = 0; i < event.NumMedia; i++) {
msg.media(event[`MediaUrl${i}`]);
}
callback(null, twiml);
};
This will forward any SMS messages to MY_NUMBER, including any attachments. When I send an SMS from MY_NUMBER, I need to prepend the destination number followed by a colon, and it will forward it along to that number. The idea being I can text guests simply by texting my Twilio number and prepending the message with the guest number. Getting attachments to work is simple, but took some experimentation, as documentation and examples are lacking.
Hookup Functions
The last thing we need to do now that we have our functions, is hook them up. Navigate to Manage Numbers and navigate to your number. Edit the Voice URL to use your /callForward function and your Messaging URL to use your /smsForward function. Save and test!
Zapier
Now that the number is ready to go, we can hook it up in Zapier. I disabled my old zap to email guests and enabled my new zap to text them instead. I had to shorten my messaging considerably for SMS versus email.
I also changed my mail parser to handle the original mails VRBO sends, instead of my forwarded ones with the email prepended.
Lastly, I created a rule mail rule to automatically forward new reservation emails to my new email parser. Done!
Tradeoffs
There are some dowsides to doing things this way:
- Cost can easily balloon with high usage. If you get even a call or SMS a day, I think Burner would be a better option. This method only makes sense if you need to full code control or have very low usage.
- You can't use the number for everything. Twilio cannot receive SMS messages from short code numbers. So any of those automated services that text you to verify your number? Any two-factor auth via SMS? You'll never get them. Since Burner uses Twilio, they have the same problem. Google voice does not.
- It's possible the number guests provide VRBO are not capable or receiving SMS. You'll never know and they will never get your welcome message. I'm assuming this is rare.