Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Searching DynamoDB for non primary keys and integrating into Alexa Skills

I am trying to search a non primary key using AWS Lambda and integrating it into the Alexa Skills Kit. I am very new to using DynamoDB and Alexa Skills Kit and I'm struggling to find any solutions to this online. The basic premise for what I am trying to do is querying the table yesno with two columns, id and message. Only looking through the message column to find a match with the text i specify in params.

Here is the Lambda code I am working with:

const AWSregion = 'eu-west-1';  
const Alexa = require('alexa-sdk');
const AWS = require('aws-sdk');

//params for searching table
const params = {
            TableName: 'yesno',
            Key:{ "message": 'Ben Davies' }
        };

AWS.config.update({
    region: AWSregion
});

exports.handler = function(event, context, callback) {
    var alexa = Alexa.handler(event, context);

    // alexa.appId = 'amzn1.echo-sdk-ams.app.1234';
    // alexa.dynamoDBTableName = 'YourTableName'; // creates new table for session.attributes

    alexa.registerHandlers(handlers);
    alexa.execute();
};

const handlers = {
    'LaunchRequest': function () {
        this.response.speak('welcome to magic answers.  ask me a yes or no question.').listen('try again');
        this.emit(':responseReady');
    },


    'MyIntent': function () {
        var MyQuestion = this.event.request.intent.slots.MyQuestion.value;
        console.log('MyQuestion : ' + MyQuestion);

        readDynamoItem(params, myResult=>{
            var say = MyQuestion;
            say = myResult;

            say = 'you asked, ' + MyQuestion + '. I found a reckord for: ' + myResult;
            this.response.speak(say).listen('try again');
            this.emit(':responseReady');


        });

    },
    'AMAZON.HelpIntent': function () {
        this.response.speak('ask me a yes or no question.').listen('try again');
        this.emit(':responseReady');
    },
    'AMAZON.CancelIntent': function () {
        this.response.speak('Goodbye!');
        this.emit(':responseReady');
    },
    'AMAZON.StopIntent': function () {
        this.response.speak('Goodbye!');
        this.emit(':responseReady');
    }
};

//  END of Intent Handlers {} ========================================================================================
//  Helper Function  =================================================================================================


function readDynamoItem(params, callback) {
    var AWS = require('aws-sdk');
    AWS.config.update({region: AWSregion});

    var dynamodb = new AWS.DynamoDB();

    console.log('reading item from DynamoDB table');

    dynamodb.query(params, function (err, data) {
        if (err) console.log(err, err.stack); // an error occurred
        else{
            console.log(data); // successful response
            callback(data.Item.message);
        }               
    });

}

I know I am probably doing this completely wrong but there isn't much online for integrating DynamoDB with an Alexa Skill and the only thing i was able to find was searching by ID. This doesn't work for what i want to do without pulling all the items from the table into a map or a list, and seeing as I want to create a big database it seems quite inefficient.

On the Alexa side of things I am receiving the following service request when testing the code:

    {
  "session": {
    "new": true,
    "sessionId": "SessionId.f9558462-6db8-4bf5-84aa-22ee0920ae95",
    "application": {
      "applicationId": "amzn1.ask.skill.9f280bf7-d506-4d58-95e8-b9e93a66a420"
    },
    "attributes": {},
    "user": {
      "userId": "amzn1.ask.account.AF5IJBMLKNE32GEFQ5VFGVK2P4YQOLVUSA5YPY7RNEMDPKSVCBRCPWC3OBHXEXAHROBTT7FGIYA7HJW2PMEGXWHF6SQHRX3VA372OHPZZJ33K7S4K7D6V3PXYB6I72YFIQBHMJ4QGJW3NS3E2ZFY5YFSBOEFW6V2E75YAZMRQCU7MNYPJUMJSUISSUA2WF2RA3CIIDCSEY35TWI"
    }
  },
  "request": {
    "type": "IntentRequest",
    "requestId": "EdwRequestId.7310073b-981a-41f8-9fa5-03d1b28c5aba",
    "intent": {
      "name": "MyIntent",
      "slots": {
        "MyQuestion": {
          "name": "MyQuestion",
          "value": "erere"
        }
      }
    },
    "locale": "en-US",
    "timestamp": "2018-01-25T14:18:40Z"
  },
  "context": {
    "AudioPlayer": {
      "playerActivity": "IDLE"
    },
    "System": {
      "application": {
        "applicationId": "amzn1.ask.skill.9f280bf7-d506-4d58-95e8-b9e93a66a420"
      },
      "user": {
        "userId": "amzn1.ask.account.AF5IJBMLKNE32GEFQ5VFGVK2P4YQOLVUSA5YPY7RNEMDPKSVCBRCPWC3OBHXEXAHROBTT7FGIYA7HJW2PMEGXWHF6SQHRX3VA372OHPZZJ33K7S4K7D6V3PXYB6I72YFIQBHMJ4QGJW3NS3E2ZFY5YFSBOEFW6V2E75YAZMRQCU7MNYPJUMJSUISSUA2WF2RA3CIIDCSEY35TWI"
      },
      "device": {
        "supportedInterfaces": {}
      }
    }
  },
  "version": "1.0"
}

And I am receiving a service response error simply saying 'The response is invalid'

Any help with this would be greatly appreciated

like image 967
Daniel Smith Avatar asked Nov 27 '25 01:11

Daniel Smith


1 Answers

I would like to help you in dynamo db part.

In order to access non primary key columns in dynamodb you should perform scan operation.

For your table (yesno), id is a primary key and message is an additional column.

Snippet to access non primary key column [Message]

var dynamodb = new AWS.DynamoDB();
var params = {
    TableName: 'yesno',
    FilterExpression: 'message = :value',
    ExpressionAttributeValues: { 
        ':value': {"S": "Ben Davies"}
    }
};
dynamodb.scan(params, function(err, data) {
    if (err)  // an error occurred
    else console.log(data); // successful response
});

Snippet to access primary key column [Id]

var docClient = new AWS.DynamoDB.DocumentClient();
//Get item by key
var params = {
    TableName: 'sis_org_template',
    Key: { "id": "1"}
};
docClient.get(params, function(err, data) {
    if (err)  // an error occurred
    else console.log(data); // successful response
});
like image 155
Ashok JayaPrakash Avatar answered Nov 29 '25 13:11

Ashok JayaPrakash