APIs e Microsserviços

27 jan, 2022

Como criar uma skill para a assistente virtual da Amazon, a Alexa

Publicidade

Se você não sabia, não é necessário ter um dispositivo Amazon Echo para desenvolver skills para sua plataforma, mas caso tenha interesse em adquirir algum, eu tenho a Echo da terceira geração e é sensacional, use este link. É útil para tirar dúvidas rotineiras (inclusive de idiomas), criar lembretes e tocar música, tudo isso apenas por comando de voz. Eventualmente uso para jogos com minha família também.

Outra coisa que talvez você não saiba é que geralmente a criação das skills, que são os “apps” da Alexa, é feita usando os recursos de serverless da AWS, chamado de AWS Lambda e que eu já ensinei a usar em outro tutorial aqui do blog e neste curso. Isso faz muito sentido, já que em 99% do tempo sua Alexa não estará executando essa skill e portanto não faria sentido ter um VPS para esta aplicação. Aqui vamos fazer desta forma e com Node.js, mas saiba que pode usar qualquer tecnologia web que você conheça e que “fale” HTTP.

Mas o que vamos fazer?

Que tal uma skill que permita à Alexa lhe passar a cotação atual de criptomoedas? Bacana, não?

Para isso vamos usar as APIs públicas da Binance, a maior corretora de criptomoedas do mundo e que eu já ensinei a criar bots aqui no blog em outras oportunidades.

Apesar de eu já estar definido o exemplo que vamos fazer, sinta-se livre para adaptar à sua realidade, prometo fazer algo que seja útil e adaptável a outros contexto, diferente dos tutoriais de “olá mundo” genéricos.

As partes deste tutorial são:

  1. Criando o Projeto
  2. Testando o Projeto
  3. Capturando o Input
  4. Consultando API

Caso prefira assistir ao invés de ler, você pode acompanhar todo este tutorial no vídeo abaixo.

#1 – Criando o Projeto

Para conseguir fazer este tutorial você precisará ter uma conta de desenvolvedor na Amazon, que você pode criar gratuitamente neste link. Após criar sua conta você cairá no painel abaixo onde pode criar suas skills, mas não vamos criar por ele, segue comigo.

Que tal instalar a extensão de desenvolvimento para Alexa no VS Code? Assim você pode gerenciar e codificar por ele também. Procure na aba Extensions pela Alexa Skills Kit Toolkit e instale ela.

Após a instalação talvez seja necessário reiniciar o VS Code. Faça isso e uma nova opção vai aparecer na barra lateral, onde você pode clicar para se autenticar na sua conta de AWS Developer que criou há pouco tempo. Repare que uma série de permissões vão ser solicitadas, apenas dê elas se você reconhece que instalou a extensão correta criada pela Amazon, que coloquei o print acima.

Agora use a opção Create Skill e na tela seguinte configure o nome da sua skill (este é o nome público que vai aparecer para os usuários), o idioma, o modelo (custom) e o método de hospedagem, que aqui vamos usar o “Alexa-hosted Node.js”.

Neste método, nós não vamos nos preocupar com a infraestrutura da aplicação por trás da skill e sequer precisaremos de uma conta na AWS. Sequer precisaremos pagar por este serviço, claro que dentro de limites de uso, mas bem generosos na minha opinião. Apenas vamos codar e subir nosso código pra AWS e ela vai se virar para garantir que ele rode toda vez que um usuário chamar a sua skill. Esse é o jeito mais recomendado de criar, apenas ficando o jeito mais complexo para skills muito grandes e/ou muito famosas.

A região de hospedagem é relativamente irrelevante, eu costumo usar N. Virginia e o último campo é o diretório na sua máquina onde o repositório local será criado (o remoto fica na AWS mesmo, em um serviço de git chamado Code Commit). Defina estas últimas configurações e mande criar a sua skill.

O processo de criação leva alguns minutos e quando ele finalizar o projeto estará aberto no VS Code com vários códigos de exemplo em uma pasta lambda.

#2 – Testando o Projeto

Toda vez que você alterar estes fontes e fizer push, seu código será enviado para o servidor e estará disponível em ambiente de desenvolvimento, então pode fazer isso agora. Após o push terminar, volte ao Developer Console e na aba Code conseguirá ver se o build está acontecendo ainda.

Este projeto vem configurado com um olá mundo, então é ele que nós vamos testar primeiro para entender como tudo funciona e posteriormente, modificá-lo. Enquanto que o primeiro build estiver rolando, dê uma olhada no arquivo pt-BR.json que fica dentro de skill-package/interactionModels/custom ou no Developer Console vá na aba Build > Invocations > Skill Invocation Name e veja o comando de invocação da sua skill. No meu caso estava “change me” e troquei para “abrir criptomoedas”. Você pode trocar para qualquer combinação de duas ou mais palavras, mas se fizer pelo VS Code, não esqueça de fazer commit e push. Independente do que decidir, guarde esta frase de invocação.

