question

cd avatar image
cd asked

Fundamentals: Access custom skill slot values using nodejs

I have a need to access custom slot values after an interaction and update a dynamodb table. As a model, I am using this example:

Recipe Organizer Skill

However, when I attempt to access the slot user values I am coming up empty. Testing the lambda function, it looks like the "this.event.request.intent" object is undefined so my path to the value I am after is not valid. I was using the util module to inspect the object but I am unsure of what I am missing here in terms of the response/request structure and how to get this value. Clearly, it works in the cited example - not sure what it is about my structure that is throwing this off. Thanks in advance for any pointers! Below is my model. I am trying to get the VoterName slot value.

{
  "interactionModel": {
    "languageModel": {
      "invocationName": "voting booth",
      "intents": [
        {
          "name": "AMAZON.CancelIntent",
          "samples": []
        },
        {
          "name": "AMAZON.HelpIntent",
          "samples": []
        },
        {
          "name": "AMAZON.StopIntent",
          "samples": []
        },
        {
          "name": "AMAZON.YesIntent",
          "samples": []
        },
        {
          "name": "RegisterIntent",
          "slots": [
            {
              "name": "VoterName",
              "type": "VoterName",
              "samples": [
                "mom",
                "dad",
                "son"
              ]
            }
          ],
          "samples": [
            "register to vote",
            "register"
          ]
        }
      ],
      "types": [
        {
          "values": [
            {
              "id": "",
              "name": {
                "value": "Son",
                "synonyms": []
              }
            },
            {
              "id": "",
              "name": {
                "value": "Dad",
                "synonyms": []
              }
            },
            {
              "id": "",
              "name": {
                "value": "Mom",
                "synonyms": []
              }
            }
          ],
          "name": "VoterName"
        }
      ]
    },
    "dialog": {
      "intents": [
        {
          "name": "RegisterIntent",
          "confirmationRequired": false,
          "slots": [
            {
              "name": "VoterName",
              "type": "VoterName",
              "elicitationRequired": true,
              "confirmationRequired": false,
              "prompts": {
                "elicitation": "Elicit.Intent-RegisterIntent.IntentSlot-VoterName"
              }
            }
          ]
        }
      ]
    },
    "prompts": [
      {
        "id": "Elicit.Intent-RegisterIntent.IntentSlot-VoterName",
        "variations": [
          {
            "type": "PlainText",
            "value": "Voter ID is crucial to democracy - can I have your name please?"
          }
        ]
      }
    ]
  }
}
alexa skills kitslotsinteraction model
1 comment
10 |5000

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

This is really weird. The console tester shows the object as expected and what you outline. However, in testing the lambda function is reporting that the object is not there. Details here:

developer console object when entering the RegisterIntent:

"request": {
"type": "IntentRequest",
"requestId": "amzn1.echo-api.request.2fd6950f-41a9-43ea-aff5-595b0c0c5e31",
"timestamp": "2018-03-17T12:46:47Z",
"locale": "en-US",
"intent": {
"name": "RegisterIntent",
"confirmationStatus": "NONE",
"slots": {
"VoterName": {
"name": "VoterName",
"confirmationStatus": "NONE"
}
}
},

Lambda test console when testing the intent with this code in index.js

'RegisterIntent': function() {
    /*console.log(
      "before intent invocation dialogState:" + this.event.request.dialogState
    );*/
    console.log(
        "inspect on this.event.request.intent:" + util.inspect(this.event.request.intent, false, null)
      );
      console.log(
        "inspect on this.event.request:" + util.inspect(this.event.request, false, null)
      );

output:

2018-03-17T12:41:06.518Z	752d5b8a-29e0-11e8-b712-bf2941397e51	inspect on this.event.request.intent:undefined
2018-03-17T12:41:06.556Z	752d5b8a-29e0-11e8-b712-bf2941397e51	inspect on this.event.request:{ type: 'RegisterIntent',
  requestId: 'amzn1.echo-api.request.49eeb9ed-9144-4e02-bf14-f4a716382030',
  timestamp: '2018-03-13T11:36:26Z',
  locale: 'en-US' }
0 Likes 0 ·
Jenn@amazon avatar image
Jenn@amazon answered

this.event.request.intent will return an JSON object.

Request JSON:

{
  "session": {
    "sessionId": "SessionId.f4cd357d-c94b-4401-813e-56e30ac8b3b1",
    "application": {
      "applicationId": "amzn1.ask.skill.b925ac6c-dab0-"
    },
    "attributes": {},
    "user": {
      "userId": "amzn1.ask.account.AFP3ZWPOS2BGJR7OWJZ3D"
    },
    "new": true
  },
  "request": {
    "type": "IntentRequest",
    "requestId": "EdwRequestId.e83e0e0d-563e-410b-a876-4cb7cedf546b",
    "locale": "en-US",
    "timestamp": "2018-03-13T19:40:19Z",
---> "intent": {
      "name": "DollarAmount",
      "slots": {
        "cents": {
          "name": "cents",
	  "value": "20"
        },
        "dollar": {
          "name": "dollar",
          "value": "5"
        }
      }
    } <---
  },
  "version": "1.0"
}

So to get the value of the Slots using the tutorial you're using:

var mySlots = this.event.request.intent;

var centsSlot = mySlots.slots.cents.value;
var dollarSlot = mySlots.slots.dollar.value;

or the method I use for my US Dollar Amounts Interaction sample:

var centsSlot = this.event.request.intent.slots.cents.value;
var dollarSlot = this.event.request.intent.slots.dollar.value;
10 |5000

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

cd avatar image
cd answered

Ok. This helps clarify. When I inspect the object, the intent attributes of the object is not populated. I guess it's the async piece going on and I am trying to get at the value before it is populated. I am using a :delegate dialog directive which is a divergence from the recipe example.

10 |5000

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.