Learn About Custom Interfaces


To enable communication between a gadget and an Alexa skill, you can create Custom Interfaces. Custom Interfaces enable a skill to trigger gadget behaviors, and enable the skill to act on information it receives from a gadget.

Note that the interfaces that the Alexa Gadgets Toolkit provides enable you to trigger gadget behaviors in reaction to Alexa's native capabilities, such as notifications and wake word detection. Unlike Custom Interfaces, these interfaces cannot be accessed from an Alexa skill.

This topic describes ways that you can use a Custom Interface, how to define a Custom Interface, and what your gadget needs to do to support that interface. The directives and events that you create under a Custom Interface can only be used through a custom skill. To do this, you first define a Custom Interface as described in this topic. You then access the interface from your skill by using the Custom Interface Controller as described in Send a Gadget a Custom Directive from a Skill and Receive a Custom Event from a Gadget.

Overview

Your Custom Interface can include custom directives, custom events, or both. Custom directives and custom events are separate; you do not need to use one to use the other.

  • Custom directives – These are sent from the skill to the gadget. You might use custom directives to:

    Use of custom directives Example

    Trigger device behavior based on skill content

    A game board that flashes light animations at the opening of a skill or a windmill gadget that changes its speed based on the report from a wind skill.

    Support implicit commands from the user

    Alexa says, "How about a game of battleship?" A user response of "yes" would set the mode of the game to battleship mode.

    Support explicit, but more complex commands from the user

    A user says, "Alexa, ask my robot to rotate three times."
  • Custom events – These are sent from a gadget to a skill. Custom events enable your skill to process and act on information from the gadget. For example, you might create custom events that:

    Use of custom events Example

    Trigger an immediate skill response such as voice or audio

    Inform the skill that a robot has completed its spin. Alexa responds "Your robot is warmed up and ready to go! Let's start the game!"

    Report a gadget's status

    After a race challenge, have Alexa summarize key aspects of the race, such as, "your car drove for 35 seconds, went up an incline of 15%, and rotated three times."

    Collect and apply business logic to one or a set of events

    Inform the skill of the order in which a user pressed lighted buttons on a board during a sequence game, so that the skill can determine if the buttons were pressed in the correct order.

Because gadgets do not connect directly to the Alexa cloud, they use an Echo device to handle communication with the skill. The following figure shows how a gadget and a skill exchange directives and events.

Passage of directives and events from an Alexa gadget to an Alexa skill.

Data format

Your gadget sends and receives custom events and directives, respectively, using the following format:

  • Custom directives – The skill sends the directive to the Alexa cloud in JSON using the same response format that other custom skills use. The Alexa cloud passes it to the Echo device, which sends the directive to the gadget encoded as UTF-8 in a binary data format based on protocol buffers.
  • Custom events – The gadget encodes the string into a binary data format based on protocol buffers, and sends it to the Echo device. The Echo device sends the event to the Alexa cloud, which passes it to the skill in JSON, using the same request format that other custom skills use.

Limits

Limits related to Custom Interfaces are as follows:

Description Limit

Custom directive size

1 KB (1,000 bytes)

Custom event size

1 KB (1,000 bytes)

Custom event maximum rate

5 events per second

Namespace

  • The namespace must start with the word Custom followed by a period
  • The full namespace can't be longer than 127 characters
  • The full namespace must contain only uppercase or lowercase letters and periods (regex pattern: [Cc]ustom.[a-zA-Z][a-zA-Z.]{0,120})

Custom directive and event names

  • The full name of a custom event or directive can't be longer than 127 characters
  • The full name of a custom event must contain only lowercase or uppercase letters and may include periods but must start with a letter (regex pattern: [a-zA-Z][a-zA-Z.]{0,126})

Event handler duration

Minimum: 1 second (1,000 ms)
Maximum: 90 seconds (90,000 ms)

How to define and use a Custom Interface on your gadget

The steps to defining and using a Custom Interface on a gadget are as follows:

Step 1: Name your interface, directives, and events

When you define a Custom Interface for your gadget, you must choose:

  • A name for the interface. This will be the namespace for the interface, and must start with Custom. Namespaces must conform to the limits described in Limits.
  • A name for any custom directive(s) that you want the interface to include. Custom directive names must conform to the limits described in Limits.
  • A name for any custom event(s) that you want the interface to include. Custom event names must conform to the limits described in Limits.

You can define a namespace for each directive and event, or you can include multiple directives and events in a single namespace.

