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 736 forks source link

progressive response is not progressive #406

Closed alrouen closed 6 years ago

alrouen commented 6 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

When sending a progressive response (https://developer.amazon.com/docs/custom-skills/send-the-user-a-progressive-response.html) is a lambda function (nodejs 8.x + ask-sdk-core 2.0.5), I'm expecting Alexa to send a response (i.e. : ok please wait...) before executing an async/long running action (i.e.: sleep, calling another ) and finally giving a final response.

Current Behavior

The progressive response is not sent before executing the next promise running task but:

So if your handler behavior is the following:

You expect to ear:

You will ear:

Steps to Reproduce (for bugs)

This bug can be reproduced by using the sample code from the Alexa cookbook.

Context

Building an Alexa skill that have to deal with async task. Big impact on user experience if not fixed.

Your Environment

Node.js and NPM Info

alrouen commented 6 years ago

I got a response from the Alexa support team explaining me that this is the expected behavior when testing the skill using the alexa console.

But I also get the same behavior from the device.

sgmbh commented 6 years ago

I have the same problem... After the spoken command the echo spot is silent for 3-4 seconds an then speaks the "please wait" & "finished successfully" just after each other. It's like one response.

lucas-rudd commented 6 years ago

Is there any update on this? We've run into this issue when testing our new Skill and it is a serious roadblock for us. In theory the progressive response API sounds like a game-changer; but, we've experienced the same issue reported above in both the simulator and on an echo dot.

tianrenz commented 6 years ago

Hi all,

Sorry kept you all waiting. I tested this with a sample hello world skill and have no issue with the response order. Below are the code sample i used.

const HelloWorldIntentHandler = {
  canHandle(handlerInput) {
    return handlerInput.requestEnvelope.request.type === 'IntentRequest'
      && handlerInput.requestEnvelope.request.intent.name === 'HelloWorldIntent';
  },
  async handle(handlerInput) {
    const speechText = 'Hello World!';

    await callDirectiveService(handlerInput);

    return new Promise((resolve, reject) => {
      setTimeout(() => {
        const response = handlerInput.responseBuilder
                        .speak(speechText)
                        .withSimpleCard('Hello World', speechText)
                        .getResponse();
        resolve(response)
      }, 3000);
    })
  },
};

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

  const requestId = requestEnvelope.request.requestId;

  // build the progressive response directive
  const directive = {
    header: {
      requestId,
    },
    directive: {
      type: 'VoicePlayer.Speak',
      speech: `this is a test speech`,
    },
  };

  // send directive
  return directiveServiceClient.enqueue(directive);
}

Please make sure you are testing this on an physical alexa device. The test console on developer portal doesn't support progressive response at the moment.

Regards

artemkovalyov commented 6 years ago

@tianrenz, your solution worked for me. Thank you very much for testing as it's lacking from the docs, how to use this part of SDK. By the way, in web testing tool it was fine as well.

nikhilym commented 6 years ago

Thanks for confirming @artemkovalyov !!

@alrouen , @sgmbh , @lucas-rudd did you guys try it out with @tianrenz's code-snippet? Please update the issue with your findings!!

sgmbh commented 6 years ago

My skill is based on ASK SDK v1. Is it possible that the progressive response only works with the v2 request handler interface? Or have I made a mistake in my code? I tested this with the online tool from amazon and with my real echo spot. Everything works, only the progressive response is to late. The behaviour is exactly like alrouen said:

Thanks for your help!

'MyIntent': function () {
    .....
    callDirectiveService(this.event)
    .....
    apiRequestService.send(this.event.session.user.accessToken, '/api/devices/Ping')
        .then((success) => {
            const speechOutput = PING_MESSAGE;
            this.response.cardRenderer(SKILL_NAME, PING_MESSAGE);
            this.response.speak(speechOutput);
            this.emit(':responseReady');
        })
        .catch((err) => {
            const speechOutput = ERROR_MESSAGE;
            const reprompt = HELP_REPROMPT;
            this.response.cardRenderer(SKILL_NAME, ERROR_MESSAGE);
            this.response.speak(speechOutput).listen(reprompt);
            this.emit(':responseReady');
        });
},

.....

function callDirectiveService(event) {
// Call Alexa Directive Service.
const ds = new Alexa.services.DirectiveService();
const requestId = event.request.requestId;
const directive = new Alexa.directives.VoicePlayerSpeakDirective(requestId, WAIT_MESSAGE);
const endpoint = event.context.System.apiEndpoint;
const token = event.context.System.apiAccessToken;
return ds.enqueue(directive, endpoint, token);
};
tianrenz commented 6 years ago

Hi @sgmbh ,

callDirectiveService(event) returns a Promise. So you need to put your following code in the then((data) => {}) to ensure the correct execution order.

Regards

tianrenz commented 6 years ago

Hi all,

Closing this issue. Please reference the solution posted above.

Regards

sgmbh commented 6 years ago

Hi @tianrenz, I should have thought of that myself. Thanks a lot! It works now. Regards

tianrenz commented 6 years ago

Hi @artemkovalyov ,

We are aware of the indeterministic behavior. In our testing, the scenario described would happen randomly. Unfortunately, there's no clear reason as for what triggers it. We believe it could be a service issue, not SDK related. We would recommend to report this on Alexa developer forum.

Regards

jimenaCabrejas commented 5 years ago

Hi,

Do you know if this solution should work on the Amazon Alexa Android App? I tried @tianrenz example skill but I got the problem described above. It waits for 3 seconds then says this is a test speech and hello world just after each other.

Thanks and regards

Junot-Jean commented 1 year ago

hi? i'm having the same issue, i've been trying to solve it with @tianrenz code but nothing changes.