Last updated: August 29th, 2019

Introduction

Voicehub is a content management and analytics platform for voice based apps. In its core, Voicehub lets you manage the content your voice apps sends out to your users, and combines it with extensive analytical features.

Voicehub allows you to make dynamic changes to the content of your voice app and push it live in real time, while it also collects analytical metrics about the performance of your app, helping you understand how your voice app is being used.

Quick Start Video

Projects

With Voicehub, you can manage multiple projects such as Alexa Skills, Google Actions or generic voice apps in one place.

Create a new Project

To onboard a project onto Voicehub, you can create a new project on the Projects Page of your Voicehub Account. Of course, you can also onboard any of your already existing Skills or Actions onto Voicehub. You can also create generic apps on Voicehub, which let you create exactly what you need. This is ideal for working with frameworks which have a single codebase for multiple platforms. In general, you can use this any time if your project does not specifically fit the other two options.
Create new Voice App
Project Name
Specify a name for your project, can be any name you like.
Type
Specify if this project is an Alexa Skill, Google Action or a generic project.
Locales
Select all the locales you are planning to support.
Default/Fallback Locale
Select a fallback locale which will be used in case of missing content.

You can then see your created project in the overview.

Project Overview
API Username
This is the username the developer who is implementing Voicehub needs to use when talking to the Voicehub API. Every project has its own API username.

Switch between Projects

At any time, you can switch between your projects on the very top of the page. The content will change automatically.
Project Overview

You can switch between your projects anytime at the very top of the page.

States

States are the building blocks of a voice app. They act as a collection of intents and content which deal with a specific state of the logic of your application. A Root State, being the default state, is already created for you for every project you create.

States Overview

The CMS Overview Page is the overview page over all your states, intents and posts. It gives you a visual overview of how your voice app looks like and where what content is returned to the user.

States Overview

A state holds intents, which then hold the actual content in form of posts. By the way, you can rearrange the order of the states and intents like you want, simply drag a them across the site by grabbing the handle on the header.

Create new States

Adding a new state is simple and straightforward. Simply click on the +State button on the overview page. A new state will be added automatically. You can then rename it or change the description as you like.

Create new State
A new empty state. Click on the name or the description to change it.

Delete a State

You can delete a state by hovering on its header and clicking the settings cog in the menu. Note that you can not delete the default root state.

Delete a State

Intents

An intent is the second building block of a voice app. They deal with a specific query the user asked your voice app within a specific state. For example: Depending on the question, a user could answer 'yes' or 'now', so you would have a 'YesIntent' and a 'NoIntent'. However, what you reply in response totally depends on the state the user is currently in. That is why its preferred to have the same intents defined across different states, because the content within those is different.

State holding Intents

A state holding multiple intents.

Create a new Intent

Adding a new intent is simple and straightforward. Simply hover above the state header to see the context menu to add an intent.

Create new Intent

By the way, you can rearrange intents within states by grabbing the handle on their headers.

Delete an Intent

Just like with states, you can delete an intent by hovering on its header and clicking the settings cog in the menu.

Delete Intent

Posts

Posts are the key pieces from which the content in your voice app is made up. Every post belongs to an intent within a state. A post can have any kind an amount of fields you want. In addition, the post can have multiple localized versions of a field, if you wish to support multiple locales with your application.

Posts Overview

The Content Page gives you an overview of your posts.

Posts Overview

On the overview page, you can easily see which posts are used in which parts of your voice app. Here you can also add new content to your voice app.

Create a Post

By clicking on the add post button, you can create a new post, which will automatically open.

You can then start writing your post. A new post page will be empty at first, you can start by adding a speech field by clicking on it at the bottom, or if you already have other posts and you want to keep working with their structure or content, you can copy over their structure and content at the top.

Note that depending on the field you add here, the data type for the content retrieved via the Voicehub API might change. For more details on that, check the Data Types Section.

Create Post

