Alexa.NET es una librera auxiliar que permite trabajar con peticiones y respuestas para skills de Alexa en C#. Si estas utilizando el servicio de AWS Lambda o tienes hospedado tu propio servicio en tu propio servidor, esta libreria tiene como objetivo simplemente hacer que trabajar con Alexa API sea mas natural para desarrolladores C#, usando un modelo de objetos fuertemente tipado.
Alexa.NET también sirve como base para un conjunto de extensiones adicionales para el desarrollo con alexa creado por Steven Pears:
- Management GitHub / NuGet
- In-skill Pricing GitHub / NuGet
- Messaging GitHub / NuGet
- Gadgets GitHub / NuGet
- Customer Profile API GitHub / NuGet
- Settings API GitHub / NuGet
- APL Support GitHub / NuGet
- Reminders API GitHub / NuGet
- Proactive Events API GitHub / NuGet
- CanFulfillIntent Request Support GitHub / NuGet
Independiente de tu arquitectura, tu función para alexa deberá aceptar un SkillRequest y retornar un SkillResponse y la deserialización de la petición dentro del objecto SkillRequest denpenderá de tu framework.
public SkillResponse FunctionHandler(SkillRequest input, ILambdaContext context)
{
// La logica de tu función va aquí
return new SkillResponse("OK");
}
- Alexa Skills SDK para .NET
- Configuración
- Tabla de contenido
- Tipos de peticiones
- Manipulando la petición AccountLinkSkillEventRequest
- Manipulando la petición AudioPlayerRequest
- Manipulando la petición DisplayElementSelectedRequest
- Manipulando la petición IntentRequest
- Manipulando la petición LaunchRequest
- Manipulando la petición PermissionSkillEventRequest
- Manipulando la petición PlaybackControllerRequest
- Manipulando la petición SessionEndedRequest
- Manipulando la petición SkillEventRequest
- Manipulando la petición SystemExceptionRequest
- Respuestas
- Variables de sesión
- Respuestas sin funciones auxiliares
- Respuestas progresivas
Alexa enviará diferentes tipos de peticiones dependiendo de los eventos que deba responder. A continuación se encuentran todos los tipos de peticiones:
AccountLinkSkillEventRequest
AudioPlayerRequest
DisplayElementSelectedRequest
IntentRequest
LaunchRequest
PermissionSkillEventRequest
PlaybackControllerRequest
SessionEndedRequest
SkillEventRequest
SystemExceptionRequest
Esta petición es usada para enlazar Alexa con otra cuenta. La peticion vendrá con el token de acceso necesario para interactuar con el servicio conectado. Estos eventos solo se envian si han sido suscritos.
var accountLinkReq = input.Request as AccountLinkSkillEventRequest;
var accessToken = accountLinkReq.AccessToken;
La petición de reproducción de audio se envía cuando un skill pretende reproducir audio o si un cambio en le estado de este ha ocurrido en el dispositivo.
// hacer lago con la respuesta del audio
var audioRequest = input.Request as AudioPlayerRequest;
if (audioRequest.AudioRequestType == AudioRequestType.PlaybackNearlyFinished)
{
// Poner en cola otro archivo de audio
}
Cada AudioPlayerRequest
viene también con un tipo de petición que describe el cambio de estado:
PlaybackStarted
PlaybackFinished
PlaybackStopped
PlaybackNearlyFinished
PlaybackFailed
La petición de mostar elemento seleccionado será enviada cuando un skill tiene GUI (Interfaz gráfica de usuario) y uno de los botones fue seleccionado por el usuario. Esta petición llega con un token que dirá que elemento de la interfaz fue seleccionado.
var elemSelReq = input.Request as DisplayElementSelectedRequest;
var buttonID = elemSelReq.Token;
Este es problamente el tipo mas usado. IntentRequest también viene con un objeto Intent
y un DialogState
con valor STARTED
, IN_PROGRESS
o COMPLETED
Cada intención (intent) esta definida por el nombre configurado en la consola de desarrollo de Alexa. Si tu intención (intent) incluye spacios (slots) serán incluidas en el objeto junto con el estado de confirmación.
var intentRequest = input.Request as IntentRequest;
// Revisa el nombre que determina lo que se debe hacer
if (intentRequest.Intent.Name.Equals("MyIntentName"))
{
if(intentRequest.DialogState.Equals("COMPLETED"))
{
// obtiene los espacios
var firstValue = intentRequest.Intent.Slots["FirstSlot"].Value;
}
}
Este tipo de petición es enviado cuando tu skill es abierto sin una intención (intent) específica. Deberias recibir y procesar un IntentRequest
.
if(input.Request is LaunchRequest)
{
return ResponseBuilder.Ask("How can I help you today?");
}
Este evento es enviado cuando un cliente otorga o anula permisos.
Esta petición incluirá un objeto tipo SkillEventPermissions
que incluye el cambio en los permisos. Estos eventos solamente se envian si han sido suscritos.
var permissionReq = input.Request as PermissionSkillEventRequest;
var firstPermission = permissionReq.Body.AcceptedPermissions[0];
Este evento es enviado para controlar la reproducción de fondo de un skill que contiene un reproductor de audio.
var playbackReq = input.Request as PlaybackControllerRequest;
switch(playbackReq.PlaybackRequestType)
{
case PlaybackControllerRequestType.Next:
break;
case PlaybackControllerRequestType.Pause:
break;
case PlaybackControllerRequestType.Play:
break;
case PlaybackControllerRequestType.Previous:
break;
}
Este evento es enviado si el usuario solicita salir, si su respuesta toma mucho tiempo o ha ocurrido un error en el dispositivo.
var sessEndReq = input.Request as SessionEndedRequest;
switch(sessEndReq.Reason)
{
case Reason.UserInitiated:
break;
case Reason.Error:
break;
case Reason.ExceededMaxReprompts:
break;
}
Este evento es enviado cuando el usuario habilita o desabilita el skill. Estos eventos solomente se envian si han sido suscritos.
Cuando un error ocurre, bien sea como resultado de un evento mal estructurado o de muchas peticiones, Alexa retornará un mensaje al cliente que incluye el código de la excepción y una descripción.
var sysException = input.Request as SystemExceptionRequest;
string message = sysException.Error.Message;
string reqID = sysException.ErrorCause.requestId;
switch(sysException.Error.Type)
{
case ErrorType.InvalidResponse:
break;
case ErrorType.DeviceCommunicationError:
break;
case ErrorType.InternalError:
break;
case ErrorType.MediaErrorUnknown:
break;
case ErrorType.InvalidMediaRequest:
break;
case ErrorType.MediaServiceUnavailable:
break;
case ErrorType.InternalServerError:
break;
case ErrorType.InternalDeviceError:
break;
}
Hay 2 métodos auxiliares para formar una respuesta de voz con ResponseBuilder
:
var finalResponse = ResponseBuilder.Tell("We are done here.");
var openEndedResponse = ResponseBuilder.Ask("Are we done here?");
Usando 'Tell' asignamos ShouldEndSession
el valor true
. Usando 'Ask' asignamos ShouldEndSession
el valor false
. Se debe usar la función apropiada dependiendo si queremos continuar el diálogo o no.
SSML puede ser usada para personalizar la forma en que Alexa habla. A continuación vemos un ejemplo usando SSML con las funciones auxiliares.
// build the speech response
var speech = new SsmlOutputSpeech();
speech.Ssml = "<speak>Today is <say-as interpret-as=\"date\">????0922</say-as>.<break strength=\"x-strong\"/>I hope you have a good day.</speak>";
// create the response using the ResponseBuilder
var finalResponse = ResponseBuilder.Tell(speech);
return finalResponse;
En las respuestas también puedes incluir un 'Card', el cual representa elementos UI (Interfaz gráfica) para Alexa. ResponseBuilder
solo construye 'cards' simples, que contienen un titulo y un texto plano.
// crea la respuesta de habla - 'cards' todavia necesitan respuesta de voz
var speech = new SsmlOutputSpeech();
speech.Ssml = "<speak>Today is <say-as interpret-as=\"date\">????0922</say-as>.</speak>";
// crea la respuesta con card
var finalResponse = ResponseBuilder.TellWithCard(speech, "Your Card Title", "Your card content text goes here, no HTML formatting honored");
return finalResponse;
Si quieres un reprompt (doble aviso) para el usuario, usa la función auxiliar de Ask (Pregunta). Un reprompt puede ser útil si deseas continuar una conversación or si deseas recordar al usuario responder una pregunta.
// create the speech response
var speech = new SsmlOutputSpeech();
speech.Ssml = "<speak>Today is <say-as interpret-as=\"date\">????0922</say-as>.</speak>";
// create the speech reprompt
var repromptMessage = new PlainTextOutputSpeech();
repromptMessage.Text = "Would you like to know what tomorrow is?";
// create the reprompt
var repromptBody = new Reprompt();
repromptBody.OutputSpeech = repromptMessage;
// create the response
var finalResponse = ResponseBuilder.Ask(speech, repromptBody);
return finalResponse;
Si tu skill esta registrado como reproductor de audio, puede enviar alguna de estas directivas (Instrucciones para reproducir, encolar or detener un audio).
// crea una respuesta de habla
string audioUrl = "http://mydomain.com/myaudiofile.mp3";
string audioToken = "a token to describe the audio file";
var audioResponse = ResponseBuilder.AudioPlayerPlay(PlayBehavior.ReplaceAll, audioUrl, audioToken);
return audioResponse
Las variables de sesión son variables que pueden ser guardadas dentro de una respuesta y serán enviadas de ida y de regreso mientras la sesión permanezca abierta.
string speech = "The time is twelve twenty three.";
Session session = input.Session;
if(session.Attributes == null)
session.Attributes = new Dictionary<string, object>();
session.Attributes["real_time"] = DateTime.Now;
return ResponseBuilder.Tell(speech, session);
Session session = input.Session;
DateTime lastTime = session.Attributes["real_time"] as DateTime;
return ResponseBuilder.Tell("The last day you asked was at " + lastTime.DayOfWeek.ToString());
Si no quieres usar las funciones auxiliares Tell/Ask, Puedes construir la respuesta manualmente usando los objetos Response
y IOutputSpeech
. Si quisieras incluir StandardCard
o LinkAccountCard
dentro de la respuesta, puedes hacerlo dentro del cuerpo de la repuesta:
// crea la respuesta de habla
var speech = new SsmlOutputSpeech();
speech.Ssml = "<speak>Today is <say-as interpret-as=\"date\">????0922</say-as>.</speak>";
// crea el doble aviso (reprompt)
var repromptMessage = new PlainTextOutputSpeech();
repromptMessage.Text = "Would you like to know what tomorrow is?";
// crea el objecto del doble aviso (reprompt)
var repromptBody = new Reprompt();
repromptBody.OutputSpeech = repromptMessage;
// crea la respuesta
var responseBody = new ResponseBody();
responseBody.OutputSpeech = speech;
responseBody.ShouldEndSession = false; // esto desencadena el doble aviso
responseBody.Reprompt = repromptBody;
responseBody.Card = new SimpleCard {Title = "Test", Content = "Testing Alexa"};
var skillResponse = new SkillResponse();
skillResponse.Response = responseBody;
skillResponse.Version = "1.0";
return skillResponse;
Tu skill puede enviar respuestas progresivas para mantener al usuario enganchado mientras este prepara la respuesta completa o respuesta final de la petición. A continuación un ejemplo de una respuesta progresiva:
var progressiveResponse = new ProgressiveResponse(skillRequest);
progressiveResponse.SendSpeech("Please wait while I gather your data.");