Protocol Buffer Format for Alexa Gadgets


Gadgets are typically resource-constrained devices, so they do not communicate with the Alexa cloud directly. Instead, gadgets communicate with an Echo device, which handles all communication with the Alexa cloud.

To keep the exchanged information as small as possible, the gadget and the Echo device exchange messages in binary format. This topic explains how your gadget can encode and decode the associated information into and out of binary format.

Overview

When an Echo device and the Alexa cloud exchange directives and events, they use JSON format. However, because gadgets are resource-constrained devices, the Echo device and the gadget exchange this information in binary format instead.

To facilitate encoding and decoding the information to and from binary, we use a mechanism called protocol buffers to represent the fields of directives and events in a platform-agnostic way. A .proto file is similar to a JSON file in that it represents structured data, but you can run a compiler on the .proto file to generate code that can read and write the data in the programming language of your choice.

For more information about protocol buffers, see Protocol Buffer Developer Guide on Google's site. Gadgets use version 3 (proto3) of the protocol buffer format.

Downloads

Before you get started writing code for your gadget, you must download the following:

  • Alexa Gadgets .proto files – Download and unzip the .proto files from the Alexa Gadgets Sample Code GitHub repository.
  • .Proto compiler – For Alexa Gadgets, we recommend the nanopb .proto compiler, which you can download from the nanopb website. It is a C implementation that generates small-size code for memory-restricted systems. For a discussion of .proto compilers in other programming languages, see Generating Your Classes on Google's site.

How to compile the .proto files

After you download and install the .proto compiler and .proto files described previously, you can compile the Alexa Gadgets files to produce access classes for Alexa Gadgets directives and events. You then use the date access classes in your gadget code to encode and decode directives and events.

The way that you run the .proto compiler depends on the operating system that you run the compiler on, as described next. For more information about using .proto compilers, see Generating Your Classes on Google's site.

Windows

This example shows how to build C++ handlers for the notifications.setIndicator directive on Windows.

  1. On a command line, navigate to the Notifications\SetIndicator folder.
  2. Execute the protoc compiler by typing the following line:

    protoc --proto_path=..\..\common;.\ --cpp_out=. notificationsSetIndicatorDirective.proto
    

    The output files will be notificationsSetIndicatorDirective.pb.h and notificationsSetIndicatorDirective.pb.cc.

Mac and Linux

To compile all the Alexa Gadgets .proto files on Mac and Linux, run the shell script in the Alexa Gadgets sample code GitHub repository as follows:

  1. Go to the AlexaGadgetsProtoBuf/utils directory of your Alexa Gadgets Sample Code GitHub repository download.
  2. Open compile_nanos.sh and make sure that your nanopb .proto compiler is located at the specified PROTO_COMPILE_PATH.
  3. Run compile_nanos.sh. This generates .c and .h files for all the Alexa Gadgets .proto files, and puts them in the current directory.

If you don't want to use the script (for example, you want to compile a single .proto file), one way to do so is to run the .proto compiler in the directory that contains the .proto and .options files as follows:

protoc -I=. --nanopb_out=. <fileName.proto>

For example, to run the .proto compiler on notificationSetIndicatorPayload.proto, do the following:

protoc -I=. --nanopb_out=. notificationsSetIndicatorDirectivePayload.proto

.Proto file format

For modularity, each directive and event uses three .proto files: a header, a payload, and an overall file that imports the header and payload .proto files. The protoc compilation process brings these together to create the final code.

The directive header is common to all directives, and the event header is common to all events.

Directive .proto files

This section provides examples of the three .proto files that represent a directive.

Directive header

The .proto format of the directive header, directiveHeader.proto, which is common to all directives, is as follows:


syntax = "proto3";
package header;
option java_package = "com.amazon.proto.avs.v20160207.header";
option java_outer_classname = "DirectiveHeader";
message DirectiveHeaderProto {
   string namespace = 1;
   string name = 2;
   string messageId = 3;
}

Directive payload

There is one payload .proto file for each directive. The following file, notificationsSetindicatorDirectivePayload.proto, is an example of the .proto file for the notifications.setIndicator directive:


syntax = "proto3";
package notifications;
option java_package = "com.amazon.proto.avs.v20160207.notifications";
option java_outer_classname = "SetindicatorDirectivePayload";

