One of Esper’s customers came to us with an interesting challenge: they’d provision devices that would then sit in the warehouse, switched off, until they were needed—sometimes for a long period of time. While these devices were on the shelf, the customer would continue to update their app. When the customer would finally pull devices from inventory to ship to their end-customers, they would have outdated versions of their app loaded.

The customer came to us to find a way to automatically push the latest version of the app to these devices as soon as they came online.

The Esper Solution

The solution was to create an AWS Lambda, (an event-driven, serverless computing platform provided by Amazon Web Services), with an API gateway in front of it, used in concert with Esper’s Device SDK. After one of these stored devices is booted up, the customer’s kiosk mode app calls the lambda and passes the app’s build number (versionCode) as well as the Esper Device ID obtained by the app using the Device SDK

The Lambda calls the Esper platform to determine if a more recent version of the app has been uploaded to the customer’s endpoint. If it has, the Lambda sends a message to the Esper platform to update the device with the latest version of their app.

Let’s put it all together, step by step.

AWS Lambda to call Esper API

The purpose of the lambda is to call Esper’s app install API. The lambda will be triggered by your app on the device whenever it boots up after sitting in inventory. You can natively use Esper APIs to build and deploy your own lambda or use the one we have open sourced for our customers here

You can also follow the instructions below to setup the lambda.

Setup

  • Clone the lambda repository to your PC
$ git clone https://github.com/esper-io/esper-sample-solutions.git
  • Ensure you have an environment with Python 3.7 available.
  • Ensure you have the SAM CLI installed. This will be used to create a server less application that you can package and deploy in AWS cloud. Ensure you have Docker installed.

Note: Docker is only a prerequisite for testing your application locally.

  • Change you working directory to esper-sam-auto-app-updater
  • Modify the samconfig.toml file and change the stack_name, s3_bucket, s3_prefix and region to suit your infrastructure setup. Sample setting values are given below
stack_name = "esper-sam-auto-app-updater"
s3_bucket = "auto-app-updater"
s3_prefix = "esper-sam-auto-app-updater"
  • Additionally, you will need following credentials to talk to Esper APIs
    • Endpoint name (x), if the URL for your Esper endpoint is foo.esper.cloud, use foo here.
    • API Key (y) from your console. See Generating an API Key.
    • Enterprise ID (z)  from your console. You can get your Enterprise ID from the web dashboard in the Company Settings tab.

Usage

Build the lambda:  To build locally, issue the following command:

$ sam build --parameter-overrides EndpointName=x ApiKey=y EnterpriseId=z

Run locally: Once built, you can run it locally using the following command

$ sam local start-api --parameter-overrides EndpointName=x ApiKey=y EnterpriseId=z

With the above command, you will see something like this:

Mounting EsperSamAutoAppUpdaterFunction at http://127.0.0.1:3000/updateme [POST]

You can now browse to the above endpoints to invoke your functions. You do not need to restart/reload SAM CLI while working on your functions, changes will be reflected instantly/automatically. You only need to restart SAM CLI if you update your AWS SAM template

2020-06-08 13:57:58  * Running on http://127.0.0.1:3000/ (Press CTRL+C to quit)

Invoking app.lambda_handler (python3.7)

Fetching lambci/lambda:python3.7 Docker container image......

Mounting /projects/esper-sample-solutions/esper-sam-auto-app-updater/.aws-sam/build/EsperSamAutoAppUpdaterFunction as /var/task:ro,delegated inside runtime container

Your lambda can be accessed at http://127.0.0.1:3000/updateme

Trigger Lambda from Device

Once the lambda is up and running, you will have to trigger the lambda from the device when your application is launched the first time after boot. An update will be triggered only when the latest version of the app is present in the Esper console. 

To trigger the lambda make a HTTP POST call to lambda endpoint with the following payload

 {
    "device_id":"<e.g. ESP-DMO-ABCD>",
    "pkg":"<e.g. io.esper.foo>",
    "build_number":"<e.g. 29>"
  }

device_id: It’s the unique name assigned to devices provisioned on Esper.  You will need to use the Esper Device SDK in your application to get the device ID

pkg: This is the package name of  the Android application.
build_number: This is the existing build number of  the Android application on device.

Now you can test locally using the following commands:

curl -s --header "Content-Type: application/json"   
--request POST
 --data '{"device_id":"SNA-SNL-2CCF","pkg":"io.esper.foo","build_number":"32"}'
 http://127.0.0.1:3000/updateme

The Lambda will give one of two possible responses:

  • Successfully pushed the newest app to the device:
{"status": "Request Succeeded", "msg": ""}
  • Failure message with appropriate reason:
{"status": "Request failed", "msg": "App is not compatible"}

If status is Request succeeded the update has succeeded.

Note: Please ensure you call this API only once per boot session. Also, limit the calls to the Lambda as much as possible.

Deploy to Production

To deploy this to production, issue the following command:

$ sam deploy --parameter-overrides EndpointName=x ApiKey=y EnterpriseId=z

At the end of the command, you will see something like this:

CloudFormation outputs from deployed stack
------------------------------------------------------------
Outputs
------------------------------------------------------------
.
.
.
Key            EsperSamAutoAppUpdaterApi
Description    API Gateway endpoint URL for Prod stage for EsperSamAutoAppUpdater function
Value          https://r89y34l2j4.execute-api.us-west-2.amazonaws.com/Prod/updateme/
------------------------------------------------------------

You can now issue commands from the device to the URL listed above (e.g. https://r89y34l2j4.execute-api.us-west-2.amazonaws.com/Prod/updateme/ in the above case)

curl -s --header "Content-Type: application/json" \
  --request POST \
  --data '{"device_id":"ABC-DEF-GHIJ","pkg":"io.esper.foo","build_number":"99"}' \
  https://r89y34l2j4.execute-api.us-west-2.amazonaws.com/Prod/updateme/

To learn more about Esper’s developer tools, get in touch with us for a demo.