Alexa Programming Languages and Tools

Building Alexa Skills means you have a Voice User Interface (VUI) and the fulfilling programming logic. For simplicity think of the frontend for the VUI and the backend for the programming logic. There are several ways doing the fulfillment of an Alexa Skill. Often developer use Amazon Web Services (AWS) Lambda which is a perfect fit: Simply enter the Lambda’s ARN (Amazon Resource Name) inside the Skill’s configuration. AWS Lambda supports code written in Node.js (JavaScript), Java, Python, or C#.

There is also an alternative approach: You can enter a SSL/TLS secured https-address as the endpoint for other technologies and programming languages independently from AWS. Under the hood, there is only JSON via REST going back and forth. Thus every technology supporting that might work. In case you prefer your own infrastructure to AWS Lambda, please make sure to secure everything accordingly and always provide valid responses.

Dealing with Java Script Notification Objects (JSON) might be tedious. Therefore, it is good to have some helpers out there, which can make your life easier – despite the preferred technology. Here is a brief list for your convenience:

JavaScript / Node.js

Alexa Skills Kit SDK for JavaScript / Node.js (Lambda)
Alexia (framework for creating Skills using Node.js)
alexa-app (Node module to simplify the development of Alexa Skills)
Several libraries used to build both custom Skills and smart home Skills
Creating SSML (Speech Synthesis Markup Language) using the builder pattern

Java / Kotlin

Java Alexa Skills Kit SDK (Lambda)
Alexa States SDK for Java (extends the Java Alexa Skills Kit SDK)
Aleksa (framework for writing Skills in Kotlin)

Python

Flask-Ask
Python Alexa

C# / .NET

Alexa Skills SDK for .NET

PHP

Voice Skill Management System (Skeleton)
PHP Library for Amazon Alexa Skills
Amazon Alexa PHP Library
AlexaApp (classes to make creating Skills with Laravel and Lumen)
Alexa Custom Skill for Patami Framework

Command Line Tools (CLI)

Alexa Skills Kit Command Line Interface (ASK CLI)
Bespoken CLI (Develop, Debug, and Test Live on Your Laptop)

Designing / Protoyping

Sayspring (Voice Prototypes for Amazon Alexa)

Anything missing? Feel free to send me suggestions to complete the list, please!

Alexa Links (English/Deutsch)

Here is a brief list of some Alexa related links (both from Amazon and *independent). I hope those are handy if you like to start, discuss, or simply need help with Alexa. Suggestions are welcome.

Hier ist eine kurze Liste einiger hilreicher Links zu Alexa (sowohl von Amazon als auch *unabhängig). Ich hoffe, diese sind hilfreich. Sollte was fehlen, dann bitte einfach Bescheid sagen.

Docs

Alexa Skills Kit
Alexa Skills Kit in Deutschland (Deutsch)

Code

Alexa Skill Building Cookbook
Alexa Github Repository
Sascha Wolter Github Repository (Deutsch)

Design

Amazon Alexa Voice Design Guide

Slides

Slidedeck “Build Voice-Enabled Experiences with Alexa”

Video-Trainings (Screencasts, Webinare etc.)

Alexa Developers on YouTube
Amazon Alexa on Twitch
Amazon Alexa Developer Channel Germany on YouTube (Deutsch)

Boards and Communities

Amazon Developer Forums
Alexa Developers Slack Channel*
stackoverflow Alexa-tagged questions*
Amazon Alexa Entwickler für D-A-CH auf Facebook* (Deutsch)
Das inoffizielle deutsche Alexa und Echo Forum.* (Deutsch)

Support

Amazon Developer Support and Contact
Amazon Developer Support (Deutsch)

Twitter

@alexadevs – Alexa Developers
@maxamorde – Max Amordeluso, Alexa Evangelist EU*
@muttonia – Andrea Muttonia, Alexa Evangelist EU*
@saschawolter – Sascha Wolter, Alexa Evangelist DE/AT/EU* (Deutsch)

Tools and SDKs

