<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Paulo Guilherme </title>
    <description>The latest articles on DEV Community by Paulo Guilherme  (@mrmorales).</description>
    <link>https://dev.to/mrmorales</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F881731%2F10ead3f5-1e27-416f-a672-5a762af50d81.jpeg</url>
      <title>DEV Community: Paulo Guilherme </title>
      <link>https://dev.to/mrmorales</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mrmorales"/>
    <language>en</language>
    <item>
      <title>Grafana k6 - usando JS para testes de carga</title>
      <dc:creator>Paulo Guilherme </dc:creator>
      <pubDate>Mon, 22 Aug 2022 01:51:00 +0000</pubDate>
      <link>https://dev.to/mrmorales/grafana-k6-usando-js-para-testes-de-carga-lle</link>
      <guid>https://dev.to/mrmorales/grafana-k6-usando-js-para-testes-de-carga-lle</guid>
      <description>&lt;p&gt;Atualmente uma das melhores maneiras de testar e simular o comportamento da sua API em mar aberto é com testes de carga.&lt;/p&gt;

&lt;p&gt;Várias ferramentas estão disponíveis na nossa comunidade &lt;a href="https://jmeter.apache.org" rel="noopener noreferrer"&gt;JMeter&lt;/a&gt;, &lt;a href="https://katalon.com" rel="noopener noreferrer"&gt;Katalon&lt;/a&gt;, &lt;a href="https://www.postman.com" rel="noopener noreferrer"&gt;Postman&lt;/a&gt; são algumas das principais.&lt;/p&gt;

&lt;p&gt;Vamos falar de uma ferramenta especial nesse artigo, ela é fácil, &lt;em&gt;open source&lt;/em&gt; e muito simples de configurar.&lt;/p&gt;

&lt;p&gt;Se até pro espaço nosso querido JavaScript já foi... Claro que vamos ter ele por aqui quando o assunto é &lt;strong&gt;teste de carga&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1561509981941284864-515" src="https://platform.twitter.com/embed/Tweet.html?id=1561509981941284864"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1561509981941284864-515');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1561509981941284864&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;- Ladies and gentlemen i present you k6!&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;



&lt;h2&gt;
  
  
  k6
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffr6yi9t6iu0mdaty4a55.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffr6yi9t6iu0mdaty4a55.png" alt="logotipo k6"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://k6.io" rel="noopener noreferrer"&gt;k6&lt;/a&gt; é uma ferramenta &lt;em&gt;open source&lt;/em&gt; desenvolvido pelo time do Grafana Labs, focada em realização de testes de carga orientado a objetivos.&lt;/p&gt;

&lt;p&gt;Usando o k6, você pode testar a confiabilidade e o desempenho de seus sistemas e detectar regressões e problemas de desempenho mais cedo. &lt;/p&gt;
&lt;h3&gt;
  
  
  How it works
&lt;/h3&gt;

&lt;p&gt;k6 trabalha com o conceito de usuários virtuais (VUs) que executam scripts. Eles são essencialmente loops &lt;code&gt;while(true)&lt;/code&gt; paralelos.&lt;/p&gt;

&lt;p&gt;Os scripts devem conter, no mínimo, uma função padrão exportada - isso define o ponto de entrada para suas VUs, semelhante à função &lt;code&gt;main()&lt;/code&gt; em várias linguagens.&lt;/p&gt;

&lt;p&gt;Para cada bateria de teste é necessário especificar quantos &lt;strong&gt;&lt;em&gt;VUs&lt;/em&gt;&lt;/strong&gt; serão utilizados além dos &lt;strong&gt;&lt;em&gt;scripts&lt;/em&gt;&lt;/strong&gt; que executaram as chamadas e suas regras.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;em&gt;scripts&lt;/em&gt;&lt;/strong&gt; - escritos em JavaScript devem exportar uma função &lt;em&gt;default&lt;/em&gt; que servirá como &lt;em&gt;main&lt;/em&gt; para a bateria de testes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;em&gt;VUs&lt;/em&gt;&lt;/strong&gt; - ou &lt;em&gt;virtual users&lt;/em&gt; são usuários gerados pelo k6 em tempo de execução que farão requisicões HTTP em &lt;em&gt;looping&lt;/em&gt; durante todo o tempo da bateria de testes.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Key features
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;CLI&lt;/strong&gt; com APIs amigáveis ​​ao desenvolvedor.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;JavaScript ES2015/ES6&lt;/strong&gt; - com suporte para módulos locais e remotos&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Checks e Thresholds&lt;/strong&gt; - para testes de carga orientados para objetivos e fáceis de automatizar&lt;/li&gt;
&lt;/ul&gt;



