アクセスいただきありがとうございます。こちらのページは現在英語のみのご用意となっております。順次日本語化を進めてまいりますので、ご理解のほどよろしくお願いいたします。

Receive Echo Button Events

This topic provides an overview of how your skill receives input from Echo Buttons.

Overview

To receive input from Echo Buttons, your skill sends directives to, and receives notifications from, a component within Alexa called the Game Engine. The Game Engine enables your skill to define Input Handlers that filter button presses into named events that it forwards to your skill when conditions in the Input Handler definition are met.

For example, you can define an event for "the first time a player presses a red button." In this case, the Game Engine will only notify your skill under that condition. It won't, for example, notify your skill when a player presses a yellow button, or a player presses a red button the second time. Each skill instance can have only one active Input Handler at a time, and you can define up to 32 different Input Handler events for a single Input Handler. If a skill has an active Input Handler, Echo Button presses interrupt text-to-speech (TTS).

Skill Interaction with Alexa

The Game Engine doesn't change the way that your skill receives requests from, or responds to, Alexa, it just provides additional directives and events that your skill can use when it exchanges information with Alexa in the usual way. The exchange of information is as follows:

  • Skill to Game Engine – To send directives to the Game Engine, respond to any request from Alexa.
  • Game Engine to skill – The Game Engine sends your skill Input Handler events in the form of requests, similar to any other event request from Alexa.

The following figure shows how your skill and the Game Engine interact.

Receiving Echo Button Input

Skill Flow

The following is the typical flow of a skill that interacts with Echo Buttons:

  1. Starting Input Handlers – Your skill starts an Input Handler by responding to any request from Alexa. In the response, your skill includes a directive that configures the Input Handler parameters. These configurations include the conditions under which your skill should be notified of events, the length of the timeout window, and so on. As usual, you can also include voice output and any other available directives. To learn more about starting an Input Handler, see Starting Input Handlers.
  2. Receiving Input Handler events from the Game Engine – Your skill receives Input Handler events through requests from Alexa. These events are triggered when the event conditions that your skill defined are met. The payload of the event includes a list of the raw button events that contributed to the event conditions being met. To learn more about receiving events from the Game Engine, see Receiving Input Handler events from the Game Engine.
  3. Stopping Input Handlers – An Input Handler stops either because the skill configured it to stop under certain conditions, the skill explicitly stopped the Input Handler using a directive, the Input Handler timed out after the length of time that the skill specified, or the user quit the skill. To learn more about stopping an Input Handler, see Stopping Input Handlers.

Important Points About Input Handlers

Three important things to remember are:

  • Only one Input Handler is active at a time – When you start a new Input Handler, it replaces the previous Input Handler.
  • Input Handlers are meant to receive input for sections of your skill, not for an entire skill – That is, as your skill runs, it typically starts and stops Input Handlers many times. For example, your skill must first take a roll call to find out which Echo Buttons are connected and ready to use. To implement roll call, you might configure an Input Handler to notify you when each button is pressed once. After roll call ends, you might start a new Input Handler, and configure it for a certain type of gameplay. For example, you might configure an Input Handler to send your skill an event when a user presses the buttons in a certain winning sequence.
  • Expect old events – Although only one Input Handler can be active at any time, your skill must be prepared to receive and discard events that an earlier Input Handler generated. This is because it is possible for an earlier event to be "in transit" to the skill, while the skill has moved on and started a new Input Handler. Your skill must check the originatingRequestIdof incoming events against the requestId that the skill saved when it started the current Input Handler.

The following figure shows an example of the life span of Input Handlers for a three-question trivia game.

Trivia Game Input Handlers

Starting Input Handlers

You start an Input Handler by sending a GameEngine.StartInputHandler directive in response to any request from Alexa. In this directive, you specify the conditions under which your skill should be notified of Echo Button events. For an example of how to assemble this directive using the Alexa Skill Kit (ASK) SDKs, see StartInputHandler Example.

Each call to StartInputHandler replaces any existing Input Handler with a new Input Handler.

The following is the general structure of the StartInputHandler directive.

{
  "type": "GameEngine.StartInputHandler",
  "timeout": 5000,
  "proxies": [],
  "recognizers": {},
  "events": {}
}

