On my second week at Interknowlogy they gave me a great task 🙂 work around with Amazon’s Echo, which is a voice command device from Amazon.com that can answer you questions, play music and control smart devices. This device responds to the name “Alexa” (you can configure it to respond to Amazon too). So my main job was to try to find out how Alexa works.
Alexa’s knowledge is given from her skills which you can add at the developer site of amazon . To access this site, you have to register and go to the  Apps&Services section and get started in the Alexa Skill Kit.
Each skill has a Name, Invocation Name (how users will interact with the service), Version and an Endpoint. The last option is the URL service that will provide all the info of your skill to Alexa, you can choose between two options for your endpoint, you can decide between Lambda ARN (Amazon Resouce Name), that has to be developed with Java or Node.js, or your own service, the only thing that amazon requires its that it has to be a HTTPS server.
So I am going to explain how to do an Alexa skill in C# using your own server.
The technologies I used are:
- ASP.NET Web API
- Azure Websites
So, to create your Web API you follow the next steps:
Create new project -> ASP.NET Web Application
Choose the Web API option ( from ASP.NET 4.5.2 Templates) and connect it to an Azure Web App.
And then you have to Configure all your Azure Website stuff with your credentials to be ready to code 🙂
So what we want to do is to create a Controller that will have a post method and this method will receive all the requests from Alexa.
[Route( "alexa/hello" )] [HttpPost] public async Task<HttpResponseMessage> SampleSession() { var speechlet = new GetMatchesSpeechlet(); return await speechlet.GetResponse( Request ); }
To understand all these requests I used AlexaSkillsKit that is a NuGet package made by FreeBusy which you can find in this link, it’s pretty great, it helps you understand how Alexa works. Once you install that package you want to create a class that will derive from Speechlet (FreeBusy’s class) and override the following methods 🙂
- OnSessionStarted
private static Logger Log = NLog.LogManager.GetCurrentClassLogger(); public override void OnSessionStarted(SessionStartedRequest request, Session session) { Log.Info("OnSessionStarted requestId={0}, sessionId={1}", request.RequestId, session.SessionId); }
- OnLaunch
This method is called at the start of the application.
public override SpeechletResponse OnLaunch(LaunchRequest request, Session session) { Log.Info("OnLaunch requestId={0}, sessionId={1}", request.RequestId, session.SessionId); return GetWelcomeResponse(); } private SpeechletResponse GetWelcomeResponse() { string speechOutput = "Welcome to the Interknowlogy's Yellowjackets app, How may I help you?"; return BuildSpeechletResponse("Welcome", speechOutput, false); }
- OnIntent
This method will identify the intent that Alexa needs, so the API will receive an Intent with a name and it will be compared to do some action.
private const string NAME_SLOT = "name"; public override async Task<SpeechletResponse> OnIntent(IntentRequest request, Session session) { Log.Info("OnIntent requestId={0}, sessionId={1}", request.RequestId, session.SessionId); Intent intent = request.Intent; string intentName = (intent != null) ? intent.Name : null; if ("LastScore".Equals(intentName)) { //method that does some magic in my backend return await GetLastMatchResponse(); } if ("GetPlayerLastScore".Equals(intentName)) { Dictionary<string, Slot> slots = intent.Slots; Slot nameSlot = slots[NAME_SLOT]; //method that does some magic in my backend return await GetLastMatchPlayerResponse(nameSlot.Value); } else { return BuildSpeechletResponse("Hey", "What can I help you with?", false); } throw new SpeechletException("Invalid Intent"); }
Intents names are preset at amazon’s developer site with a json, and the example is the following:
In this page you will preset an Intent Schema which is in a Json format:
{ "intents": [ { "intent": "LastScore", "slots": [] }, { "intent": "GetPlayerLastScore", "slots": [ { "name": "name", "type": "LITERAL" }] }
This json format text describes that there will be two available intents, one named “LastScore” and the other one “GetPlayerLastScore”, and the last one recieves a “field” that is text.
Now the question is… How do I define the sentences and the parameters that the user of my echo will tell to alexa? In the same page of the developer site is a field that let you provide examples of the usage of Alexa. Which are the following:
Taking the last samples the interaction with alexa will be the following:
Alexa, ask Yellowjackets..
Welcome to the Interknowlogy’s Yellowjackets app, How may I help you?
What was the last ping pong score for Kevin?
…..
Build Responses
To Build responses (in custom methods) you will need to build a Speechlet response that contains a speech response and also can contain a card (optional), that is a graphic representation of a response of alexa that is displayed in the Echo App which is available online and in the following mobile OS:
- Fire OS 2.0 or higher
- Android 4.0 or higher
- iOS 7.0 or higher
The only available cards for devs (right know) are the Simple cards, that only contain plain text. Cards with pictures are not open for non-amazon devs.
To create a Speechlet response we will be using the cool Freebusy’s Nuget package class SpeechletResponse like this:
private SpeechletResponse BuildSpeechletResponse(string title, string output, bool shouldEndSession) { // Create the Simple card content. SimpleCard card = new SimpleCard(); card.Title = String.Format("YellowJackets - {0}", title); card.Subtitle = String.Format("YellowJackets - Sub Title"); card.Content = String.Format("YellowJackets - {0}", output); PlainTextOutputSpeech speech = new PlainTextOutputSpeech(); speech.Text = output; // Create the speechlet response. SpeechletResponse response = new SpeechletResponse(); response.ShouldEndSession = shouldEndSession; response.OutputSpeech = speech; response.Card = card; return response; }
The next steps will be to complete the skill configuration at amazon’s developer site. Â Which will be the SSL certificate, that will be pointing to my domain, because our WEB Api is a wildcard certificate from Azure.
Also you need to enable test mode to check out your service and Alexa’s interaction in your Amazon Echo.
So, there it is, hope this blog helped you in your adventure with Alexa (Amazon Echo) 🙂