alexa not recognizing intent

The solution is to add a line to the response in the LaunchRequest:

.withShouldEndSession(false)

If you don't add it, the default is set to true, so the skill will end right after giving the first response (welcome intent). See the documentation:https://ask-sdk-for-nodejs.readthedocs.io/en/latest/Response-Building.html

Thanks to Suneet Patil I updated the script accordingly (see below) At first only this worked:

  • User: 'Alexa, ask my personal heartbeat how fast my heart is beating right now.'
  • Alexa: '75 bpm'

But I could not reach the intent:

  • User: 'Alexa talk to my personal heartbeat'
  • Alexa: 'Welcome to your personal heart health monitor. What would you like to know?'(exits skill by default)
  • User: 'How fast is my heart beating right now?'
  • Alexa: 'Sorry, I'm not sure.'

With the new script below:

/* eslint-disable  func-names */
/* eslint-disable  no-console */

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

const GetNewFactHandler = {
  canHandle(handlerInput) {
    const request = handlerInput.requestEnvelope.request;
    return request.type === 'LaunchRequest'
      || (request.type === 'IntentRequest'
        && request.intent.name === 'start');
  },
  handle(handlerInput) {
    const speechOutput = "Welcome to your personal heart health monitor. What would you like to know?";

    return handlerInput.responseBuilder
      .speak(speechOutput)
      .withSimpleCard(speechOutput)
      .withShouldEndSession(false)
      .getResponse();

  },
};

const CurrentBPMHandler = {
  canHandle(handlerInput) {
    const request = handlerInput.requestEnvelope.request;
    return request.type === 'IntentRequest'
      && request.intent.name === 'currentbpm';
  },
  handle(handlerInput) {
    return handlerInput.responseBuilder
      .speak('seventy five bpm')
      .reprompt('seventy five bpm')
      .getResponse();
  },
};


const HelpHandler = {
  canHandle(handlerInput) {
    const request = handlerInput.requestEnvelope.request;
    return request.type === 'IntentRequest'
      && request.intent.name === 'AMAZON.HelpIntent';
  },
  handle(handlerInput) {
    return handlerInput.responseBuilder
      .speak(HELP_MESSAGE)
      .reprompt(HELP_REPROMPT)
      .getResponse();
  },
};

const ExitHandler = {
  canHandle(handlerInput) {
    const request = handlerInput.requestEnvelope.request;
    return request.type === 'IntentRequest'
      && (request.intent.name === 'AMAZON.CancelIntent'
        || request.intent.name === 'AMAZON.StopIntent');
  },
  handle(handlerInput) {
    return handlerInput.responseBuilder
      .speak(STOP_MESSAGE)
      .getResponse();
  },
};

const SessionEndedRequestHandler = {
  canHandle(handlerInput) {
    const request = handlerInput.requestEnvelope.request;
    return request.type === 'SessionEndedRequest';
  },
  handle(handlerInput) {
    console.log(`Session ended with reason: ${handlerInput.requestEnvelope.request.reason}`);

    return handlerInput.responseBuilder.getResponse();
  },
};

const ErrorHandler = {
  canHandle() {
    return true;
  },
  handle(handlerInput, error) {
    console.log(`Error handled: ${error.message}`);

    return handlerInput.responseBuilder
      .speak('Sorry, an error occurred.')
      .reprompt('Sorry, an error occurred.')
      .getResponse();
  },
};

const HELP_MESSAGE = 'You can say tell me a space fact, or, you can say exit... What can I help you with?';
const HELP_REPROMPT = 'What can I help you with?';
const STOP_MESSAGE = 'Goodbye!';


const skillBuilder = Alexa.SkillBuilders.standard();

exports.handler = skillBuilder
  .addRequestHandlers(
    GetNewFactHandler,
    CurrentBPMHandler,
    HelpHandler,
    ExitHandler,
    SessionEndedRequestHandler
  )
  .addErrorHandlers(ErrorHandler)
  .lambda();

This works now:

  • User: 'Alexa talk to my personal heartbeat'
  • Alexa: 'Welcome to your personal heart health monitor. What would you like to know?'
  • User:'How fast is my heart beating right now?'
  • Alexa: 'seventy-five bpm.'(skill stays open to ask another question)

For any request, if not provided, shouldEndSession defaults to true. In your case, the response to LaunchRequest will not have this shouldEndSession parameter and the session closes.

Though you can always use ask-nodejs-sdk's shouldEndSession(false) to keep-alive the session, you don't have to specifically set this to false every time. Instead, a better approach would be to use a reprompt in your LaunchRequest. And if you include a reprompt() then, the sdk will automatically add "shouldEndSession": false in your response.

With your code as it is right now, your LaunchRequest will wait for 8 seconds and if there is no user response the session will close. But, for CurrentBPMHandler or HelpHandler you have included a reprompt and it will wait another additional 8 seconds after the reprompt. It's always a good idea to include a reprompt when you expect a response from the user.

Your interaction model has an AMAZON.FallbackIntent intent defined, but you haven't handled it in your code. The AMAZON.FallbackIntent helps you handle unexpected utterances, or when a user says something that doesn’t map to any intents in your skill. If there is no handler, then it will be caught in your error handler. There is no issue to handle it as an error, but a better approach would be to add a handler specifically for this and give a response like "Sorry, I didn't understand, can you please rephrase your question" or something similar.