Exotel HQ, Bangalore, 6:30 PM. The view from the roof of our office is one like no other. We face west only to see the beautiful Ulsoor lake and serene Buffalo Ganj smack dab in the middle of it. The warm, familiar smell of petrichor reminds me that it’s that time of the year again. My friends leave early to avoid the downpour but I stay behind, with the intent to watch the sun burrow itself into the ground behind the now-drizzle.
It’s now 7:00 PM, and I step out of the office. There are grand plans for the evening, and if Lady Luck smiles on me from behind those clouds, it’ll be an amazing way to end the week – a little rain won’t dampen my spirits. But the traffic might. And maybe even burn a hole in my wallet.
If you live in a trafficked place like Bangalore, your evening could look like this:
Add rainy evenings to this. And then, ‘low battery’ on your phone.
I don’t need to tell you how annoying this situation is and facing it every day is not any prettier.
It was one such Friday evening, and a mix of everything was in the air.
Rain, traffic, frustration and time to kill. Plus, the unique combination of laziness, impatience, hubris that define a typical programmer – as mentioned by Larry Wall.
That’s when I decided to flex my programming muscles and build a nifty hack.
What if I could create my personal assistant using Uber and Exotel?
This is what I wanted to build: Check the availability of cabs near my office. Give me a call when there were cabs with no surge available.
I looked up the Uber API doc, and it did not disappoint. There was the Estimates API that could do the trick.
Go to https://developer.uber.com/ and create a developer account. Click on the “New App” button and give it a fancy name. I call it the “No Surge Assistant.” Click on the App and copy the Server Token. Let’s call it the Uber Token. This will come in handy later.
Create an app with a simple IVR. Something that can simply say “cabs available with no surge in your area”. Note the ID of the App you just created. Let’s call it the exotelAppId. Like all good things, it will come in handy later too.
Uber has some simple to use SDKs. But I used the estimates API and thought I would use plain old CURL and get the job done. Replace $uberToken with the token you copied in Step 1. The $from and $to are lats, long coordinates of your current location and the destination. I always take the UberGo. YMMV
function getRideData($from, $to = null) { global $uberToken; $ch = getCurlObj(); $url = "https://api.uber.com/v1/estimates/price"; $params = "start_latitude=$from[0]&start_longitude=$from[1]"; if (!is_null($to)) { $params .= "&end_latitude=$to[0]&end_longitude=$to[1]"; } $url .= "?" . $params; curl_setopt($ch, CURLOPT_HTTPHEADER, array( "authorization: Token $uberToken" ) ); curl_setopt($ch, CURLOPT_URL, $url); $res = curl_exec($ch); $error = curl_error($ch); $httpStatusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); if ($httpStatusCode == 200) { $res = json_decode($res); } else { $res = $httpStatusCode; } curl_close($ch); return $res; } function isUberSurging($data) { if (empty($data->prices)) { echo "No rides available"; return true; } else { foreach ($data->prices as $uberProduct) { if ($uberProduct->display_name == "uberGO" && $uberProduct->distance < 3 && $uberProduct->surge_multiplier == 1.0) { return false; } } } return true; }
And when your code finds that your favorite Uber is not surging, invoke the Exotel APIs to connect you to the App you created. The $appId is the Id of the app you set up in Step 2.
You can pick up your $exotelToken and $exotelSid from here.
function intimateSubscriber($subscriberNum) { global $exotelToken, $exotelSid, $appId, $exotelVn; $postData = array( 'From' => "$subscriberNum", 'To' => $exotelVn, 'CallerId' => $exotelVn, 'Url' => "http://my.exotel.in/exoml/start/". $appId, 'CallType' => "trans" ); $ch = getCurlObj(); curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData)); curl_setopt($ch, CURLOPT_USERPWD, $exotelSid . ":" . $exotelToken); $url = "https://twilix.exotel.in/v1/Accounts/".$exotelSid."/Calls/connect"; curl_setopt($ch, CURLOPT_URL, $url); $http_result = curl_exec($ch); $error = curl_error($ch); $http_code = curl_getinfo($ch ,CURLINFO_HTTP_CODE); curl_close($ch); }
I set this up to run after 7 PM every day and check continuously for Uber cabs. After you find your cab, you can stop running this script. Or, another user-friendly way to do this to build a slightly longer Exotel app with an IVR option to stop looking for a cab after you book one. The Exotel app can have a passthru applet which pings your backend to stop the script.
You could take this a step forward by building a complete app that even books your cab using Uber’s Request API. But this will require you to spend more time and put in some more effort.
You can find code here for my app here
Feel free to fork the code and play around with it. Let’s build things!