Alexa Skills son las "apps" que puedes crear para ejecutar en dispositivos de Amazon como Echo, Echo Dot, etc. En esta entrada de blog, aprenderás a crear una skill de Alexa utilizando Azure Functions sin servidor y un backend Couchbase ejecutándose en Azure. Esta entrada se basa en un montón de entradas de blog que he escrito sobre Azure Functions, Serverless, y Couchbase en Azure en el pasado:
-
Arquitectura sin servidor con computación en nube - ¿Qué es serverless?
-
Funciones Azure e inicialización perezosa con Couchbase Server - Recomendaciones para el uso conjunto de Couchbase y Azure Functions
-
Chatbot en Azure y Couchbase para Viber - Un caso de uso similar a una habilidad de Alexa
-
Azure: Empezar es fácil y gratis - Cómo utilizar Azure Marketplace para crear fácilmente un clúster de Couchbase
¿Qué tipo de habilidades Alexa estoy construyendo?
Trabajo como Developer Advocate, lo que significa que a menudo paso tiempo en los stands de los patrocinadores en eventos para desarrolladores. Me encanta hacer esto: Puedo decirle a la gente lo bueno que es Couchbase, y a menudo recibo comentarios de los desarrolladores sobre los problemas que están tratando de resolver con Couchbase.
Si hay algo que no me gusta de trabajar en un stand es la repetición. A menudo me hacen las mismas preguntas cientos de veces en cada evento:
-
¿Qué es Couchbase? (base de datos de documentos NoSQL distribuida con una arquitectura que prioriza la memoria)
-
¿En qué se diferencia Couchbase de MongoDB? (ambas son bases de datos documentales, pero Couchbase tiene importantes diferencias en cuanto a características y arquitectura)
-
¿Es lo mismo Couchbase que CouchDB? (No.)
No me quejo. Es sólo que es difícil mostrarse entusiasmado cuando se responde a la pregunta por centésima vez cuando la conferencia está a punto de clausurarse.
¿Pero sabes quién es siempre entusiasta? Alexa. Así que, si llevo mi Echo Dot al próximo evento, quizá pueda ayudarme:
-
¿Qué es Couchbase? - Alexa dirá un hecho interesante al azar sobre Couchbase
-
¿En qué se diferencia Couchbase de MongoDB? Alexa dirá una diferencia arquitectónica o de características aleatoria.
-
¿Es lo mismo Couchbase que CouchDB? Alexa dirá "no".
Si estas habilidades de Alexa resultan útiles, puedo ampliarlas más adelante para responder a preguntas más complejas.
Si quieres seguir el hilo de este post y crear tus propias Alexa skills, la página completa de El código fuente está disponible en Github.
Diseño
Las habilidades de Alexa están registradas en Amazon. En su mayor parte, realizan simples solicitudes HTTP al endpoint que designes y esperan una determinada respuesta JSON. Azure Functions puede procesar peticiones HTTP. Las Azure Functions pueden hacer consultas a una base de datos llena de respuestas, y también pueden realizar un seguimiento de cuántas veces se ha dado cada respuesta.
A continuación se muestra un diagrama de arquitectura de alto nivel de mi proyecto de habilidades mínimas viables de Alexa:

