Search code examples
node.jsjsonalexa-skills-kit

My Alexa intent has no slot defined, no matter what I ask


I'm using a custom Lambda function to handle my custom Alexa skill. I have a single slot, which I want to capture. Unfortunately, the intent slot is never populated with any value, and seems to be getting ignored, despite being in the request.

Here is my code (note: the JSON.stringify is there to help me debug):

'use strict';
var Alexa = require("alexa-sdk");

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

var handlers = {
    'LaunchRequest': function () {
        this.emit('Snow');
    },
    'Snow': function () {
        var place = this.event.request.intent.slots.Place;

        var text = 'Over the next 9 days you can expect 12 centimeters of snowfall in '+ JSON.stringify(place) +'.  The upper piste has a depth of 75 centimeters and the lower piste has a depth of 35 centimeters.  All 19 lifts are currently open.';

        this.emit(':tell', text);
    }
};

I have an Intent called "Snow" and a slot called "Place". Here is my interaction model:

{
    "interactionModel": {
        "languageModel": {
            "invocationName": "ski club",
            "intents": [
                {
                    "name": "AMAZON.FallbackIntent",
                    "samples": []
                },
                {
                    "name": "AMAZON.CancelIntent",
                    "samples": []
                },
                {
                    "name": "AMAZON.HelpIntent",
                    "samples": []
                },
                {
                    "name": "AMAZON.StopIntent",
                    "samples": []
                },
                {
                    "name": "AMAZON.NavigateHomeIntent",
                    "samples": []
                },
                {
                    "name": "Snow",
                    "slots": [
                        {
                            "name": "Place",
                            "type": "AMAZON.City"
                        }
                    ],
                    "samples": [
                        "how the powder is",
                        "what the powder is like",
                        "how the snow is",
                        "what the snow is like",
                        "snow conditions",
                        "snow condition",
                        "snow fall",
                        "snowfall",
                        "powder levels",
                        "powder level",
                        "snow level",
                        "powder depth",
                        "snow levels",
                        "snow depth",
                        "powder",
                        "snow",
                        "the snow"
                    ]
                }
            ],
            "types": []
        },
        "dialog": {
            "intents": [
                {
                    "name": "Snow",
                    "confirmationRequired": false,
                    "prompts": {},
                    "slots": [
                        {
                            "name": "Place",
                            "type": "AMAZON.City",
                            "confirmationRequired": false,
                            "elicitationRequired": true,
                            "prompts": {
                                "elicitation": "Elicit.Slot.115004419453.153941565683"
                            }
                        }
                    ]
                }
            ]
        },
        "prompts": [
            {
                "id": "Elicit.Slot.115004419453.153941565683",
                "variations": [
                    {
                        "type": "PlainText",
                        "value": "Where would you like to know about the snow?"
                    }
                ]
            }
        ]
    }
}

I would expect to be able to ask:

Alexa ask my app how the snow is in Morzine

And I would expect an answer back with the static text from my Lambda function, including the name inserted. However, I'm getting the following:

{
    "body": {
        "version": "1.0",
        "response": {
            "outputSpeech": {
                "type": "SSML",
                "ssml": "<speak> Over the next 9 days you can expect 12 centimeters of snowfall in {\"name\":\"Place\",\"confirmationStatus\":\"NONE\"}.  The upper piste has a depth of 75 centimeters and the lower piste has a depth of 35 centimeters.  All 19 lists are currently open. </speak>"
            },
            "shouldEndSession": true
        },
        "sessionAttributes": {},
        "userAgent": "ask-nodejs/1.0.25 Node/v8.10.0"
    }
}

It seems Place never has a value.

I get the exact same response if I omit the Place slot entirely:

Alexa ask my app how the snow is

Here I would expect to be asked to give a slot.

Here is the JSON Input from Alexa (I've redacted some keys):

{
    "version": "1.0",
    "session": {
        "new": true,
        "sessionId": "amzn1.echo-api.session.***",
        "application": {
            "applicationId": "amzn1.ask.skill.***"
        },
        "user": {
            "userId": "amzn1.ask.account.***"
        }
    },
    "context": {
        "System": {
            "application": {
                "applicationId": "amzn1.ask.skill.***"
            },
            "user": {
                "userId": "amzn1.ask.account.***"
            },
            "device": {
                "deviceId": "amzn1.ask.device.***",
                "supportedInterfaces": {}
            },
            "apiEndpoint": "https://api.eu.amazonalexa.com",
            "apiAccessToken": "***.***.***
        },
        "Viewport": {
            "experiences": [
                {
                    "arcMinuteWidth": 246,
                    "arcMinuteHeight": 144,
                    "canRotate": false,
                    "canResize": false
                }
            ],
            "shape": "RECTANGLE",
            "pixelWidth": 1024,
            "pixelHeight": 600,
            "dpi": 160,
            "currentPixelWidth": 1024,
            "currentPixelHeight": 600,
            "touch": [
                "SINGLE"
            ]
        }
    },
    "request": {
        "type": "IntentRequest",
        "requestId": "amzn1.echo-api.request.92fc43d8-0dc2-4a08-a31a-70a031e2fef7",
        "timestamp": "2018-11-16T16:51:17Z",
        "locale": "en-GB",
        "intent": {
            "name": "Snow",
            "confirmationStatus": "NONE",
            "slots": {
                "Place": {
                    "name": "Place",
                    "confirmationStatus": "NONE"
                }
            }
        },
        "dialogState": "STARTED"
    }
}

Solution

  • My intents need to include the slot itself, it isn't assumed to be in there like I thought. This is done by appending {Place}.