I’m pretty excited to be a part of the Google Glass Explorer program.  Being in the Explorer program is like being one of the first users of the early Apple II: the tech is great and you can tell it’s just the tip of the wearable computing iceberg.

There are multiple ways you can integrate with Glass using Google’s Mirror API, but they boil down to three options: sending data to Glass, use Glass to send data somewhere or a combination. The Mirror API is how you interact with Glass.  Everyone can peruse the Mirror API docs, but you have to be specially authorized to have access to the API in the Google API console.

For my example, I’ve chosen to send data from Salesforce to Glass.  The basic use case is that someone inserts a record into Salesforce, the record is owned by someone who has configured Glass integration, and a trigger on that object then sends a snapshot of that data to the user’s Glass.  In my example, I’ve used the Lead object.  You can see the full code on Github, where you will also find a link to an unmanaged package.

The first step is app configuration on the Google API panel. Simply turn on the Mirror API in the Google API console and create a new Client ID.  I used the web application flow.

You can see from the screenshot that you get the same basic information you’re used to getting when you setup a connected app in Salesforce.  You’ll need to store this on the Salesforce side of the house.  I used a custom setting, hierarchy with public visibility.  It contains a single record.

Next is user level authorization.  Google uses OAuth2, so if you’ve had a chance to use Salesforce’s OAuth2 services, you know that this is pretty easy.  I created some simple code and a Visualforce page to manage this process.  The most interesting portion of this code, for me, was mocking out the classes needed for test coverage.  In the standard OAuth2 flow, you will as a normal part of the operation, run into an error condition that requires your code to branch.  In order for this to work, your mock call outs have to simulate that branching behavior.  Here you can see we have three steps: the first one fails, the second one succeeds, and then we have to handle the first one again but this time let it succeed.

@isTest
//has to handle a three step request -- access token is expired, so request a new one, then send timeline request again
global class LAB_Mirror_Mock_TimelineThenToken_Impl implements HTTPCalloutMock {
    static Boolean stepOne = false;
    static Boolean stepTwo = false;

    global HTTPResponse respond(HTTPRequest req) {
        // Create a fake response
        HttpResponse res = new HttpResponse();
        res.setHeader('Content-Type', 'application/json');

        if (!stepOne && !stepTwo) {
            System.assertEquals('https://www.googleapis.com/mirror/v1/timeline', req.getEndpoint());
	        res.setStatusCode(401);  
            res.setBody('{"error":"error"}');
            stepOne = true;
        } else if (stepOne && !stepTwo) {
            System.assertEquals('https://accounts.google.com/o/oauth2/token', req.getEndpoint());
	        res.setStatusCode(200);  
			res.setBody('{"access_token":"mock_access", "refresh_token":"mock_refresh", "id_token":"mock_id", "access_type":"mock_type", "expires_in":"3920"}');           
            stepTwo = true;           
        } else {
            System.assertEquals('https://www.googleapis.com/mirror/v1/timeline', req.getEndpoint());
	        res.setStatusCode(200);            
			res.setBody('{"kind":"mirror#timelineItem", "id":"mockid", "created":"2013-07-31T12:07:34.882Z", "updated":"2013-07-31T12:07:34.882Z", "etag":"\\"ZECOuWdXUAqVdpmYErDm2-91GmY/NVMWuR8LJyCKttsmne9R4K8n7YI\\"", "text": "New Lead: OauthCheck EarlyAm, Google, Inc., (234) 567-8900"}');           
        }

        return res;
    }
}

I haven’t tested the idea, but this basic OAuth2 code should work with any Google API service, not just with the Mirror API.

Finally, the last step is to publish events to the Glass Timeline.  This is trivial.  The class “LAB_Mirror_Publisher” handles the details, but the magic happens in this method:

public static Integer handleTimelinePost(String access_token, String message) {

    TimelineMessage timelineMsg = new TimelineMessage();
    timelineMsg.text =message;

    HttpRequest firstPost = new HttpRequest();
    firstPost.setEndpoint('https://www.googleapis.com/mirror/v1/timeline');
    firstPost.setMethod('POST');
    firstPost.setHeader('Authorization', 'Bearer ' + access_token);
    firstPost.setBody(JSON.serialize(timelineMsg));
    firstPost.setHeader('Content-Type', 'application/json');
    HttpResponse res2 = new Http().send(firstPost);
    String mirrorResponse = res2.getBody();
    result = (TimelineResult) JSON.deserialize(mirrorResponse, LAB_Mirror_Publisher.TimelineResult.class);

    return res2.getStatusCode();
}

You can see I’ve created utility classes for constructing the message and handling the responses.  You could certainly handle these differently, but I found this approach efficient.  This code creates a Glass Timeline entry which looks like this (with apologies, as always, to Josh Birk).

Note that this screenshot is actually from the Mirror API Playground which also shows you the JSON responsible for it.

There’s quite a few things I’d like to do with the code (make the Timeline object more robust, handle different types of integration, etc), but I feel pretty good about this as a start.  There are great things to come in wearable computing.  If you have any use case suggestions you think I should explore, please drop me a note.

@ReidCarlberg

tagged , , , , , , Bookmark the permalink. Trackbacks are closed, but you can post a comment.
  • Chirag Mehta

    great post and seems like endless new possibilities!

  • Phillip Southern

    great post, very simple and straightforward…this was inevitable!

  • http://www.tgerm.com/ Abhinav Gupta

    Nice post, I was expecting this since I saw your pics with Google Glass :)

  • Sagar Pareek

    Great Post.

  • Roy Gilad

    Like!

  • subodhbahl

    Wow, an amazing post.

  • Salman Zafar

    Awesome!!

  • Enrico Murru

    Great post, but I envy you can put hands on google glasses!!