Alexa Skills são os "aplicativos" que você pode criar para executar em dispositivos da Amazon, como o Echo, o Echo Dot etc. Nesta postagem do blog, você aprenderá a criar uma habilidade da Alexa usando o Azure Functions sem servidor e um backend do Couchbase em execução no Azure. Esta postagem se baseia em várias postagens de blog que escrevi sobre o Azure Functions, Serverless e Couchbase no Azure no passado:
-
Arquitetura sem servidor com computação em nuvem - O que é sem servidor?
-
Azure Functions e Lazy Initialization com o Couchbase Server - Recomendações ao usar o Couchbase e o Azure Functions juntos
-
Chatbot no Azure e no Couchbase para o Viber - Um caso de uso semelhante a uma habilidade da Alexa
-
Azure: Começar a usar é fácil e gratuito - Como usar o Azure Marketplace para criar facilmente um cluster do Couchbase
Que tipo de habilidades da Alexa estou desenvolvendo?
Trabalho como Developer Advocate, o que significa que frequentemente passo tempo em estandes de patrocinadores em eventos para desenvolvedores. Adoro fazer isso: Posso dizer às pessoas como o Couchbase é excelente e frequentemente recebo feedback dos desenvolvedores sobre os problemas que eles estão tentando resolver com o Couchbase.
No entanto, se há uma coisa que não gosto em trabalhar em um estande é a repetição. Muitas vezes me fazem o mesmo conjunto de perguntas centenas de vezes por evento:
-
O que é o Couchbase? (banco de dados de documentos NoSQL distribuído com uma arquitetura que prioriza a memória)
-
Qual é a diferença entre o Couchbase e o MongoDB? (ambos são bancos de dados de documentos, mas o Couchbase tem grandes diferenças arquitetônicas e de recursos)
-
O Couchbase é a mesma coisa que o CouchDB? (Não.)
Não estou reclamando, veja bem. Só que é difícil ficar entusiasmado ao responder à pergunta pela centésima vez quando a conferência está prestes a ser encerrada.
Mas você sabe quem está sempre entusiasmado? A Alexa! Então, se eu levar meu Echo Dot para o próximo evento, talvez ela possa me ajudar:
-
O que é o Couchbase? - Alexa dirá um fato interessante aleatório sobre o Couchbase
-
Qual é a diferença entre o Couchbase e o MongoDB? Alexa dirá uma diferença aleatória de arquitetura ou de recursos.
-
O Couchbase é a mesma coisa que o CouchDB? Alexa dirá "não".
Se essas habilidades da Alexa se mostrarem úteis, poderei expandi-las posteriormente para responder a perguntas mais complexas.
Se você quiser acompanhar esta postagem e criar suas próprias habilidades com a Alexa, a versão completa O código-fonte está disponível no Github.
Design
As habilidades da Alexa são registradas na Amazon. Na maioria das vezes, elas fazem solicitações HTTP simples para o endpoint que você designou e esperam uma determinada resposta JSON. O Azure Functions pode processar solicitações HTTP. O Azure Functions pode fazer consultas a um banco de dados cheio de respostas e também pode acompanhar quantas vezes cada resposta foi dada.
Abaixo está um diagrama arquitetônico de alto nível do meu projeto de habilidades mínimas viáveis para a Alexa:
Armazenamento e design de dados
A habilidade vai, em última análise, consultar alguns dados do Couchbase Server. Começarei com dois tipos diferentes de documentos. (Se essas habilidades da Alexa se mostrarem úteis, adicionarei coisas mais complexas posteriormente).
Design de documentos
Cada documento representa uma possível resposta. Cada um terá 3 campos:
-
tipo
- Isso será "mongodbcomparison" ou "whatiscouchbase". -
número
- O número de vezes que essa resposta foi usada (começando em 0). -
texto
- O texto que eu quero que as habilidades da Alexa digam.
O design da chave do documento desses documentos não é importante (pelo menos por enquanto), pois usarei apenas consultas N1QL (SQL para JSON) para recuperá-los. No entanto, decidi criar chaves como "mongo::2" e "couchbase::5".
Para começar, armazenarei esses dados em um único nó do Couchbase em uma VM do Azure de baixo custo. Um único nó com uma pequena quantidade de dados deve ser capaz de lidar sem problemas com o tráfego pesado da cabine. Mas se, por exemplo, eu instalasse essas cabines como quiosques em aeroportos de todo o mundo, com certeza precisaria ampliar meu cluster do Couchbase. O Couchbase e o Azure facilitam isso.
Design de consultas
Para obter um documento aleatório, preciso executar uma consulta N1QL:
1 2 3 4 5 |
SELECIONAR m.*, META(m).id DE serviço de inicialização m ONDE m.tipo = 'mongodbcomparison' ORDEM BY UUID() LIMITE 1; |
O UUID está funcionando como um gerador de números aleatórios. Não é bem para isso que ele serve, mas é "bom o suficiente". Se eu realmente precisasse de uma verdadeira aleatoriedade, poderia criar um solicitação curl em N1QL para API do random.org.
Para executar essa consulta, preciso criar um índice para o campo "type":
1 |
CRIAR ÍNDICE ix_type ON serviço de inicialização(tipo); |
Funções do Azure
Para criar uma Função do Azure, usei uma biblioteca .NET existente chamado AlexaSkills.NET, que torna muito fácil escrever o código necessário para criar as habilidades da Alexa.
Depois de criar minha solução do Azure Functions, eu a adicionei com o NuGet.
Usando o AlexaSkills.NET
Em seguida, criei uma classe "speechlet". Optei por tornar meu speechlet assíncrono, mas também existe uma opção síncrona. Há quatro métodos que precisam ser criados. Neste momento, só preciso de dois deles para a habilidade.
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 |
público classe BoothDutySpeechlet : SpeechletBase, ISpeechletWithContextAsync { público assíncrono Tarefa<SpeechletResponse> OnIntentAsync(IntentRequest intentRequest, Sessão sessão, Contexto contexto) { tentar { var intentName = intentRequest.Intenção.Nome; var intentProcessor = IntentProcessor.Criar(intentName); retorno aguardar intentProcessor.Executar(intentRequest); } captura (Exceção ex) { var resp = novo SpeechletResponse(); resp.ShouldEndSession = falso; resp.OutputSpeech = novo PlainTextOutputSpeech() { Texto = ex.Mensagem }; retorno aguardar Tarefa.FromResult(resp); } } público Tarefa<SpeechletResponse> OnLaunchAsync(LaunchRequest launchRequest, Sessão sessão, Contexto contexto) { var resp = novo SpeechletResponse(); resp.ShouldEndSession = falso; resp.OutputSpeech = novo PlainTextOutputSpeech() { Texto = "Bem-vindo ao estande do Couchbase. Pergunte-me sobre o Couchbase." }; retorno Tarefa.FromResult(resp); } público Tarefa OnSessionStartedAsync(SessionStartedRequest sessionStartedRequest, Sessão sessão, Contexto contexto) { retorno Tarefa.Atraso(0); // nada a fazer (ainda) } público Tarefa OnSessionEndedAsync(SessionEndedRequest sessionEndedRequest, Sessão sessão, Contexto contexto) { retorno Tarefa.Atraso(0); // nada a fazer (ainda) } // Só preciso usar isso quando estou testando localmente // public override bool OnRequestValidation(SpeechletRequestValidationResult result, DateTime referenceTimeUtc, // SpeechletRequestEnvelope requestEnvelope) // { // retorna true; // } } |
O OnLaunchAsync
é a primeira coisa que um usuário do Echo alcançará. O usuário dirá algo como "Alexa, abra o ajudante de cabine do Matt", e esse código responderá com algumas instruções básicas.
O OnIntentAsync
é onde a maior parte da solicitação de habilidades da Alexa será processada. Estou usando um padrão de código de fábrica/estratégia aqui para instanciar um objeto diferente, dependendo da intenção que está sendo invocada (mais sobre "intenções" posteriormente).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
público estático IIntentProcessor Criar(string intentName = "FallbackIntent") { interruptor (intentName) { caso "MongodbComparisonIntent": retorno novo MongoDbComparisonIntentProcessor(CouchbaseBucket.GetBucket()); caso "WhatIsCouchbaseIntent": retorno novo WhatIsCouchbaseIntentProcessor(CouchbaseBucket.GetBucket()); caso "CouchDbIntent": retorno novo CouchDbIntentProcessor(); caso "FallbackIntent": retorno novo Processador de intenção de retorno (FallbackIntentProcessor)(); padrão: retorno novo Processador de intenção de retorno (FallbackIntentProcessor)(); } } |
Conexão com o Couchbase
CouchbaseBucket.GetBucket()
está usando Preguiçoso
nos bastidores, conforme descrito em meu postagem anterior do blog sobre o Azure Functions.
Portanto, sempre que uma intenção "O que é o Couchbase" é recebida, uma WhatIsCouchbaseIntentProcessor
é instanciado e executado.
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 |
público classe WhatIsCouchbaseIntentProcessor : BaseIntentProcessor { privado somente leitura IBucket _bucket; público WhatIsCouchbaseIntentProcessor(IBucket balde) { _bucket = balde; } público anular assíncrono Tarefa<SpeechletResponse> Executar(IntentRequest intentRequest) { // obter um fato aleatório do balde var n1ql = @"select m.*, meta(m).id de boothduty m where m.type = 'whatiscouchbase' order by `number`, uuid() limite 1;"; var consulta = Solicitação de consulta.Criar(n1ql); var resultado = aguardar _bucket.QueryAsync<BoothFact>(consulta); se (resultado == nulo || !resultado.Fileiras.Qualquer()) retorno aguardar CreateErrorResponseAsync(); var fato = resultado.Primeiro(); // incrementar a contagem de fatos aguardar _bucket.Mutação<dinâmico>(fato.Id) .Balcão("número", 1) .ExecuteAsync(); // retorna o texto do fato retorno aguardar CreatePlainTextSpeechletReponseAsync(fato.Texto); } } |
Observe o uso da consulta N1QL que foi mencionada anteriormente (ligeiramente ajustada para que os fatos com números mais baixos tenham prioridade). Esse código também está usando o API de subdocumentos do Couchbase para incrementar o campo "number" em 1.
Você pode visualizar o código completo do outros processadores de intenção no Githubmas eles são muito semelhantes (apenas com N1QL ligeiramente diferente).
Conexão com o Azure Functions
Por fim, quando meu speechlet estiver pronto, é fácil conectá-lo a uma Função do Azure.
1 2 3 4 5 6 7 8 9 |
público estático classe BoothDuty { [FunctionName("BoothDuty")] público estático assíncrono Tarefa<HttpResponseMessage> Executar([Acionador http(Nível de autorização.Anônimo, "obter", "post", Rota = nulo)]HttpRequestMessage req, Rastreador registro) { var discurso = novo BoothDutySpeechlet(); retorno aguardar discurso.GetResponseAsync(req); } } |
Agora você pode testar isso localmente com o Postman ou com a interface Alexa após a implantação no Azure.
Criando as habilidades do Alexa
Não vou analisar todo o processo, pois há muita documentação sobre como configurar as habilidades da Alexa. Acho que tenho mais trabalho a fazer antes que minha habilidade seja oficialmente certificada, mas ela é boa o suficiente para testes beta.
Depois de obter o URL do Azure Functions, você o usará com a Alexa. A Alexa exige que as habilidades usem HTTPS, mas, felizmente, o Azure Functions vem com HTTPS em um subdomínio azurewebsites.net. Aqui está uma captura de tela:
Mencionei "intenções" anteriormente. Esses são vários tipos de ações que as habilidades da Alexa podem processar, juntamente com suas entradas. Pense nelas como assinaturas de funções. Atualmente, criei 3 intents e não tenho parâmetros para eles (ainda). Portanto, meu esquema de intenção é uma parte muito simples de JSON:
Para cada intenção, você pode criar "enunciados" que mapeiam as intenções. Essas são as frases que um usuário do Echo falará e a qual intenção elas correspondem.
Tentei pensar em todas as variações diferentes. Mas se eu realmente quisesse que isso funcionasse de forma mais geral, eu configuraria parâmetros para que um usuário pudesse fazer a pergunta "Qual é a diferença entre o Couchbase e {x}".
Echo Dot em ação
Não publiquei esse aplicativo na Alexa Store. Eu o implementei como um "teste beta", portanto, se você quiser experimentá-lo, terei prazer em lhe enviar um convite para obtê-lo.
Aqui está um vídeo em que eu o testei no meu Echo Dot (que foi um alto-falante dado de presente no ano passado pelo pessoal da DevNexus):
[youtube https://www.youtube.com/watch?v=RaYV6jDO8Q8&w=560&h=315]
Isso realmente funcionará em uma cabine barulhenta? Bem, digamos que ainda não estou pronto para levar uma poltrona e um travesseiro para o estande. Mas é uma maneira divertida de demonstrar o poder do Couchbase como um banco de dados de engajamento.
Resumo
As habilidades da Alexa são um ótimo lugar para usar a arquitetura sem servidor, como o Azure Functions. As habilidades serão usadas de forma intermitente, e o Azure Functions cobrará apenas pelo tempo em que forem executadas.
O Couchbase Server é novamente um ótimo banco de dados para esse tipo de aplicativo. Ele pode começar pequeno para lidar com um único estande, mas pode ser dimensionado facilmente para acomodar uma demanda maior.
Tem alguma dúvida sobre o Couchbase? Visite o site Fóruns do Couchbase.
Tem alguma pergunta para mim? Encontre-me em Twitter @mgroves.
Não deixe de conferir todas as excelentes Documentação da Microsoft sobre o Azure Functionse a documentação sobre o Alexa Skills Biblioteca .NET.
Essa é uma postagem de blog incrível - obrigado, Matt! Preciso comprar algum hardware Alexa para brincar.
Obrigado pela leitura. Eu adoraria ver o que mais pode ser feito com o Couchbase em uma habilidade do Alexa.
[...] Habilidades da Alexa com o Azure Functions e o Couchbase [...]