Skip to content
This repository was archived by the owner on Mar 31, 2023. It is now read-only.
This repository was archived by the owner on Mar 31, 2023. It is now read-only.

CustomInterfaceEventHandler (line 211) is getting into infinite loop #16

@monupurohit

Description

@monupurohit

//
// Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// These materials are licensed under the Amazon Software License in connection with the Alexa Gadgets Program.
// The Agreement is available at https://aws.amazon.com/asl/.
// See the Agreement for the specific terms and conditions of the Agreement.
// Capitalized terms not defined in this file have the meanings given to them in the Agreement.
//
'use strict';

const Alexa = require('ask-sdk-core');
const Uuid = require('uuid/v4');

let skill;
exports.handler = function(event, context) {

if (!skill) {
    skill = Alexa.SkillBuilders.custom()
        .addRequestHandlers(
            handler.LaunchRequestHandler,
            handler.YesIntentHandler,
            handler.ToyIntentHandler,
			handler.StopToyIntentHandler,
            handler.NoIntentHandler,
            handler.CustomInterfaceEventHandler,
            handler.CustomInterfaceExpirationHandler,
            handler.StopAndCancelIntentHandler,
            handler.SessionEndedRequestHandler,
            handler.DefaultHandler
        )
        .addRequestInterceptors(handler.RequestInterceptor)
        .addResponseInterceptors(handler.ResponseInterceptor)
        .addErrorHandlers(handler.ErrorHandler)
        .withApiClient(new Alexa.DefaultApiClient())
        .create();
}
return skill.invoke(event, context);

};

