Tendo um feliz, nerd Natal … criando uma habilidade Alexa com ASP.Net Web API

Zona Blocked Desbloquear Seguir Seguindo 4 de janeiro de 2017

Graças à generosidade do Papai Noel e ao novo assistente de voz da Amazon, nosso chefe de desenvolvimento em .NET, Andy Butland, não precisa mais se perguntar o que sua filha está fazendo amanhã …

Amazon Echo Dot

Junto com, eu suspeito, muitas outras pessoas, um dos presentes de Natal que eu mais me diverti com esse ano foi um Amazon Echo Dot .

Fora da caixa vem com um número de recursos ativados por voz, como responder a perguntas, fornecer alarmes e temporizadores e até mesmo responder de maneira espirituosa quando você pergunta coisas como “quem é o mais justo de todos”. É extensível com uma ampla gama de habilidades , fornecidas por vários terceiros. E você pode escrever o seu próprio, que é o que eu tinha um olhar sobre o Boxing Day.

A habilidade que eu construí não era útil para muitas pessoas, então não é pública, mas será uma adição útil para a nossa casa. Quando minha filha almoça na escola, é útil saber o que ela teve ou ter, para que possamos planejar o que cozinhar para a refeição da noite. A escola tem um menu rolante de quatro semanas, então, mesmo com uma cópia no papel, é necessário um pouco de cálculo para descobrir o que ela está tendo em um determinado dia. Eu queria poder fazer perguntas parecidas com “Alexa, perguntar ao 'Menu Escolar' o que eles estão comendo amanhã” e obter uma resposta descrevendo o cardápio daquele dia.

Efetivamente, a habilidade é implementada como um serviço da Web – um terminal HTTPS que retorna uma resposta JSON especificamente estruturada. O Echo Dot digitaliza a mensagem de voz recebida e a transmite para o serviço Alexa da Amazon, que analisa a mensagem para descobrir como responder à pergunta. Se um "nome de invocação" for fornecido – no meu caso, "menu da escola" – ele procura por uma habilidade personalizada ou de terceiros associada à conta de usuários para enviar a solicitação, traduzindo a mensagem de voz em uma solicitação HTTPS apropriada para a Web serviço. Em seguida, o serviço da Web responde com uma resposta em texto, que é traduzida de volta para voz e enviada de volta através do interlocutor Echo Dot.

O código para a habilidade descrita neste artigo está no Github e usa ASP.Net Web API.

Implementando a lógica do menu

Deixando de lado a integração de voz para começar, o primeiro desafio foi implementar a lógica para descobrir o cardápio do almoço de um dia. Para os dados de origem, criei um arquivo JSON contendo uma estrutura com a data inicial do menu rolante, junto com o menu para cada dia das quatro semanas. Dado Alexa não pode (ainda) falar italiano, eu também traduzi o menu para o Inglês.

Um par complementar de classes também foi criado em C #, cujas instâncias seriam mantidas na memória assim que os dados fossem carregados do arquivo JSON:

Para essas classes de modelo adicionei algum comportamento, em primeiro lugar para criar a mensagem descrevendo o menu para um determinado dia ( DateTimeProvider é um invólucro simples em torno de System.DateTime , para que eu possa conectar datas conhecidas ao testar unidades):

E em segundo lugar para descobrir, para uma determinada data após a primeira data do menu, qual menu é para o almoço:

Criando a habilidade

Para expor essa lógica como algo com o qual o serviço Alexa pode interagir, fiz uso da biblioteca .Net do Alexa Skill Kit, que é de código aberto no GitHub e pode ser adicionada ao projeto como um pacote NuGet . Esta biblioteca fornece uma classe base chamada Speechlet da qual você deriva para implementar seu serviço controlado por voz.

Existem quatro métodos que podem ser substituídos, para os quais, para os meus propósitos, eu só precisava me preocupar com dois. A primeira é uma resposta simples para quando alguém “abre” a sua aplicação – através de um comando de voz semelhante ao “Alexa, abra o 'Menu da Escola'” . No meu caso, isso simplesmente retorna uma mensagem instrutiva.

