Nuxeo Alexa Skill - Ask Alexa to Search your Documents in Nuxeo


Thu 09 March 2017 By Rémi Cattiau

At AWS re:Invent 2016, Alexa and virtual assistant were some of the highlights and they drew a lot of interest. Alexa is the voice service that powers Amazon Echo, Echo Dot, Echo Tap, and Fire TV, and provides capabilities, or skills, that enable customers to interact with devices in a more intuitive way using voice. As an early adopter, I have the first generation of Echo, and Echo Dot, and actually have 3 of those devices in my small apartment! They are pretty great, I must say.

I believe Alexa will soon be a part of our future - it’s already being integrated into cars by Ford and Volkswagen, and there’s no doubt that we will see more of such integrations. At Nuxeo, we try to keep up with the latest technology and have fun building cool new features and integrations that add an edge to the platform. So, I decided to create a Nuxeo skill that will allow us to search the documents in the Nuxeo Platform through Alexa.

You can see the skill in action in this playlist:




You can find all the sources in my GitHub repository. Let’s take a detailed look at the implementation now.

Skill Information

First, you have to define the generic information about your skill, like the language, name, and icon.

Nuxeo Skill Information

Integration Model

The next step is to define how to interact with your skill, the different intents and their contents.

{
  "intents": [
    {
      "intent": "GetMyLast"
    },
    {
      "intent": "GetMyTasks"
    },
    {
      "intent": "Search",
      "slots": [
        {
          "name": "Criteria",
          "type": "Value"
        }
      ]
    },
    {
      "intent": "AMAZON.RepeatIntent"
    },
    {
      "intent": "AMAZON.HelpIntent"
    },
    {
      "intent": "AMAZON.StopIntent"
    },
    {
      "intent": "AMAZON.CancelIntent"
    }
  ]
}

The AMAZON.* is the predefined intent used for navigation. Then you have the GetMyLast and GetMyTasks that takes no parameters, and finally, the Search intent, which takes a Criteria parameter.

Nuxeo Authentication screen shot

Configuration

Account Linking

For us to be able to query the Nuxeo server we need to create a token that allows to store credentials and use it to query the server dynamically.

The requirements for the UI Authentication is to have SSL and a unique URL. So I had to create a UI that allows you to type in the URL of your server to only have one Alexa skill. Of course, feel free to fork and create your own to contribute back.

Once the UI validates your account, it generates a token authentication on Nuxeo and combines it with the user and the server URL as a new Alexa Token Auth.

Nuxeo Authentication screen shot

As my hosting was supporting PHP natively, I did that part with the Nuxeo PHP Client and Polymer for the UI, because at Nuxeo we love Polymer.

You'll find the sources on this GitHub repository

Now, we just need to setup our skill with this authentication UI.

Nuxeo Authentication configuration

Lambda

Now you have to define the service endpoint. A Lambda seems pretty easy to set up, so that's what we will use.

Nuxeo Executor configuration

I choose to use NodeJS and the Nuxeo JavaScript client as it is quick and easy.

The dependencies of the project are:

  • alexa-sdk: For Alexa primitive
  • alexa-app: A small framework to simplify Alexa app development
  • nuxeo: To access the Nuxeo server
  • striptags: To remove any HTML tags from the answer as Alexa doesn’t like tags

For each intent, you have a method to specify:

app.intent('Search', function(request, response) {
    // Retrieve the criteria
    var criteria = request.slot("Criteria");
    // Load the token from the request
    return loadToken(request)
        .then(function(nuxeo) {
            // Search Nuxeo
            return nuxeo.repository().query({...});
        })
        .then(function(doc) {
            // List the results
            ...
            for (let id in doc.entries) {
                ...
                docs += res;
                response.say(res);
            }
            // Add a result card for the Alexa UI
            response.card({type: 'Standard', ...}});
        }).catch ( function(err) {
            // Handle Error
            handleError(err, request, response);
        });
});

You'll find the sources in the GitHub repository.

Thanks

A big thanks to the different API clients, PHP and NodeJS that made this integration way easier for me. Hope you enjoy this skill as much as I do!


Tagged: AWS, Nuxeo Integration, How to