There’s a button for that

Andrew (Andy) Warr
Uber Developers
Published in
4 min readMay 30, 2016

It’s Saturday night and my wife and I are getting ready to go out. We are nearly ready and it is time to call an Uber. To do this we have to:

  1. Find our phone
  2. Unlock the phone
  3. Find the Uber app
  4. Open the Uber app
  5. Select the service e.g. UberX
  6. Position the pin
  7. Set the pickup location
  8. Request a driver

This is a lot of work! There must be an easier way!

I recently purchased an Amazon Web Services (AWS) Internet of Things (IoT) Button. The AWS IoT Button is a programmable button based on the Amazon Dash Button — a Wi-Fi connected device that reorders your favorite product with the press of a button.

I thought to myself, if the Amazon Dash Button could be used to order a product with the press of a button, could the AWS IoT Button be programmed to request an Uber.

I was not the first person to have this idea. Geoffrey Tisserand wrote a Medium article in October 2015 describing how to summon Uber with the AWS IoT Button and had hacked an Amazon Dash Button to order Uber rides in September 2015.

Geoffrey Tisserand had published his code to Github — thank you — so I forked his repo and made some edits. The edits I made related to one of the open issues: use the different types of button presses. Specifically, if the button were pressed once it would request an UberX; if the button were pressed twice it would request an UberBlack; and, if the button were pressed and held down it would cancel the requested Uber. I also wanted to automatically handle surge pricing. When I call an Uber I generally need to go somewhere at that moment and therefore am willing to accept surge pricing.

In this article I am not going to describe how to set-up an AWS IoT Button. You can refer to the AWS IoT Button product page and step-by-step tutorial for this information. Instead, I will focus on the specifics of my implementation.

Detecting button states

When the AWS IoT Button is pressed it sends a JSON object an AWS endpoint that can be passed to an AWS Lambda.

{
“serialNumber”: “GXXXXXXXXXXXXXXXXX”,
“batteryVoltage”: “mV”,
“clickType”: “SINGLE | DOUBLE | LONG”
}

The clickType can be detected using conditional statements.

In the single click condition an UberX is requested and a UberBlack is requested for the double click condition. This is achieved by passing the product_id for an UberX or UberBlack to the requestUber function. You can find more information on getting product_ids here. In the long click condition an Uber request is cancelled by calling the cancelUber function.

Requesting an Uber

Requesting an Uber requires making a http POST request. The request includes the latitude and longitude of the pick-up location. The latitude and longitude of the destination is not included as the user may want to go to a different place with each press of the button. The user can instead enter their destination into the Uber app or tell the driver. Not knowing the end destination does however prevent services such as UberPool from being used. The http POST request also includes the product_id of the service being requested which was passed to the requestUber function depending on the clickType.

Assuming the http POST request is successful the Uber API returns http status code 202.

Accepting Surge Pricing

There are occasions when surge pricing is in effect. In these cases the user has to explicitly accept the surge pricing. However, this would require additional interaction. As mentioned before, when I call an Uber I generally need to go somewhere at that moment and therefore am willing to accept surge pricing. As such, my code automatically accepted surge pricing.

If surge pricing is in effect, http status code 409 is returned by the Uber API, along with a JSON object that includes a surge_confirmation_id property. Using a http GET request the HTML code of the webpage a user has to accept the surge pricing can be requested. This webpage includes a csrf_token that can be posted to the webpage using a http POST request to get a surge_confirmation_token. Apologies for the hacky way the csrf_token is extracted from the HTML in the code above. The returned surge_confirmation_token indicates the user is willing to accept surge pricing. Requesting an Uber again by passing the surge_confirmation_token as the surge_confirmation_id parameter will successfully request an Uber with surge pricing.

Cancelling an Uber

An Uber can be cancelled using a http DELETE request, which will cancel the last requested Uber.

Uber Button

To summarize with the press of a button the Uber button can:

  • Request an UberX (automatically accepting surge pricing)
  • Request an UberBlack (automatically accepting surge pricing)
  • Cancel an Uber

With a functioning button the only thing left to do was decorate it. A Photoshop template I created for the AWS IoT Button can be found here and my code for the AWS Lambda function is available on Github.

--

--