const handler = {
LaunchRequestHandler: {
canHandle(handlerInput) {
let { request } = handlerInput.requestEnvelope;
console.log("LaunchRequestHandler: checking if it can handle " + request.type);
return request.type === 'LaunchRequest';
},
async handle(handlerInput) {
console.log("== Launch Intent ==");
console.log(JSON.stringify(handlerInput.requestEnvelope));

        let response;
        try {
            // Get connected gadget endpointId.
            console.log("Checking endpoint");
            response = await getConnectedEndpointsResponse(handlerInput);
            console.log("v1/endpoints response: " + JSON.stringify(response));

            if ((response.endpoints || []).length === 0) {
                console.log('No connected gadget endpoints available');
                response = handlerInput.responseBuilder
                    .speak("No gadgets found. Please try again after connecting your gadget.")
                    .getResponse();
                return response;
            }

            let endpointId = response.endpoints[0].endpointId;

            // Store endpointId for using it to send custom directives later.
            console.log("Received endpoints. Storing Endpoint Id: " + endpointId);
            const attributesManager = handlerInput.attributesManager;
            let sessionAttributes = attributesManager.getSessionAttributes();
            sessionAttributes.endpointId = endpointId;
            attributesManager.setSessionAttributes(sessionAttributes);

            return handlerInput.responseBuilder
                .speak("Hello, Welcome to Virtual Diwali " +
                    "Today we will fire crackers in a eco friendly way. Say start the show when you are you ready?")
                .withShouldEndSession(false)
                // Send the BlindLED directive to make the LED green for 20 seconds.
                .addDirective(buildBlinkLEDDirective(endpointId, ['GREEN'], 1000, 20, false))
                .getResponse();
        }
        catch (err) {
            console.log("An error occurred while getting endpoints", err);
            response = handlerInput.responseBuilder
                .speak("I wasn't able to get connected endpoints. Please try again.")
                .withShouldEndSession(true)
                .getResponse();
            return response;
        }
    }
},
YesIntentHandler: {
    canHandle(handlerInput) {
        let { request } = handlerInput.requestEnvelope;
        let intentName = request.intent ? request.intent.name : '';
        console.log("YesIntentHandler: checking if it can handle " +
            request.type + " for " + intentName);
        return request.intent && request.intent.name === 'AMAZON.YesIntent';
    },
    handle(handlerInput) {
        // Retrieve the stored gadget endpointId from the SessionAttributes.
        const attributesManager = handlerInput.attributesManager;
        let sessionAttributes = attributesManager.getSessionAttributes();
        let endpointId = sessionAttributes.endpointId;

        // Create a token to be assigned to the EventHandler and store it
        // in session attributes for stopping the EventHandler later.
        sessionAttributes.token = Uuid();
        attributesManager.setSessionAttributes(sessionAttributes);

        console.log("YesIntent received. Starting game.");

        return handlerInput.responseBuilder
            // Send the BlindLEDDirective to trigger the cycling animation of the LED.
            .addDirective(buildBlinkLEDDirective(endpointId, ['RED', 'YELLOW', 'GREEN', 'CYAN', 'BLUE', 'PURPLE', 'WHITE'],
                1000, 2, true))
            // Start a EventHandler for 10 seconds to receive only one
            // 'Custom.ColorCyclerGadget.ReportColor' event and terminate.
            .addDirective(buildStartEventHandlerDirective(sessionAttributes.token, 10000,
                'Custom.ColorCyclerGadget', 'ReportColor', 'SEND_AND_TERMINATE',
                { 'data': "You didn't press the button. Good bye!" }))
            .getResponse();
    }
},
ToyIntentHandler: {
    canHandle(handlerInput) {
        let { request } = handlerInput.requestEnvelope;
        let intentName = request.intent ? request.intent.name : '';
        console.log("ToyIntentHandler: checking if it can handle " +
            request.type + " for " + intentName);
        return request.intent && request.intent.name === 'ToyIntent';
    },
    handle(handlerInput) {
        // Retrieve the stored gadget endpointId from the SessionAttributes.
        const attributesManager = handlerInput.attributesManager;
        let sessionAttributes = attributesManager.getSessionAttributes();
        let endpointId = sessionAttributes.endpointId;

        // Create a token to be assigned to the EventHandler and store it
        // in session attributes for stopping the EventHandler later.
        sessionAttributes.token = Uuid();
        attributesManager.setSessionAttributes(sessionAttributes);

        console.log("ToyIntent received. Starting game.");

		return handlerInput.responseBuilder
                .speak("Put the cracker on launchpad and say fire")
                .withShouldEndSession(false)
                //.addDirective(buildBlinkLEDDirective(endpointId, ['GREEN'], 1000, 20, false))
				.addDirective(buildLightDirective(endpointId, 0, true))
				.reprompt('Say Fire when you are ready')
                .getResponse();
    }
},
StopToyIntentHandler: {
    canHandle(handlerInput) {
        let { request } = handlerInput.requestEnvelope;
        let intentName = request.intent ? request.intent.name : '';
        console.log("StopToyIntentHandler: checking if it can handle " +
            request.type + " for " + intentName);
        return request.intent && request.intent.name === 'StopToyIntent';
    },
    handle(handlerInput) {
        // Retrieve the stored gadget endpointId from the SessionAttributes.
        const attributesManager = handlerInput.attributesManager;
        let sessionAttributes = attributesManager.getSessionAttributes();
        let endpointId = sessionAttributes.endpointId;

        // Create a token to be assigned to the EventHandler and store it
        // in session attributes for stopping the EventHandler later.
        sessionAttributes.token = Uuid();
        attributesManager.setSessionAttributes(sessionAttributes);

        console.log("StopToyIntent received. Stoping game.");
        //var speechText = 'Sure, here we go' + '<audio src="soundbank://soundlibrary/air/fire_extinguisher/fire_extinguisher_01"/>';
		return handlerInput.responseBuilder
                //.speak(speechText)
                .speak("Firing the selected cracker")
                .withShouldEndSession(false)
                //.addDirective(buildBlinkLEDDirective(endpointId, ['GREEN'], 1000, 20, false))
				.addDirective(buildLightStopDirective(endpointId, 1, true))
				// Start a EventHandler for 10 seconds to receive only one
               // 'Custom.ColorCyclerGadget.ReportColor' event and terminate.
                .addDirective(buildStartEventHandlerDirective(sessionAttributes.token, 10000,
                'Custom.ColorCyclerGadget', 'ReportColor', 'SEND_AND_TERMINATE',
                { 'data': "You didn't press the button. Good bye!" }))
                .getResponse();	
    }
},
NoIntentHandler: {
    canHandle(handlerInput) {
        let { request } = handlerInput.requestEnvelope;
        let intentName = request.intent ? request.intent.name : '';
        console.log("NoIntentHandler: checking if it can handle " +
            request.type + " for " + intentName);
        return request.intent && request.intent.name === 'AMAZON.NoIntent';
    },
    handle(handlerInput) {
        console.log("Received NoIntent..Exiting.");
        const attributesManager = handlerInput.attributesManager;
        let sessionAttributes = attributesManager.getSessionAttributes();

        // Send StopLED directive to stop LED animation and end skill session.
        return handlerInput.responseBuilder
            .addDirective(buildStopLEDDirective(sessionAttributes.endpointId))
            .speak("Alright. Good bye!")
            .withShouldEndSession(true)
            .getResponse();
    }
},
CustomInterfaceEventHandler: {
    canHandle(handlerInput) {
        let { request } = handlerInput.requestEnvelope;
        console.log("CustomEventHandler: checking if it can handle " + request.type);
        return request.type === 'CustomInterfaceController.EventsReceived';
    },
    handle(handlerInput) {
        console.log("== Received Custom Event ==");

        let { request } = handlerInput.requestEnvelope;

        const attributesManager = handlerInput.attributesManager;
        let sessionAttributes = attributesManager.getSessionAttributes();

        // Validate eventHandler token 123
        if (sessionAttributes.token !== request.token) {
            console.log("EventHandler token doesn't match. Ignoring this event.");
            return handlerInput.responseBuilder
                .speak("EventHandler token doesn't match. Ignoring this event.")
                .getResponse();
        }

        let customEvent = request.events[0];
        let payload = customEvent.payload;
        let namespace = customEvent.header.namespace;
        let name = customEvent.header.name;

        let response = handlerInput.responseBuilder;
        var speechText;
        //var speechText = 'here we go' + '<audio src="soundbank://soundlibrary/impacts/amzn_sfx_fireworks_firecrackers_01"/>';
       //var speechText = 'here we go' + '<audio src="soundbank://soundlibrary/air/fire_extinguisher/fire_extinguisher_01"/>';
       
       
       if (payload.color === 'RED')
       {
           speechText = 'here we go' + '<audio src="soundbank://soundlibrary/impacts/amzn_sfx_fireworks_firecrackers_01"/>';
       }
       if (payload.color === 'BLUE')
       {
           speechText = 'here we go' + '<audio src="soundbank://soundlibrary/air/fire_extinguisher/fire_extinguisher_01"/>';
       }


        if (namespace === 'Custom.ColorCyclerGadget' && name === 'ReportColor') {
            //return response.speak(payload.color + ' is the selected color. Thank you for playing. Good bye!')
            return response.speak(payload.color + ' is the selected color' +  speechText)
                .withShouldEndSession(false)
                .reprompt('what next do you want')
                .getResponse();
        }
        
        //return response;
    }
},
CustomInterfaceExpirationHandler: {
    canHandle(handlerInput) {
        let { request } = handlerInput.requestEnvelope;
        console.log("CustomEventHandler: checking if it can handle " + request.type);
        return request.type === 'CustomInterfaceController.Expired';
    },
    handle(handlerInput) {
        console.log("== Custom Event Expiration Input ==");

        let { request } = handlerInput.requestEnvelope;

        const attributesManager = handlerInput.attributesManager;
        let sessionAttributes = attributesManager.getSessionAttributes();

        // When the EventHandler expires, send StopLED directive to stop LED animation
        // and end skill session.
        return handlerInput.responseBuilder
            .addDirective(buildStopLEDDirective(sessionAttributes.endpointId))
            .withShouldEndSession(true)
            .speak(request.expirationPayload.data)
            .getResponse();
    }
},
StopAndCancelIntentHandler: {
    canHandle(handlerInput) {
        const { request } = handlerInput.requestEnvelope;
        const intentName = request.intent ? request.intent.name : '';
        console.log("StopAndCancelIntentHandler: checking if it can handle " +
            request.type + " for " + intentName);
        return request.type === 'IntentRequest' &&
            (intentName === 'AMAZON.StopIntent' || intentName === 'AMAZON.CancelIntent');
    },
    handle(handlerInput) {
        console.log("Received a Stop or a Cancel Intent..");

        let { attributesManager, responseBuilder } = handlerInput;
        let sessionAttributes = attributesManager.getSessionAttributes();

        // When the user stops the skill, stop the EventHandler,
        // send StopLED directive to stop LED animation and end skill session.
        if (sessionAttributes.token) {
            console.log("Active session detected, sending stop EventHandlerDirective.");
            responseBuilder.addDirective(buildStopEventHandlerDirective(sessionAttributes.token));
        }

        return responseBuilder.speak("Alright. see you later.")
            .addDirective(buildStopLEDDirective(sessionAttributes.endpointId))
            .withShouldEndSession(true)
            .getResponse();
    }
},
SessionEndedRequestHandler: {
    canHandle(handlerInput) {
        return handlerInput.requestEnvelope.request.type === 'SessionEndedRequest';
    },
    handle(handlerInput) {
        console.log(`Session ended with reason: ${handlerInput.requestEnvelope.request.reason}`);
        return handlerInput.responseBuilder.getResponse();
    },
},
ErrorHandler: {
    canHandle(handlerInput, error) {
        let { request } = handlerInput.requestEnvelope;
        console.log("ErrorHandler: checking if it can handle " +
            request.type + ": [" + error.name + "] -> " + !!error.name);
        return !!error.name;
    },
    handle(handlerInput, error) {
        console.log("Global.ErrorHandler: error = " + error.message);

        return handlerInput.responseBuilder
            .speak("I'm sorry, something went wrong!")
            .getResponse();
    }
},
RequestInterceptor: {
    process(handlerInput) {
        let { attributesManager, requestEnvelope } = handlerInput;
        let sessionAttributes = attributesManager.getSessionAttributes();

        // Log the request for debugging purposes.
        console.log(`==Request==${JSON.stringify(requestEnvelope)}`);
        console.log(`==SessionAttributes==${JSON.stringify(sessionAttributes, null, 2)}`);
    }
},
ResponseInterceptor: {
    process(handlerInput) {

        let { attributesManager, responseBuilder } = handlerInput;
        let response = responseBuilder.getResponse();
        let sessionAttributes = attributesManager.getSessionAttributes();

        // Log the response for debugging purposes.
        console.log(`==Response==${JSON.stringify(response)}`);
        console.log(`==SessionAttributes==${JSON.stringify(sessionAttributes, null, 2)}`);
    }
},
DefaultHandler: {
    canHandle(handlerInput) {
        let { request } = handlerInput.requestEnvelope;
        let intentName = request.intent ? request.intent.name : '';
        console.log("DefaultHandler: checking if it can handle " +
            request.type + " for " + intentName);
        return true;
    },
    handle(handlerInput) {
        console.log("Unsupported Intent receive..Exiting.");
        return handlerInput.responseBuilder
            .speak("Unsupported Intent received. Exiting.")
            .getResponse();
    }
}

};