The following is a description of each field. For detailed API information, see the Game Engine Interface Reference.

  • type – The type of directive, which is GameEngine.StartInputHandler.
  • timeout – The maximum run time for this Input Handler, specified in milliseconds. You are required to declare this upper bound, but you can later specify events with conditions on which to end the Input Handler earlier. The maximum timeout value is 90 seconds, or 90,000 milliseconds.
  • proxies – Temporary identifiers to assign to gadgets that your skill hasn’t yet discovered. For more information about proxies, see Proxies.
  • recognizers – Named, declarative functions that produce an outcome of true or false. You can provide a maximum of 20 recognizers, or you can leave this empty if you don't have any to declare. For more information about recognizers, see Recognizers.
  • events – Groups of recognizers together in boolean logical relationships that, when met, will trigger an invocation of your skill in the form of an InputHandlerEvent request. When you set up an Input Handler, you must define at least one event, and you can define as many as 32. For more information about defining events, see Define Echo Button Events.

Receiving Input Handler events from the Game Engine

After your skill starts an Input Handler by responding to a request from Alexa, your skill will receive Input Handler events as GameEngine.InputHandlerEvent requests from Alexa.

These requests contain button event information in two forms: Input Handler events and raw button events.

  • Input Handler events – These are named events that you define when you start an Input Handler. For example, your skill might define an event called winningSequence that notifies the skill when a player presses the buttons in a certain order. Input Handler events are what trigger the Game Engine to report an event to your skill. To learn more, see Define Echo Button Events.
  • Raw button events – These correspond to a press or release of a button. In JSON, the raw button events are inputEvents within the Input Handler events object. You can configure the Input Handler to include all the raw button events since the Input Handler started, just the ones that triggered your Input Handler event conditions, or none at all.

The following is an example of a request that contains events.

{
  "version": "1.0",
  "session": {
    "application": {},
    "user": {}
   }, 
  "request": {
    "type": "GameEngine.InputHandlerEvent",  
    "requestId": "amzn1.echo-api.request.406fbc75-8bf8-4077-a73d-519f53d172a4",
    "timestamp": "2017-08-18T01:29:40.027Z",
    "locale": "en-US",
    "originatingRequestId": "amzn1.echo-api.request.406fbc75-8bf8-4077-a73d-519f53d172d6",
    "events": [
      {       
        "name": "myEventName",
        "inputEvents": [
          {
            "gadgetId": "someGadgetId1",
            "timestamp": "2017-08-18T01:32:40.027Z",
            "action": "down",
            "color": "FF0000"
          }
        ]
      }
    ]
  }
}

In addition to the fields that are common to all Alexa Skills Kit requests (type, requestId, timestamp, and locale), the fields are as follows:

  • originatingRequestId – The request ID of the request to which you responded with a StartInputHandler directive. You should store this request ID to use as a filter to reject any old asynchronous Input Hander events that come in after you've started a new Input Handler.
  • events – A list of named Input Handler events that triggered the request. When an event's conditions become true, the event is sent to your skill only once. However, there may be multiple named events within one request if more than one such event became true at the same time.
  • name – The name of the event as you defined it in your StartInputHandler directive.
  • inputEvents – A chronologically ordered report of the raw button events that contributed to this Input Handler event. You can analyze this list to discover things like intervals between events, or conformance to some function with which to judge player performance. Raw button events have the following fields:
    • gadgetId – The permanent identifier of the Echo Button. This is the gadget ID you discovered in roll call.
    • action – This is down for a button press or up for a button release.
    • color – The hexadecimal RGB values of the button LED at the time of the event.
    • timestamp – The raw button event's original moment of occurrence, in ISO format.

For detailed API information, see the Game Engine Interface Reference.

Stopping Input Handlers

To end an Input Handler ahead of schedule, reply to any request with a GameEngine.StopInputHandler directive and include the originating requestId that you saved from the original request that you responded to when you started the Input Handler. For an example of how to assemble this directive using the ASK SDKs, see StopInputHandler Example.

If you attempt to stop an old or nonexistent Input Handler, Alexa will ignore the request and leave any active Input Handler running. The Input Handler will run until it times out, is stopped by an event, or the user ends the skill.

The StopInputHandler directive has the following form.

{
  "type": "GameEngine.StopInputHandler",
  "originatingRequestId": "amzn1.echo-api.request.406fbc75-8bf8-4077-a73d-519f53d172a4"
}

The fields are as follows:

  • type – The type of directive, which is GameEngine.StopInputHandler.
  • originatingRequestId – The request ID of the request to which you responded with a StartInputHandler directive.