Once you either imported existing content or added a field, you will notice the switch at the top, where you can switch between the "live" and the "draft" stage.
Voicehub uses a live and draft stage system, allowing you to have a draft stored next to your live contents. As you type, Voicehub automatically saves your content separately as draft, so you will not loose anything and you can save your work for later.

Edit a Post

Once you are happy with your content, you can click "Publish Changes" to have the contents in the live stage overwritten by your edits in the draft stage.

Post Scheduling

Voicehub allows you to schedule content dynamically for your users. This can be easily achieved by simply assiging a start and end date and time for that post. Keep in mind that all dates and times you see and input are in UTC, so check if you need to convert your local time to UTC first and then use the result on Voicehub.

Post Scheduling

Post Tagging

Post tags allow you to classify content into any kind of categories or types you want. Tags can be very helpful for content retrieval and filtering within an application. Assign a tag simply by adding it into the tags field on the right.

Post Tagging

Post Data Types

Each field in a post has a certain data type. The data type ensures that the developer can rely on the content he is retrieving and enables integration of many different types of content.

For example, you could build a voice app having several characters play against each other, and you could give them different strengths and weaknesses using numbers, like an attack speed value or a defensive value. Or with a recipe app, you can use the list of speech as the list of ingredients.

Data Types

The data type you choose for a field determines the type of input you will get when you edit the post. It also determines the data type of the field for the developer when the post is retrieved via the API.

Speech Field

Speech

API Datatype: string

Selecting speech for the data type will give you the possibility of writing SSML enhanced speech content with our SSML editor. You can also listen to the speech you just wrote by pressing the play button and having it read out by the corresponding Amazon or Google voice for your app. The editor is documented in detail in the editor section.

Voicehub SSML Editor
Number Field

Number

API Datatype: number

When you select number as data type, you get a simple number input field. You can input both positive and negative integers (e.g. 7) and floats (7.25).

Number Field
List Field List Field

List

API Datatype: array

When you select list as type, you get another option to chose what the list will be composed of. You have two options here: list of speech and list of numbers.

List of Speech

With a list of speech, you get an ordered list of multiple SSML editors, allowing you to write ordered content.

List of Numbers

A list of numbers gives you multiple input fields for an ordered list of numbers.

Card Field

Cards

API Datatype: object

You can of course build cards with Voicehub. Selecting this datatype will provide you with our card builder. For Alexa, you can select between a simple card with just a title and a text body, or a standard card with a title, text and an image. For Google Actions, the basic card exists, with a title, subtitle, text body and a button with a link. You may also use some formatting in the latter. Cards also support parameters in all text fields (except image urls and button properties).

Parameter

API Datatype: string

The parameter type allows you to make your content highly dynamic. When you add a parameter to a post, you can use it inside the content and upon retrieval via the API, a value for that parameter can be supplied by you. This way, you can dynamically create speech which changes based on the parameter input.

An simple example is asking the user for his age, and then using what he answered in the next turn. Or if you wish to include formulas, that is also possible. You could have a recipe post with a "portions" parameter, allowing you to dynamically calculate the required amounts in the speech and return it to the user.

Dynamic Parameters

As a content editor, you create a parameter you would like to use in the content. The developer integrating Voicehub then needs to provide a value for this parameter, which gets dynamically injected into your written speech content.

Click on the little sign in the SSML editor to create or add a parameter. It's up to you how you want to use it, just make sure, a value for it will be provided when the post is requested. Also, if you are planning on writing a formula, the provided value should of course be a number.

Dynamic Speech Parameters

Use dynamic parameters in your speech content to make it more dynamic, inject phrases, numbers or results from API calls which are created on the fly.

Voicehub SSML Editor
Beta

Our SSML editor is a tool assisting you in creating great voice-first speech content. Is has multiple features allowing you to write visually flavoured SSML and also listen to an audio playback of what you just wrote.

Voicehub SSML Editor Features

SSML Type: break
Example: <break time="1s"/>

The break tool allows to you insert a pause between sentences or words in your voice content.

SSML Type: emphasis
Example: <emphasis level="strong">Voicehub<emphasis>

