Mobile Locker

Suggest Edits

Authentication

 

Log in to the admin portal and go to My Account > API Tokens:
https://mobilelocker.com/admin/tokens

Click New Token and give your token a name.

Copy the token value to your clipboard

If you are on a Mac or Linux machine, create a blank file in your home directory named .mobilelocker (it is a hidden file with a period at the front) and enter the following into it:

ML_API_TOKEN=YOUR_TOKEN_HERE

Save that file.

All API requests must be made over HTTPS. Calls made over plain HTTP will fail. API requests without authentication will also fail.

Suggest Edits

Get a Presentation's ID

 

You'll need the presentation's ID to interact with it using the API.
Open the admin portal and navigate to the presentation's page. The Presentation ID is the number the URL.

Suggest Edits

Upload a presentation programatically

 

Get the Presentation's ID from the admin portal - and paste it into line 4 of this script.

The basic idea is that it will generate a zip file for your HTML presentation and upload it to Mobile Locker using curl.

Save this script to your project's root directory as deploy-prod.sh and make it executable. Review the code line-by-line first because you might need to adjust for your build environment.

#!/bin/bash

source $HOME/.mobilelocker
PRESENTATION_ID=[The presentation ID from the admin portal]
API_URL="https://mobilelocker.com/api/presentations/$PRESENTATION_ID/upload"
clear
echo "PRESENTATION_ID: $PRESENTATION_ID"
echo "API_URL:         $API_URL"
read -p "Press ENTER to continue."

# If you're not using gulp to build your presentation, replace this with your build command
gulp --production

# zip everything in the "public" directory into "presentation.zip"
rm -f presentation.zip
cd public
zip -r --exclude=.gitignore ../presentation.zip .
cd ../

read -p "ZIP Complete. Press ENTER to upload."

# Upload the zip file to Mobile Locker using your API TOKEN
AUTH_HEADER="Authorization: Bearer $ML_API_TOKEN"
curl \
    --header "$AUTH_HEADER" \
    --form file=@presentation.zip \
    "$API_URL"

echo ""
echo "COMPLETE"

Now you can quickly upload your changes to Mobile Locker.

You'll receive a notification email as soon as the new version is ready.

You can also be notified by SMS if you add your mobile number to your profile.

Suggest Edits

Upload a file programmatically

 

You can upload individual files into an HTML presentation programmatically. This could be useful if your presentation has a data file that changes frequently (such as a customer list).

#!/bin/bash

source ~/.mobilelocker
# This is the ID of the presentation in Mobile Locker.  Look at your browser's URL to retrieve this value.
PRESENTATION_ID=[The presentation ID from the admin portal]

if [ "$#" -ne 2 ]
then
  echo "Usage: ./upload-file.sh LOCAL_FILE UPLOAD_PATH"
  echo "LOCAL_PATH is the location of the file on your computer.  EX: dist/index.html
  echo "UPLOAD_PATH is the path to the file, relative to the presentation's base directory in Mobile Locker.  It should not start with a slash.  EX: index.html, js/data.json
  exit 1
fi

LOCAL_FILE=$1
UPLOAD_PATH=$2

# Use CURL to upload the file file.
AUTH_HEADER="Authorization: Bearer $API_TOKEN"
UPLOAD_URL="https://mobilelocker.com/api/presentations/$PRESENTATION_ID/files/upload"
curl \
--header "$AUTH_HEADER" \
--form path="$UPLOAD_PATH" \
--form file=@$LOCAL_FILE \
"$UPLOAD_URL"

# You will receive an email notification (and SMS if you added your mobile number) when it's ready.
# Open Mobile Locker and pull-to-refresh to get the latest changes
Suggest Edits

API Endpoints for the apps

 

The endpoints for the apps are documented here:
https://mobilelocker.com/swagger/?url=/swagger-app.yml

Suggest Edits

Get the SDK

 

Use the Source!

The JavaScript SDK is hosted on BitBucket:
https://bitbucket.org/vorenusventures/mobilelocker-tracking