Should a user explicitly quit your skill (for example, by saying "Alexa, quit"), then Alexa will automatically terminate your open Input Handler in the same way, and your skill will not be invoked with any further Input Handler events.

Examples

This section provides examples of StartInputHandler and StopInputHandler directives and how you can assemble them using the ASK SDKs. It also provides an example of receiving and parsing an Input Handler event.

For complete sample skills, see Hello Buttons and Color Changer in GitHub.

Start Input Handler Example

This example configures an Input Handler to notify the skill when the user presses or releases a button, or the Input Handler times out, which is in thirty seconds.

This example also shows how to save the request ID of the original request to the session attributes. This request ID serves as the ID of the Input Handler in case you ever need to explicitly stop the Input Handler with StopInputHandler (see the tab for the Node.js SDK or Java SDK in the Stop Input Handler example).

Copied to clipboard.

{
    "outputSpeech": {
        "type": "SSML",
        "ssml": "<speak>This directive configures the Input Handler to send an event if the user presses or releases a button, or the Input Handler reaches its 30-second timeout. <audio src=\"https://s3.amazonaws.com/ask-soundlibrary/foley/amzn_sfx_rhythmic_ticking_30s_01.mp3\"/></speak>"
    },
    "shouldEndSession": false,
    "directives": [
        {
            "type": "GameEngine.StartInputHandler",
            "timeout": 30000,
            "recognizers": {
                "buttonDownRecognizer": {
                    "type": "match",
                    "fuzzy": false,
                    "anchor": "end",
                    "pattern": [
                        {
                            "action": "down"
                        }
                    ]
                },
                "buttonUpRecognizer": {
                    "type": "match",
                    "fuzzy": false,
                    "anchor": "end",
                    "pattern": [
                        {
                            "action": "up"
                        }
                    ]
                }
            },
            "events": {
                "buttonDownEvent": {
                    "meets": [
                        "buttonDownRecognizer"
                    ],
                    "reports": "matches",
                    "shouldEndInputHandler": false
                },
                "buttonUpEvent": {
                    "meets": [
                        "buttonUpRecognizer"
                    ],
                    "reports": "matches",
                    "shouldEndInputHandler": false
                },
                "timeoutEvent": {
                    "meets": [
                        "timed out"
                    ],
                    "reports": "history",
                    "shouldEndInputHandler": true
                }
            }
        }
    ]
}

Copied to clipboard.

This sample code uses the Alexa Skills Kit SDK for Node.js (v2).

const StartInputIntentHandler = {
  canHandle(handlerInput) {
    return handlerInput.requestEnvelope.request.type === 'IntentRequest'
      && handlerInput.requestEnvelope.request.intent.name === 'StartInputHandlerIntent';
  },
  handle(handlerInput) {

      // Save the request ID because we'll need it if we explicitly
      // stop this Input Handler using StopInputHandler later.
      const sessionAttributes = handlerInput.attributesManager.getSessionAttributes();
      const { request } = handlerInput.requestEnvelope;
      sessionAttributes.currentInputHandlerId = request.requestId;

      // Set up an Input Handler to notify this skill when the user
      // presses or releases an Echo Button, or the Input Handler
      // times out.
      const response = handlerInput.responseBuilder
          .speak("This directive configures the Input Handler to send an event "
                  + "if the user presses or releases a button, or the Input Handler "
                  + "reaches its 30-second timeout. "
                  + "<audio src=\"https://s3.amazonaws.com/ask-soundlibrary/foley/amzn_sfx_rhythmic_ticking_30s_01.mp3\"/>")
          .withShouldEndSession(false)
          .addDirective({
            'type': 'GameEngine.StartInputHandler',
            'timeout': 30000,
            'recognizers': {
               'buttonDownRecognizer': {
                  'type': 'match',
                  'fuzzy': false,
                  'anchor': 'end',
                  'pattern': [
                      {
                         'action': 'down'
                      }
                   ]
                },
                'buttonUpRecognizer': {
                   'type': 'match',
                   'fuzzy': false,
                   'anchor': 'end',
                   'pattern': [
                       {
                           'action': 'up'
                       }
                    ]
                 }
            },
            'events': {
                'buttonDownEvent': {
                    'meets': [
                       'buttonDownRecognizer'
                    ],
                    'reports': 'matches',
                    'shouldEndInputHandler': false
                },
                'buttonUpEvent': {
                    'meets': [
                       'buttonUpRecognizer'
                    ],
                    'reports': 'matches',
                    'shouldEndInputHandler': false
                },
                'timeoutEvent': {
                    'meets': [
                       'timed out'
                    ],
                    'reports': 'history',
                    'shouldEndInputHandler': true
                }
            }
         })
          .getResponse();

         console.log('===RESPONSE=== '+ JSON.stringify(response));
         return response;

   }
};