Put emphasis on words using the emphasis tool.

SSML Type: prosody
Example: <prosody speed="fast" volume="loud" pitch="high">Have fun!<prosody>

You can change volume, speed and pitch of your content using the prosody tool.

SSML Type: say-as
Example: <say-as interpret-as="spell-out">SSML<say-as>

Using the say-as tool, you can have speech interpreted differently, such as spelled out characters and numbers, or have the assistant read out fractions, telephone numbers or addresses as a human would do it.

The formula tool helps you to write any arithmetic expression with a parameter used in the post as variable, for example portions * 2, which will get calculated and injected into the speech when the post is retrieved with a value for the used parameter.

The parameter injection tool lets you insert parameters into your content when you want to use them as a stand-alone entity. You can also create new parameters on the spot. When the post is requested and a value for the used parameter is provided, it will get replaced with that value. If you have more complex requirements, consider using the formula tool as described above to write more complex logic involving dynamic parameters.

When you press play, the contents of the editor will be read out to you by the same engine your voice app uses. So if you work on an Alexa Skill, it will sound (almost) like Alexa by using Amazon Polly, and for Google Actions, it will utilize Googles Wavenet voices, which are also used in Google Actions.

Migration

Migration from typical Skill or Action setups to Voicehub is easy. First of all, you do not have to change anything about how you host your voice app. You can of course continue to use AWS Lambda, Google Firebase or your own solution for hosting your code. In order to make full use of Voicehub, you should however consider migrating the data from the database containing user data of your voice app. Not only can it be much cheaper to use Voicehub for managing your users, it also enables Voicehubs analytics features to the full extend and allows for the generation of reports and other insights.

Amazon DynamoDB Migration

In order to not interrupt the proper functionality of your existing Alexa Skill, you can easily copy over stored user data from DynamoDB to Voicehub when the user first calls the Skill after you have implemented Voicehub.


const LaunchRequestHandler = {
	canHandle(handlerInput) {
		return handlerInput.requestEnvelope.request.type === 'LaunchRequest';
	},
	async handle(handlerInput) {
		const { attributesManager } = handlerInput;

		/* Retrieve existing Properties */
		const attributes = await attributesManager.getPersistentAttributes() || {};
		/* Find or Create a new User */
		const user = await voicehub.user(handlerInput).findOrCreate();

		/* Copy over existing Properties if the user is new on Voicehub */
		if (user.isNew && Object.keys(attributes).length > 0) {
			user.set(attributes);
			await user.save();
		}
		// the rest of your code ...
	},
}

Node.js SDK

We provide a Node.js for you to integrate into your voice app. In general, all Node.js environments are supported, thus you can use our SDK in combination with alexa-skills-kit, dialogflow-fulfillment-nodejs or a framework like Jovo.

Install

Our SDK is available via npm. Use the following command to install and save it to your projects dependencies.

npm i -S @voicehub/voicehub

Initalize & Authenticate
At the very top of your code, require the module and provide your API username (which is your Voicehub App ID) and your API key:
  • APP_ID: The ID of your App on Voicehub, can be found here.
  • API_KEY: An API Key from your Voicehub Account, can be found here.
const voicehub = require('@voicehub/voicehub')('APP_ID', 'API_KEY');
The SDK is open source! If you have any ideas, requests or issues, don't hesitate and check out the Github repository. We also provide samples for an easy start:

Retrieve Content

Using the SDKs methods, you can easily retrieve content in form of posts created on Voicehub from within your voice app code.

Filter Content

You can utilize schedules and tags which were assigned to a post using the SDK.

Manage Users

You can fully manage the users of your voice app with Voicehub. You can store any kind of information about your user within Voicehub, and retrieve it when you need need it in your code. The SDK provides an easy interface to interact with the API.

Analytics

Voicehub is not only a content management platform for the content of you voice app, it also has extensive analytics features. Using the SDK, you can let Voicehub analyze many metrics about your voice app with just a few lines of code.

Reference

