Cloud, Commerce, Java

Voice commerce – Integrating ElasticPath with Amazon Alexa

Purpose

To showcase integration between ElasticPath eCommerce platform, that exposes RESTful Cortext APIs, with Amazon’s Alexa Voice Service.

Use Cases

A user with a registered Alexa device can
– Initiate eCommerce transaction by adding product to cart, checkout and get order number.
– Get previous order history.
– Get available coupons.

Pre-requisites

An active AWS account.
Alexa enabled device, such as Amazon Echo.
ElasticPath Platform with access to Cortex RESTful APIs.

High Level Architecture

 

Integration

  • Create and Configure Alexa Skill Kit
  • Create and configure AWS Lambda function
  • Testing with either Alexa enabled device or with web-based https://echosim.io/

Alexa Skill Kit

1. Login to developer.amazon.com, click on Alexa tab and Get Started Alexa Skills Kit

2. Click Add New Skill

3. Enter the Name of the skill & Invocation Name and click Save. The resulting screen shows Application ID or  Skill ID

4.  Specify following Intent Schema

{
"intents": [
{
"intent": "AMAZON.ResumeIntent"
},
{
"intent": "AMAZON.PauseIntent"
},
{
"intent": "GetCoupons"
},
{
"slots": [
{
"name": "Number",
"type": "AMAZON.NUMBER"
},
{
"name": "Code",
"type": "AMAZON.FOUR_DIGIT_NUMBER"
}
],
"intent": "GetOrderStatus"
},
{
"slots": [
{
"name": "Product",
"type": "LIST_OF_PRODUCTS"
},
{
"name": "Number",
"type": "AMAZON.NUMBER"
}
],
"intent": "AddToBasket"
},
{
"intent": "AMAZON.YesIntent"
},
{
"intent": "AMAZON.NoIntent"
}
]
}

5.  Add Custom Slot Type LIST_OF_PRODUCTS  and one value Nairobi runners (which represents product)

6. Enter following Sample Utterances

GetCoupons what are the active coupons
GetOrderStatus order status of {Number}
GetOrderStatus get my orders
AddToBasket add {Product} to cartSign-in to AWS console at aws.amazon.com and Lambda create function

This should complete the Interaction model.

7.  Select AWS Lambda ARN and Account Linking as No

8. Ensure Alexa Skill is enabled for testing


9. Note down the ID of your Skill which is also called Skill ID

Lambda Function

1. Login to aws.amazon.com

2. Give Lambda a Name, choose a role or create new role and select Node.js Runtime and click Create Function

3. Add Alexa Skills Kit trigger in the Designer.  Enter Skill ID configured in developer.amazon.com (See Alexa Skills step 9 above)

4. Following is the sample Nodejs handler with life cycle methods (REST API calls omitted for brevity) that process speech by invoking ElasticPath’s Cortex API (See step 5)

'use strict';


// --------------- Functions that control the skill's behavior -----------------------
/**
 * Called when the user specifies an intent for this skill. Redirects to the proper
 * function.
 */
function onIntent(intentRequest, session, callback) {
    // Dispatch to the skill's intent handlers
    if (intentName === 'GetCoupons') {
        getCouponResponse(callback);
    } else if (intentName === 'GetOrderStatus') {
        getOrderStatusResponse(callback);
    } else if (intentName === 'AddToBasket') {
        getAddToBasketResponse(callback, intentRequest);
    } else if (intentName === 'AMAZON.NoIntent') {
        callback({}, buildSpeechletResponse("End Session", "", "", true));
    } else if (intentName === 'AMAZON.YesIntent') {
        getYesResponse(session, callback);
    } else{
        getCatchAllResponse(intentName, callback);
     }
}
// --------------- Events -----------------------
/**
 * Called when the session starts.
 */
function onSessionStarted(sessionStartedRequest, session) {
    console.log(`onSessionStarted requestId=${sessionStartedRequest.requestId}, sessionId=${session.sessionId}`);
}
/**
 * Called when the user launches the skill without specifying what they want.
 */
function onLaunch(launchRequest, session, callback) {
    console.log(`onLaunch requestId=${launchRequest.requestId}, sessionId=${session.sessionId}`);
    // Dispatch to your skill's launch.
    getWelcomeResponse(callback, session.application.applicationId);
}