Copied to clipboard.

This sample code uses the Alexa Skills Kit SDK for Java.

package com.amazon.ask.buttonsamples.handlers;
import com.amazon.ask.dispatcher.request.handler.HandlerInput;
import com.amazon.ask.dispatcher.request.handler.RequestHandler;
import com.amazon.ask.model.Response;
import static com.amazon.ask.request.Predicates.intentName;
import com.amazon.ask.model.services.gameEngine.*;
import com.amazon.ask.model.interfaces.gameEngine.*;
import java.util.Optional;
import java.util.Collections;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.HashMap;

public class StartInputIntentHandler implements RequestHandler {

    @Override
    public boolean canHandle(HandlerInput handlerInput) {
        return handlerInput.matches(intentName("StartInputHandlerIntent"));
    }

    @Override
    public Optional<Response> handle(HandlerInput handlerInput) {

      // Save the request ID because we'll need it if we explicitly
      // stop this Input Handler using StopInputHandler later.
      String requestId = handlerInput.getRequestEnvelope().getRequest().getRequestId();
      handlerInput.getAttributesManager().setSessionAttributes
                        (Collections.singletonMap("currentInputHandlerId", requestId));

      // Build the pattern that our button down recognizer will use.
      Pattern buttonDownPattern = Pattern.builder()
        .withAction(InputEventActionType.DOWN)
        .build();

      // Build the pattern that our button up recognizer will use.
      Pattern buttonUpPattern = Pattern.builder()
        .withAction(InputEventActionType.UP)
        .build();

      // Build the recognizer that looks for button downs.
      PatternRecognizer buttonDownRecognizer = PatternRecognizer.builder()
        .withFuzzy(false)
        .withAnchor(PatternRecognizerAnchorType.END)
        .withPattern((List<Pattern>)Arrays.asList(buttonDownPattern))
        .build();

      // Build the recognizer that looks for button ups.
      PatternRecognizer buttonUpRecognizer = PatternRecognizer.builder()
        .withFuzzy(false)
        .withAnchor(PatternRecognizerAnchorType.END)
        .withPattern((List<Pattern>)Arrays.asList(buttonUpPattern))
        .build();

       // Put the recognizers into a map.
       HashMap<String, Recognizer> recognizerMap = new HashMap<String, Recognizer>();
       recognizerMap.put("buttonDownRecognizer", buttonDownRecognizer);
       recognizerMap.put("buttonUpRecognizer", buttonUpRecognizer);

      // Define the event that will be triggered by the button down recognizer.
      Event buttonDownEvent = Event.builder()
        .withShouldEndInputHandler(false)
        .withReports(EventReportingType.MATCHES)
        .withMeets((List<String>)Arrays.asList("buttonDownRecognizer"))
        .build();

      // Define the event that will be triggered by the button up recognizer.
      Event buttonUpEvent = Event.builder()
        .withShouldEndInputHandler(false)
        .withReports(EventReportingType.MATCHES)
        .withMeets((List<String>)Arrays.asList("buttonUpRecognizer"))
        .build();

      // Define the event that will be triggered by the time out recognizer.
      Event timeoutEvent = Event.builder()
        .withShouldEndInputHandler(true)
        .withReports(EventReportingType.HISTORY)
        .withMeets((List<String>)Arrays.asList("timed out"))
        .build();

       // Put the events into a map.
       HashMap<String, Event> eventMap = new HashMap<String, Event>();
       eventMap.put("buttonDownEvent", buttonDownEvent);
       eventMap.put("buttonUpEvent", buttonUpEvent);
       eventMap.put("timeoutEvent", timeoutEvent);

      // Assemble an Input Handler directive with the parameters defined above.
      // This directive tells the Input Handler to notify the skill when the user
      // presses or releases a button, or the Input Handler times out.
      StartInputHandlerDirective directive = StartInputHandlerDirective.builder()
        .withTimeout((long)30000)
        .withRecognizers(recognizerMap)
        .withEvents(eventMap)
        .build();

      // Assemble the response.
      Optional<Response> response = handlerInput.getResponseBuilder()
        .withSpeech("This directive configures the Input Handler to send an event "
                     + "if the user presses or releases a button, or the Input Handler "
                     + "reaches its 30-second timeout. "
                     + "<audio src=\"https://s3.amazonaws.com/ask-soundlibrary/foley/amzn_sfx_rhythmic_ticking_30s_01.mp3\"/>")
        .withShouldEndSession(false)
        .addDirective(directive)
        .build();

      // Write the response to CloudWatch.
      String responseLog = response.toString();
      responseLog = responseLog.replace("\n", " ").replace("\r", " ");
      System.out.println("===RESPONSE=== " + responseLog);

      // Return the response.
      return response;

    }
}