voicehub('app_id': string, 'api_key': string): Voicehub

Construct a Voicehub Instance

Construct a Voicehub Instance
Parameter Type Example Description
app_id

string

5ce68ed502ef3e46342d6712 The ID of your App in Voicehub.
api_key

string

058fbd3a-b590-4997-9c38-ee01a8256a6f Any one of your API Keys.

Content Management


.setLocale('locale': string | object | null): void

Set the Locale for the Instance

Parameter Type Example Description
locale

string | object | null

en-US Use a BCP-47 tag as string or handlerInput/agent object to set a locale for posts to be retrieved. When set, you can call post.fieldName and get the contents directly, instead of calling post.body.fieldName.content['en-US']. You can also set the locale to null to switch back to the "default behaviour".
.post('post_id': string): Post

Construct a Post Instance by _id

Parameter Type Example Description
post_id

string

5ce544e6dac9001d0s23cc5a Use this method to construct a post with its internal _id instead of its name. This makes you independent of the post name on Voicehub, which can be changed. You can however use the post name if you prefer, look at below .intent() method.
Properties of Post Instance
Property Description

_id

Returns internal _id for this post. Readonly.

locale

Returns the set locale for the user, or null.

app_id

Returns the Voicehub app_id for this user. Readonly.

state_id

Returns internal state_id of the state this post is in. Readonly.

intent_id

Returns the internal intent_id this post is in. Readonly.

field_order

Returns internal field_order display order in the frontend. Readonly.

tags

Returns the tags of the post as array of strings. Readonly.

schedule

Returns the schedule object of the post containing start and end in UTC. Readonly.

postIdentifier

Returns the post identifier used to construct this instance.

parameters

Returns parameters object used to construct this post instance, can be null.

body

Returns the post body containing the post fields.

has_draft

Returns true if there is draft content saved in this post, false otherwise.

field_order

Returns the order of the fields used in the front end. Readonly.

createdAt

Returns UTC string of time of creation of this post. Readonly.

updatedAt

Returns UTC string of time of last update of this post. Readonly.
.withParameters(parameters: object): Post

Inject Parameters into Post

Parameter Type Example Description
parameter

object

{ age: 21 } If a post has a dynamic parameter in its content, you can provide a value for it here to have it resolved. You must provided all parameters that are used within the post, or none to retrieve it unresolved.
.get(): Promise<Post>

Retrieve Post from Voicehub

.state('state_id': string): State

Construct an State Instance by Name or _id

Parameter Type Example Description
state_id

string

My State The name of the state on Voicehub or its internal _id, case-insensitive.
.intent('intent_id': string): Intent

Construct an Intent Instance by Name or _id

Parameter Type Example Description
intent_id

string

My Super Cool Intent The name of the intent on Voicehub or its internal _id, case-insensitive.
.post('post_id': string): Post

Construct a Post Instance by Name or _id

Parameter Type Example Description
post_id

string

My Cool Post Name Either the name of the post on Voicehub, or its internal _id.
Properties of Post Instance
Property Description

_id

Returns internal _id for this post. Readonly.

locale

Returns the set locale for the user, or null.

app_id

Returns the Voicehub app_id for this user. Readonly.

state_id

Returns internal state_id of the state this post is based on. Readonly.

intent_id

Returns the internal intent_id this post is in. Readonly.

field_order

Returns internal field_order display order in the frontend. Readonly.

tags

Returns the tags of the post as array of strings. Readonly.

schedule

Returns the schedule object of the post containing start and end in UTC. Readonly.

postIdentifier

Returns the post identifier used to construct this instance.

intentIdentifier

Returns the intent identifier used to construct this instance.

body

Returns the post body containing the post fields.

has_draft

Returns true if there is draft content saved in this post, false otherwise.

createdAt

Returns UTC string of time of creation of this post. Readonly.

updatedAt

Returns UTC string of time of last update of this post. Readonly.
.withParameters(parameters: object): Post

Inject Parameters into Post

Parameter Type Example Description
parameter

object