Recommended: Using the module

The Mobile Locker SDK is available as an ES2015 module:

# Recommended: Install it using yarn (https://yarnpkg.com):
yarn add --dev mobilelocker-tracking

# Or install it using npm
npm install --save-dev mobilelocker-tracking

Include it in your JS file:

# ES2015:
import mobilelocker from 'mobilelocker-tracking';

# CommonJS:
const mobilelocker = require('mobilelocker-tracking');
Suggest Edits

Framework Recommendations

 

You can build your presentations using any JavaScript libraries you want (jQuery, Angular, React) but we have a few recommendations:

Our Recommendations

We recommend building presentations using:

Suggest Edits

Sample Presentations

 

Explore the source

Download sample presentations from our BitBucket repos:
https://bitbucket.org/account/user/vorenusventures/projects/MOB

Suggest Edits

Track events in a presentation

 

The SDK is flexible and does not impose any restrictions on what events you track in a presentation.

For example, if you have a multi-screen presentation, you probably want to record an event each time a user navigates from one screen to another. If your HTML has navigation links that look like this:

<ul>
  <li><a href="products.html">Products</a></li>
  <li><a href="product-a.html">Product A</a></li>
  <li><a href="product-b.html">Product B</a></li>
  <li><a href="about-us.html">About Us</a></li>
</ul>

Then you could use jQuery (or whichever framework you want) to log an event each time a user taps one of those links like this:

$('a').click(function() {
	var target = $(this).attr('href');
  //the first parameter is a category, the second is the action in that category.
  //Both are arbitrary, but these are the recommended values for consistency
  mobilelocker.logEvent('navigate', 'tap', target);
  return false;
});

So if the user navigated from products to product-a, to about-us, the following events will be logged:

mobilelocker.logEvent('navigate', 'tap', 'products.html');
mobilelocker.logEvent('navigate', 'tap', 'product-a.html');
mobilelocker.logEvent('navigate', 'tap', 'about-us.html');

The app will immediately log that event to the app's database. If you have an internet connection, it will also send it to the admin portal. To view the events it logs in each user session, go to Presentations > [ Your Presentation] > Sessions, and select the session.

The logEvent function takes 3 arguments:

Argument
Description

category

A high level grouping of what the user did. Examples: navigate, Video

action

What the user did within that category: tap, open

path (or uri)

The path or URL on which the event occurred: /products.html, /more-info.html, etc.

// This example logs the user interacting with a video
mobilelocker.logEvent('video', 'open', 'video-1.mp4');
mobilelocker.logEvent('video', 'pause', 'video-1.mp4');
mobilelocker.logEvent('video', 'fast-forward', 'video-1.mp4');
mobilelocker.logEvent('video', 'close', 'video-1.mp4');

You can use the SDK to get logged events too.

Suggest Edits

Google Analytics

You can log events to Google Analytics

 

The same event-tracking you configured above can also be sent to a Google Analytics profile. Configuring GA for a presentation is simple:

Create the Property in Google Analytics like you normally would.

  • Select Website
  • For Website Name, enter the name of the presentation
  • For Website URL, enter a fake URL, like presentation-name.your-company.com
  • Select an Industry category if you want
  • Select the reporting time zone.
  • Click Get Tracking ID
Create the profile for your presentation

Create the profile for your presentation

Make note of the Profile ID, which looks like UA-########

Get the Tracking ID

Get the Tracking ID

Edit the Presentation in ML Admin Portal, entering the GA Tracking ID into the field. Save the changes.

Edit your presentation in the admin portal.  Set the Tracking ID.

Edit your presentation in the admin portal. Set the Tracking ID.

That's it. The next time Mobile Locker syncs, the events will be sent to the admin portal and to Google Analytics.

Google Analytics is for trending, not precise measurement.

Data does not appear in Google Analytics right away. It may take 24-36 hours for GA to update. Also, GA is an aggregate, trending tool. You will not be able to see what an individual user did in a presentation. That is what the ML admin is for, and specifically, the Sessions and Dashboard tabs on each presentation