Depois que o build terminar (caso ele não inicie sozinho após um push, você pode iniciar manualmente o deploy na aba Code do Developer Console), vá na aba Test do Developer Console e selecione o ambiente de desenvolvimento para podermos fazer um teste rápido.

Na coluna da esquerda você tem um chat para interagir com o simulador da Alexa, com o qual você pode enviar mensagens de texto e de voz, e ela lhe responderá por voz e texto também. Experimente digitar (ou falar, segurando o ícone do microfone) a frase de ativação da sua skill e ela será ativada.

Esse comportamento inicial da Alexa, que é disparado toda vez que você fala a frase de invocação é definido pelo LaunchRequestHandler presente no arquivo lambda/index.js. Experimente mudar a string da const speakOutput e fazer novo deploy para ver que a Alexa mudará a frase inicial da skill. Vou trazer a frase para nosso contexto de criptomoedas.

Você vai reparar que depois desta frase de boas vindas que a Alexa diz, ela espera uma resposta sua. Isso é devido ao LaunchIntentHandler possuir aquela chamada de “reprompt” na penúltima linha de código. Enquanto que a função speak informa que a Alexa deve falar algo, a função reprompt indica que ela deve “escutar” uma resposta. Com base nesta resposta a Alexa vai procurar no seu arquivo do Modelo de Interações alguma intenção associada à frase que o usuário acabou de dizer.

Caso ela encontre alguma frase, ela vai disparar o respectivo handler de intenção. Repare abaixo como o handler HelloWorldIntent está preparado para ser disparado com diversas frases (dentro do array samples).

Ou seja, se o usuário disser qualquer uma dessas frases, será disparado o handler de mesmo nome no código do projeto. Além do console web, outra opção que você tem para testar as suas alterações, um pouco mais limitada, é por dentro do próprio VS Code, indo na aba da Alexa e escolhendo a opção “Test Skill”, o que vai abrir um simulador dentro do VS Code que permite apenas input e output de texto.

Entendido o que acontece quando a frase de invocação é dita e como é ativado o intent de olá mundo, vamos alterar nosso modelo de interação para capturar o que o usuário disser.

#3 – Capturando o Input

Seja para enviarmos mensagens ao usuário ou capturarmos respostas dele, tudo passa pelas intenções e as intenções são definidas no modelo de interação. Para criar o modelo de interação você pode editar o arquivo JSON no seu projeto todo manualmente, mas eu prefiro usar o editor visual disponível no Developer Console. Se quiser fazer como eu, vá no Developer Console, na aba Build, menu Interaction Model > Intents. O painel vai lhe listar as intents mapeadas para esta aplicação e recomendo que você selecione a HelloWorld pois vamos modificá-la.

Repare que troquei o nome de HelloWorldIntent para GetCryptoIntent, já que o objetivo dela será capturar a criptomoedas que o usuário quer saber a cotação. Em Sample Utterances, você exclui as existentes e coloca as frases de ativação desta intent, sendo que quando queremos capturar uma parte desta frase, como se fosse uma variável, usamos entre chaves como na imagem acima.

No nosso exemplo, quando a skill for invocada a Alexa vai questionar qual cripto o usuário quer a cotação. Quando ele responder alguma das frases acima, ela vai entender que a intenção é GetCryptoIntent e vai executar um código que vamos definir, usando a variável entre chaves como parâmetro do código.

Adicione quantos samples vocês quiser, quanto mais melhor pois deixa sua skill mais inteligente. No exemplo acima, meu usuário pode falar “cotação do btc”, “valor do eth” ou ainda “preço do mana”. Todas essas são frases válidas e serão entendidas como GetCryptoIntent, sendo que btc/eth/mana serão capturados como sendo variáveis da frase.

O nome técnico destas variáveis da skill é slot, e todo slot é identificado pelo seu nome único e deve ter um tipo definido. Como vamos usar uma string genérica, o tipo recomendado é AMAZON.SearchQuery, como abaixo.

Com essas alterações feitas o nosso interaction model está pronto e devemos voltar nossa atenção ao código, para que consiga lidar com tudo isso que fizemos. A primeira coisa que você deve saber é que quando usamos o editor visual do modelo de interação as alterações não vêm parar no nosso código automaticamente. Ainda pelo editor visual, vá no menu Interaction Model > JSON Editor e copie o código JSON do seu interaction model, usando-o para substituir o conteúdo do arquivo pt-BR.json no seu projeto de skill no VS Code.

Ele deve ficar parecido com abaixo.

