====== Creating A Custom Skill for Alexa ====== **Author:** [[:unlv_hament|Blake Hament]] **Email:** blakehament@gmail.com \\ **Date:** 12/30/16 \\ **Keywords:** Alexa, custom, skill, python, echo, voice interface \\ This tutorial will get you started making custom skills for Alexa by adapting the flash brief skill scripts presented in a previous tutorial. This tutorial is for anyone looking to start making their own Alexa skills. ===== Motivation and Audience ===== This tutorial should be helpful for anyone interested in developing custom skills for Alexa. Alexa is a platform for voice-based web interface. There are limitless possibilities for making new Alexa capabilities, and this tutorial will give you a quick overview of how to adapt an existing Alexa skill to your custom purpose. This tutorial is for those with interest in: * Voice interface * Alexa skills * IoT This tutorial assumes the reader has some familiarity with: * python The rest of the tutorial is organized as follows: - Bill of Materials - Programming - Final Words ===== Bill of Materials ===== This tutorial utilizes an Amazon Echo Dot, but you can test your custom skill without a device. ^PART NAME/DESCRIPTION ^VENDOR ^VENDOR Number or URL ^PRICE ^QTY ^ | Amazon Echo Dot | Amazon.com |https://www.amazon.com/All-New-Amazon-Echo-Dot-Add-Alexa-To-Any-Room/dp/B01DFKC2SO/ref=sr_1_2?ie=UTF8&qid=1483065428&sr=8-2&keywords=echo |$49.99 | 1 | \\ ===== Programming ===== There are two types of edits we will need to make to the code: functionality and formatting. What I mean by functionality is that you will want to change the task(s) that Alexa performs when you initiate your skill. By formatting, I mean editing the script so that it refers Alexa to the right data points for your skill. ==== Functionality ==== This tutorial assumes you already have scripts written to perform an interesting task over the web or wired connections. Your script should include all necessary functions, or include a function for communicating with another machine that will perform the task. For the Stock Tracker skill in a previous tutorial, this includes functions like get_data(), get_ticker_code(), get_current_price(), get_low(), etc. These functions use the web crawler BeautifulSoup to grab stock data from yahoo.com. You can write your own functions, or adapt these to grab other interesting data, like show times or sports statistics. Once you have these functions defined in your script, you will map intents to these functions like so if intent_name == "GetCurrentPrice": return get_current_price(intent) "Intents" are the Alexa schema syntax for defining the services Alexa performs within a skill and the voice commands that invoke them. In designing your custom skill, it might be a good idea to begin by making a list of all the services you want to develop along with the voice commands you would like to employ. These can be arranged in a flow chart that maps the dialogue involved in user interface. Once the functionality of your skill is solid, it's time to make some formatting changes to the script to adapt it to your new skill. ==== Formatting ==== First, we need to change the application ID to match the one for your custom skill in the developer portal. def lambda_handler(event, context): #Checks to make sure application id is same as alexa skill (links) if (event['session']['application']['applicationId'] != #Change to application id listed under your alexa skill in the developer portal "amzn1.ask.skill.f976aad9-6567-4a27-8bce-7a0cfe9861e7"): raise ValueError("Invalid Application ID") Next we will edit the intent function def on_intent(intent_request, session): intent = intent_request["intent"] intent_name = intent_request["intent"]["name"] if intent_name == "__GetCurrentPrice__": return get_current_price(intent) elif intent_name == "__GetHigh__": return get_high(intent) elif intent_name == "__GetLow__": return get_low(intent) elif intent_name == "AMAZON.HelpIntent": return get_welcome_response() elif intent_name == "AMAZON.CancelIntent" or intent_name == "AMAZON.StopIntent": return handle_session_end_request() else: raise ValueError("Invalid intent") Replace or delete the functions relevant to stock tracking with the functions for your custom skill, and rename the __intent_name's__ appropriately. Look for references to "Stocker" and change to the name of your custom skill def handle_session_end_request(): card_title = "Stocker" speech_output = "I'm sorry, I'm afraid I can't do that." should_end_session = True return build_response({}, build_speechlet_response(card_title, speech_output, None, should_end_session)) Edit the dialogue so that it suits your user interface needs def get_welcome_response(): #Response to user invoking stock app without parameters/intents session_attributes = {} card_title = "Stocker" speech_output = "Welcome to the Stocker skill. " \ "You can ask me for current stock prices, or " \ "ask me about stock highs and lows." reprompt_text = "Please ask me for stock prices, " \ "for example Apple stock price." should_end_session = False return build_response(session_attributes, build_speechlet_response( card_title, speech_output, reprompt_text, should_end_session)) Now the script is repurposed and ready for use! ===== Final Words ===== Often it is easier to adapt working code to a new purpose than to write a script from scratch. This method may leave the user lacking important functionality if the code is repurposed for a drastically different skill, so check the resources on the Amazon web developers [[https://developer.amazon.com/|portal]] before taking starting an ambitious project.