Almacenamiento y diseño de datos
La habilidad en última instancia va a consultar algunos datos de Couchbase Server. Empezaré con 2 tipos diferentes de documentos. (Si estas habilidades de Alexa resultan ser útiles, añadiré cosas más complejas más adelante).
Diseño de documentos
Cada documento representa una posible respuesta. Cada uno tendrá 3 campos:
-
tipo- Será "mongodbcomparison" o "whatiscouchbase". -
número- El número de veces que se ha utilizado esta respuesta (empezando por 0). -
texto- El texto que quiero que digan las habilidades de Alexa.
El diseño de la clave de estos documentos no es importante (al menos no todavía), ya que voy a utilizar sólo consultas N1QL (SQL para JSON) para recuperarlos. Sin embargo, he decidido crear claves como "mongo::2" y "couchbase::5".
Para empezar, almacenaré estos datos en un único nodo Couchbase en una VM Azure de bajo coste. Un solo nodo con una pequeña cantidad de datos debería ser capaz de manejar incluso el tráfico pesado de la cabina sin problemas. Pero si, por ejemplo, instalara estos quioscos en aeropuertos de todo el mundo, definitivamente necesitaría escalar mi clúster de Couchbase. Couchbase y Azure lo hacen fácil.
Diseño de consultas
Para obtener un documento aleatorio, necesito ejecutar una consulta N1QL:
|
1 2 3 4 5 |
SELECT m.*, META(m).id FROM boothduty m WHERE m.type = 'mongodbcomparison' ORDER BY UUID() LIMIT 1; |
UUID funciona como un generador de números aleatorios. No es realmente para eso, pero es "suficientemente bueno". Si realmente necesitara verdadera aleatoriedad, podría hacer un solicitud curl en N1QL a API de random.org.
Para ejecutar esa consulta, necesito crear un índice para el campo "tipo":
|
1 |
CREATE INDEX ix_type ON boothduty(type); |
Funciones Azure
Para crear una función Azure, utilicé una biblioteca .NET existente llamado AlexaSkills.NET, que facilita enormemente la escritura del código necesario para crear habilidades de Alexa.
Después de crear mi solución Azure Functions, la añadí con NuGet.
Utilización de AlexaSkills.NET
A continuación, he creado una clase "speechlet". Elegí hacer mi speechlet asíncrono, pero también existe una opción síncrona. Hay cuatro métodos que necesitan ser creados. Sólo necesito dos de ellos para la habilidad en este punto.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
public class BoothDutySpeechlet : SpeechletBase, ISpeechletWithContextAsync { public async Task<SpeechletResponse> OnIntentAsync(IntentRequest intentRequest, Session session, Context context) { try { var intentName = intentRequest.Intent.Name; var intentProcessor = IntentProcessor.Create(intentName); return await intentProcessor.Execute(intentRequest); } catch (Exception ex) { var resp = new SpeechletResponse(); resp.ShouldEndSession = false; resp.OutputSpeech = new PlainTextOutputSpeech() { Text = ex.Message }; return await Task.FromResult(resp); } } public Task<SpeechletResponse> OnLaunchAsync(LaunchRequest launchRequest, Session session, Context context) { var resp = new SpeechletResponse(); resp.ShouldEndSession = false; resp.OutputSpeech = new PlainTextOutputSpeech() { Text = "Welcome to the Couchbase booth. Ask me about Couchbase." }; return Task.FromResult(resp); } public Task OnSessionStartedAsync(SessionStartedRequest sessionStartedRequest, Session session, Context context) { return Task.Delay(0); // nothing to do (yet) } public Task OnSessionEndedAsync(SessionEndedRequest sessionEndedRequest, Session session, Context context) { return Task.Delay(0); // nothing to do (yet) } // I only need to use this when I'm testing locally // public override bool OnRequestValidation(SpeechletRequestValidationResult result, DateTime referenceTimeUtc, // SpeechletRequestEnvelope requestEnvelope) // { // return true; // } } |
En OnLaunchAsync es lo primero a lo que llegará un usuario de Echo. El usuario dirá algo como "Alexa, abre el ayudante de cabina de Matt", y este código responderá con algunas instrucciones básicas.
En OnIntentAsync es donde la mayoría de las peticiones de Alexa skills serán procesadas. Estoy usando un patrón de código de fábrica/estrategia aquí para instanciar un objeto diferente dependiendo de qué intención se está invocando (más sobre "intenciones" más adelante).
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
public static IIntentProcessor Create(string intentName = "FallbackIntent") { switch (intentName) { case "MongodbComparisonIntent": return new MongoDbComparisonIntentProcessor(CouchbaseBucket.GetBucket()); case "WhatIsCouchbaseIntent": return new WhatIsCouchbaseIntentProcessor(CouchbaseBucket.GetBucket()); case "CouchDbIntent": return new CouchDbIntentProcessor(); case "FallbackIntent": return new FallbackIntentProcessor(); default: return new FallbackIntentProcessor(); } } |
Conexión a Couchbase
CouchbaseBucket.GetBucket() está utilizando Perezoso entre bastidores, como se indica en mi entrada anterior sobre Azure Functions.
Por lo tanto, cada vez que se recibe un intento de "¿Qué es Couchbase? WhatIsCouchbaseIntentProcessor es instanciado y ejecutado.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
public class WhatIsCouchbaseIntentProcessor : BaseIntentProcessor { private readonly IBucket _bucket; public WhatIsCouchbaseIntentProcessor(IBucket bucket) { _bucket = bucket; } public override async Task<SpeechletResponse> Execute(IntentRequest intentRequest) { // get random fact from bucket var n1ql = @"select m.*, meta(m).id from boothduty m where m.type = 'whatiscouchbase' order by `number`, uuid() limit 1;"; var query = QueryRequest.Create(n1ql); var result = await _bucket.QueryAsync<BoothFact>(query); if (result == null || !result.Rows.Any()) return await CreateErrorResponseAsync(); var fact = result.First(); // increment fact count await _bucket.MutateIn<dynamic>(fact.Id) .Counter("number", 1) .ExecuteAsync(); // return text of fact return await CreatePlainTextSpeechletReponseAsync(fact.Text); } } |
Observe el uso de la consulta N1QL mencionada anteriormente (ligeramente modificada para que los hechos con números más bajos tengan prioridad). Este código también utiliza el método API de subdocumentos de Couchbase para incrementar el campo "número" en 1.
Puede consultar el código completo del otros procesadores de intenciones en Githubpero son muy similares (sólo que con un N1QL ligeramente diferente).
Conexión a Azure Functions
Por último, una vez que mi speechlet está listo, es fácil de conectar a una función de Azure.
|
1 2 3 4 5 6 7 8 9 |
public static class BoothDuty { [FunctionName("BoothDuty")] public static async Task<HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)]HttpRequestMessage req, TraceWriter log) { var speechlet = new BoothDutySpeechlet(); return await speechlet.GetResponseAsync(req); } } |
Ahora puedes probar esto localmente con Postman, o con la interfaz Alexa una vez que despliegues en azure.
Crear las habilidades de Alexa
No voy a pasar por todo el proceso, ya que hay un montón de documentación sobre cómo configurar las habilidades de Alexa. Creo que tengo más trabajo que hacer antes de que mi habilidad esté oficialmente certificada, pero es lo suficientemente buena para las pruebas beta.
Una vez que tengas la URL de Azure Functions, la usarás con Alexa. Alexa requiere que las habilidades usen HTTPS, pero afortunadamente Azure Functions viene con HTTPS en un subdominio azurewebsites.net. Aquí tienes una captura de pantalla:

Antes he mencionado las "intenciones". Son varios tipos de acciones que las habilidades de Alexa pueden procesar, junto con sus entradas. Piensa en ellos como firmas de función. Actualmente, he diseñado 3 intents, y no tengo parámetros en estos (todavía). Así que mi esquema de intención es una pieza muy simple de JSON:

Para cada intención, puedes crear "expresiones" que se correspondan con las intenciones. Estas son las frases que un usuario de Echo pronunciará, y a qué intención corresponden.

He intentado pensar en todas las diferentes variaciones. Pero si realmente quisiera que esto funcionara de forma más general, configuraría parámetros para que un usuario pudiera hacer la pregunta "¿Cuál es la diferencia entre Couchbase y {x}".
Echo Dot en acción
No he publicado esto en la tienda de Alexa. Lo hice desplegar como una "prueba beta", así que si quieres probarlo, yo estaría encantado de enviarle una invitación para conseguirlo.
Aquí hay un video de mi probarlo en mi Echo Dot (que fue un regalo de altavoz el año pasado de la gente fina en DevNexus):
[youtube https://www.youtube.com/watch?v=RaYV6jDO8Q8&w=560&h=315]
¿Funcionará realmente en una cabina ruidosa? Bueno, digamos que todavía no estoy preparado para llevar un sillón y una almohada a la cabina. Pero es una forma divertida de demostrar el poder de Couchbase como base de datos de compromiso.
Resumen
Las habilidades de Alexa son un gran lugar para utilizar la arquitectura sin servidor como Azure Functions. Las habilidades se utilizarán de forma intermitente, y Azure Functions solo te facturará por el tiempo que se ejecuten.
Couchbase Server es una base de datos ideal para este tipo de aplicaciones. Puede empezar siendo pequeña para gestionar un único puesto, pero puede escalarse fácilmente para adaptarse a una demanda mayor.
¿Tiene alguna pregunta sobre Couchbase? Visite la página Foros de Couchbase.
¿Tiene alguna pregunta? Encuéntrame en Twitter @mgroves.
No se pierda las magníficas documentación de Microsoft sobre Azure Functionsy la documentación sobre las Alexa Skills Biblioteca .NET.
Es una entrada de blog impresionante - ¡gracias, Matt! Tengo que conseguir un poco de hardware Alexa para jugar.
Gracias por leernos. Me encantaría ver qué más se puede hacer con Couchbase en una habilidad de Alexa.
[...] Alexa Skills con Azure Functions y Couchbase [...]