Skillinator: Node.js Codegenerator
Alexa Skills Kit SDK for Node.js
Alexa Programming Languages and Tools

Optimizing Audio

How Loud Is Too Loud? Tips for Setting Your Alexa Skill’s Audio Volume Level
Normalizing the Loudness of Audio Content

Amazon Alexa im lokalen Smart Home programmieren

Amazon Echo und die eingebaute Sprachassistentin Alexa erlauben eine mehr oder weniger natürliche sprachgesteuerte Interaktion mit vernetzten Geräten wie Leuchten, Thermostaten, Schaltern usw. Doch die Entwicklung neuer Fähigkeiten namens Skills ist etwas mühsam, da es in der Natur von Alexa liegt, dass diese nur über die Cloud funktionieren. Außerdem scheint Amazon die Nutzung der hauseigenen Cloud-Dienste und das entsprechende Tooling zu bevorzugen. Doch dem damit verbundenen zeitraubenden Workflow kann man zumindest während der Entwicklung leicht entkommen. Im Folgenden verbinden wir dafür Alexa über einen sogenannten Tunnel mit dem eigenen Entwicklungsrechner. Das bedeutet, dass der selbsterstellte Skill als Services nun lokal bearbeitet, deployed und getestet wird.

Skill konfigurieren

In der Amazon Developer Console legt man über das Alexa Skills Kit einen Skill an und konfiguriert diesen.

Es gibt verschiedene Arten von Skills. In diesem Beispiel kommt die beliebteste und am wenigsten reglementierte Variante des „Custom Skills“ zum Einsatz. Die Sprache und der Aufruf-Namen (Invocation Name) bestimmen nun den „Rufnamen“, mit dem ein Anwender den Skill anspricht.

Der nächste Schritt legt die Art der Interaktion fest, indem ein Schema mit den möglichen Absichten (Intents) des Anwenders angelegt wird. Die Intents können auch über Variablen verfügen, die Slots genannt werden. Außerdem sind für jede Absicht noch passende Beispiel-Äußerungen (Sample Utterances) erforderlich, mit denen die Absichten aufgerufen werden können.

Innerhalb der Konfiguration kommt nun der entscheidende Schritt für den lokalen Test: Die Auswahl von HTTPS als Endpunkt-Typ und die Angabe einer entsprechenden remote URL für den Tunnel zum lokalen Rechner. Diese Tunnel und die zugehörige URL generieren wir mit Hilfe von ngrok. Dieses Werkzeug besteht aus einem Cloud-Service für den Remote-Zugriff. Außerdem gehört ein für zahlreiche gängige Betriebssysteme verfügbares Kommandozeilentool dazu, um den lokalen Endpunkt für den Tunnel bereitzustellen. Das Kommando

1
ngrok http 3000

leitet beispielsweise Anfragen an eine URL wie https://b22ec890.ngrok.io/ an einen lokalen HTTP-Server mit Port 3000 weiter.

Noch verbirgt sich hinter dem Endpunkt ja noch nichts, aber sobald das im nächsten Schritt erledigt ist, kann der Skill durch die Angabe von beliebigen Äußerungen in Textform innerhalb der Amazon Developer Console getestet werden. Noch realitätsnäher wird der Test natürlich, wenn auch ein Amazon Echo oder Amazon Echo Dot mit dem Entwickler-Konto verbunden ist.

Skill programmieren

