How to Work With Alexa Entities
With Alexa Entities, you can build engaging Skills with rich content
Join the DZone community and get the full member experience.
Join For FreeIn Alexa Live 2020, the Amazon Alexa Team launched a feature called Alexa Entities. This feature is aimed to use the Alexa Graph Knowledge to retrieve extra information from some Built-in Slots like places, actors, people, etc. After a year, this feature has been launched in more locales including Spanish, German, French, and Italian. Whew! With Alexa Entities, you don't need to access external API to get some extra data. Each entity will provide an URL from the Alexa Knowledge graph where you can get that information.
Prerequisites
Here you have the technologies used in this project
- Node.js v14.x
- Visual Studio Code
- Alexa Extension on VS Code
Setting Up Our Alexa Skill
As I pointed above, when we add a built-in slot in our interaction model, let's say AMAZON.Actor
for example and that slot has a successful match, we will receive on our AWS Lambda that this slot has been matched and also some extra info. That extra info will be a slot resolution with the Alexa Entity information. What is that information? It will be a link where we can fetch all the data from that Alexa Entity that has been matched. This link looks like this: https://ld.amazonalexa.com/entities/v1/KmHs1W4gVQDE9HHq72eDLs'
Because of this, we need to set up our Alexa Skill backend. As we are going to fetch some data, the first step we need to do is add one package npm: axios
To install this dependency you have to run these commands:
- For npm:
npm install --save axios
- For yarn:
yarn add axios
Axios is one of the most common libraries used in Node.js to make HTTP requests.
With this package installed/updated, we have done good progress on this journey!! Let's continue with the following steps.
Alexa Entities Resolution
As it is explained in the official documentation: "Each entity is a node linked to other entities in the knowledge graph".
So let's go back to our example, the AMAZON.Actor
one. Imagine that we have a slot called actor
with that built-in type. When we request information of an actor and that actor is matched with the intent and also that actor exists on the Alexa Knowledge graph, we will get an URL to fetch its data.
But, where can we find that URL? where is it located within the request? This is what Alexa calls Slot Resolution. The Slot Resolution is the way that Alexa tells you, as a developer that a slot has successfully matched and which is the authority that resolved the value of that slot. For instance, a slot can be resolved by these 3 authorities ways:
- As a Custom value. For example, a custom actor that we added manually.
- As a Dynamic entity. The custom values that we can add programmatically.
- As an Alexa Entity. When the actor exists in the Alexa Knowledge Graph.
The Slot resolution authorities and their resolutions can be found within the request here:
In this example, when we fetch that data, we will see some properties like birthdate
, birthplace
or an array called child
. This array contains the child or children of the actor that we have requested. In each object of the child
array, we will find a URL where we can fetch the data of that child.
It is important to note here that each entity has its own schema. All the types are explained here.
Play With Alexa Entities
Once we have the packages we have installed/upgraded and we understood the Alexa Entities resolution and how it works, we need to modify our AWS Lambda to play with Alexa Entities.
For this example I created one intent to get information of actors:
The actor slot is using the AMAZON.Actor
built-in slot:
Then we have a handler for this intent called EntityIntentHandler
. The first thing that this handler going to do is to check if the slot actor
is matched and if it is matched with an Alexa Entity:
const actor = Alexa.getSlot(handlerInput.requestEnvelope, 'actor')
const resolutions = getSlotResolutions(actor);
This is how the getSlotResolutions
function looks like:
function getSlotResolutions(slot) {
return slot.resolutions
&& slot.resolutions.resolutionsPerAuthority
&& slot.resolutions.resolutionsPerAuthority.find(resolutionMatch);
}
function resolutionMatch(resolution) {
return resolution.authority === 'AlexaEntities'
&& resolution.status.code === 'ER_SUCCESS_MATCH';
}
When we have the slot and it is successfully resolved as an Alexa Entity we need to get a token. This token is included in each request. For that you just need to call this function:
const apiAccessToken = Alexa.getApiAccessToken(handlerInput.requestEnvelope);
Note that the Alexa
object is the object we got by importing the ask-sdk-core
lib:
const Alexa = require('ask-sdk-core');
With that information collected, we can call the Alexa Knowledge Graph using axios
(make sure you have already imported it):
const entityURL = resolutions.values[0].value.id;
const headers = {
'Authorization': `Bearer ${apiAccessToken}`,
'Accept-Language': Alexa.getLocale(handlerInput.requestEnvelope)
};
const response = await axios.get(entityURL, { headers: headers });
It is important to add the locale in order to get the data in the proper language.
If the call is successful, we can prepare our string that we are going to return to Alexa using the data from the Alexa Knowledge Graph:
if (response.status === 200) {
const entity = response.data;
const birthplace = entity.birthplace.name[0]['@value']
const birthdate = new Date(Date.parse(entity.birthdate['@value'])).getFullYear()
const childsNumber = entity.child.length
const occupation = entity.occupation[0].name[0]['@value']
const awards = entity.totalNumberOfAwards[0]['@value']
const name = entity.name[0]['@value']
if (Alexa.getLocale(handlerInput.requestEnvelope).indexOf('es') != -1){
speakOutput = name + ' nació en ' + birthplace + ' en '+ birthdate +' y tiene ' + childsNumber + ' hijos. Actualmente trabaja como ' + occupation + '. Tiene un total de ' + awards + ' premios.'
}else{
speakOutput = name + ' was borned in ' + birthplace + ' in ' + birthdate + ' and has ' + childsNumber + ' children. Now is working as a ' + occupation + '. Has won ' + awards + ' awards.'
}
}else{
if (Alexa.getLocale(handlerInput.requestEnvelope).indexOf('es') != -1){
speakOutput = 'No he encontrado informacion sobre ese actor.'
}else{
speakOutput = 'Didnt find information about that actor.'
}
}
And this is the final result:
English
Spanish
Which Alexa Entities are available?
It is important to notice that not all the Alexa built-in slots have the Alexa Entities resolution. It depends on the locale and the built-in slot itself. To make sure which ones are available you can check the official documentation.
Resources
- Official Alexa Skills Kit Node.js SDK - The Official Node.js SDK Documentation
- Official Alexa Skills Kit Documentation - Official Alexa Skills Kit Documentation
- Official Alexa Entities Documentation - Official Alexa Entities Documentation
Conclusion
As you can see the Alexa Entities can help us to build nice voice interactions with rich content. Looking forward to seeing what you are going to develop!
I hope this example project is useful to you.
You can find the code here.
That's all folks!
Happy coding!
Opinions expressed by DZone contributors are their own.
Comments