alexa / alexa-skills-kit-sdk-for-nodejs

The Alexa Skills Kit SDK for Node.js helps you get a skill up and running quickly, letting you focus on skill logic instead of boilerplate code.
Apache License 2.0
3.13k stars 738 forks source link

Alexa invokes intent with certain slot values but not others? #545

Closed dillonharlessNHRMC closed 5 years ago

dillonharlessNHRMC commented 5 years ago

I'm submitting a...

[x ] Bug report

I have an intent that should be invoked on 'yes', 'no', or 'repeat'. On 'no' and 'repeat' it works absolutely perfectly. On 'yes', i get an error. Then I check Cloudwatch and it says it couldn't find a suitable handler. However, when I test in Lambda with 'yes' in the value of the slot, it works perfectly.

Expected Behavior

Intent should be invoked and sent to proper handler on 'yes', 'no', or 'repeat'

Current Behavior

Intent only invoked and sent to proper handler on 'no' and 'repeat'

Possible Solution

Keeping track of current Intent and using global YesNo intent to push into. Starts turning into spaghetti code though, and would like to avoid that with my current implementation.

Steps to Reproduce (for bugs)

Here is the JSON you could use to make the intent:

{
            "name": "RoundingVerifyIntent",
            "slots": [
                {
                    "name": "RoundingVerify",
                    "type": "ROUNDING_VERIFY"
                }
            ],
            "samples": [
                "{RoundingVerify}"
            ]
        },

And here is the code you could use to make the slot type:

               { 
                    "name": "ROUNDING_VERIFY",
                    "values": [
                        {
                            "name": {
                                "value": "no",
                                "synonyms": [
                                    "that's wrong",
                                    "wrong",
                                    "nah",
                                    "noooo",
                                    "no way",
                                    "nope",
                                    "nah"
                                ]
                            }
                        },
                        {
                            "name": {
                                "value": "yes",
                                "synonyms": [
                                    "correct",
                                    "that's correct",
                                    "yop",
                                    "yup",
                                    "yep",
                                    "yeah"
                                ]
                            }
                        },
                        {
                            "name": {
                                "value": "repeat",
                                "synonyms": [
                                    "pardon me",
                                    "say again",
                                    "repeat again"
                                ]
                            }
                        }
                    ]
                },

Then just make an intent handler with a canHandle like so and put it in a skill in Lambda:

const RoundingVerifyHandler = {
  canHandle(handlerInput) {
    const request = handlerInput.requestEnvelope.request
    const sessionAttributes = handlerInput.attributesManager.getSessionAttributes()
    return (request.type === 'IntentRequest' &&
      request.intent.name === 'RoundingVerifyIntent')

UPDATE: I just tried to add a directive of type elicit.slot and i am left with the same functionality. How is this even possible?

Context

Project work has halted for my company

Your Environment

Node.js and NPM Info

dillonharlessNHRMC commented 5 years ago

Okay so I got it working after I edited the directive. This got it to work.

.addDirective({
          "type": "Dialog.ElicitSlot",
          "slotToElicit": "RoundingVerify",
          "updatedIntent": {
            "name": "RoundingVerifyIntent",
            "confirmationStatus": "NONE",
            "slots": {
              "RoundingVerify": {
                "name": "RoundingVerify",
                "value": "yes",
                "resolutions": {},
                "confirmationStatus": "NONE"
              }
            }
          }
        })

I assumed that if I put the value in there it would automatically set it to yes which is not what I want... but for some reason it waits for user input. Can someone tell me why this is?

Thanks a lot.

ShenChen93 commented 5 years ago

Hi @dillonharlessNHRMC

Sorry for responding late. I am trying to reproduce the problem you met by using the intent and slots you provided. However, for my test code, the yes utterance can correctly mapped to RoundingVerifyIntent. Even I add AmazonYes intent to my skill, the custom intent always has the priority to be consumed. I wonder if you can provide me with the JSON input to your lambda when you say yes to your skill, and find out which intent is invoked.

Thanks, Shen

dillonharlessNHRMC commented 5 years ago

@ShenChen-Amazon Hey, Shen. Thanks for responding. Unfortunately I didn't save a version of the code that wasn't working... It was just strange that without eliciting the slot directly, it wouldn't understand 'yes'. However, since it's working now, I think we can close this and I may open another issue about my further, not-exactly-related questions.

Thanks again!

ShenChen93 commented 5 years ago

Hi @dillonharlessNHRMC ,

Thanks for updating. Close this issue for now. Please feel free to reopen it if you meet similar problem again.

Shen