Es gibt zahlreiche Möglichkeiten einen Skill zu programmieren. Zu den populärsten zählt sicherlich die Nutzung von Node.js. Amazon stellt extra dafür sogar ein NPM-Paket namens Alexa Skills Kit SDK for Node.js (kurz alexa-sdk) zu Verfügung. Es gibt jedoch leider einen Haken: Dieses Modul arbeitet so erst einmal nur im Rahmen von Amazon Lambda und nicht mit einem lokal laufenden Node.js-Server. Eine Lösung wäre der Verzicht auf das offizielle Alexa SDK und die direkte Verwendung der eingehenden REST-Aufrufe wie hier beschrieben – charmanter Nebeneffekt ist, dass REST auch mit vielen anderen Programmiersprachen und Server-Umgebungen harmoniert. Der Node.js-Code sieht dann so aus:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
app.use(bodyParser.json());
app.post('/', function(req, res) {
  // Deal with incoming request...
  if (req.body.request.type === 'IntentRequest') {
    // ...and build JSON response
    res.json({
      "version": "1.0",
      "response": {
        "shouldEndSession": true,
        "outputSpeech": {
          "type": "SSML",
          "ssml": "<speak>Hmmm</speak>"
        }
      }
    });
  }
}
// Start server and listen for incoming requests
app.listen(3000, function () {
  console.log('Example app listening on port 3000!');
});

Doch mit einem kleinen Trick wird auf das „Nachbauen“ der REST-Schnittstelle verzichtet und doch direkt mit dem offiziellen Alexa SDK gearbeitet. Alles was dafür zusätzlich zu den normalen Beispielen für das SDK getan werden muss ist a) wie oben im Code bereits beschrieben der explizite Start eines Servers und b) das manuelle Erstellen des Context-Objektes. Nun können die Intents genauso verarbeitet werden wie in den offiziellen Beispielen:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
// Initialize the Alexa SDK
var Alexa = require('alexa-sdk');
app.use(bodyParser.json());
app.post('/', function(req, res) {
    // Build the context manually, because Amazon Lambda is missing
    var context = {
        succeed: function (result) {
            console.log(result);
            res.json(result);
        },
        fail:function (error) {
            console.log(error);
        }
    };
    // Delegate the request to the Alexa SDK and the declared intent-handlers
    var alexa = Alexa.handler(req.body, context);
    alexa.registerHandlers(handlers);
    alexa.execute();
});
// Declare handlers for processing the incoming intents
var handlers = {
    'SwitchOnIntent': function () {
        var item = this.event.request.intent.
         slots.item.value;
        doRequest("ON");
        this.emit(':tell', 'Schalte ' + item);
    },
    'SwitchOffIntent': function () {
        var item = this.event.request.intent.
         slots.item.value;
        doRequest("OFF");
        this.emit(':tell', 'Schalte ' + item);
    }
};
app.listen(3000, function () {
  console.log('Example app listening on port 3000!');
});

Die im Code referenzierte Funktion doRequest macht übrigens nichts Anderes als REST-Aufrufe an andere Geräte zu senden, um beispielsweise eine Philips HUE Leuchte ein oder auszuschalten. Dafür nutzt das Beispiel Eclipse SmartHome bzw. openHAB. Diese Heimautomatisierungs-Gateways verfügen über eine REST-Schnittstelle deren Dokumentation normalerweise über http://127.0.0.1:8080/doc/index.html erreichbar ist. Dort können passende REST-Aufrufe leicht ausprobiert werden:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// body holds one of the supported values for the used channel (i.e. ON or OFF)
var doRequest = function (body) {
    var request = new http.ClientRequest({
        hostname: "127.0.0.1",
        port: 8080,
        // Path to the channel for the device we like to control (see REST documentation)
        path: "/rest/items/minecraft_minecraft_switch_192_168_0_17__9998_88ad955d_ce14_4c78_bb2c_942a64a9da7c_channelPowered",
        method: "POST",
        headers: {
            "Content-Type": "text/plain",
            "Content-Length": Buffer.byteLength(body)
        }
    })
    request.end(body)
}

Um die Entwicklung eines Amazon Alexa Skills zu erleichtern, kann also ein lokaler Server leicht über einen Tunnel genutzt werden. Auch für Tests und private Einsatzzwecke hat sich das bewährt. Eine Veröffentlichung eines Skills ist so jedoch nicht möglich, da beispielweise die Verifikation von Aufrufen fehlt. Dies ließe sich dadurch lösen, dass der fertige Skill doch bei Amazon Lambda landet. Alternativ könnte diese Verifikation auch mit Hilfe eines weiteren NPM-Paketes wie hier beschrieben umgesetzt werden.