GA is for trending.  Go to the Dashboard and Sessions tabs if you want all of the data captured by Mobile Locker.

GA is for trending. Go to the Dashboard and Sessions tabs if you want all of the data captured by Mobile Locker.

Suggest Edits

Capture a form in a presentation

 

You can insert a <form> into an HTML presentation. Intercept the submit() event in JavaScript so the submitted data will be serialized to JSON and sent to the admin portal, where it can be exported to CSV or sent to another system using a webhook.

Example: Take attendance at a conference or event

Sample Code

Download this attendance-taking presentation here:
https://bitbucket.org/vorenusventures/kazaamax-attendance

Example: Take attendance at a conference

Example: Take attendance at a conference

View the submitted data in the admin portal

The data is logged as an event and viewable in the admin portal like this:

The submitted form data can be viewed in the admin portal.

The submitted form data can be viewed in the admin portal.

Example Implementation

This example uses jQuery but the sample attendance app uses VueJS.

<form id="attendance" method="post" action="mobilelocker/api">
  <input type="text" name="first_name" value="Joe" />
  <input type="text" name="last_name" value="Smith" />
  <button type="submit">Submit</button>
</form>
$('#attendance').submit(function(event) {
  event.preventDefault();
  // https://api.jquery.com/serializeArray/
  var tempData = $(this).serializeArray();
  var formData = {};
  // optional: convert the array to an object with the corresponding name-values
  for (var i = 0; i < tempData.length; i++) {
    formData[tempData[i].name] = tempData[i].value;
  }
  mobilelocker.submitForm('attendance-form', formData);
  alert('Thank you for registering');
  return false;
});
Suggest Edits

Capture a signature

 

There are many JavaScript libraries that let a user draw using their finger on a CANVAS object and convert that to a PNG or JSON. We recommend fabric.js and you can see how we used it in this sample project:
https://bitbucket.org/vorenusventures/kazaamax-attendance

Inspect resources/assets/js/components/Edit-Attendee.vue to see how we made it work in that presentation. Fabric serializes the CANVAS object is serialized to a base-64 encoded PNG. When you view the event in the portal, the image of the signature is displayed:

The base64-encoded PNG of the signature is displayed in the portal and can be exported using the API.

The base64-encoded PNG of the signature is displayed in the portal and can be exported using the API.

Other libraries you could use

Suggest Edits

The forms.json file

 

If you want to be able export form submissions to a CSV file from the admin portal, you'll need to let the portal know what the fields are in your presentation's form(s), so it can properly generate the columns and rows in the CSV file. This is the purpose of the forms.json file.
In your presentation's root folder (next to index.html), create a file named forms.json like this:

{
  "signup-form": {
    "title": "Signup Form",
    "fields": [
      "name",
      "email",
      "company",
      "country",
      "signatureJSON"
    ]
  },
  "form-2": {
    "title": "Friendly title to display in the admin portal",
    "fields": [
      "Field-1",
      "Field-2",
      "Field-3"
    ]
  }
}

signup-form and form-2 are the names of the form that are passed in as the first parameter to the mobilelocker.submitForm(formName, data) function. Internally, it maps to the action attribute in the Event Logging system.

title is the friendly title that will appear in the list of exportable forms on the presentation's forms tab in the portal:

Suggest Edits

Open a PDF

 

Mobile Locker uses PSPDFKit to display PDF files

iOS can display PDF files natively, but it is not very good and can crash when opening complex PDFs.

Mobile Locker for iOS uses PSPDFKit library to display PDF files.

Direct links or JavaScript

<!-- A direct link to a relative PDF will by opened by the PDF viewer. -->
<a href="pdf/employee-handbook.pdf">Employee Handbook</a>
// Or you can open it from JavaScript.
// The relative path is the first parameter.  The title is the second.
mobilelocker.openPDF('pdf/product-info.pdf', 'Product Information');

When the user taps that link, the app will intercept it and open that PDF in PSPDFKit:

Suggest Edits