For example, if your gadget is a robot that spins around, you might create a Custom.Robot namespace and define a directive called Spin that instructs the robot to spin, and an event called SpinStatus for the robot to send when it has completed its spin.

Step 2: Declare support for the interface

Your gadget must declare support for the interface within the Alexa.Discovery.Discover.Response event that it sends the Echo device in response to the Alexa.Discovery.Discover directive.

Continuing the previous example, to indicate that your gadget supports the Custom.Robot interface and all the directives and events declared under it, your gadget's Alexa.Discovery.Discover.Response event must include the Custom.Robot interface in its array of Capabilities as follows:

Copied to clipboard.

{
   "type": "AlexaInterface",
   "interface": "Custom.Robot",
   "version": "1.0"
}

Step 3: Handle directives on your gadget

If your Custom Interface includes directives, your gadget code should decode and take action on the directives that the skill sends it. Although your gadget receives custom directives in a data format similar to the directives included in the Alexa Gadgets Toolkit, there are a few differences. For custom directives, the payload is a string, in bytes, encoded as UTF-8. To decode the payload, you first extract the payload from the overall directive, which is encoded using protocol buffers. You then simply parse the fields of the payload string. The code to deserialize the directive would look similar to the following:

Copied to clipboard.

#include <stdio.h>
#include "pb.h"
#include "pb_decode.h"
#include "pb_encode.h"
#include "directiveHeader.pb.h"
#include "directiveParser.pb.h"
 
typedef unsigned char uint8_t;
typedef unsigned char BOOL;

void parse_directive_proto(uint8_t* buffer, int len)
{
   pb_istream_t stream = pb_istream_from_buffer(buffer, len);
   directive_DirectiveParserProto envelope = directive_DirectiveParserProto_init_default; 
  
   pb_decode(&stream, directive_DirectiveParserProto_fields, &envelope);
   printf("name=%s, namespace=%s, payload=%s\n", 
      envelope.directive.header.name, 
      envelope.directive.header.namespace,   
      envelope.directive.payload.bytes); 
}
  

The deserialized directive would look similar to the following:

Copied to clipboard.

{
   "directive": {
      "header": {
         "namespace": "Custom.Robot", 
         "name": "Spin"
      },
      "payload": "{\"direction\":\"clockwise\",\"times\":5}"
   }
} 

Step 4: Send events from your gadget

First, put your event in a JSON-formatted string, including the outer braces. For example, the robot gadget described previously might assemble a Custom.Robot.SpinStatus event payload such as {"finished":"yes", "remainingBatteryPercent":80}.

Then, before sending the event to the Echo device, your gadget must put the event into a binary data format based on protocol buffers. The format of the event will be similar to the Alexa.Discovery.Discover.Response event.

The following is an example of a protocol buffer file that you can use to encode event data before sending it to the Echo device. The Echo device sends the event to Alexa, which sends it to the skill.

Copied to clipboard.

syntax = "proto3";

import "eventHeader.proto";

message CustomEventProto {
    Event event = 1;
    message Event {
        header.EventHeaderProto header = 1;
        string payload = 2;
    }
}

The following is an example of the accompanying options file. In this example, the options file sets the maximum payload size to the maximum allowable value, which is 1,000 bytes.

Copied to clipboard.

CustomEventProto.Event.payload    max_size:1000

The following code provides an example of how to encode an event.

Copied to clipboard.

#include "customEvent.pb.h"

void encode_custom_event(uint8_t* buffer, size_t len, char *namespace, char *name, char *payload)
{
    pb_ostream_t stream = pb_ostream_from_buffer(buffer, len);
    CustomEventProto custom_event_envelope =
           CustomEventProto_init_default;

    strcpy(custom_event_envelope.event.header.namespace, namespace);
    strcpy(custom_event_envelope.event.header.name, name);

    strcpy(custom_event_envelope.event.payload, payload);

    BOOL status = pb_encode(&stream, CustomEventProto_fields, &custom_event_envelope);
    if (!status)
    {
      printf("%s: Error encoding message\n", __FUNCTION__);
      return;
    }
}

For example, to send the custom event SpinStatus from your robot gadget, you might encode the data as follows:

Copied to clipboard.

size_t len = 256;
uint8_t payload[len];

char* namespace = "Custom.Robot";
char* name = "SpinStatus";
char* payload = "{\"finished\":\"yes\", \"remainingBatteryPercent\" : 80}";

encode_custom_event(payload, len, namespace, name, payload);

The gadget can then send the encoded custom event to the Echo device in the same way that it sends the Alexa.Discovery.Discover.Response event.


Was this page helpful?

Last updated: Feb 14, 2022