Copied to clipboard.

This sample code uses the Alexa Skills Kit SDK for Python.

from ask_sdk_core.dispatch_components import AbstractRequestHandler
from ask_sdk_core.handler_input import HandlerInput
from ask_sdk_core.utils import is_intent_name
from ask_sdk_model import Response
from ask_sdk_model.interfaces.game_engine import StartInputHandlerDirective
from ask_sdk_model.services.game_engine import (
    Event, EventReportingType, PatternRecognizer, Pattern,
    InputEventActionType, PatternRecognizerAnchorType)


class StartInputIntentHandler(AbstractRequestHandler):
    def can_handle(self, handler_input):
        # type: (HandlerInput) -> bool
        return is_intent_name("StartInputHandlerIntent")(handler_input)

    def handle(self, handler_input):
        # type: (HandlerInput) -> Response

        # Save the request ID because we'll need it if we explicitly
        # stop this Input Handler using StopInputHandler later.
        request_id = handler_input.request_envelope.request.request_id
        session_attributes = handler_input.attributes_manager.session_attributes
        session_attributes['currentInputHandlerId'] = request_id

        #  Build the pattern that our button down recognizer will use.
        button_down_pattern = Pattern(action=InputEventActionType.down)

        # Build the pattern that our button up recognizer will use.
        button_up_pattern = Pattern(action=InputEventActionType.up)

        # Build the recognizer that looks for button downs.
        button_down_recognizer = PatternRecognizer(
            fuzzy=False, anchor=PatternRecognizerAnchorType.end,
            pattern=[button_down_pattern])

        # Build the recognizer that looks for button ups.
        button_up_recognizer = PatternRecognizer(
            fuzzy=False, anchor=PatternRecognizerAnchorType.end,
            pattern=[button_up_pattern])

        # Put the recognizers into a map.
        recognize_map = {
            "buttonDownRecognizer": button_down_recognizer,
            "buttonUpRecognizer": button_up_recognizer
        }

        # Define the event that will be triggered by the
        # button down recognizer.
        button_down_event = Event(
            should_end_input_handler=False, reports=EventReportingType.matches,
            meets=["buttonDownRecognizer"])

        # Define the event that will be triggered by the
        # button up recognizer.
        button_up_event = Event(
            should_end_input_handler=False, reports=EventReportingType.matches,
            meets=["buttonUpRecognizer"])

        # Define the event that will be triggered by the
        # time out recognizer.
        time_out_event = Event(
            should_end_input_handler=True, reports=EventReportingType.history,
            meets=["timed out"])

        # Put the events into a map.
        event_map = {
            "buttonDownEvent": button_down_event,
            "buttonUpEvent": button_up_event,
            "timeoutEvent": time_out_event
        }
    
        # Assemble an Input Handler directive with the parameters
        # defined above. This directive tells the Input Handler to
        # notify the skill when the user presses or releases a button,
        # or the Input Handler times out.
        start_inpout_handler_directive = StartInputHandlerDirective(
            timeout=30000, recognizers=recognize_map, events=event_map)

        speech_text = (
            'This directive configures the Input Handler to send an event '
            'if the user presses or releases a button, or the Input Handler '
            'reaches its 30-second timeout. '
            '<audio src="https://s3.amazonaws.com/ask-soundlibrary/foley/'
            'amzn_sfx_rhythmic_ticking_30s_01.mp3"/>')

        # Assemble the response.
        response = handler_input.response_builder.speak(
            speech=speech_text).set_should_end_session(
            False).add_directive(
            start_inpout_handler_directive).response

        # Write the response to CloudWatch.
        print("===RESPONSE===\n {}".format(response))

        # Return the response.
        return response