message SetindicatorDirectivePayloadProto {
   bool persistVisualIndicator = 1;
   bool playAudioIndicator = 2;
   Asset asset = 3;
   message Asset {
      string assetId = 1;
      string url = 2;
   }
}

Directive options

There is an options file that corresponds to the .proto file of each directive that contains one or more fields in its payload. (For example, the payload of the notifications.clearIndicator directive contains no fields, so this directive does not have an options file.) Options files are not mandatory, but they enable you to provide a maximum size for the fields within the directive. The following file, notificationsSetIndicatorDirectivePayload.options, is an example of the options file for the notifications.setIndicator directive:


notifications.SetIndicatorDirectivePayloadProto.Asset.assetId    max_size:32
notifications.SetIndicatorDirectivePayloadProto.Asset.url    max_size:64

Overall directive file

Each directive has a .proto file that represents the entire message that the gadget receives from the Echo device. The following file, notificationsSetindicatorDirective.proto, is an example of the .proto file for the notifications.setIndicator directive:


syntax = "proto3";
package notifications;
option java_package = "com.amazon.proto.avs.v20160207.notifications";
option java_outer_classname = "SetindicatorDirective";

import "directiveHeader.proto";
import "notificationsSetindicatorDirectivePayload.proto";

message SetindicatorDirectiveProto {
   Directive directive = 1;
   message Directive {
      notifications.SetindicatorDirectivePayloadProto payload = 2;
      header.DirectiveHeaderProto header = 1;
   }
}

Event .proto files

This section provides examples of the three .proto files that represent an event.

Event header

The .proto format of the event header, eventHeader.proto, which is common to all events, is as follows:


syntax = "proto3";

package header;
option java_package = "com.amazon.proto.avs.v20160207.header";
option java_outer_classname = "EventHeader";

message EventHeaderProto {
   string namespace = 1;
   string name = 2;
   string messageId = 3;
}

Event payload

There is one payload .proto file for each event. The following file, discoveryResponseAlexadiscoveryEventPayload.proto, is an example of the .proto file for the Alexa.Discovery.Discover.Response event:


syntax = "proto3";

package discoveryResponse;

option java_package = "com.amazon.proto.avs.v20160207.discoveryResponse";

option java_outer_classname = "AlexadiscoveryEventPayload";

message AlexadiscoveryEventPayloadProto {
   repeated Endpoints endpoints = 1;
   message Endpoints {
      string deviceType = 5;
      repeated Capabilities capabilities = 11;
      message Capabilities {
         string configuration = 4;
         string type = 1;
         string interface = 2;
         string version = 3;
      }
      string endpointId = 1;
      string manufacturerName = 4;
      string description = 3;
      string envelopeVersion = 10;
      string firmwareVersion = 8;
      string encoding = 9;
      string friendlyName = 2;
      string deviceTokenType = 7;
      bytes deviceToken = 6;
   }
}

Event options

There is an options file that corresponds to each event .proto file. Options files are not mandatory, but they enable you to provide a maximum size for the fields within the event. The following excerpt, which is from alexaDiscoveryDiscoverResponseEventPayload.options, is an example of the options file for the Alexa.Discovery.Discover.Response event:


alexaDiscovery.DiscoverResponseEventPayloadProto.endpoints    max_count:1
alexaDiscovery.DiscoverResponseEventPayloadProto.Endpoints.capabilities    max_count:10

... (more entries) ...

alexaDiscovery.DiscoverResponseEventPayloadProto.Endpoints.endpointId    max_size:32
alexaDiscovery.DiscoverResponseEventPayloadProto.Endpoints.description    max_size:32
alexaDiscovery.DiscoverResponseEventPayloadProto.Endpoints.friendlyName    max_size:32

Overall event file

Each event has a .proto file that represents the entire message that the gadget sends to the Echo device. The following file, discoveryResponseAlexadiscoveryEvent.proto, is an example of the .proto file for the Alexa.Discovery.Discover.Response event:


syntax = "proto3";

package discoveryResponse;

option java_package = "com.amazon.proto.avs.v20160207.discoveryResponse";

option java_outer_classname = "AlexadiscoveryEvent";

import "eventHeader.proto";
import "discoveryResponseAlexadiscoveryEventPayload.proto";

message AlexadiscoveryEventProto {
   Event event = 1;
   message Event {
      discoveryResponse.AlexadiscoveryEventPayloadProto payload = 2;
      header.EventHeaderProto header = 1;
   }
}


Was this page helpful?

Last updated: Feb 14, 2022