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.12k stars 737 forks source link

Getting 401 when sending Progressive Response | Alexa #594

Closed guruprasaad123 closed 4 years ago

guruprasaad123 commented 4 years ago

I'm submitting a...


[ ] Regression (a behavior that used to work and stopped working in a new release)
[ x ] Bug report  
[ ] Performance issue
[ ] Feature request
[ ] Documentation issue or request
[ ] Other... Please describe:

Expected Behavior

As mentioned this article on Progressive response . I have implemented my code to send progressive response.

DirectiveService to loader response

function callDirectiveService(handlerInput) {
 // Call Alexa Directive Service.
const requestEnvelope = handlerInput.requestEnvelope;
const directiveServiceClient = handlerInput.serviceClientFactory.getDirectiveServiceClient();

const requestId = requestEnvelope.request.requestId;
const endpoint = requestEnvelope.context.System.apiEndpoint;
const token = requestEnvelope.context.System.apiAccessToken;

 // build the progressive response directive
const directive = {
      header: {
        requestId,
      },
      directive: {
        type: 'VoicePlayer.Speak',
        speech: `please wait till we fetch providers for you `,
      },
    };

    // send directive
    return directiveServiceClient.enqueue(directive, endpoint, token);
  }   

Sending progressive response while fetching GET response ( Intent Handler )

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

const TestIntentHandler = {
  canHandle(handlerInput) {
    return handlerInput.requestEnvelope.request.type === 'IntentRequest'
      && handlerInput.requestEnvelope.request.intent.name === 'TestIntent';
  },
  handle(handlerInput) {
    let name = handlerInput.requestEnvelope.request.intent.slots.name.value;

    const directivePromise = callDirectiveService(handleInput);
    const promise = axios.get('https://someurl.com');
    return Promise.all([directivePromise, promise ]).then((data)=>{
          const speechText = `Fetch successful thanks for waiting `;
    return handlerInput.responseBuilder
      .speak(speechText)
      .getResponse();
    })

  },
};
exports.handler = skillBuilder
  .addRequestHandlers(
    LaunchRequestHandler,
    TestIntentHandler,
    HelpIntentHandler,
    CancelAndStopIntentHandler,
    SessionEndedRequestHandler
  ).withApiClient(new Alexa.DefaultApiClient())
  .addErrorHandlers(ErrorHandler)
  .lambda();

Current Behavior

Instead of sending the progressive Response as mentioned in the article am getting this below mentioned Error :

{ ServiceError: Not Authorized.
    at DirectiveServiceClient.<anonymous> (/var/task/node_modules/ask-sdk-model/index.js:149:35)
    at step (/var/task/node_modules/ask-sdk-model/index.js:42:23)
    at Object.next (/var/task/node_modules/ask-sdk-model/index.js:23:53)
    at fulfilled (/var/task/node_modules/ask-sdk-model/index.js:14:58)
    at process._tickCallback (internal/process/next_tick.js:68:7)
  name: 'ServiceError',
  statusCode: 401,
  response:
   {
 type: 'EXPIRED_AUTHENTICATION_TOKEN',
 message: 'The authentication token has expired.' } 
}

Possible Solution

For now am unable to deduce an solution yet.

Steps to Reproduce (for bugs)

Run the following code in Lambda (Nodejs10.x / us-east-1).

Context

Your Environment

  "dependencies": {
    "axios": "0.19.0",
    "moment": "^2.24.0",
    "redis": "^2.8.0",
    "crypto-js": "^3.1.9-1",
    "ask-sdk-core": "~2.7.0",
    "ask-sdk-model": "~1.23.1"
  }

Node.js and NPM Info

ShenChen93 commented 4 years ago

Hi @guruprasaad123 ,

Sorry for responding late. I fetch out your code base and found some issues:

Could you please try above suggestions and see if the issue still exist ?

Thanks, Shen

ShenChen93 commented 4 years ago

Also, from the error message you provided. I guess you copy the request body from somewhere(maybe the developer console) and create a new lambda test event to test your lambda code. If that is the case, you probably need to use the console to get the latest request and then update the lambda test event.

ShenChen93 commented 4 years ago

Close for now, feel free to reopen if issues still exist