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

`withAskForPermissionsConsentCard` generating errors #738

Open GonzaloHirsch opened 1 year ago

GonzaloHirsch commented 1 year 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

I am following the guide on using the DeviceAddressServiceClient, but the code snippets shown in that section cause an error. It should prompt the user for permissions in a device with a screen or just let the user know they need to grant the permissions.

Current Behavior

I get the There was a problem with the requested skill's response error when testing it both in the test console and a real device. I am using the exact same code given by Amazon in the guide I linked above.

Part of my code is:

const consentToken = requestEnvelope.context.System.user.permissions
        && requestEnvelope.context.System.user.permissions.consentToken;
    if (!consentToken) {
        return buildResponse(false, responseBuilder
            // .speak('Please enable Location permissions in the Amazon Alexa app.')
            // .reprompt('Please enable Location permissions in the Amazon Alexa app.')
            .withAskForPermissionsConsentCard(['read::alexa:device:all:address'])
            .getResponse());
    }

After testing with commenting/uncommenting the .withAskForPermissionsConsentCard(['read::alexa:device:all:address']) line, I have figured out that the problem is there.

The response I get from my Cloud Function is:

{
    "body": {
        "version": "1.0",
        "response": {
            "card": {
                "type": "AskForPermissionsConsent",
                "permissions": [
                    "read::alexa:device:all:address"
                ]
            },
            "type": "_DEFAULT_RESPONSE"
        },
        "sessionAttributes": {},
        "userAgent": "ask-node/2.14.0 Node/v18.16.0"
    }
}

This seems to be ok at first sight (I'm not very experienced with Alexa development, this is my first rodeo on this). If I remove that line of code, everything works normally.

Possible Solution

I'm not sure how you can solve this, as I don't have enough information on it.

Steps to Reproduce (for bugs)

This is my wrapper for getting a country code:

const buildResponse = (success, payload) => {
    return {
        success: success,
        payload: payload
    }
}

const getCountryCode = async (handlerInput) => {
    // Split variables
    const { requestEnvelope, serviceClientFactory, responseBuilder } = handlerInput;
    // Get the consent token for the location
    const consentToken = requestEnvelope.context.System.user.permissions
        && requestEnvelope.context.System.user.permissions.consentToken;
    if (!consentToken) {
        return buildResponse(false, responseBuilder
            // .speak('Please enable Location permissions in the Amazon Alexa app.')
            // .reprompt('Please enable Location permissions in the Amazon Alexa app.')
            .withAskForPermissionsConsentCard(['read::alexa:device:all:address'])
            .getResponse());
    }

    // Try to get the address
    try {
        const { deviceId } = requestEnvelope.context.System.device;
        const deviceAddressServiceClient = serviceClientFactory.getDeviceAddressServiceClient();

        // Try to get the full address
        const address = await deviceAddressServiceClient.getCountryAndPostalCode(deviceId);

        // Only intend on looking for the country code
        if (address.countryCode === null) {
            return buildResponse(false, responseBuilder
                .speak(`It looks like you don't have an address set. You can set your address from the companion app.`)
                .reprompt(`It looks like you don't have an address set. You can set your address from the companion app.`)
                .getResponse());
        }
        return buildResponse(true, address.countryCode);
    } catch (error) {
        if (error.name !== 'ServiceError') {
            console.error(`Error response: ${error.message}`)
            return buildResponse(false, responseBuilder
                .speak('Uh Oh. Looks like something went wrong.')
                .reprompt('Uh Oh. Looks like something went wrong.')
                .getResponse());
        }
        throw error;
    }
}

module.exports = {
    getCountryCode
}

You can run this in an intent handler and just call this function.

Context

I cannot develop the visual part for devices enabled with screens.

Your Environment

Cloud Function hosted on AWS using the nodejs18.x runtime.