Skip to Content

When I received my Amazon Echo Dot I started using it for various things just like everyone else.  Looking around you see examples of people writing Alex Skills for various different use cases.  At SAP there are plenty of people that have written Alex Skills for IOT, CRM, Analytics and more.

I do various different customer facing things for our Mobile Solutions, and recently I’ve been working with SAP Cloud Platform Mobile Services: Mobile Card Kit or formerly known as SAP’s Content to Go.  If you are familiar with this solution you can take a look at this post that gives a good high level overview.

When you configure a “card” for Mobile Card Kit, you configure a REST or oData query that, when requested, will pull the data from the configured destination and provide the returned data to be written to the card.  You can trigger this in various different ways, but one way is requesting the data to be sent when someone performs and action to send the data to a card from an HTML app by simply pressing a button.  In the background this is telling the server the identifier of Mobile Card Kit and telling it to send the card to the registered devices/users.  I decided to see if instead of doing this through an HTML page, you could have the user ask Alexa to send the card based on a users input.

Here is the video that shows the end result.

This is not a difficult skill to develop and there are a lot of enhancements that can be done from the skill that I wrote.  I kept it very simple, you’ll want to do things like allowing for users to input their username, as I’ve hard coded mine.  Other ideas to take this further is to use Alex to do questions that allow you to drill down to find an object before sending, for example ask Alexa “What kind of product are you looking for?” or “Alexa look for products with stock under 5”.  Doing this would allow you to search your products and then once you find a relevant match you would send the content as a card.  Cards can be sent from many different backends so you could configure the Skill to ask where you would like to look for the information, for example Success Factors, Ariba, Hybris, etc.

Let’s see how I went about doing this.

The first thing you need to do is go through the Setup, Basic and Intermediate Tutorials.  This will get you to where you have the same Product Listing application that you see in my video, and you can verify that in fact you can receive the cards correctly in the application.

This is not a full tutorial so I will make some assumptions that you are either familiar with developing an Alexa Skill or you can easily search on at least getting started with developing an Alexa Skill, there are plenty of examples.

For the Skill that I wrote, I started with a Custom Interaction Model with a name of “Send Card” and the Invocation Name is “content to go”.  I used the Skill Builder that is still in Beta at the time of this post to build my Skill.

I created an Intent called GetProdCodeIntent.  You can put in multiple Utterances.  I used ones like “Send Card {productCode}” or “Send Content to Go Card for {productCode}”

For the Slot Type productCode I provided the values of several products that are int he backend (1110, 1055, 1018).

Now for the code.  From AWS Lambda Service the code I wrote was with Node.js6.10.

First setup your variables and constants

se strict';

const Alexa = require('alexa-sdk');

const APP_ID = undefined;  // TODO replace with your app ID (OPTIONAL).

var welcomeMessage = "What is the prodcut number?"

var output = '';
var inputUserInput = '';
var querystring = require('querystring');
var https = require('https');

Next setup the handlers, GetProdCodeIntent is the function where we collect all the information and send a POST request to SAP Cloud Platform Mobile Services.

const handlers = {
    'LaunchRequest': function () {
        output = welcomeMessage;
        this.emit(':ask', output);
    },
    'Unhandled': function () {
        this.emit(':tell', 'Sorry this was unhanled');
    },
    'GetProdCodeIntent': function(){
        var that = this;
        var productCode = '';

        //Make sure that the user did input a valid code
        var productCodeSlotValid = isproductCodeSlotValid(this.event.request.intent);
        if(productCodeSlotValid)
             productCode = this.event.request.intent.slots.productCode.value;
        console.log("Product code: " + productCode);
        
        
        var bodyJson = JSON.stringify({
            //Pass in what the query needs and I've hard coded my SAP Cloud Platform User
            resourceIdentifiers: [{ "uri": "/Products('HT-" + productCode + "')" }],
            username: "P****"
        });
    
        var options = {
            //SAP CPms host
            host: 'hcpms-p******trial.hanatrial.ondemand.com',
            //This is the path for the Card Type GUID that you will find in your SAP Cloud Platform SAP Content to Go configuration
            path: '/mobileservices/origin/hcpms/CARDS/v1/cardTypes/39649BB5-0C2C-4B91-A96A-10481C8B14D3/cardInstances',
            port: '443',
            method: 'POST',
            headers: {
                //You need to BASE64 encode your user and password
                'Authorization': 'Basic *********************',
                'Content-Type': 'application/json'
            }        
        };
               
        console.log('About to send https request');
        var req = https.request(options, function (res) {
            var body = '';
            var statusCode = res.statusCode;
            console.log('Status:', statusCode);
            console.log('Headers:', JSON.stringify(res.headers));
            res.setEncoding('utf8');
            res.on('data', function (chunk) {
                body += chunk;
            });
            res.on('end', function () {
                if(statusCode == '201'){
                console.log('Successfully processed HTTPS response');
    
                body = JSON.parse(body);
    
                console.log(body);
    
               that.emit(':tell', "The SAP Content to Go Card " + productCode + " was sent");
                }
                else{
                    console.log("Card did not send");
                    that.emit(':tell', "The Card was not sent, make sure it wasn't already sent");
                }
    
            });
        }).on('error', (e) => { console.error(e);
        });
        req.write(bodyJson);
        req.end();
    },
    'AMAZON.HelpIntent': function () {
        const speechOutput = this.t('HELP_MESSAGE');
        const reprompt = this.t('HELP_MESSAGE');
        this.emit(':ask', speechOutput, reprompt);
    },
    'AMAZON.CancelIntent': function () {
        this.emit(':tell', this.t('STOP_MESSAGE'));
    },
    'AMAZON.StopIntent': function () {
        this.emit(':tell', this.t('STOP_MESSAGE'));
    },
};

The Last part of the code is the helper function for making sure there is a valid product and your handler export

function isproductCodeSlotValid(intent) {
    var productCodeSlotFilled = intent && intent.slots && intent.slots.productCode && intent.slots.productCode.value;
    return productCodeSlotFilled
}

exports.handler = function (event, context) {
    const alexa = Alexa.handler(event, context);
    alexa.APP_ID = APP_ID;
    alexa.registerHandlers(handlers);
    alexa.execute();
};

You will need to make a few changes like the user information as well as the card GUID and URL information, but once you have this in place you should be able to do the following:

User: “Alexa ask Content to Go”

Alexa: “What  is the product number?”

User: “1023”

Alexa: “The SAP Content to Go card 1023 was sent”

 

To report this post you need to login first.

Be the first to leave a comment

You must be Logged on to comment or reply to a post.

Leave a Reply