function handleSessionEndRequest(callback) {
    const cardTitle = 'Session Ended';
    const speechOutput = 'Thank you for trying the Alexa Skills Kit sample. Have a nice day!';
    // Setting this to true ends the session and exits the skill.
    const shouldEndSession = true;
    callback({}, buildSpeechletResponse(cardTitle, speechOutput, null, shouldEndSession));
}
/**
 * Called when the user ends the session.
 * Is not called when the skill returns shouldEndSession=true.
 */
function onSessionEnded(sessionEndedRequest, session) {
    console.log(`onSessionEnded requestId=${sessionEndedRequest.requestId}, sessionId=${session.sessionId}`);
    // Add cleanup logic here
}
// --------------- Main handler -----------------------
// Route the incoming request based on type (LaunchRequest, IntentRequest,
// etc.) The JSON body of the request is provided in the event parameter.
exports.handler = (event, context, callback) => {
    try {
        console.log(`event.session.application.applicationId=${event.session.application.applicationId}`);
        if (event.session.application.applicationId !== 'amzn1.ask.skillID') { // TA Digital store skill
             console.log('Invalid application ID: '+ event.session.application.applicationId);
             callback('Invalid Application ID');
        }
        if (event.session.new) {
            onSessionStarted({ requestId: event.request.requestId }, event.session);
        }
       if (event.request.type === 'LaunchRequest') {
            onLaunch(event.request,
                event.session,
                (sessionAttributes, speechletResponse) => {
                    callback(null, buildResponse(sessionAttributes, speechletResponse));
                });
        } else if (event.request.type === 'IntentRequest') {
            onIntent(event.request,
                event.session,
                (sessionAttributes, speechletResponse) => {
                    callback(null, buildResponse(sessionAttributes, speechletResponse));
                });
        } else if (event.request.type === 'SessionEndedRequest') {
            onSessionEnded(event.request, event.session);
            callback();
        }
    } catch (err) {
        callback(err);
    }
}

5.  ElasticPath checkout flow – Cortex API reference (used in Lambda function step 4)


How does the Integration sound?

Thanks to my colleague Priyanka Naithani who orders stuff routinely for our office testing out Alexa Skill

Limitations

Amazon’s account linking capability connects Alexa user to ElasticPath user account. This demo does not use account link and uses existing user in EP. Currently a DemoPaymentGateway and sample store provided OOTB in ElasticPath are used, as such, order processing has no integration with any external system.
Voice is no replacement to Content Management Systems and is not particularly user friendly for a voice assistant to read out large number of categories and products, as such, this demo uses single product.
Alexa Skill TA Digital Demo is not certified yet as this is just a demonstration connecting all the pieces together.

Testing

There are several ways to test Alexa Skill.
1. Using Alexa companion app on phone or signin to alexa.amazon.com and configure your device.
Because this is a test skill, it will be available under “DEV SKILL” tab.

2. Testing with Json simulator within the Alexa Skill. Note the json request/responses.

3. Sign-in to https://echosim.io/ with AWS account and it identifies Alexa Skill configured in your AWS account.

4. TA Digital Demo is a test skill and is not certified yet, so it is not available to test on other Echo devices.
But Skills Beta Testing allows sharing the skill with other device users by managing their emails.

Logs & Debug

Because Lambda function is invoked in the AWS console, logging is available in CloudWatch logs.


Alexa voice service converts user speech into text and this text is key identifier in the Lambda function.
For example, when user says “Nairobi Runners”, the text available in lambda function is “Nairobi runners”.
This sort of subtle differences can be identified/fixed by trawling CloudWatch logs and pepper code with Debug statements which is not too efficient.
However, there are tools for faster development such as Ask Developer Console

Summary

Voice commerce is fast becoming one of the consumer buying options. It helps in supplementing/ complementing user buying experience. For example, an office administrator ordering refills and supplies as in the video. Customers with visual challenges being able to order known products. Pushing out special deals, discounts, flash sales, product information to customers. This exercise is one such demonstration of these use cases.

Credits: This blog is put together with guidance from AWS Alexa Quick Start Tutorial and Stan Klabbers post in ElasticPath support community.

 

 

 

 

 

 

 

 

 

About The Author

Leave a Reply

*