{ age: 21 } If a post has a dynamic parameter in its content, you can provide a value for it here to have it resolved. You must provided all parameters that are used within the post, or none to retrieve it unresolved.
.get(): Promise<Post>

Retrieve Post from Voicehub

.posts({ schedule: Date | int, tags: Array<String>}): Array.<Object>

Get all Posts from Intent with optional Filtering

Parameter Type Example Description
schedule

date || UTC timestamp (ms)

new Date() Provide a javascript date object or a UTC timestamp in milliseconds to get all posts from the intent which are scheduled for that point in time, meaning the start is smaller and the end is greater than the provided point in time.
tags

array of strings

['cool', 'warm'] Provide an array of strings to get all posts from the intent which have the provided tags. The logic is AND, so all provided tags must exist in the post in order for it to be returned.

Example Response:

[
		{
			_id: "5ce5508b3a7776sega6a6727",
			name: "Returning User Welcome",
			app_id: "5ce544e6dac90234f13cc5a",
			state_id: "5ce54f4cf1dawdsd884128a",
			intent_id: "5ce544e6dac934sge13cc5d",
			field_order: ['speech', 'reprompt'],
			tags: ['warm', 'cool'],
			schedule: {
				start: null,
				end: null,
			},
			has_draft: false,
			body: {
				speech: {
					type: "long_speech",
					localized: false,
					content: {
						en-US: "<speak>Welcome to Voicehub</speak>"
					}
				},
				reprompt: {
					type: "long_speech",
					localized: false,
					content: {
						en-US: "<speak>What can I do for you?</speak>"
					}
				}
			},
			createdAt: "2019-05-22T13:37:15.170Z",
			updatedAt: "2019-05-22T15:00:48.076Z"
		}
]
		

User Management


.user('vendor_user_id': string | object): User

Construct a User

Parameter Type Examples Description
vendor_user_id

string | object

handlerInput

agent

'amzn1.ask.account.AESY7...'

Provide the SDK specific objects here to construct the user, which are 'handlerInput' for Alexa Skills and 'agent' for Google Actions. Alternatively, though not recommended, provide a string manually.
Example User Creation
/* Alexa */
const user = await voicehub.user(handlerInput).findOrCreate();
/* Dialogflow */
const user = await voicehub.user(agent).findOrCreate();
Properties of User Instance
Property Description

_id

Returns internal _id for this user. Readonly.

locale

Returns the set locale for the user. Readonly.

isNew

Returns true if user was just created (after .findOrCreate()), false otherwise. Readonly.

properties

Returns the set (custom) properties for this user. Can be set to null to override stored information.

app_id

Returns the Voicehub app_id for this user. Readonly.

vendor_user_id

Returns the vendor_user_id the user was created with. Readonly.

createdAt

Returns UTC string of time of creation of this user. Readonly.

updatedAt

Returns UTC string of time of last update of this user. Readonly.
User Methods
.findOrCreate(): Promise<User>

Find or Create User on Voicehub

.set(parameters: object): User

Set Object of Attributes for User

Parameter Type Example Description
parameters

object

{ age: 21 } Set a whole object of attributes for a user with this method. Don't forget to call user.save() afterwards!
.save(): Promise<User> | null

Save User to Voicehub

.get(): Promise<User> | null

Retrieve User from Voicehub

Analytics


.actionInterceptor(agent: object): void

Log Google Action Interactions

Parameter Type Description
agent

object

To use Voicehubs analytics features, you need to connect your Google Action with Voicehub using this method.
.interactionInterceptor(handlerInput: object): void

Log Alexa Skill Interactions

Parameter Type Description
handlerInput

object

To use Voicehubs analytics features, you need to connect your Alexa Skill with Voicehub using this method.

Contact and Support

Our goal is to assist you in creating great voice-first experiences by using Voicehub and utilizing our tools. If you have any questions, please reach out to us. We are active on Spectrum, our community hub, where you can ask your questions not only to us, but also to other Voicehub users. You can also write us a mail to info@voicehub.io.