Scan a QR code or barcode

 

New Feature

This functionality is available in Mobile Locker 3.0.4 (iOS) and later.

If you attend conferences or events where attendees have QR codes or barcodes on their name badges and you want to capture their information, this is the feature for you.

Supported codes

Mobile Locker can scan any of these codes:

  • Aztec
  • Code 39
  • Code 39, Mod 43
  • Code 93
  • Code 128
  • Data Matrix
  • Interleaved 2of5
  • ITF-14
  • PDF417
  • QR codes
  • UPC-E

Read more about these codes on barcode-generator.org

Open the Scanner

mobilelocker.openScanner()

See it working

The kazaamax-starter presentation has the scanner functionality for you to test.

The kazaamax-starter presentation has the scanner button.

The kazaamax-starter presentation has the scanner button.

Test the scanner

Create a QR code with one of the many free services such as qr-code-generator.com

It's really easy to generate QR codes

It's really easy to generate QR codes

Use the kazaamax-starter presentation, or create your own, with a button to open the scanner as described above.

Scan the QR code. It will display the captured information in the alert. Tap OK to save the captured data, or tap Try again.

The raw data contained within the QR code.  It was a VCARD in this example but it could be anything that can be represented in a QR or barcode.  See [barcode-generator.org](http://www.barcode-generator.org/)

The raw data contained within the QR code. It was a VCARD in this example but it could be anything that can be represented in a QR or barcode. See barcode-generator.org

The scanner will close and you'll return to the screen you were on. You'll see the green Code captured banner at the top, and the data was saved as a regular Device Event.

The kazaamax-starter presentation displays the recorded event in a table.  You can do whatever you want with the captured data.

The kazaamax-starter presentation displays the recorded event in a table. You can do whatever you want with the captured data.

In the admin portal, the event will be saved with the following attributes:

  • Category: data-capture
  • Action: scan-code
  • Path: (the URL you were on in the presentation)

The data field will contain:

  • type: the type of code that was scanned
  • code: the raw data that was captured from the QR or barcode
The event will look like this in the portal.

The event will look like this in the portal.

{
  "type": "org.iso.QRCode",
  "code": "BEGIN:VCARD\nVERSION:3.0\nN:Stralka;Mark\nFN:Mark Stralka\nORG:Mobile Locker\nTITLE:President\nADR:;;72 North Main St;Hudson;OH;44236;USA\nTEL;WORK;VOICE:215-315-3543\nTEL;CELL:555-555-5555\nTEL;FAX:\nEMAIL;WORK;INTERNET:mark@mobilelocker.com\nURL:https://mobilelocker.com\nBDAY:\nEND:VCARD\n"
}

What can you do with the captured QR code or barcode?

Once the code is captured to Mobile Locker, you can view the data in the portal as described above, or setup a create a webhook send the data to any other system you choose. If you need to do something else with the data, shoot us an email.

Scan the QR code on a name tag to capture the person's contact information.

Scan the QR code on a name tag to capture the person's contact information.

Suggest Edits

Get the current Mobile Locker user

 

You can personalize the presentation to the current user by retrieving the User from the app.

let user;

mobilelocker.getUser()
.then(mobilelockerUser => {
  user = mobilelockerUser;
})
.catch(err => {
  if (err.response) {
    console.error('There was an error': err.response.data);
  } else {
    console.error('There was an error');
  }
})

The JSON response looks like this:

{
    "name": "Mark Stralka",
    "last_name": "Stralka",
    "email": "mstralka@vorenusventures.com",
    "id": 3,
    "first_name": "Mark",
    "timezone": "America/New_York",
    "teams": [
        {
            "id": 1,
            "name": "Demo Team",
            "theme": {
                "header_bg": "#00A9CC",
                "table_tint": "#00334D",
                "footer_bg": "#00A9CC",
                "footer_tint": "#FFFFFF",
                "label_tint": "#FFFFFF",
                "table_divider": "#00334D",
                "header_tint": "#FFFFFF",
                "section_bg": "#EEEEEE",
                "table_bg": "#FFFFFF",
                "section_tint": "#00334D",
                "label_bg": "#00A9CC"
            }
        }
    ],
    "current_team_id": 1,
    "country": "US"
}

The Kazaamax Starter presentation demonstrates this functionality:

Suggest Edits

Close a presentation

 

You can close the current presentation programmatically:

mobilelocker.closePresentation();
<a href="mobilelocker/api?method=close-presentation">Close presentation</a>
Suggest Edits

Get the current presentation

 

You can access the current presentation:

// Using the SDK:
mobilelocker.getPresentation()
.then(presentation => {
  // do something with the presentation JSON object
})

// Using axios (https://github.com/mzabriskie/axios):
axios.get('mobilelocker/api/presentation')
	.then(response => {
  	// do something with the presentation JSON object
	})

// Using jQuery:
$.get('mobilelocker/api/presentation', function(data) {
  // do something with the presentation JSON object
})

The JSON looks like this:

{
    "name": "Demo Presentation 1",
    "status": "Installed",
    "installed": true,
    "id": 1,
    "files": [
        {
            "status": "Installed",
            "installed": true,
            "path": "pdf_template.html",
            "id": 1,
            "size": 198,
            "mime_type": "text/html"
        },
        {
            "status": "Installed",
            "installed": true,
            "path": "email_template.html",
            "id": 10,
            "size": 374,
            "mime_type": "text/html"
        },
        {
            "status": "Installed",
            "installed": true,
            "path": "js/mobilelocker-user.js",
            "id": 24,
            "size": 762,
            "mime_type": "application/x-javascript"
        },
        {
            "status": "Installed",
            "installed": true,
            "path": "css/site.css",
            "id": 11,
            "size": 1417,
            "mime_type": "text/css"
        },
        {
            "status": "Installed",
            "installed": true,
            "path": "js/mobilelocker-screenshot.js",
            "id": 18,
            "size": 2134,
            "mime_type": "application/x-javascript"
        },
        {
            "status": "Installed",
            "installed": true,
            "path": "js/site.js",
            "id": 12,
            "size": 2245,
            "mime_type": "application/x-javascript"
        },
        {
            "status": "Installed",
            "installed": true,
            "path": "js/jquery.plugin.html2canvas.js",
            "id": 21,
            "size": 2438,
            "mime_type": "application/x-javascript"
        },
        {
            "status": "Installed",
            "installed": true,
            "path": "js/base64.js",
            "id": 15,
            "size": 2986,
            "mime_type": "application/x-javascript"
        },
        {
            "status": "Installed",
            "installed": true,
            "path": "images/kazaam_mobileicon.png",
            "id": 3,
            "size": 3209,
            "mime_type": "image/png"
        },
        {
            "status": "Installed",
            "installed": true,
            "path": "js/jquery.url.js",
            "id": 17,
            "size": 4776,
            "mime_type": "application/x-javascript"
        },
        {
            "status": "Installed",
            "installed": true,
            "path": "js/mobilelocker-tracking-2.0.js",
            "id": 14,
            "size": 5166,
            "mime_type": "application/x-javascript"
        },
        {
            "status": "Installed",
            "installed": true,
            "path": "js/canvas2image.js",
            "id": 16,
            "size": 6770,
            "mime_type": "application/x-javascript"
        },
        {
            "status": "Installed",
            "installed": true,
            "path": "images/thumbnail.png",
            "id": 8,
            "size": 7962,
            "mime_type": "image/png"
        },
        {
            "status": "Installed",
            "installed": true,
            "path": "images/fpo_picture.png",
            "id": 6,
            "size": 13571,
            "mime_type": "image/png"
        },
        {
            "status": "Installed",
            "installed": true,
            "path": "js/html2canvas.min.js",
            "id": 13,
            "size": 21916,
            "mime_type": "application/x-javascript"
        },
        {
            "status": "Installed",
            "installed": true,
            "path": "images/fpo_bar_chart.png",
            "id": 5,
            "size": 22963,
            "mime_type": "image/png"
        },
        {
            "status": "Installed",
            "installed": true,
            "path": "images/fpo_line_chart.png",
            "id": 2,
            "size": 25452,
            "mime_type": "image/png"
        },
        {
            "status": "Installed",
            "installed": true,
            "path": "index.html",
            "id": 26,
            "size": 26220,
            "mime_type": "text/html"
        },
        {
            "status": "Installed",
            "installed": true,
            "path": "js/jquery.form.js",
            "id": 22,
            "size": 27135,
            "mime_type": "application/x-javascript"
        },
        {
            "status": "Installed",
            "installed": true,
            "path": "images/fpo_table.png",
            "id": 9,
            "size": 28766,
            "mime_type": "image/png"
        },
        {
            "status": "Installed",
            "installed": true,
            "path": "images/fpo_chart.png",
            "id": 4,
            "size": 32238,
            "mime_type": "image/png"
        },
        {
            "status": "Installed",
            "installed": true,
            "path": "images/kazaam_mobile.jpg",
            "id": 7,
            "size": 54352,
            "mime_type": "image/jpeg"
        },
        {
            "status": "Installed",
            "installed": true,
            "path": "js/html2canvas.js",
            "id": 19,
            "size": 76526,
            "mime_type": "application/x-javascript"
        },
        {
            "status": "Installed",
            "installed": true,
            "path": "assets/search-engine-optimization-starter-guide.pdf",
            "id": 25,
            "size": 4318447,
            "mime_type": "application/pdf"
        },
        {
            "status": "Installed",
            "installed": true,
            "path": "js/mobilelocker-tracking-legacy.js",
            "id": 16276,
            "size": 7916,
            "mime_type": "application/x-javascript"
        },
        {
            "status": "Installed",
            "installed": true,
            "path": "js/jquery.min.js",
            "id": 16277,
            "size": 86709,
            "mime_type": "application/x-javascript"
        }
    ],
    "description": "Quae iure et aspernatur et inventore aut et quia. Distinctio neque vero officia et facilis qui quis alias. Quia temporibus quo officiis et.",
    "type": "HTML",
    "main_path": "index.html"
}
Suggest Edits

Get all presentations

 

You can retrieve a list of the presentations that the current Mobile Locker user has access to:

// The ML Library
mobilelocker.getPresentations()
.then(presentations => {
  // do something with them
})

// Using axios
axios.get('mobilelocker/api/presentations')
.then(presentations => {
  // do something with them
})

// Using jQuery
$.get('mobilelocker/api/presentations', function(data) {
  // do somethign with them
})

The JSON response is an array of presentation objects.

The Kazaamax Starter presentation demonstrates this functionality:

Suggest Edits

Get logged events

 

You can retrieve a list of the events logged by the SDK.

For the current session

mobilelocker.getSessionEvents()
.then(events => {
  // do something with the events
});
// The legacy SDk does not have a function but you can do it manually:
$.get('mobilelocker/api/session/events', function(events) {
  // do something with the events
});

All events in all sessions for the presentation on this device.

mobilelocker.getPresentationEvents()
.then(events => {
  // do something with the events
});
// The legacy SDk does not have a function but you can do it manually:
$.get('mobilelocker/api/presentation/events', function(events) {
  // do something with the events
});

The Kazaamax Starter presentation demonstrates this functionality. After performing several actions that logged events, it displays those events in a table.

The Kazaamax Starter presentation demonstrates this functionality.

The Kazaamax Starter presentation demonstrates this functionality.

Suggest Edits

Compose an Email

Compose an email using the native Mail app

 

You can send an email from within a Mobile Locker presentation using the iOS Mail app's Compose Email window.

/**
* recipient - optional, the email address of the recipient
* subject - the subject line of the email
* body - the body of the email (it can be HTML code)
* isHTML - boolean TRUE if the body is HTML, false otherwise
* attachmentPath - optional, path to the file in the presentation to attach to the email
**/
mobilelocker.composeEmail(recipient, subject, body, isHTML, attachmentPath);
Suggest Edits

Live Mode and Practice Mode

If you activate practice mode, the session will not be included in reports.

 

In active development (December 2017)

This feature is in active development so its functionality may change. You need to be using version 3.0.47 or later of the mobilelocker-tracking library for this to work.

By default, when a user opens a presentation in the app, the session is in "live mode", which means it will be recorded and included in reports. Sometimes, a user opens a presentation as a "test", and wants to explore the presentation without having it included in reports. To exclude a session from reports, you can provide a button that will put the session into "practice mode".

Put a session into practice mode

// Put the session into live mode (default)
mobilelocker.liveMode();

// Put the session into practice mode
mobilelocker.practiceMode();

Events from Practice Mode sessions are still recorded and visible in the website, but the events from these sessions will not be included in the reporting dashboards.

Mobile Locker supports webhooks which are a way to send form submission data to a specified URL when a form submission occurs. Webhooks can be used in place of or as a supplement to our API.

Testing Webhooks

If you need to test your webhooks, we suggest using a service such as requestb.in.

We send the data through an HTTP POST request as a JSON string.

Suggest Edits

Create a Webhook

 

A Webhook is created for a presentation through the webhooks admin screen.

If you want a form to be sent through the webhook, set the event category to data-capture.

Adding security to your webhooks

In the webhook configuration options, Mobile Locker allows you to specify a secret key to send along with each request to verify that the request is coming from Mobile Locker. We also send along an HMAC with each request using your secret key so that you can verify that the request body hasn't changed en route to your webhook URL. The secret key is included as an HTTP header named X-MobileLocker-Signature

{
  "environment": "production",
  "sender": {
    "id": 3,
    "first_name": "Mark",
    "last_name": "Stralka",
    "name": "Mark Stralka",
    "name_reverse": "Stralka, Mark",
    "email": "mark@mobilelocker.com",
    "verified": 1,
    "status": "Active",
    "phone": "+1 215-821-6450",
    "country": {
      "id": "US",
      "name": "United States"
    },
    "timezone": "America\/New_York",
    "external_id": null,
    "photo_url": "https:\/\/www.gravatar.com\/avatar\/c90d44f533d302c9f64d8b83771f8c12.jpg?s=200&d=mm",
    "current_team_id": 1,
    "last_accessed_at": "2017-01-10T18:20:05+00:00",
    "created_at": "2016-11-25T22:14:52+00:00",
    "updated_at": "2017-01-10T18:12:28+00:00"
  },
  "presentation": {
    "id": 404,
    "team_id": 1,
    "name": "Kazaamax Starter",
    "code": "kazaamax_starter",
    "status": "Active",
    "presentation_type": "HTML",
    "icon": "fa-html5",
    "description": "A starter presentation used for demos",
    "main_path": "index.html",
    "main_filename": "index.html",
    "thumbnail": null,
    "settings": {
      "ga_profile_id": null,
      "rotation_mode": "both",
      "legacy": {
        "hide_status_bar": false,
        "supports_rotation": false,
        "supports_zoom": false,
        "rotation_mode": "landscape",
        "menu_bar_taps": 2,
        "bounce_enabled": true,
        "bounce_zoom_enabled": true,
        "clear_cache_on_open": false,
        "clear_cache_on_exit": false
      }
    },
    "ga_profile_id": null,
    "files_hash": "79b959f38f925f540228cd725d0896bf773446cb",
    "files": [],
    "labels": [],
    "last_accessed_at": "2017-01-10T18:17:40+00:00",
    "created_at": "2017-01-06T19:26:35+00:00",
    "updated_at": "2017-01-10T04:05:52+00:00"
  },
  "device": {
    "id": 667,
    "uuid": "*****************************",
    "icon": "fa-tablet",
    "status": "Active",
    "team_id": 1,
    "user_id": 3,
    "device_type": "iPad",
    "model": "iPad",
    "localized_model": "iPad",
    "name": "a1000.vorenusventures",
    "user_agent": "MobileLocker-iOS-10.2 v:3.00.33 App:ED3D1A0A-BFF5-49EB-8C21-81356149077A",
    "os_name": "iOS",
    "os_version": "10.2",
    "app_version": "3.00",
    "last_ip_address": "174.104.199.128",
    "last_connected_at": "2017-01-10 18:20:05",
    "last_connected_at_timestamp": 1484072405,
    "created_at": "2017-01-05 18:52:57",
    "updated_at": "2017-01-10 18:17:25"
  },
  "device_session": {
    "id": 45563,
    "uuid": "5A7044EE-A7FD-442A-AE9C-2AD1C5288DFA",
    "session_type": "normal",
    "device_id": 667,
    "user_id": 3,
    "team_id": 1,
    "presentation_id": 404,
    "ip_address": "151.181.232.44",
    "num_events": 4,
    "num_forms": 3,
    "num_screenshots": 0,
    "started_at": "2017-01-10T18:17:40+00:00",
    "ended_at": null,
    "duration": null,
    "created_at": "2017-01-10T18:18:50+00:00",
    "updated_at": "2017-01-10T18:20:05+00:00"
  },
  "device_event": {
    "id": 337538,
    "uuid": "02B3BEE0-34F8-443A-8AB6-1DE7E59A8851",
    "event_at": "2017-01-10T18:20:05+00:00",
    "category": "data-capture",
    "action": "signup-form",
    "path": "signup-form",
    "event_type": "normal",
    "data": {
      "data_type": "parsed",
      "data": {
        "signature": null,
        "name": "Mark",
        "email": "Stralka",
        "company": "mark@mobilelocker.com",
        "signatureJSON": null,
        "country": "US"
      }
    },
    "device_id": 667,
    "ip_address": "151.181.232.44",
    "session_id": 45563,
    "user_id": 3,
    "team_id": 1,
    "presentation_id": 404,
    "created_at": "2017-01-10T18:20:05+00:00",
    "updated_at": "2017-01-10T18:20:05+00:00",
    "flattened_data": {
      "signature": null,
      "name": "Mark Stralka",
      "email": "mark@mobilelocker.com",
      "company": "Mobile Locker",
      "signatureJSON": 'base-64-encoded PNG, truncated for brevity',
      "country": "US"
    }
  }
}
sha256=909a04cfee970d5c0dda83abb3760c3ee02cde0b9583e72c8d4ff0dd5c2239c2

To validate the request with the signature header value, you will need to encrypt the body of the webhook request with HMAC using the SHA256 hashing function and your shared key.

<?php
$postdata = file_get_contents("php://input");
list ($method, $signature) = explode('=', $_SERVER['HTTP_X_FS_SIGNATURE'], 2);

if (hash_hmac($method, $postdata, 'secretkey') === $signature) {
  // Verified
}
Suggest Edits

Built-in webhooks

 
Suggest Edits

Email the user

 

We provide a webhook that will send the event in an email to the Mobile Locker user who created it. This is useful if you want the user to receive a copy or receipt each time they submit a form.

Create a webhook with this endpoint:

/webhook/email-user
An example of the email that will be sent to the Mobile Locker user.

An example of the email that will be sent to the Mobile Locker user.

If your form captured a signature as a base64-encoded PNG, the image will be attached to the email.

Twine is an open-source tool for telling interactive, nonlinear stories.

You don't need to write any code to create a simple story with Twine, but you can extend your stories with variables, conditional logic, images, CSS, and JavaScript when you're ready.

Twine publishes directly to HTML, so you can post your work nearly anywhere. Anything you create with it is completely free to use any way you like, including for commercial purposes.

Suggest Edits

iSpring Converter Pro

 

iSpring Converts PowerPoints to HTML5, preserving animations, transitions, and effects.

We'll convert your PowerPoint files for you

If you have a PowerPoint file that you want to convert to HTML5 for Mobile Locker but can't buy a license, send it to us and we'll do it for you.

Phaser is a fast, free and fun open source framework for Canvas and WebGL powered browser games.