&lt;h2&gt;
  
  
  Hands on
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fc.tenor.com%2FruSOhVUzF_oAAAAd%2Fhackerman.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fc.tenor.com%2FruSOhVUzF_oAAAAd%2Fhackerman.gif" alt="hackerman"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Uma das características principais do k6 é que ele possui uma alta integração com diversos serviços de &lt;em&gt;cloud&lt;/em&gt; e &lt;em&gt;observability&lt;/em&gt; do mercado.&lt;/p&gt;

&lt;p&gt;Para esse artigo vamos utilizar alguma delas, são elas: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Grafana Dashboards&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Influx DB&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Docker&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;recomendo fortemente a leitura da documentação oficial do &lt;a href="https://k6.io/docs/" rel="noopener noreferrer"&gt;k6&lt;/a&gt; que além de muito abrangente é recheada de exemplos de demonstrações de utilização.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  Let's code
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwrfb3a34yboyv79pjftd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwrfb3a34yboyv79pjftd.png" alt="arquitetura"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A imagem acima demonstra como vamos estruturar nosso projeto, com a ajuda do Docker vamos preparar um ambiente que nos fornecerá toda a infraestrutura necessária e também recursos para a visualização dos resultados em tempo real.&lt;/p&gt;

&lt;p&gt;Todo o código desenvolvido para esse artigo foi &lt;strong&gt;publicado em meu GitHub&lt;/strong&gt; e poderá ser acessado nesse &lt;a href="https://github.com/pgsilva/k6-load-test" rel="noopener noreferrer"&gt;repositório&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  O que vamos testar?
&lt;/h3&gt;