function getConnectedEndpointsResponse(handlerInput) {
return handlerInput.serviceClientFactory.getEndpointEnumerationServiceClient().getEndpoints();
}

function buildBlinkLEDDirective(endpointId, colors_list, intervalMs, iterations, startGame) {
return {
type: 'CustomInterfaceController.SendDirective',
header: {
name: 'BlinkLED',
namespace: 'Custom.ColorCyclerGadget'
},
endpoint: {
endpointId: endpointId
},
payload: {
colors_list: colors_list,
intervalMs: intervalMs,
iterations: iterations,
startGame: startGame
}
};
}

function buildLightDirective(endpointId, colors_state, startGame) {
return {
type: 'CustomInterfaceController.SendDirective',
header: {
name: 'BlinkLight',
namespace: 'Custom.ColorCyclerGadget'
},
endpoint: {
endpointId: endpointId
},
payload: {
colors_state: colors_state,
startGame: startGame
}
};
}

function buildLightStopDirective(endpointId, colors_state, startGame) {
return {
type: 'CustomInterfaceController.SendDirective',
header: {
name: 'StopLight',
namespace: 'Custom.ColorCyclerGadget'
},
endpoint: {
endpointId: endpointId
},
payload: {
colors_state: colors_state,
startGame: startGame
}
};
}

function buildStopLEDDirective(endpointId) {
return {
type: 'CustomInterfaceController.SendDirective',
header: {
name: 'StopLED',
namespace: 'Custom.ColorCyclerGadget'
},
endpoint: {
endpointId: endpointId
},
payload: {}
};
}

function buildStartEventHandlerDirective(token, durationMs, namespace, name, filterMatchAction, expirationPayload) {
return {
type: "CustomInterfaceController.StartEventHandler",
token: token,
eventFilter: {
filterExpression: {
'and': [
{ '==': [{ 'var': 'header.namespace' }, namespace] },
{ '==': [{ 'var': 'header.name' }, name] }
]
},
filterMatchAction: filterMatchAction
},
expiration: {
durationInMilliseconds: durationMs,
expirationPayload: expirationPayload
}
};
}

function buildStopEventHandlerDirective(token) {
return {
type: "CustomInterfaceController.StopEventHandler",
token: token
};
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions