This goal of the Nuget package is:
- Provide POCO classes and serialization helpers to send and receive messages to and from Alexa
- Integrate with the Amazon's Alexa related services to:
- Get users security information like the user name, device address, etc.
These Alexa Skills are in production and use this project:
Animal Farm P.I.
Eye of the Elder Gods
Clinical Trial Finder
If you release any Alexa Skills using this library, please let us know at info@whetstonetechnologies.io and we'll add it to the list.
CanFulfillIntent Processing - Details on how to use nameless invocation
Sending a Progressive Response - Send the user a message while processing long running Alexa requests
master
The Whetstone.Alexa Nuget package includes classes for serialization and deserializing common requests and responses passed to and from Alexa Skills. The same structures apply irrespective of whether the client service is deployed as a web API or a Lambda Function.
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Whetstone.Alexa;
. . .
namespace Whetstone.Alexa.EmailChecker.WebApi.Controllers
{
[Produces("application/json")]
[Route("api/alexa")]
public class AlexaController : Controller
{
[HttpPost]
public async Task<ActionResult> ProcessAlexaRequest([FromBody] AlexaRequest request)
{
AlexaResponse resp = await _emailProcessor.ProcessEmailRequestAsync(request);
return Ok(resp);
}
using Amazon.Lambda.Core;
using Whetstone.Alexa
. . .
// Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class.
[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.Json.JsonSerializer))]
namespace Whetstone.Alexa.EmailChecker.Lambda
{
public class Function
{
public async Task<AlexaResponse> FunctionHandlerAsync(AlexaRequest request, ILambdaContext context)
{
var emailProcessor = _serviceProvider.Value.GetRequiredService<IEmailProcessor>();
return await emailProcessor.ProcessEmailRequestAsync(request);
}
The most useful values on the AlexaRequest is the request type,
intent, and slot values.
Get the request type:
RequestType reqType = request.Request.Type;
Get the name of the intent:
string intent = request.Request.Intent.Name;
Get a slot value from the intent:
string selectedCity = request.Request.Intent.GetSlotValue("city");
Alexa can speak a plain text response to the user or process Speech Synthesis Markup Language (SSML).
SSML include speech directives to tell change the volume of Alexa's voice, speed up or slow the response, and play MP3 files. The total time to provide the response the user cannot exceed 90 seconds. If the user
does not respond, Alexa uses a reprompt to elicit a response from the user. Optionally, a
card response can send plain text along with small images. Card responses appear in the user's Alexa mobile application and on alexa.amazon.com.
The following sample sends a plain text response, a reprompt, and a standard card response.
string textResp = "You are following a path in forest and have come to a fork. Would you like to go left or right?";
AlexaResponse resp = new AlexaResponse
{
Version = "1.0",
Response = new AlexaResponseAttributes
{
OutputSpeech = OutputSpeechBuilder.GetPlainTextSpeech(textResp),
Card = CardBuilder.GetSimpleCardResponse("Fork in the Road", textResp),
Reprompt = new RepromptAttributes
{
OutputSpeech = OutputSpeechBuilder.GetPlainTextSpeech("Left or right?"),
},
ShouldEndSession = false
},
};
To include an image in the card response, provide a publicly accessible URL for both a small image (720w x 480h) and large image (1200w x 800h). For more information, please see Create a Home Card to Display Text and an Image.
. . .
Card = CardBuilder.GetStandardCardResponse("Fork in the Road",
textResponse,
"https://dev-customapp.s3.amazonaws.com/adventuregame/images/forkintheroad_720x800.png",
"https://dev-customapp.s3.amazonaws.com/adventuregame/images/forkintheroad_1200x800.png"
),
. . .
The following sample shows how to include MP3 files in the response using the audio tag along with supported SSML tags. For a comprehensive list of Alexa-supported SSML tags, please see Speech Synthesis Markup Language (SSML) Reference.
StringBuilder ssmlSample = new StringBuilder();
ssmlSample.Append("<speak><audio src='https://dev-sbsstoryengine.s3.amazonaws.com/stories/animalfarmpi/audio/Act1-OpeningMusic-alexa.mp3'/> ");
ssmlSample.Append("It was a dark and stormy night. <break time='500ms'/>");
ssmlSample.Append("<say-as interpret-as='interjection'>no way!</say-as> ");
ssmlSample.Append("I'm not doing this. That doesn’t make any sense! That music didn’t sound dark and stormy at ");
ssmlSample.Append("<prosody volume='x-loud' pitch='+10%'>all!</prosody>");
ssmlSample.Append(" It sounds to me more like a bright and chipper morning! Should we go with dark and stormy, or bright and chipper?");
ssmlSample.Append("</speak>")
AlexaResponse resp = new AlexaResponse
{
Version = "1.0",
Response = new AlexaResponseAttributes
{
OutputSpeech = OutputSpeechBuilder.GetSsmlSpeech(ssmlSample.ToString()),
Amazon has provided a sound library that includes animal, game show, and other sounds. This may be a viable alternative if the needs for sounds is limited. The Whetstone.Alexa Nuget package includes constants that link to all of the sounds provided in the Alexa Skills Kit Sound Library.
using Whetstone.Alexa.Audio.AmazonSoundLibrary;
. . .
StringBuilder librarySample = new StringBuilder();
librarySample.Append("<speak>");
librarySample.Append(Office.ELEVATOR_BELL_1X_01);
librarySample.Append("Your hotel is booked!");
librarySample.Append("</speak>");
If you'd like to include and reference MP3 files and images, they must be publicly available. If hosting on S3 storage, then use a bucket policy
to limit the public files only to directories need to be exposed.
The following bucket policy exposes only the files in the audio and image subfolders to the public.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AddPerm",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": [
"arn:aws:s3:::bucketname/projects/*/audio/*",
"arn:aws:s3:::bucketname/projects/*/image/*"
]
}
]
}
In order to allow the Alexa mobile app to download the image, CORS restrictions must allow for GET requests from ask-ifr-download.s3.amazonaws.com.
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>http://ask-ifr-download.s3.amazonaws.com</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
</CORSRule>
<CORSRule>
<AllowedOrigin>https://ask-ifr-download.s3.amazonaws.com</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
</CORSRule>
</CORSConfiguration>
The following enhancements are planned:
- Dialog state processing
- Streaming audio management using the AudioPlayer Interface