Stop Input Handler Example

The following directive stops an Input Handler, if one is running. This directive requires the ID of the request to which you responded with a StartInputHandler directive. You can save this request ID as an attribute in the session object. For an example of how to save the request ID, see the tab for the Node.js SDK or Java SDK in the Start Input Handler example.

Copied to clipboard.

{
    "shouldEndSession": false,
    "outputSpeech": {
        "type": "SSML",
        "ssml": "<speak>Stopping the Input Handler, if one was running.</speak>"
    },
    "directives": [
        {
            "type": "GameEngine.StopInputHandler",
            "originatingRequestId": "request-id-that-you-saved"
        }
    ]
}

Copied to clipboard.

This sample code uses the Alexa Skills Kit SDK for Node.js (v2).

const StopInputIntentHandler = {
  canHandle(handlerInput) {
    return handlerInput.requestEnvelope.request.type === 'IntentRequest'
      && handlerInput.requestEnvelope.request.intent.name === 'StopInputHandlerIntent';
  },
   handle(handlerInput) {

      // Retrieve the session attributes, which is where
      // we stored the request ID of the original request
      // that we responded to when we started the Input
      // Handler.
     const sessionAttributes = handlerInput.attributesManager.getSessionAttributes();

     // Start building a response.
     const responseBuilder = handlerInput.responseBuilder;
     responseBuilder.withShouldEndSession(false)
                    .speak("Stopping the Input Handler, if one was running.");

     // If we were able to retrieve an Input Handler's originating
     // request ID from the session attributes, stop the Input Handler
     // with it. If the ID was from an Input Handler that is no longer
     // running, it is ok because in that case the Game Engine will
     // ignore this directive.
     if (sessionAttributes.currentInputHandlerId) {
           // Add the directive.
           responseBuilder.addDirective({
               'type': 'GameEngine.StopInputHandler',
               'originatingRequestId': sessionAttributes.currentInputHandlerId
             });            
     }

      // Build the response.
      const response = responseBuilder.getResponse();

      // Write the response to CloudWatch.
      console.log('===RESPONSE=== '+ JSON.stringify(response));

      // Return the response.
      return response;

   }
};

Copied to clipboard.

This sample code uses the Alexa Skills Kit SDK for Java.

package com.amazon.ask.buttonsamples.handlers;

import com.amazon.ask.dispatcher.request.handler.HandlerInput;
import com.amazon.ask.dispatcher.request.handler.RequestHandler;
import com.amazon.ask.model.Response;
import com.amazon.ask.response.ResponseBuilder;
import com.amazon.ask.model.services.gameEngine.*;
import com.amazon.ask.model.interfaces.gameEngine.*;
import java.util.Optional;

import static com.amazon.ask.request.Predicates.intentName;

public class StopInputIntentHandler implements RequestHandler {

    @Override
    public boolean canHandle(HandlerInput handlerInput) {
        return handlerInput.matches(intentName("StopInputHandlerIntent"));
    }

    @Override
    public Optional<Response> handle(HandlerInput handlerInput) {

      // Retrieve the session attribute that we used to store
      // the request ID of the original request that we responded
      // to when we started the Input Handler.
      String currentInputHandlerId = (String) handlerInput.getAttributesManager().getSessionAttributes().get("currentInputHandlerId");

      // Start building a response.
      ResponseBuilder responseBuilder = handlerInput.getResponseBuilder()
         .withShouldEndSession(false)
         .withSpeech("Stopping the Input Handler, if one was running.");

      // If we were able to retrieve an Input Handler's originating
      // request ID from the session attributes, stop the Input Handler
      // with it. If the ID was from an Input Handler that is no longer
      // running, it is ok because in that case the Game Engine will
      // ignore this directive.
      if (currentInputHandlerId != null) {

      	// Assemble the directive.
        StopInputHandlerDirective directive = StopInputHandlerDirective.builder()
          .withOriginatingRequestId(currentInputHandlerId)
          .build();

      	// Add the directive that stops the Input Handler.
        responseBuilder.addDirective(directive);
      }

      // Build the response.
      Optional<Response> response = responseBuilder.build();

      // Write the response to CloudWatch.
      String responseLog = response.toString();
      responseLog = responseLog.replace("\n", " ").replace("\r", " ");
      System.out.println("===RESPONSE=== " + responseLog);

      // Return the response.
      return response;

    }

}