Agora temos que ajustar o index.js da nossa lambda, já que alteramos draticamente a HelloWorldIntent, transformando-a em GetCryptoIntent. Temos não apenas de ajustar estes nomes como poderemos capturar o slot {crypto} para usá-lo na lógica da nossa skill. Inicialmente, vamos fazer a Alexa responder a mesma crypto que ela ouviu, só para garantir que estamos capturando o slot corretamente. Mais tarde usaremos esta informação de maneira mais útil.

Ajuste o seu HelloWorldIntentHandler para que fique deste jeito.

No código acima, não mudei apenas o nome do Handler e a condição dentro de canHandle, mas principalmente capturei o slot crypto dentro da lógica handle e alterei a resposta da Alexa para dizer a crypto que ela acabou de ouvir. Um último ajuste é necessário neste arquivo para que ele funcione como esperado.

Bem ao final do mesmo index.js, ajuste o código de exportação para substituir o antigo HelloWorldIntentHandler por GetCryptoIntentHandler.

Uma vez feito isso, commite o código, faça push, aguarde o build finalizar e teste novamente a skill.

#4 – Consultando API

Agora você conseguirá de fato interagir com a Alexa indo na aba Test do Developer Console. Quando a skill iniciar (pelo invocation name), a Alexa vai lhe perguntar qual criptomoeda deseja saber a cotação. Você vai responder usando alguma das sample utterances e ela vai lhe responder confirmando a criptomoeda que você citou, o que indica que conseguiu capturar o slot corretamente.

Mas claro que você não deseja fazer uma skill de “eco”, que repete o que você diz. Você quer que a Alexa use da informação capturada na resposta do usuário para fazer alguma coisa útil, certo?

Pensei aqui que seria muito legal de fato ela consultar alguma API pública e me trazer a cotação atualizada da criptomoeda que o usuário solicitou. Para isso, vamos usar as APIs REST da Binance, a maior corretora de criptomoedas do mundo. Mas não se preocupe, é uma API pública que não exige cadastro e portanto não custa nada. Ainda assim, se quiser substituir por qualquer outra API pública, sinta-se livre para isso.

Mas voltando à API sugerida, cuja documentação você encontra neste link, podemos facilmente consultar o preço médio de um par de moedas usando uma string como abaixo.

Repare no final da URL o par de moedas em letras maiúsculas. É assim que tem de passar e se colar essa URL no navegador verá que ela retorna um objeto JSON com uma informação price, que é o que nos interessa. O que temos de fazer em nosso código é uma chamada HTTP para este endereço, passando a criptomoeda que o usuário informou + USDT (substitua a segunda moeda por BRL caso queira a cotação em Reais).

O primeiro passo para fazer uma request em uma API REST é ter um cliente HTTP na sua aplicação Node.js. Usarei aqui o Axios que é um cliente HTTP muito popular. Para instalar o Axios no seu projeto é muito simples: abra o terminal de linha de comando e navegue com cd até a pasta da lambda. Dentro dela, rode o seguinte comando de instalação.

Uma vez com o Axios instalado, agora abra o index.js e modifique novamente o seu GetCryptoIntentHandler para que faça uma chamada HTTP usando o Axios para a URL que citei antes, pegando o price do retorno e enviando para a Alexa falar a cotação, como abaixo.

No exemplo acima, logo após capturar o slot e guardar na variável crypto, eu carreguei o Axios e disse para ele fazer um HTTP GET para obter o retorno da URL fornecida, onde concateno as maiúsculas de crypto (toUpperCase) com USDT. Como o Axios trabalha com requisições assíncronas, tenho de tratar a Promise retornada com then e catch.

Em caso de sucesso, o código do then será executado e nele eu formato o preço que veio em response.data para ter apenas duas casas decimais, separadas por uma vírgula. Essa informação é usada para montar a frase de resposta da Alexa onde coloquei ainda um cifrão na frente pra ela entender que é um valor monetário.

Em caso de erro eu digo para a Alexa me ler o erro também.

Depois de commitar, fazer push e aguardar o build, o resultado é surpreendente pois a Alexa agora é capaz de responder a cotação de qualquer criptomoedas operada na Binance de maneira rápida e assertiva, e o mais legal: tudo controlado pela sua voz!

Futuramente, caso deseje você pode publicar esta skill na loja da Amazon pelo próprio Developer Console, bastando preencher um formulário. Para usar este skill em produção, você precisará possuir algum dos fantásticos dispositivos Amazon Echo.

Então é isso, espero que tenha gostado deste tutorial e que tenha conseguido implementá-lo na prática, seja à risca ou seguindo as mesmas ideias e mudando o que tiver vontade. Tendo qualquer dúvida, deixa nos comentários ao final deste post e se quiser baixar os fontes, tem um formulário ao final do post também.

Um abraço e sucesso!