O segundo método – OnIntentAsync – é chamado quando uma instrução específica é recebida. Semelhante ao Luis Framework que estive examinando com o Microsoft Bot Framework , há duas informações importantes que precisam ser analisadas pelo usuário. Uma é a intenção – o pedido específico que estão fazendo, no meu caso, sendo apenas um "diga-me o menu" . E o segundo é um ou mais slots – informações adicionais que definem o pedido. Novamente nesta aplicação, há apenas um deles, a data . Com a intenção e o slot analisados, posso carregar o menu se ainda não estiver na memória, delegar ao modelo para obter uma descrição do menu para a data e retorná-lo como a resposta.

A última parte do código é expor o discurso como um ponto de extremidade da API, que é feito por meio de um simples controlador de API que chama a classe speechlet:

Testando a habilidade

Embora a lógica principal do aplicativo possa ser facilmente testada, quando se trata de partes com dependências de solicitações da Web recebidas do Alexa, as coisas são um pouco mais complicadas. A razão para isso é que, pelo menos sem uma configuração bastante complexa , não é possível para o serviço Alexa fazer uma solicitação HTTPS em um aplicativo em execução no meu laptop, no host local. Embora seja possível publicar o serviço em um ponto de extremidade disponível publicamente, esse não é um excelente fluxo de trabalho, pois é necessária uma implantação completa para testar as alterações.

Para contornar isso, seguindo uma dica que peguei em um encontro recente em Londres , usei o Ngrok . Uma vez baixado, esta ferramenta útil pode ser executada com um comando semelhante ao seguinte para criar uma URL pública que se conecta ao aplicativo em execução localmente e, assim, expor o aplicativo em uma URL temporária, como https://a2245b14.ngrok.io/api / menu .

 cd C:  Arquivos de programas  Ngrok  
ngrok http 4173 -host-header = ”localhost: 4173"

Registrando a habilidade

Para registrar a habilidade com o Alexa e testá-lo de ponta a ponta, configure-o no portal do desenvolvedor da Amazon . Existem alguns passos envolvidos aqui. Em primeiro lugar, o tipo de habilidade é escolhido – para um serviço da Web como este, "Custom Interaction Model" é a opção escolhida. Você então seleciona o idioma e escolhe um nome para a habilidade e sua palavra de invocação (no meu caso, ambos eram “Menu Escolar”).

Em seguida, você deve fornecer uma estrutura JSON descrevendo as intenções e slots disponíveis que o aplicativo suporta, que se parece com isso:

E algumas declarações de amostra que os usuários usarão para acessar a habilidade:

 MenuForDateIntent qual é o menu para {Date} 
MenuForDateIntent qual foi o menu para {Date}
MenuForDateIntent o que eles estão comendo em {Date}
MenuForDateIntent o que eles estavam comendo em {Date}
MenuForDateIntent o que eles estão comendo? {Date}
MenuForDateIntent o que eles estavam comendo {Date}

Por fim, forneça o URL para o serviço de habilidades e indique o tipo de certificado SSL em vigor (para Ngrok e para o meu destino final do Azure, “Escolher Meu nó de extremidade de desenvolvimento é um subdomínio de um domínio que possui um certificado curinga de um autoridade de certificação ” é a opção a escolher). Há uma opção para usar o Amazon Lamda também.

Implantando

Uma vez que o teste foi concluído, eu poderia desligar o URL temporário gerado pelo Ngrok e enviar o serviço para o Azure, usando um App Api. O endereço azure padrão vem com suporte a HTTPS, então, para algo com baixo tráfego como esse, é um lugar barato e fácil para hospedar o serviço.

Com isso, vamos ao ar no início do novo mandato, em 9 de janeiro, e esperamos que esses dias de porções duplas de risoto tenham terminado para sempre!