Introduction
In this article, I am going to demonstrate how to create a custom Alexa skill on Alexa Hosted node.js server to extract slot values for different slots defined in an interaction model of an Alexa skill. For that, I will be creating a custom Alexa skill named getting input. With the help of this skill, Users can tell Alexa about themselves. The backend code required for the Alexa skill to work will be stored in a lambda function inside the Amazon developer console.
Creating Custom Alexa Skill
To create a new skill, first we need to login into the Alexa developer console, we need to mention the unique skill name and select the default language according to our location.
After that, we can choose a model to add to our skill. To create a custom skill, we can select custom model.
We can also choose a method or a template to host the skill’s backend code inside a lambda function.
We can choose Alexa hosted node.js or python template. We can also mention our own endpoint or server to store backend resources for the required Alexa skills.
The next step is to choose a template to add to our skill, which we customize later according to our need and click on the create skill button. Now as a skill has been created, we need to make adjustments to the skill’s frontend. Now I will be creating intents, slots, and custom slot types to create skill’s frontend.
First, we need to mention the invocation name. Users say a skill's invocation name to begin an interaction with a particular custom skill.
Now we have to create intents:
Here, I have added a new intent named MyNameIsIntent along with a sample utterance. Inside the utterance “{name}” and “{name} is my name”, name is a slot defined for this skill. Slots are defined within curly brackets.
Slots and slot type of each slot is defined as follows:
Here Amazon.FirstName is a pre-defined slot created for the above-mentioned intent.
After creating a model for a particular skill, we can save and build the model by clicking on save model and build model button on the top.
Json code for the interaction model is as follows,- {
- "interactionModel": {
- "languageModel": {
- "invocationName": "getting input",
- "modelConfiguration": {
- "fallbackIntentSensitivity": {
- "level": "LOW"
- }
- },
- "intents": [
- {
- "name": "AMAZON.NavigateHomeIntent",
- "samples": []
- },
- {
- "name": "AMAZON.CancelIntent",
- "samples": []
- },
- {
- "name": "AMAZON.HelpIntent",
- "samples": []
- },
- {
- "name": "AMAZON.StopIntent",
- "samples": []
- },
- {
- "name": "AMAZON.FallbackIntent",
- "samples": []
- },
- {
- "name": "MyNameIsIntent",
- "slots": [
- {
- "name": "name",
- "type": "AMAZON.FirstName"
- }
- ],
- "samples": [
- "{name}",
- "{name} is my name",
- "my name is {name}",
- "i am {name}",
- "you can call me {name}"
- ]
- }
- ],
- "types": []
- }
- }
- }
Creating the backend resource for the Alexa skill
To create backend code inside the lambda function, we can write code inside the index.js node.js file. The code for the custom Alexa skill is as follows:
- const Alexa = require('ask-sdk-core');
-
-
- const LaunchRequestHandler = {
- canHandle(handlerInput) {
- return handlerInput.requestEnvelope.request.type === 'LaunchRequest';
- },
- handle(handlerInput) {
- const speechText = 'Hi, What is your name?';
- const repromptText = 'can you tell me your name?';
-
-
- return handlerInput.responseBuilder
- .speak(speechText)
- .reprompt(repromptText)
- .getResponse();
- },
- };
-
- const MyNameIsIntentHandler = {
- canHandle(handlerInput) {
- return handlerInput.requestEnvelope.request.type === 'IntentRequest'
- && handlerInput.requestEnvelope.request.intent.name === 'MyNameIsIntent';
- },
- handle(handlerInput) {
-
-
- const userName = handlerInput.requestEnvelope.request.intent.slots.name.value;
- const speechText = `Hello ${userName}. It is nice to meet you.`;
-
-
- return handlerInput.responseBuilder
- .speak(speechText)
- .getResponse();
- },
- };
-
-
-
-
- const HelpIntentHandler = {
- canHandle(handlerInput) {
- return handlerInput.requestEnvelope.request.type === 'IntentRequest'
- && handlerInput.requestEnvelope.request.intent.name === 'AMAZON.HelpIntent';
- },
- handle(handlerInput) {
-
-
- const speakOutput ='You can introduce yourself by telling me your name.';
-
-
- return handlerInput.responseBuilder
- .speak(speakOutput)
- .reprompt(speakOutput)
- .getResponse();
- },
- };
-
- const CancelAndStopIntentHandler = {
- canHandle(handlerInput) {
- return handlerInput.requestEnvelope.request.type === 'IntentRequest'
- && (handlerInput.requestEnvelope.request.intent.name === 'AMAZON.CancelIntent'
- || handlerInput.requestEnvelope.request.intent.name === 'AMAZON.StopIntent');
- },
- handle(handlerInput) {
-
-
- const speakOutput = 'Goodbye!';
-
- return handlerInput.responseBuilder
- .speak(speakOutput)
- .getResponse();
- },
- };
-
- const SessionEndedRequestHandler = {
- canHandle(handlerInput) {
- return handlerInput.requestEnvelope.request.type === 'SessionEndedRequest';
- },
- handle(handlerInput) {
- console.log(`Session ended with reason: ${handlerInput.requestEnvelope.request.reason}`);
-
- return handlerInput.responseBuilder.getResponse();
- },
- };
-
-
- const ErrorHandler = {
- canHandle() {
- return true;
- },
- handle(handlerInput, error) {
- console.log(`Error handled: ${error.message}`);
-
-
- return handlerInput.responseBuilder
- .speak('Sorry I can\'t understand the command. please say again.')
- .reprompt('Sorry I can\'t understand the command. please say again.')
- .getResponse();
- },
- };
-
-
-
-
- const skillBuilder = Alexa.SkillBuilders.custom();
-
- exports.handler = skillBuilder
- .addRequestHandlers(
-
- LaunchRequestHandler,
- MyNameIsIntentHandler,
-
- HelpIntentHandler,
- CancelAndStopIntentHandler,
- SessionEndedRequestHandler,
-
- )
-
- .addErrorHandlers(ErrorHandler)
-
- .lambda();
To receive request from the user, request handlers are created for each intent to handle. Inside each handlers, canHandle and handle functions are written.
The canHandle() function is where you define what requests the handler responds to. The handle() function returns a response to the user. If your skill receives a request, the canHandle() function within each handler determines whether or not that handler can service the request.
In this case, the user wants to launch the skill, which is a LaunchRequest. Therefore, the canHandle() function within the LaunchRequestHandler will let the SDK know it can fulfill the request. In computer terms, the canHandle returns true to confirm it can do the work.
After that, MyNameIsIntentHandler is defined to handle each and every request of user to tell Alexa about themselves. This handler will receive Name as requested slot parameter and extract the slot value mention by the user and prompts a dialog mentioning user name accordingly.
Output
As we can see from the above output, a user can invoke the skill by saying just the invocation name which is getting input. Then Alexa greets user asks for his/her name. As soon as the user mentions his/her name, Alexa extracts the slot value from the slot and prompts a message saying “Hello Abhishek. It is nice to meet you”.
Summary
In this article, I created a custom Alexa skill. I also defined intents, slots and custom slot types for each slot. I demonstrated how to extract slot values for different slots defined in an interaction model of an Alexa skill. Proper coding snippets along with the output for the backend of the skill are also provided.