Copied to clipboard.

This sample code uses the Alexa Skills Kit SDK for Python.

from ask_sdk_core.dispatch_components import AbstractRequestHandler
from ask_sdk_core.handler_input import HandlerInput
from ask_sdk_core.utils import is_intent_name
from ask_sdk_model import Response
from ask_sdk_model.interfaces.game_engine import StopInputHandlerDirective


class StopInputIntentHandler(AbstractRequestHandler):
    def can_handle(self, handler_input):
        # type: (HandlerInput) -> bool
        return is_intent_name("StopInputHandlerIntent")(handler_input)

    def handle(self, handler_input):
        # type: (HandlerInput) -> Response

        # Retrieve the session attribute that we used to store
        # the request ID of the original request that we responded
        # to when we started the Input Handler.
        session_attributes = handler_input.attributes_manager.session_attributes

        # Assign an empty string if key doesn't exist in session attributes
        current_input_handler_id = session_attributes.get(
            "currentInputHandlerId", "")

        # Start building a response.
        response_builder = handler_input.response_builder.set_should_end_session(
            False).speak(
            speech="Stopping the Input Handler, if one was running.")

        # If we were able to retrieve an Input Handler's originating
        # request ID from the session attributes, stop the Input Handler
        # with it. If the ID was from an Input Handler that is no longer
        # running, it is ok because in that case the Game Engine will
        # ignore this directive.
        if current_input_handler_id is not None:

            #  Assemble the directive.
            stop_input_handler_directive = StopInputHandlerDirective(
                originating_request_id=current_input_handler_id)

            # Add the directive that stops the Input Handler.
            response_builder.add_directive(stop_input_handler_directive)

        # Build the response.
        response = response_builder.response

        # Write the response to CloudWatch.
        print("===RESPONSE===\n {}".format(response))

        # Return the response.
        return response

Input Handler Event Parsing Example

The following code shows an Input Handler event and how to extract the fields using the ASK SDKs.

Copied to clipboard.

{
    "type": "GameEngine.InputHandlerEvent",
    "requestId": "amzn1.echo-api.request.12345-678910",
    "timestamp": "2018-10-11T19:09:56Z",
    "locale": "en-US",
    "originatingRequestId": "amzn1.echo-api.request.12345-678910",
    "events": [
        {
            "name": "buttonUpEvent",
            "inputEvents": [
                {
                    "gadgetId": "amzn1.ask.gadget.12345678910",
                    "timestamp": "2018-10-11T19:09:56.287Z",
                    "color": "000050",
                    "feature": "press",
                    "action": "up"
                }
            ]
        }
    ]
}

Copied to clipboard.

This sample code uses the Alexa Skills Kit SDK for Node.js (v2).

const InputHandlerEventHandler = {
  canHandle(handlerInput) {
    return handlerInput.requestEnvelope.request.type === 'GameEngine.InputHandlerEvent';
  },

  handle(handlerInput) {
   const request = handlerInput.requestEnvelope.request;
   const events = request.events;
   var infoToSpeak = '';

   // Loop over the list of Input Handler events that triggered this
   // request. When an Input Handler event's conditions become true,
   // the event is sent to your skill only once. However, there may
   // be multiple Input Handler events within one request if more
   // than one such event became true at the same time.
   events.forEach(function(event){

      const numRawEvents = event.inputEvents.length;
      console.log('===INPUT HANDLER EVENT INFO=== name: ' + event.name +
            ', number of raw events: ' + numRawEvents);

      infoToSpeak = 'There was an Input Handler event of type ' + event.name;

      // Loop over the list of raw button events that contributed
      // to this Input Handler event.
      event.inputEvents.forEach(function(rawEvent){
          console.log('===RAW EVENT INFO=== gadget ID: ' + rawEvent.gadgetId +
          ' timestamp: ' + rawEvent.timestamp +
          ', action: ' + rawEvent.action +
          ', color: ' + rawEvent.color);
      });
   });

   return handlerInput.responseBuilder
      .speak(infoToSpeak)
      .withShouldEndSession(false)
      .getResponse();
  }
};

Copied to clipboard.

This sample code uses the Alexa Skills Kit SDK for Java.

package com.amazon.ask.buttonsamples.handlers;

