• Stars
    star
    164
  • Rank 230,032 (Top 5 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created over 8 years ago
  • Updated about 4 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A Framework for creating Amazon Echo (Alexa) skills using Node.js

Alexia

A Framework for creating Amazon Echo (Alexa) skills using Node.js

NPM Version Build Status Coverage Status

const alexia = require('alexia');
const app = alexia.createApp();

app.intent('HelloIntent', 'Hello', () => {
  return 'Hello from Alexia app';
});

HTTPS Server

app.createServer().start();

or

AWS Lamba

exports.handler = (event, context, callback) => {
  app.handle(event, data => {
    callback(null, data);
  });
};

Installation

npm install alexia --save

Optional: requires Handling Amazon Requests manually

npm install hapi --save

Overview

Alexia helps you to write Amazon Echo skills using Node.js. This framework handles Amazon Echo requests and automatically calls intents in your application. See the Features and Samples

Table of Contents

Terminology

Creating new skills for Amazon Echo using alexia requires you to understand some basic terms. This part should clarify the most of them.

  • Skill - Alexa app
  • Intent - Invoked if one of intent utterances is recognized
  • Utterance - Voice input example
  • Slot - Variable part of utterance
  • Session Attributes - data persisted through the session
  • Cards - visual output displayed in Alexa app

Features and Samples

Create App

To create new app simply call alexia.createApp()

const alexia = require('alexia');
const app = alexia.createApp('MyApp');

Set default value for shouldEndSession

If you want to set default value of shouldEndSession response property you can do it by specifying shouldEndSessionByDefault property in App options.

const app = alexia.createApp('MyApp', {shouldEndSessionByDefault: true});

Alternatively you can use app.setShouldEndSessionByDefault() method.

app.setShouldEndSessionByDefault(true);

Create Intents

You have to give a name for the intent when you are creating it. Also you can set multiple utterances for any of your intents.

// Named intent
app.intent('MyIntent', 'Hello Alexa my name is Michael', () => 'Hi Michael');

// Intent with more utterances
app.intent('AnotherIntent', ['Hello', 'Hi', 'Whats up'], () => 'Hello yourself');

Create Welcome Message

If you want more than just a generic "Welcome" from Alexa, you can use the onStart method to help you achieve that.

app.onStart(() => {
  return 'Welcome to My Hello World App, say hello world to get started, or say help to get more instructions';
});

Built-in Intents

Amazon Alexa Skills Kit provides a collection of built-in intents. These are intents for very common actions. Alexia provides convenient methods for their reusing and extending.

List of built-in intents: cancel, help, next, no, pause, previous, repeat, resume, startOver, stop, yes.

See official Amazon docs: [Available Built-in Intents](https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/implementing-the-built-in-intents#Available Built-in Intents)

// Use default built-in utterances
app.builtInIntent('stop', () => 'Stopping now');

// Extend built-in utterances
app.builtInIntent('stop', 'Stop now', () => 'Stopping now');
app.builtInIntent('stop', ['Stop now', 'Please stop'], () => 'Stopping now');

Slots

As mentioned in Terminology section - slots represent variable part of user input in utterances. To make their creation bit easier our utterances contain slot name with type. These samples are converted into common utterances recognized by Alexa and slots are included in intentSchema.

app.intent('SlotIntent', 'My number is {num:Number}', (slots) => {
  return `Your number is ${slots.num}`;
});

Custom Slots

Alexia helps you to create custom slots by specifying its name and utterances

app.customSlot('Name', ['Arnold', 'Otto', 'Walda', 'Pete']);

app.intent('CustomSlotIntent', 'My name is {name:Name}', (slots) => {
  return `Hi ${slots.name}`;
});

Session Attributes

Intent can be resolved using simple string (a text response) or more complex responseObject. Its attribute attrs will override current sessionAttributes. If you wish to extend current session attributes you can use for example Object.assign method. Make sure you set end attribute to false to keep the session open (default: true). See Session Attributes example. Session attribute previousIntent is reserved.

app.intent('AttrsIntent', 'session attributes test', (slots, attrs) => {
  return {
    text: 'Alexa response text here',
    attrs: {
      attr1: 'Whatever to be remebered in this session'
    },
    end: false
  };
});

Cards

To display card in Alexa app add configuration to responseObject card property

app.intent('CardsIntent', 'Whats in shopping cart', () => {
  return {
    text: 'Your shopping cart contains Amazon Echo Device and 2 more items. To see the full list check out your Alexa app',
    card: {
      title: 'Shopping cart',
      content: 'You shopping cart contains: Amazon Echo, Amazon Tap, Echo Dot'
    }
  };
});

Reprompt

To add reprompt text to your response add reprompt string value to responseObject

app.intent('RepromptIntent', 'Send email to Mom', () => {
  return {
    text: 'What is the text of your message',
    reprompt: 'Sorry I did not catch it. What is the text of your message'
  };
});

SSML

Use SSML to create more complex text responses. Just set the ssml parameter of responseObject to true and enter SSML into text property. See official Amazon docs: Speech Synthesis Markup Language

app.intent('SSMLIntent', 'what are the digits of number {num:Number}', (slots) => {
  return `<say-as interpret-as="digits">${number}</say-as>`
});

Read Original Request Data

You can access the original Amazon request data from third parameter of handler. See example below.

app.intent('OriginalRequestData', 'read original request data', (slots, attrs, data) => {
  console.log('userId', data.session.user.userId);
  return 'Hi';
});

Asynch Intent Handling

For asynchronous intent handling add fourth parameter to your handler callback and call it when your response is ready. The response structure is identical to responseObject.

app.intent('AsyncIntent', 'Search for something in database', (slots, attrs, data, done) => {
  setTimeout(() => {
    done('Work complete');
  }, 120);
});

Generate Speech Assets

To minimize manual work needed while deploying your Alexa skills you can use our speechAssets generator. This helps you to create intentSchema, sampleUtterances and customSlots for your apps.

Speech assets consists of:

  • intentSchema - array of intents with slots
  • utterances - phrases that are used to invoke intents
  • customSlots - custom slot types with samples

For more information see interaction model reference

const speechAssets = app.speechAssets(); // object
console.log(speechAssets.toString()); // stringified version - f.e. copy paste from console

Save Speech Assets To Directory

If you want to use your assets (intentSchema, sampleUtterances and customSlots) later and have them stored, this function will do it for you. You can pass the name of your directory or leave it empty which defaults to /speechAssets.

Directory structure looks like this:

โ”œโ”€โ”€ speechAssets
    โ”œโ”€โ”€ intentSchema.json
    โ”œโ”€โ”€ utterances.txt
    โ””โ”€โ”€ customSlots
        โ”œโ”€โ”€ Name.txt
        โ”œโ”€โ”€ Age.txt
        ...
app.saveSpeechAssets('speechAssets'); // No argument leads to default value 'speechAssets'

Register Intents using pattern matching

If your intents are located in separate files you need to register them to the app. One way how to do this is to wrap intent into function taking app as a parameter.

src/intents/hello-intent.js

module.exports = app => app.intent('HelloIntent', 'hello', () => {
  return 'Hello';
});

Next you need to register it by importing it manually and supplying the app as a parameter.

You can also use our shorthand function for finding and registering all intents files that match pattern. See node-glob for more pattern matching examples.

src/app.js

app.registerIntents('src/intents/*-intent.js');

Actions

Feature of Alexia that helps you to control flow of the intents. To understand it easier see the code below.

By defining the action you enable transition from one intent to another. When no actions are specified, every intent transition is allowed.

Action properties from and to can be defined as string (one intent), array (multiple intents) or '*' (all intents).

Each action could have condition to check whether the transition should be handled or the fail method should be invoked. If no fail method is defined app.defaultActionFail() is invoked when condition of handling is not met or the action (transition) is not defined.

// Allow transition from any intent to `intent1`.
app.action({
  from: '*',
  to: 'intent1'
});

// Allow transition from `@start` intent to `intent2`.
app.action({
  from: '@start',
  to: 'intent2'
});

// Allow transition from `intent1` to `intent2` if condition is met using custom fail handler
app.action({
  from: 'intent1',
  to: 'intent2',
  if: (slots, attrs) => slots.pin === 1234,
  fail: (slots, attrs) => 'Sorry, your pin is invalid'
});

// Allow transition from `intent2` to `intent3` and also `intent4`.
app.action({
  from: 'intent2',
  to: ['intent3', 'intent4']
});

// Set default fail handler
app.defaultActionFail(() => 'Sorry, your request is invalid');

Localization

Alexia uses i18next for localizing response texts, utterances and custom slots.

For better understanding see localized app example: examples/multi-language.

These are the steps required to localize your existing application:

  1. Install dependencies: npm install --save i18next i18next-node-fs-backend
  2. Initialize i18next instance - see the example app
  3. Set i18next instance to your app to enable localization: app.setI18next(i18next)
  4. Create directory with all locales
  5. Omit utterances in all intents and access the translate function using app.t('key')

Localized intent example:

app.intent('LocalizedIntent', slots => {
  return app.t('text', slots);
});

Example locales directory structure:

locales/
โ”œโ”€โ”€ en/                  # Directory for all en locales
โ”‚   โ”œโ”€โ”€ translation.js   # Translations of response texts and utterances for each intent
โ”‚   โ””โ”€โ”€ custom-slots.js  # Translations of custom slots
โ””โ”€โ”€ de/                  # Directory for all de locales ...
    โ”œโ”€โ”€ translation.js
    โ””โ”€โ”€ custom-slots.js

Localization notes:

  • You can localize LaunchRequest or SessionEndedRequest as well. Just add the entry along the intent names in translations
  • To localize built in intents, say AMAZON.YesIntent use entry names after the . suffix. So AMAZON.YesIntent becomes just YesIntent
  • To access the translation use: app.t('key') This key needs to be nested in the current intent translation entry. You don't have to use the full path to the key - the prefix is automatically added depending on the current request
  • Each intent translation should have utterances property. We support the richUtterances syntax f.e: My age is {age:Number}
  • The locale to be used is decided depending on the data.request.locale Its value could be currently one of: en-US, en-GB, en-CA, en-IN, en-AU, de-DE, fr-FR, ja-JP

Handling Amazon Requests

To handle Amazon requests you need to create HTTP server with POST route. You can take advantage or our API to create Hapi server so you don't have to create it manually. This requires to install hapi as dependency:

npm install hapi --save
const options = {
  path: '/', // defaults to: '/'
  port: 8888 // defaults to: process.env.PORT or 8888
};
const server = app.createServer(options);

Handling Amazon Requests Manually

You can create your own HTTP from scratch to handle Amazon requests manually. See below example with Hapi server

const Hapi = require('hapi');
const server = new Hapi.Server();
const app = require('./app'); // Your app

server.connection({
  port: process.env.PORT || 8888
});

server.route({
  path: '/',
  method: 'POST',
  handler: (request, response) => {
    app.handle(request.payload, (data) => {
      response(data);
    });
  }
});

server.start((err) => {
  if (err) throw err;
  console.log('Server running at:', server.info.uri);
  app.saveSpeechAssets();
});

Deploy

Heroku

  1. Create free Heroku acount
  2. Install Heroku CLI
    • ensure that you donโ€™t have the legacy Heroku Toolbelt or Heroku Ruby gem installed
  3. Be sure to have start script defined in package.json
  4. Be sure to create server handler on POST endpoint. See Handling Amazon Requests
  5. Run git init if git was not yet initialized in your project
  6. Be sure to heroku login and enter your credentials
  7. Run heroku create in project directory
  8. Run git push heroku master
  9. Copy your server URL to your Alexa Skill configuration. See Create Alexa Skill

AWS Lambda

  1. Create account and login to AWS Console
  2. Create new Lambda function
  3. Set function invocation to index.handler
  4. Add Alexa Skills Kit trigger
  5. Export handler in your index.js file
  6. Upload zipped project folder into AWS Lambda
  7. Copy Lambda function ARN to your Alexa Skill configuration
exports.handler = (event, context, callback) => {
  app.handle(event, data => {
    callback(null, data);
  });
};

Create Alexa skill

  • Login to your Amazon developer account

  • Select Apps & Services

  • Select Alexa

  • Select Alexa Skills Kit

  • Add a new Skill

  • Set skill info required to run app:

    Skill Information

    • Name: Name of your app, can be whatever
    • Invocation Name: Short phrase or abbreviation of your app name. Will be used to start your app by saying: Alexa, start MyApp if your invocation name is MyApp

    Interaction model

    • Use our speech assets generator app.saveSpeechAssets() to generate and save speech assets to speechAssets directory
    • Custom Slot Types: Click Add Slot Type
      • Type: name of custom slot type
      • Values: contents of speechAssets/customSlots/** or enter custom slot samples manually
      • Do this for each custom slot
    • Intent Schema: enter contents of speechAssets/intentSchema.json
    • Sample Utterances: enter contents of speechAssets/sampleUtterances.txt

    Configuration

    • Endpoint: select HTTPS and enter url or your publicly accesible server

    SSL Certificate

    • Select what applies to your SSL certificate
    • Could remain unselected when no certificate is required

    Test

    • Enable skill testing on this account
    • Enter one of your utterances and click Ask MyApp

Testing

Device Testing

  • Connect to your Amazon Echo device using the same developer account where you created skill
  • Enable application for testing
  • Say Alexa, start <myApp>

Echosim.io (Online Simulator)

  • Open Echosim.io
  • Login with your Amazon developer account
  • Interact with Alexa simulator

Unit Testing

Each application should be unit-tested. We are exposing simple API helping you to create sample Alexa requests for testing and debugging.

alexia.createRequest({
  type: 'IntentRequest',
  name: 'UnknownIntent',
  slots: {},
  attrs: {},
  appId: 'amzn1.echo-sdk-123456',
  sessionId: 'SessionId.357a6s7',
  userId: 'amzn1.account.abc123',
  requestId: 'EdwRequestId.abc123456',
  timestamp: '2016-06-16T14:38:46Z',
  locale: 'en-US',
  new: false
});

All the properties optional and defaults to the values you see in the example above. Sample usage:

alexia.createRequest({type: 'IntentRequest', name: 'HelloIntent', slots: ..., attrs: ...});
alexia.createIntentRequest('HelloIntent', slots, attrs, isNew, appId); // Shorter version - does not support all of the properties

Before writing unit tests make sure to install all the dependencies. In our example we will be using mocha and chai with expect.

npm install mocha chai expect --save-dev

Example below illustrates simple unit testing for intentRequest. Testing of launchRequest or sessionEndedRequest would look the same

const expect = require('chai').expect;
const alexia = require('alexia');
const app = require('./path-to-app.js');

// Create sample requests
const launchRequest = alexia.createLaunchRequest();
const sessionEndedRequest = alexia.createSessionEndedRequest();
const intentRequest = alexia.createIntentRequest('MyIntent');

// Sample MyIntent test suite
describe('(Intent) MyIntent', () => {
  it('should handle MyIntent', done => {

    // Simulate Alexa request handling
    app.handle(intentRequest, response => {

      // Test the response
      expect(response).to.be.defined;
      done();
    });
  });
});

Debugging

We are using debug package to debug our alexia applications. To start application in debug mode export environment variable DEBUG

Examples:

  • DEBUG=alexia:info - print only info logs
  • DEBUG=alexia:debug - print only debug logs
  • DEBUG=alexia:* - print all logs

To start your app with info logs run in terminal:

DEBUG=alexia:info npm start

Scripts

  • npm test - run unit tests
  • npm test:dev - run unit tests in development mode using nodemon as watcher
  • npm run lint - run eslint
  • npm run lint:fix - run eslint and automatically fix problems
  • npm run toc - update TOC in README.md

Contributing

Alexia is an open source project and we encourage contributions. Please make sure to cover your code with unit tests.

After updating README.md please run: npm run toc

For more information refer to general guide Contributing to Open Source

License

MIT

More Repositories

1

AmpliGraph

Python library for Representation Learning on Knowledge Graphs https://docs.ampligraph.org
Python
2,147
star
2

Spartacus

Spartacus DLL/COM Hijacking Toolkit
C#
989
star
3

adop-docker-compose

Talk to us on Gitter: https://gitter.im/Accenture/ADOP
Shell
765
star
4

reactive-interaction-gateway

Create low-latency, interactive user experiences for stateless microservices.
Elixir
590
star
5

jenkins-attack-framework

Python
554
star
6

VulFi

IDA Pro plugin for query based searching within the binary useful mainly for vulnerability research.
Python
532
star
7

Codecepticon

.NET/PowerShell/VBA Offensive Security Obfuscator
C#
481
star
8

Ocaramba

C# Framework to automate tests using Selenium WebDriver
C#
277
star
9

CLRvoyance

Managed assembly shellcode generation
Assembly
263
star
10

protobuf-finder

IDA Pro plugin for reconstructing original .proto files from binary.
Python
256
star
11

adop-jenkins

Groovy
152
star
12

sfmc-devtools

Fast-track your developers and devops engineers by allowing them to programmatically copy-paste / deploy changes and work offline
JavaScript
137
star
13

Labs-Federated-Learning

Accenture Labs Federated Learning
92
star
14

FirmLoader

Python
90
star
15

mercury

Reference engine for composable applications
Java
81
star
16

serverless-ephemeral

This is a Serverless Framework plugin that helps bundling any stateless zipped library to AWS Lambda.
JavaScript
67
star
17

adop-platform-management

Groovy
60
star
18

adop-cartridge-java

Groovy
59
star
19

Condstanta

Python
56
star
20

EcoSonar

EcoSonar, the ecodesign audit tool
JavaScript
54
star
21

bdd-for-all

Flexible and easy to use library to enable your behavorial driven development (BDD) teams to easily collaborate while promoting automation, transparency and reporting.
Java
51
star
22

Cymple

Cymple - a productivity tool for creating Cypher queries in Python
Python
49
star
23

adop-gerrit

Shell
45
star
24

adop-aws

This repository contains a hardened, 2-tiered implementation of the DevOps Platform -> https://github.com/Accenture/adop-docker-compose
35
star
25

AARO-Bugs

Vulnerabilities, exploits, and PoCs
C
34
star
26

AIR

A deep learning object detector framework written in Python for supporting Land Search and Rescue Missions.
Python
30
star
27

generator-mario

Generator for Backbone/Marionette applications with lots of bells and whistles to help keep a non-trivial sized application moving forward at a breakneck pace!
JavaScript
29
star
28

sfmc-customapp

JavaScript
28
star
29

DBTestCompare

Application to compare results of two SQL queries
Java
25
star
30

AutoFixture.XUnit2.AutoMock

Autofixture auto-mocking for XUnit2 using a mocking library of your choice.
C#
22
star
31

kx.as.code

kx.as.code
Shell
19
star
32

openathon-2019-angular

IV OpenAthon CSE - Angular
TypeScript
19
star
33

OSDU-Ontology

An ontology designed for oil and gas, and subsurface energy data based on the industry standards.
HTML
18
star
34

alexia-starter-kit

Starter Kit project with sample Amazon Echo skill created using Alexia Framework
JavaScript
17
star
35

mv-unreal-aws

C++
16
star
36

tldr

The Lightweight Docker Runtime
Shell
15
star
37

pyheal

PyHeal is a Python wrapper for Microsoft SEAL aimed at making operations easier to use.
Python
15
star
38

openathon-2019-react

Openathon edition organised for the Accenture Technology Custom Open Cloud community where we will have again the opportunity to discover, in a practical way, the possibilities offered by the different architectures and leading frameworks in the market.
JavaScript
15
star
39

openathon-2019-docker

13
star
40

mercury-python

Python language pack for Mercury
Python
12
star
41

openathon-2020-serverless

Openathon VI - Custom Software Engineering
HTML
11
star
42

adop-sonar

Shell
11
star
43

waterfall-config

A simplistic configuration library for Java, heavily based on Typesafehub Config with some additional opinionated features
Java
9
star
44

sfmc-connector

Apex
8
star
45

askme

askme is a simple application designed to solicit immediate feedback during public speaking engagements, and is used as a demo app for multiple application architecture and dev process demos. It's also a cool and useful application in its own right.
JavaScript
8
star
46

adop-nexus

Shell
7
star
47

sfmc-devtools-copado

SFMC DevTools made easy using Copado Multi-Cloud's webinterface
JavaScript
7
star
48

mercury-composable

Reference implementation toolkit for writing composable applications
Java
7
star
49

adop-nginx

CSS
6
star
50

openathon-2020-python

openathon-2020-python
Python
6
star
51

ALM-SF-Metadata-API-Python-Tools

ALM SF Metadata API Python Tools
Python
6
star
52

DX-Mate

DX Mate
TypeScript
5
star
53

sfmc-devtools-vscode

Accenture SFMC DevTools for VS Code
TypeScript
5
star
54

Off-chain-storage-verification

A Blockchain-based Auditing Framework for Off-chain Storage
JavaScript
5
star
55

grails-spring-security-oauth-azure

grails-spring-security-oauth-azure
Groovy
5
star
56

mac-enablement

Shell
5
star
57

ALM-SF-DX-Python-Tools

ALM SF DX Python Tools
Python
5
star
58

adop-jenkins-worker

Dockerfile
4
star
59

adop-ldap-phpadmin

Shell
4
star
60

hiera-aws-sm

A Hiera 5 backend for AWS Secrets Manager
Ruby
4
star
61

Cockpit

Java
4
star
62

digital-products-boosters

digital-products-boosters
JavaScript
4
star
63

ALM-SF-DX-Pipelines

ALM SF DX Pipelines
Groovy
4
star
64

ALM-SF-Metadata-API-Pipelines

ALM SF Metadata API Pipelines
Groovy
4
star
65

openathon-2018-spring-boot-cloud

Materials (detailed guideline and exemplar solution) for the first Openathon organized by Accenture Technology Custom Software Engineering practice in Spain, focused on learning the basic to microservice development with Spring Boot and Spring Cloud.
Java
4
star
66

adop-cartridge-java-regression-tests

Java
3
star
67

speech2spikes

Python
3
star
68

mercury-nodejs

Reference engine for composable applications
TypeScript
3
star
69

alexa-pokitdok

JavaScript
3
star
70

cna-aws-cdk-patterns

TypeScript
3
star
71

openathon-2019-appian

OpenAthon 2019 - Appian
3
star
72

openathon-2021-quarkus

openathon-2021-quarkus
Shell
3
star
73

adop-cartridge-specification

Shell
3
star
74

adop-sensu

Ruby
3
star
75

azure-arc-playground-builder

Azure Arc Quickstart showcasing Arc-enabled App Service & Data Services
Shell
3
star
76

can_dlc_fuzzer

C++
3
star
77

tldr-alb

Application Load Balancer container for the The Lightweight Docker Runtime
Shell
2
star
78

evil_update

C
2
star
79

adop-cartridge-java-pipeline

Groovy
2
star
80

energy-consumption-measuring-toolkit

Python
2
star
81

openathon-2019-docker-spring-boot-app

Java
2
star
82

adop-cartridge-java-environment-template

2
star
83

DBTestCompareGenerator

Tool for generating database tests
C#
2
star
84

Mendix.RecaptchaWidget

JavaScript
2
star
85

adop-ldap-ltb

PHP
2
star
86

morpheus-data-api

Python client to Morpheus Data API https://apidocs.morpheusdata.com
Python
2
star
87

reactive_technologylearningpills

Technology Learning Pills: Reactive
TypeScript
2
star
88

adop-platform-extension-chef

Chef Server v12 extension for the ADOP platform.
2
star
89

Docknet

A pure Numpy implementation of neural networks for educational purposes
Jupyter Notebook
2
star
90

NEC850_Architecture

C++
2
star
91

Mendix.ObjectivityCommons

Java
1
star
92

Mendix.GlobusTheme

Objectivityโ€™s UI resources module and theme for building apps on the Mendix 9 platform.
SCSS
1
star
93

Mendix.IfElse

JavaScript
1
star
94

adop-logstash

1
star
95

Shakespeare_RNN

Python
1
star
96

adop-gitlab

Shell
1
star
97

CIFR_Yara

YARA
1
star
98

Mendix.CssClassSwitcher

A Mendix widget that adds CSS classes determined by a microflow (or nanoflow) to elements determined by CSS selector.
CSS
1
star
99

docker-plaso

Makefile
1
star
100

openathon-2019-docker-angular-app

TypeScript
1
star