&lt;p&gt;Durante esse artigo vamos fazer uma bateria de testes usando a API pública &lt;a href="https://swapi.dev" rel="noopener noreferrer"&gt;The Star Wars API&lt;/a&gt; como &lt;em&gt;backend&lt;/em&gt; e simularemos alguns cenários usando o k6 e acompanharemos via &lt;em&gt;dashboard&lt;/em&gt; todas as requisições  realizadas e suas métricas publicadas.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;app.js&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;k6/http&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;check&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;sleep&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;k6&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="cm"&gt;/** 
 * etapas do nosso teste:
 * os primeiros 30 segundos teremos um aumento de 0 a 20 usuarios acessando a api
 * em seguida um periodo de 1m e 30s com o pico de 20 usuarios fazendo requisicoes em loop infinito
 * depois gradativamente os usuarios vao deixar de acessar a api de 20 até chegarem a 0 em 20 segundos
 * **/&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;stages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;duration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;30s&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;duration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1m30s&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;duration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;20s&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;floor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`http://swapi.dev/api/people/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;

    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`calling [&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;]`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;//requisicao&lt;/span&gt;

    &lt;span class="nf"&gt;check&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;status is 200&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="c1"&gt;//validacao se ocorreu tudo certo&lt;/span&gt;
    &lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;//intervalo entre as chamadas&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;nesse cenário estamos fazendo pouquíssimas requisições (em média é realizada aproximadamente 200 requisições em 2m 20s) mas em um cenário com mais de 200 VUs conseguimos chegar a 150 req/segundo e um total de aproximadamente 2000 em 5 minutos.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Fica o convite para fazer um teste mais parrudo e ver como o k6 se sai. 😎&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;para os demais arquivos de configuração do &lt;em&gt;dashboard&lt;/em&gt; sugiro utilizar as métricas mais convenientes para o cenário especifico, nesse artigo acabei expondo todas.&lt;/p&gt;
&lt;/blockquote&gt;



&lt;h2&gt;
  
  
  Run
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker compose up &lt;span class="nt"&gt;-d&lt;/span&gt; influxdb grafana
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Vamos primeiro subir os contêineres que utilizaremos para a visualização dos resultados.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker compose run k6
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Executando o &lt;code&gt;run&lt;/code&gt; vamos começar a visualizar as primeiras chamadas sendo realizadas para a API.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.giphy.com%2Fmedia%2FhuJmPXfeir5JlpPAx0%2Fgiphy.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.giphy.com%2Fmedia%2FhuJmPXfeir5JlpPAx0%2Fgiphy.webp" alt="gif its happening"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Podemos visualizar em &lt;em&gt;runtime&lt;/em&gt; a execução na url &lt;a href="http://localhost:3000/d/k6/k6-load-testing-results" rel="noopener noreferrer"&gt;http://localhost:3000/d/k6/k6-load-testing-results&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5zzb59ww4ctfxfaokgbo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5zzb59ww4ctfxfaokgbo.png" alt="resultados do teste"&gt;&lt;/a&gt;&lt;/p&gt;



&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Com certeza k6 é uma excelente ferramenta para testes de performance uma ótima opção para substituir o JMeter por exemplo.&lt;/p&gt;

&lt;p&gt;Com uma série de integrações disponíveis e a facilidade de escrever cenários, regras e validações a etapa de testes de carga que normalmente é custosa e demorada consegue ser muito mais rápida e iterativa com o time.&lt;/p&gt;

&lt;p&gt;Não pense que a utilização de JavaScript faz o k6 ter uma performance inferior aos demais, sua performance é excelente e ficará limitada apenas a &lt;em&gt;hardware&lt;/em&gt; e conexão disponíveis com a opção até mesmo de ser executado em &lt;em&gt;clusteres&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Com a possibilidade de escrevermos &lt;em&gt;scripts&lt;/em&gt; com limites e regras de aceitação, além da possibilidade de gerarmos lógicas e manipulação de variáveis durante os testes fica bem difícil não querer experimentar um pouco dessa ferramenta.&lt;/p&gt;

&lt;p&gt;Recomendo fortemente a utilização do k6 para testes de carga, stress e performance e recomendo também a leitura da documentação oficial.&lt;/p&gt;

</description>
      <category>testing</category>
      <category>javascript</category>
      <category>tutorial</category>
      <category>k6</category>
    </item>
    <item>
      <title>Serverless e Alexa - personalizando sua assistente pessoal</title>
      <dc:creator>Paulo Guilherme </dc:creator>
      <pubDate>Sun, 26 Jun 2022 08:01:18 +0000</pubDate>
      <link>https://dev.to/mrmorales/serverless-e-alexa-personalizando-sua-assistente-pessoal-1fa6</link>
      <guid>https://dev.to/mrmorales/serverless-e-alexa-personalizando-sua-assistente-pessoal-1fa6</guid>
      <description>&lt;p&gt;&lt;em&gt;"Alexa o que iremos fazer hoje?"&lt;/em&gt;&lt;br&gt;
 &lt;strong&gt;&lt;em&gt;"-Vamos desenvolver nossa própria skill usando Nodejs e AWS Lambda!"&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As assistentes pessoais já fazem parte dos nossos dias, com suas inúmeras utilidades e possibilidades a &lt;a href="https://www.amazon.com.br/b?ie=UTF8&amp;amp;node=19949683011"&gt;Alexa&lt;/a&gt; tem se tornado a queridinha das assistentes.&lt;/p&gt;

&lt;p&gt;Quer aprender como desenvolver sua própria &lt;a href="https://www.amazon.com.br/b?ie=UTF8&amp;amp;node=17938238011"&gt;Skill&lt;/a&gt; e ter a Alexa um pouquinho mais com a sua cara?&lt;br&gt;
Então vem comigo, que vou mostrar um pouco como foi minha experiência desenvolvendo com a Alexa.😉&lt;/p&gt;
&lt;h2&gt;
  
  
  Antes de começarmos ...
&lt;/h2&gt;

&lt;p&gt;Todo comando que fazemos para Alexa é dividido em pequenas partes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--WgC7qlcA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ll2neuza8itsh66jtfxi.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WgC7qlcA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ll2neuza8itsh66jtfxi.jpg" alt="diagrama exibindo o fluxo de comando da alexa" width="880" height="349"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;intent&lt;/em&gt;&lt;/strong&gt;: Comando de voz.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;utterances&lt;/em&gt;&lt;/strong&gt;: Enunciado que identifica a sua intenção.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;slots&lt;/em&gt;&lt;/strong&gt;: Valor do comando que será enviado para API.&lt;/p&gt;

&lt;p&gt;A Alexa funciona dentro de uma arquitetura serverless, então para termos nossa própria &lt;em&gt;skill&lt;/em&gt; vamos precisar de uma &lt;em&gt;function&lt;/em&gt; &lt;a href="https://aws.amazon.com/pt/lambda/"&gt;AWS Lambda&lt;/a&gt; e podemos aproveitar do &lt;a href="https://aws.amazon.com/pt/free/?all-free-tier.sort-by=item.additionalFields.SortRank&amp;amp;all-free-tier.sort-order=asc&amp;amp;awsf.Free%20Tier%20Types=*all&amp;amp;awsf.Free%20Tier%20Categories=*all"&gt;Free Tier&lt;/a&gt; da AWS para desenvolver e hospedar a nossa funçãozinha. 😎&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--H7it9qpa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/be4hbstefmrnhhln6gpw.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--H7it9qpa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/be4hbstefmrnhhln6gpw.jpg" alt="alexa cloud system" width="880" height="499"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O diagrama acima exemplifica bem como vai funcionar todo o fluxo saindo do usuário até a execução da &lt;em&gt;lambda&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--iYUIBLw6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/skhuuct28xcu4x95qsrd.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--iYUIBLw6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/skhuuct28xcu4x95qsrd.gif" alt="jin carry digitando super rápido" width="220" height="132"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Show me the code
&lt;/h2&gt;

&lt;p&gt;Chega de conversa e vamos para o código, para esse tutorial vamos desenvolver uma &lt;em&gt;skill&lt;/em&gt; que nos responda com um ensinamento aleatório do nosso querido Mestre Yoda. &lt;/p&gt;

&lt;p&gt;O código dessa solução está disponível no Github, clique no &lt;a href="https://github.com/pgsilva/function-ensinamentos-yoda"&gt;link do repositório&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--goaQPq1A--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l1hzw8lwkeikntta0di5.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--goaQPq1A--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l1hzw8lwkeikntta0di5.gif" alt="Mestre Yoda - Star Wars" width="450" height="192"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Vamos usar o &lt;em&gt;framework&lt;/em&gt; &lt;a href="https://www.serverless.com"&gt;Serverles&lt;/a&gt; para nos ajudar nessa missão.&lt;br&gt;
Com ele vamos conseguir atualizar e fazer o &lt;em&gt;deploy&lt;/em&gt; da &lt;em&gt;lambda&lt;/em&gt; que será executada sempre que falarmos com a Alexa.&lt;/p&gt;
&lt;h3&gt;
  
  
  Ingredientes
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Nodejs 12.x&lt;/li&gt;
&lt;li&gt;NPM&lt;/li&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/pt/console/"&gt;AWS account&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Alexa Echo Dot&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.amazon.com"&gt;Alexa developer Amazon account&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Com todos os ingredientes no balcão e as contas devidamente criadas vamos ao modo de preparo.&lt;/p&gt;
&lt;h3&gt;
  
  
  Criando o projeto
&lt;/h3&gt;

&lt;p&gt;Vamos começar fazendo o &lt;em&gt;download&lt;/em&gt; das ferramentas que vamos utilizar.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; serverless
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Depois de instalado vamos criar uma pasta e rodar o seguinte comando.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;serverless create &lt;span class="nt"&gt;--name&lt;/span&gt; ensinamentos-yoda &lt;span class="nt"&gt;--template&lt;/span&gt; aws-nodejs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Vale lembrar que o serverless utiliza as configurações e o usuário configurado no &lt;a href="https://aws.amazon.com/pt/cli/"&gt;AWS CLI&lt;/a&gt;, caso não tenha baixado é super fácil existem vários exemplos na documentação oficial ou na nossa comunidade.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;O &lt;em&gt;framework&lt;/em&gt; Serverless tem uma variedade de &lt;em&gt;plugins&lt;/em&gt; para nos ajudar durante o desenvolvimento, nessa missão vamos precisar do &lt;a href="https://www.serverless.com/plugins/serverless-alexa-skills"&gt;serverless-alexa-skills&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;serverless plugin &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--name&lt;/span&gt; serverless-alexa-skills
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Pronto!&lt;/strong&gt; temos nosso projeto, repare na estrutura criada, temos um arquivo chamado &lt;code&gt;serverless.yml&lt;/code&gt; e outro &lt;code&gt;handler.js&lt;/code&gt; esses carinhas merecem uma atenção especial por que são os responsáveis por toda a execução da nossa &lt;em&gt;lambda&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;handler.js&lt;/strong&gt; - contém a função &lt;em&gt;main&lt;/em&gt; que será chamada sempre que a &lt;em&gt;lambda&lt;/em&gt; for disparada. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;serverless.yml&lt;/strong&gt; - arquivo de configuração responsável por toda estrutura, &lt;em&gt;plugins&lt;/em&gt;, &lt;em&gt;deploy&lt;/em&gt; e publicação da &lt;em&gt;lambda&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Para ver a &lt;em&gt;lambda&lt;/em&gt; funcionando em ambiente local é só executar o comando a seguir na pasta do projeto.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ serverless invoke local -f {$FUNCTION_NAME}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Normalmente a função criada por padrão tem o nome de &lt;code&gt;hello&lt;/code&gt;, mas durante o projeto vamos precisar renomear.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Com a função criada vamos adicionar mais alguns detalhes para conseguirmos acessar a SDK. 🚀&lt;/p&gt;

&lt;p&gt;Usando o &lt;em&gt;NPM&lt;/em&gt; conseguimos instalar a &lt;em&gt;lib&lt;/em&gt; da SDK que vamos utilizar para programar a Alexa. Na mesma pasta execute &lt;code&gt;npm install ask-sdk-core&lt;/code&gt;. &lt;/p&gt;

&lt;h3&gt;
  
  
  serverless.yml
&lt;/h3&gt;

&lt;p&gt;Vamos especificar algumas configurações logo de início.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;service&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ensinamentos-yoda&lt;/span&gt; &lt;span class="c1"&gt;#nome do projeo&lt;/span&gt;
&lt;span class="na"&gt;frameworkVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3"&lt;/span&gt;

&lt;span class="na"&gt;provider&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;aws&lt;/span&gt;
  &lt;span class="na"&gt;runtime&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nodejs12.x&lt;/span&gt; 
  &lt;span class="na"&gt;stage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;dev&lt;/span&gt; 
  &lt;span class="na"&gt;region&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;us-east-2&lt;/span&gt;

&lt;span class="na"&gt;functions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;yoda&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;handler&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;handler.yoda&lt;/span&gt; &lt;span class="c1"&gt;#nome da função que será disparada&lt;/span&gt;

&lt;span class="na"&gt;plugins&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;serverless-alexa-skills&lt;/span&gt;

&lt;span class="na"&gt;custom&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;alexa&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[]&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  handler.js
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;use strict&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ensinamentos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Muito a aprender você ainda tem, jovem Padawan.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Faça. Ou não faça. Não existe a tentativa&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;O medo leva a raiva, a raiva leva ao ódio, o ódio leva ao sofrimento&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Paciência você deve ter meu jovem Padawan&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Um Jedi usa a Força para o conhecimento e defesa, nunca para o ataque.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Raiva, medo, agressão. Ao lado sombrio elas pertencem&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;yoda&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`[INFO] &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;now&lt;/span&gt;&lt;span class="p"&gt;())}&lt;/span&gt;&lt;span class="s2"&gt; Lambda disparada `&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Lembre-se do que o mestre Yoda disse: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
    &lt;span class="nx"&gt;ensinamentos&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;floor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;ensinamentos&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Durante o desenvolvimento podemos usar o comando &lt;code&gt;serverless invoke local -f yoda&lt;/code&gt; para testar localmente sem provisionamento de cloud&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6arUXo8c--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tg08b0733ukp0bshfjp1.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6arUXo8c--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tg08b0733ukp0bshfjp1.gif" alt="mestre Yoda dançando" width="158" height="200"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Round 1
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Primeira etapa concluída!&lt;/strong&gt; temos nossa regra de negócio pronta, sempre que executada a &lt;em&gt;lambda&lt;/em&gt; responde com algum ensinamento aleatório da lista.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;serverless invoke &lt;span class="nb"&gt;local&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; yoda
&lt;span class="go"&gt;[INFO] Sun Jun 26 2022 01:48:21 GMT-0300 (Horário Padrão de Brasília) Lambda disparada 
"Lembre-se do que o mestre Yoda disse: Muito a aprender você ainda tem, jovem Padawan."

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Round 2 - Criando nossa skill
&lt;/h2&gt;

&lt;p&gt;Vamos nos autenticar com a API da Alexa, nosso amigo serverless nos ajudará muito nessa missão.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;serverless alexa auth
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Após ser redirecionado para a página do &lt;em&gt;console&lt;/em&gt; vamos fazer o &lt;em&gt;login&lt;/em&gt; com nossa conta Amazon, de preferência com a mesma conta que configuramos nosso &lt;strong&gt;Amazon Echo&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Depois de efetuar o login com sucesso receberemos a mensagem &lt;code&gt;"Thank you for using Serverless Alexa Skills Plugin!!"&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Agora autenticados podemos criar nossa &lt;em&gt;skill&lt;/em&gt; na plataforma da Amazon.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;serverless alexa create &lt;span class="nt"&gt;--name&lt;/span&gt; ensinamentos-yoda &lt;span class="nt"&gt;--locale&lt;/span&gt; pt-BR &lt;span class="nt"&gt;--type&lt;/span&gt; custom
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Se tudo der certo teremos o ID da nossa &lt;em&gt;skill&lt;/em&gt; exibido no console ao fim da execução.&lt;/p&gt;

&lt;p&gt;Acessando a página &lt;a href="https://developer.amazon.com/alexa/console/ask"&gt;Amazon Alexa Console&lt;/a&gt; conseguimos visualizar nossa &lt;em&gt;skill&lt;/em&gt; criada e prontinha para o show. 😎&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HixPYdPB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rvae6vouv50kwgtnba7d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HixPYdPB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rvae6vouv50kwgtnba7d.png" alt="screenshot exibindo o painel do console" width="880" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Fique à vontade para explorar o painel, repare que também podemos editar e configurar nossa &lt;em&gt;skill&lt;/em&gt; pela plataforma, mas vamos seguir usando o &lt;em&gt;plugin&lt;/em&gt; do serverless para o tutorial.&lt;/p&gt;

&lt;p&gt;Com a &lt;em&gt;skill&lt;/em&gt; criada vamos adicionar mais algumas configurações no &lt;code&gt;serverless.yml&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;#---resto do código---&lt;/span&gt;
&lt;span class="na"&gt;functions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;yoda&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;handler&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;handler.yoda&lt;/span&gt; &lt;span class="c1"&gt;#nome da função que será disparada&lt;/span&gt;

&lt;span class="na"&gt;plugins&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;serverless-alexa-skills&lt;/span&gt; &lt;span class="c1"&gt;#plugin alexa skill&lt;/span&gt;

&lt;span class="na"&gt;custom&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;alexa&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;skills&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${env:ALEXA_SKILL_ID}&lt;/span&gt; &lt;span class="c1"&gt;#ID informado no comando create&lt;/span&gt;
        &lt;span class="na"&gt;manifest&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;apis&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;custom&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{}&lt;/span&gt;
          &lt;span class="na"&gt;publishingInformation&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;locales&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;pt-BR&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ensinamentos-yoda&lt;/span&gt;
          &lt;span class="na"&gt;manifestVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;1.0'&lt;/span&gt;
        &lt;span class="na"&gt;models&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;pt-BR&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;interactionModel&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;languageModel&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                &lt;span class="na"&gt;invocationName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ensinamentos yoda&lt;/span&gt; &lt;span class="c1"&gt;#Nome usado para invocar a skill 'Alexa, abrir ensinamentos Yoda'&lt;/span&gt;
                &lt;span class="na"&gt;intents&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; 
                  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;AMAZON.CancelIntent&lt;/span&gt;
                    &lt;span class="na"&gt;samples&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[]&lt;/span&gt;
                  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;AMAZON.HelpIntent&lt;/span&gt;
                    &lt;span class="na"&gt;samples&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[]&lt;/span&gt;
                  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;AMAZON.StopIntent&lt;/span&gt;
                    &lt;span class="na"&gt;samples&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[]&lt;/span&gt;
                  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;PedirEnsinamentoIntent&lt;/span&gt; &lt;span class="c1"&gt;#Intenção que criaremos para executar nossa regra&lt;/span&gt;
                    &lt;span class="na"&gt;samples&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="c1"&gt;#Frases que usaremos para pedir um ensinamento, Seja Criativo!&lt;/span&gt;
                      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;O&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;que&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;o&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;yoda&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;diria'&lt;/span&gt;
                      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;me&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;fale&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;um&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;ensinamento'&lt;/span&gt;
                      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;qual&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;o&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;pensamento&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;do&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;dia'&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Lembra das &lt;em&gt;intent&lt;/em&gt; que comentamos lá em cima? A API por padrão define algumas padrões para qualquer &lt;em&gt;skill&lt;/em&gt;: &lt;strong&gt;AMAZON.CancelIntent&lt;/strong&gt;, &lt;strong&gt;AMAZON.HelpIntent&lt;/strong&gt;, &lt;strong&gt;AMAZON.StopIntent&lt;/strong&gt; &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Depois de editado o arquivo vamos executar mais dois comandinhos, eles serão nossos companheiros durante todo o desenvolvimento.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;serverless alexa update
&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;serverless alexa build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sempre que um comando é enviado para a API da Alexa precisaremos de um &lt;code&gt;handler&lt;/code&gt; próprio para resolve-lo.&lt;/p&gt;

&lt;p&gt;Para esse projeto teremos os seguintes &lt;em&gt;handlers&lt;/em&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;LaunchRequestHandler&lt;/code&gt; Quando o usuário invoca sua &lt;em&gt;skill&lt;/em&gt; sem uma intenção específica, a Alexa envia para sua &lt;em&gt;skill&lt;/em&gt; um &lt;em&gt;payload&lt;/em&gt; de LaunchRequest.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;PedirEnsinamentoIntent&lt;/code&gt; Executada sempre que o usuário pedir um ensinamento do mestre Yoda.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;HelpIntentHandler&lt;/code&gt; Executada sempre que o usuário enviar um &lt;code&gt;AMAZON.HelpIntent&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;CancelAndStopIntentHandler&lt;/code&gt; Executada sempre que o usuário enviar um &lt;code&gt;AMAZON.CancelIntent&lt;/code&gt; ou &lt;code&gt;AMAZON.StopIntent&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;SessionEndedRequestHandler&lt;/code&gt; Executada sempre que o usuário desejar encerrar a &lt;em&gt;skill&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;use strict&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Alexa&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ask-sdk-core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ensinamento&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ensinamentos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Muito a aprender você ainda tem, jovem Padawan.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Faça. Ou não faça. Não existe a tentativa&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;O medo leva a raiva, a raiva leva ao ódio, o ódio leva ao sofrimento&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Paciência você deve ter meu jovem Padawan&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Um Jedi usa a Força para o conhecimento e defesa, nunca para o ataque.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Raiva, medo, agressão. Ao lado sombrio elas pertencem&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Lembre-se do que o mestre Yoda disse: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
    &lt;span class="nx"&gt;ensinamentos&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;floor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;ensinamentos&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;LaunchRequestHandler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;canHandle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;handlerInput&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;Alexa&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getRequestType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;handlerInput&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;requestEnvelope&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;LaunchRequest&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="nx"&gt;handle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;handlerInput&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;speechText&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Olá, que a força esteja com você, me peça um ensinamento do mestre Yoda&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;handlerInput&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;responseBuilder&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;speak&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;speechText&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;reprompt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;speechText&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;withSimpleCard&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Olá, que a força esteja com você, me peça um ensinamento do mestre Yoda&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;speechText&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getResponse&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;PedirEnsinamentoIntent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;canHandle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;handlerInput&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;Alexa&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getRequestType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;handlerInput&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;requestEnvelope&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;IntentRequest&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
      &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;Alexa&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getIntentName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;handlerInput&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;requestEnvelope&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;PedirEnsinamentoIntent&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;handle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;handlerInput&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;speechText&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ensinamento&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;//chamada a nossa função&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;handlerInput&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;responseBuilder&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;speak&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;speechText&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;withSimpleCard&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Mestre Yoda.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;speechText&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getResponse&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;CancelAndStopIntentHandler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;canHandle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;handlerInput&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;Alexa&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getRequestType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;handlerInput&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;requestEnvelope&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;IntentRequest&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
      &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Alexa&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getIntentName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;handlerInput&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;requestEnvelope&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;AMAZON.CancelIntent&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
        &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;Alexa&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getIntentName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;handlerInput&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;requestEnvelope&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;AMAZON.StopIntent&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="nx"&gt;handle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;handlerInput&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;speechText&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Que a força esteja com você!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;handlerInput&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;responseBuilder&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;speak&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;speechText&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;withSimpleCard&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Que a força esteja com você!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;speechText&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;withShouldEndSession&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getResponse&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;SessionEndedRequestHandler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;canHandle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;handlerInput&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;Alexa&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getRequestType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;handlerInput&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;requestEnvelope&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;SessionEndedRequest&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="nx"&gt;handle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;handlerInput&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Any clean-up logic goes here.&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;handlerInput&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;responseBuilder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getResponse&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ErrorHandler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;canHandle&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="nx"&gt;handle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;handlerInput&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Error handled: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;handlerInput&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;responseBuilder&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;speak&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Encontrei um probleminha, vamos tentar de novo ?&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;reprompt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Encontrei um probleminha, vamos tentar de novo ?&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getResponse&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;skill&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;yoda&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`[INFO] &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;now&lt;/span&gt;&lt;span class="p"&gt;())}&lt;/span&gt;&lt;span class="s2"&gt; Lambda disparada `&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;skill&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;skill&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Alexa&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;SkillBuilders&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;custom&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addRequestHandlers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nx"&gt;LaunchRequestHandler&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;//responsável por abrir nossa skill&lt;/span&gt;
        &lt;span class="nx"&gt;PedirEnsinamentoIntent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;CancelAndStopIntentHandler&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;SessionEndedRequestHandler&lt;/span&gt; &lt;span class="c1"&gt;//responsável para encerrar nossa skill&lt;/span&gt;
      &lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addErrorHandlers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ErrorHandler&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="c1"&gt;//mensagem para caso de erros&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;create&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;skill&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Rolou muitas mudanças dessa vez, recomendo fortemente dar uma olhada na &lt;a href="https://developer.amazon.com/en-US/docs/alexa/alexa-skills-kit-sdk-for-nodejs/set-up-the-sdk.html"&gt;documentação oficial&lt;/a&gt; onde tem vários exemplos e explicações sobre as etapas e funções desse código.&lt;/p&gt;

&lt;p&gt;Nesse ponto da nossa aventura temos uma &lt;em&gt;lambda&lt;/em&gt; capaz de receber um comando de voz da Alexa e responder com um ensinamento do mestre Yoda.&lt;/p&gt;

&lt;p&gt;Não esqueça dos nossos amigos.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;serverless alexa update
&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;serverless alexa build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--G13sK58_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bin5czgx9yfs9c9631qy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--G13sK58_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bin5czgx9yfs9c9631qy.gif" alt="Todo poderoso tomando café enquanto usa o computador" width="320" height="160"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Estamos quase lá
&lt;/h3&gt;

&lt;p&gt;Já temos nosso código e nossa &lt;em&gt;skill&lt;/em&gt; agora vamos fazer todas as peças se encaixarem?&lt;/p&gt;

&lt;p&gt;Partiu!&lt;/p&gt;

&lt;h2&gt;
  
  
  Deploy
&lt;/h2&gt;

&lt;p&gt;O nosso amigo serverless também nos ajudará na etapa do &lt;em&gt;deploy&lt;/em&gt;, vamos precisar publicar nossa &lt;em&gt;lambda&lt;/em&gt; para &lt;em&gt;cloud&lt;/em&gt; e adicionar o gatilho de execução pela Alexa.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;serverless deploy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Hora da mágica!🧙‍♂️&lt;/strong&gt; esse comando vai executar todas as etapas necessária de publicação e os recursos necessários para termos o serviço na nossa conta AWS.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8ikt3bWL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u4lwn0dyy67tqb2wemuw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8ikt3bWL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u4lwn0dyy67tqb2wemuw.png" alt="painel AWS Lambda" width="853" height="278"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prontinho!&lt;/strong&gt; temos nosso &lt;em&gt;backend&lt;/em&gt; agora só precisamos adicionar um gatilho para a função.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Clique em &lt;strong&gt;Visão geral da função&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Clique em &lt;strong&gt;Adicionar gatilho&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Selecione &lt;strong&gt;Alexa&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Para &lt;strong&gt;Skill ID verification&lt;/strong&gt;, selecione &lt;strong&gt;Disable&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ike-hAoT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t6o9532sekirj0dvjb1j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ike-hAoT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t6o9532sekirj0dvjb1j.png" alt="detalhes da função no painel AWS" width="880" height="378"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Depois de criada vamos editar mais uma vez o arquivo &lt;code&gt;serverless.yml&lt;/code&gt; e adicionar o &lt;strong&gt;ARN&lt;/strong&gt; da função para ser chamada pela Alexa.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;#---resto do código---&lt;/span&gt;
 &lt;span class="na"&gt;apis&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;custom&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; 
   &lt;span class="na"&gt;endpoint&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;uri&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${env:AWS_LAMBDA_ARN}&lt;/span&gt;
&lt;span class="c1"&gt;#---resto do código---&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Lembre-se de atualizar e fazer o &lt;em&gt;build&lt;/em&gt; da &lt;em&gt;skill&lt;/em&gt; mais uma vez.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Testando
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Essa jornada foi longa mas chegamos ao final.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Para testarmos nossa &lt;em&gt;skill&lt;/em&gt; podemos usar o aplicativo, Amazon Echo ou a página de teste do Alexa Developer Console.&lt;/p&gt;

&lt;h3&gt;
  
  
  Usando o Amazon Echo Dot
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Abra o aplicativo &lt;strong&gt;Amazon Alexa&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;No menu &lt;strong&gt;Mais&lt;/strong&gt; acesse &lt;strong&gt;Skills &amp;amp; Games&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Selecione a aba &lt;strong&gt;Suas Skills&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Clique no card &lt;strong&gt;Desenv.&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Clique em &lt;strong&gt;ensinamentos-yoda&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Clique em &lt;strong&gt;Ativar Skill&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Diga &lt;strong&gt;"Alexa abrir ensinamentos yoda"&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Diga alguma das frases que configuramos, por exemplo &lt;strong&gt;"O que o Yoda diria"&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--a-jQ0j8N--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oshr0oqxvdqalgj8en5y.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--a-jQ0j8N--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oshr0oqxvdqalgj8en5y.gif" alt="Michael Scott dançando" width="220" height="222"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Desenvolver com a Alexa é uma aventura muito divertida, existem inúmeras opções e funcionalidades que podemos explorar.&lt;/p&gt;

&lt;p&gt;O objetivo desse tutorial foi tentar mostrar os primeiros passos para conseguir usar a API da Amazon e sua integração com o serviço AWS Lambda.&lt;/p&gt;

&lt;p&gt;Espero que este post tenha inspirado você a explorar o Alexa Skill Kit e criar algo para ela.😊&lt;/p&gt;

&lt;p&gt;Recomendo a leitura das documentações oficiais e os links que deixarei abaixo para definições mais técnicas e detalhadas.&lt;/p&gt;

&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/pgsilva/function-moovies"&gt;Projeto pessoal criando uma skill que diz em que plataforma de streaming filmes e séries estão disponíveis&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.amazon.com/en-US/docs/alexa/alexa-skills-kit-sdk-for-nodejs/develop-your-first-skill.html"&gt;Tutorial oficial da API Amazon&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.serverless.com/blog/how-to-manage-your-alexa-skills-with-serverless/"&gt;Blog serverless&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cGjN3Kv0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mupsj3eodpc2rxfgawz8.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cGjN3Kv0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mupsj3eodpc2rxfgawz8.gif" alt="isso é tudo pessoal" width="400" height="293"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Happy Coding!&lt;/p&gt;

</description>
      <category>node</category>
      <category>serverless</category>
      <category>lambda</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