import com.amazon.ask.dispatcher.request.handler.HandlerInput;
import com.amazon.ask.dispatcher.request.handler.RequestHandler;
import com.amazon.ask.model.Response;
import com.amazon.ask.response.ResponseBuilder;
import com.amazon.ask.model.RequestEnvelope;
import com.amazon.ask.model.services.gameEngine.*;
import com.amazon.ask.model.interfaces.gameEngine.*;
import static com.amazon.ask.request.Predicates.requestType;
import java.util.Optional;
import java.util.List;


public class InputHandlerEventHandler implements RequestHandler {

    @Override
    public boolean canHandle(HandlerInput handlerInput) {
        return handlerInput.matches(requestType(InputHandlerEventRequest.class));
    }

    @Override
    public Optional<Response> handle(HandlerInput handlerInput) {

      InputHandlerEventRequest request =
           (InputHandlerEventRequest)handlerInput.getRequestEnvelope().getRequest();
      List<InputHandlerEvent> events = request.getEvents();
      int numEvents = events.size();
      String infoToSpeak = "";

      // Loop over the list of Input Handler events that triggered this
      // request. When an Input Handler event's conditions become true,
      // the event is sent to your skill only once. However, there may
      // be multiple Input Handler events within one request if more
      // than one such event became true at the same time.
      for (int i = 0; i < numEvents; i++) {

        InputHandlerEvent event = events.get(i);
        List<InputEvent> rawEvents = event.getInputEvents();
        int numRawEvents = rawEvents.size();
        System.out.println("===INPUT HANDLER EVENT INFO=== name: " + event.getName() +
            ", number of raw events: " + numRawEvents);

        infoToSpeak = "There was an Input Handler event of type " + event.getName();

        // Loop over the list of raw button events that contributed
        // to this Input Handler event.
        for (int j = 0; j < numRawEvents; j++) {
          InputEvent rawEvent = rawEvents.get(j);
          System.out.println("===RAW EVENT INFO=== gadget ID: " + rawEvent.getGadgetId() +
            ", timestamp: " + rawEvent.getTimestamp() +
            ", action: " + rawEvent.getAction() +
            ", color: " + rawEvent.getColor());
          }
        }

      // Build a response.
      Optional<Response> response = handlerInput.getResponseBuilder()
        .withSpeech(infoToSpeak)
        .withShouldEndSession(false)
        .build();

      // Write the response to CloudWatch.
      String responseLog = response.toString();
      responseLog = responseLog.replace("\n", " ").replace("\r", " ");
      System.out.println("===RESPONSE=== " + responseLog);

      // Return the response.
      return response;

    }

}

Copied to clipboard.

This sample code uses the Alexa Skills Kit SDK for Python.

from ask_sdk_core.dispatch_components import AbstractRequestHandler
from ask_sdk_core.handler_input import HandlerInput
from ask_sdk_core.utils import is_request_type
from ask_sdk_model import Response


class InputHandlerEventHandler(AbstractRequestHandler):
    def can_handle(self, handler_input):
        # type: (HandlerInput) -> bool
        return is_request_type("InputHandlerEventRequest")(handler_input)

    def handle(self, handler_input):
        # type: (HandlerInput) -> Response

        request = handler_input.request_envelope.request
        info_to_speak = ""
        events = request.events()

        #  Loop over the list of Input Handler events that triggered this
        #  request. When an Input Handler event's conditions become true,
        #  the event is sent to your skill only once. However, there may
        #  be multiple Input Handler events within one request if more
        #  than one such event became true at the same time.
        for event in events:
            raw_events = event.input_events()

            print(
                "===INPUT HANDLER EVENT INFO=== name: {}, "
                "number of raw events: {}".format(
                    event.name, str(len(raw_events))))

            info_to_speak = ("There was an Input Handler event of "
                             "type {}".format(event.name))

            # Loop over the list of raw button events that contributed
            # to this Input Handler event.
            for raw_event in raw_events:
                print(
                    "===RAW EVENT INFO=== gadget ID: {}, timestamp: {}, "
                    "action: {}, color: {}".format(
                        raw_event.gadget_id, raw_event.timestamp,
                        raw_event.action, raw_event.color)
                      )

        # Build the response.
        response = handler_input.response_builder.speak(
            speech=info_to_speak).set_should_end_session(False).response

        # Write the response to CloudWatch.
        print("===RESPONSE===\n {}".format(response))

        # Return the response.
        return response