Google Assistant – Como fazer um agente requisitando a localização e nome do usuário

24 05 2018

Problema

Quero fazer um agente que requisite a localização e o nome do usuário e estou meio perdido de como isso funciona.

Solução

Observação 1: Esse texto foi criada no dia: 23/05/2018 e essa é uma tecnologia bem nova então pode ser que tenha mudado algo dependendo do dia que você estiver lendo esse texto.

Observação 2: Esse texto não mostra como criar projetos no DialogFlow e sim como fazer a requisição de localização ou nome do usuário.

Pré-requisitos:

  1. Seu agente estar criado no DialogFlow
  2. Webhook está implantado no Cloud Functions do Google / Firebase

Intenções necessárias

Para pegar a localização/nome do usuário você precisa pedir permissão para o usuário configurando as seguintes intenções:

  1. Intenção de gatilho para requisitar localização exemplo: request_localization_permission
    1. No backend dessa intenção você precisa pedir permissão para o usuário usando a API de permissão do actions-on-google
  2. Intenção para gerenciar a resposta da requisição exemplo: handle_permission
    1. Essa intenção deve ter o Evento actions_intent_PERMISSION configurada na aba de Eventos do DialogFlow que será chamada após o usuário responder com a permissão de acesso aos seus dados.
    2. No backend dessa intenção você recebe a informação e processa

Exemplo de fluxo de conversa:

  1. Usuário (Intenção Wellcome disparada):

    Falar com meu App de Teste 

  2. Google Assistant: 

    Olá, você sabia que eu sou adivinho! Quer que eu adivinhe o nome da sua cidade ou seu nome?

  3. Usuário (Intenção de request_localization_permission disparada):

    O nome da minha cidade 

  4. Google Assistant: 

    Para adivinhar sua cidade, eu vou precisar pegar seu endereço do Google, tudo bem? 

  5. Usuário (Intenção randle_permission disparada):

    Sim

  6. Google Assistant: 

    Hummm deixa eu pensar, sua localização é Porto Alegre.

Cadastrando intenção gatilho para pedir permissão

Intenção

  1. No DialogFlow cadastrar intenção gatilho exemplo: request_localization_permission
  2. Cadastrar frases exemplos:
    1. Sabe qual o nome da minha cidade
    2. Nome da cidade
    3. O nome da minha cidade
    4. nome cidade
    5. cidade
    6. Adivinhe o nome da minha cidade
  3. Habilitar intenção com o WebHook

Código/Backend

O código abaixo verifica se a localização ainda não esta na cache e faz o pedido informando: uma frase curta que será colocada na pergunta e a chave de permissão que será solicitada. Caso a localização já esteja na cache então será mostrado direto.

app.intent('request_location_permission', (conv) => {
  if (!conv.user.storage.location) {
    return conv.ask(new Permission({
      context: 'Para adivinhar sua cidade',
      permissions: 'DEVICE_PRECISE_LOCATION',
    }));
  }
  showLocationOnScreen(conv);
});

Cadastrando intenção para gerenciar resposta do usuário

Intenção

  1. No DialogFlow cadastrar intenção para ser acionada quando o usuário responder a pergunta de permissão,
  2. Essa intenção é acionada automaticamente pelo evento actions_intent_PERMISSION
    1. Necessário cadastrar esse evento na aba de Events da intenção
  3. Não precisa cadastrar nenhuma frase porque essa intenção será acionado automaticamente pelo evento cadastrado acima após o usuário responder.
  4. Habilitar intenção com o WebHook

Código/Backend

O código abaixo trata a intenção que gerencia a aprovação da requisição, pegando as coordenadas no caso de permissão concedida e tratando erro no caso de não concedida.

app.intent('handle_permission', (conv, params, permissionGranted) => {
  if (!permissionGranted) {
    throw new Error('Permission not granted');
  }
  const {requestedPermission} = conv.data;
  if (requestedPermission === 'DEVICE_PRECISE_LOCATION') {
    const {coordinates} = conv.device.location;
    return coordinatesToCity(coordinates.latitude, coordinates.longitude)
      .then((city) => {
        conv.user.storage.location = city;
        showLocationOnScreen(conv);
      });
  }
  throw new Error('Unrecognized permission');
});

app.catch((conv, e) => {
  console.error(e);
  conv.close(responses.readMindError);
});

Como resolver o nome da cidade com a informação de coordenadas do usuário

  1. Quando usuário aprovar a busca da localização será enviado as coordenadas de latitude e longitude
  2. Para para converter para cidade você pode usar o serviço Google Maps, fazendo uma requisição de qual cidade está naquela latitude e longitude.
  3. Antes de fazer isso é preciso configurar o acesso ao serviço de API do Google Maps (olhar na sessão abaixo)
  4. Abaixo tem um exemplo de código que acessa a API
const coordinatesToCity = (latitude, longitude) => {
  const latlng = [latitude, longitude];
  return new Promise((resolve, reject) => client.reverseGeocode({latlng},
    (e, response) => {
      if (e) {
        return reject(e);
      }
      const {results} = response.json;
      const components = results[0].address_components;
      for (const component of components) {
        for (const type of component.types) {
          if (type === 'locality') {
            return resolve(component.long_name);
          }
        }
      }
      reject(new Error('Could not parse city name from Google Maps results'));
    })
  );
};

 

Configurando o acesso ao serviço do Google Maps

Para usar o serviço do Google Maps você precisa

  1. Gerar uma chave de API nesta-pagina.
  2. Associar a API Key gerada para o Google Maps API com o seu projeto do firebase usando o seguinte comando
    1. firebase functions:config:set maps.key="<CHAVE_GERADA>"
  3. Em Google Cloud Console API Library habilitar o serviço Static Maps para o seu projeto
    1. Pesquise por Maps Static API e clique no botão ENABLE
    2. Depois de habilitado defina as restrições de acesso
      1. Clicle em Manage
      2. Depois procure pela aba Credencials
      3. Clique na chave que usou
        1. Eu usei a chave com nome Server key (auto created by Google Service)
      4. Na aba API Restrictions eu coloquei
        1. Geocoding API
        2. Cloud Functions API
        3. Dialogflow API
        4. Maps Static API
  4. Rodar novamente o deploy do seu projeto
    1. deploy --only functions

 

Considerações finais

Essa explicação nada mais é que um resumo do passo a passo desse tutorial, fiz ela com intuito de mastigar um pouco mais as informações e como elas se conectam, depois de sofrer um pouco para entender.

 

Fontes

Anúncios




ATOM – Cursor do atom escondido no tema dark

27 04 2018

Problema

Instalei o Atom no MAC com o tema dark e o cursor do mouse fica escondido, didicil de achar.

Solução

  1. Abrir o o estilo do Atom Cmd + Shift + P (Open your Style)
  2. Adicionar essas linhas e salvar
.editor {
 cursor: url(http://wiki.ooo4kids.org/images/b/b3/Cursor-Hand.svg), auto;
 }

Fonte





Docker #resumepramim

10 03 2018

Da serie #resumepramim assisti um vídeo e compilei algumas informações básicas:

Sistema de Camadas
  • O docker é baseado em camadas
  • Cada camada é read only
  • Se necessário escrever algo então é criado uma segunda camada exemplo:
    • camada básica ubunto somente leitura
    • camada secundária instalação do MySQL
  • Esse sistema de camadas vem do modelo copy and write
  • Cada container pode compartilhar várias camadas
Contêineres
  • Instancias de configurações especificas para um serviço/processo
  • Para separa os contêiner é utilizado o sistema de namespace
  • Nenhum processo de um contêiner conhece algum processo de outro contêiner
Registry
  • Repositório de imagens onde é baixado para o docker host
 Docker client
  • Console cliente para acessar e configurar os contêineres e etc..
Docker host
  • Maquina onde esta hospedado o SO e o gerenciamento dos contêineres
Comandos básicos
  • docker pull [nome imagem] – baixar imagem
  • docker umages -lista imagens
  • docker run [nome imagem]inicia imagem
  • docker ps – lista containers
  • docker exec [id do container] [comando] – Executa comando no contêiner
Contêiner não tem persistência
  • Cada vez que você instância um contêiner ele vem de acordo com que foi construido
  • Se você modificar algum arquivo dentro dele, só vai ser possível modificado naquela instância em especifico
  • É possível reiniciar contêineres já instanciados com atach
  • Tambem é possível commitar essas modificações em novos containers
  • Mas o ideal se você quer modificar algo é utilizar o sistema de build de imagens onde fica rastreado toda a modificação realizada
Utilizando persistência ou banco de dados
  • Para se utilizar persistência ou banco de dados existe um sistema de volumes externo ao container
  • Precisa montar um novo volume(tipo um HD/partição) e associar aquele volume externo ao seu contêiner
  • Assim pode se subir várias instâncias do contêiner e o volume continuará com os dados
Compartilhando de imagens
  • É possível compartilhar imagens suas customizadas na nuvem
  • Ou baixar alguma de lá
  • Então provavelmente já existe algo que você precise pronto
  • Funciona como uma biblioteca de imagens pronta para uso




Git – Problema com rebase depois de realizado o push

6 03 2018
Problema
1) Tenho um branch local A
2) Fiz um rebase do Master -> A
3) Fiz o push de A para o servidor remoto
4) O Master remoto foi alterado
5) Meu change request deu conflito
6) Atualizei meu master local e fiz um 2º rebase de master -> A
7) Tentei fazer um segundo push de A e essa uma msg parecida com essa abaixo apareceu
Your branch and 'origin/DEI-2731' have diverged, and have 45 and 4 different commits each, respectively. (use "git pull" to merge the remote branch into yours)
Causa
A causa desse problema é simples, toda a vez que o git faz um rebase ele muda o hash do seu commit, então usando o exemplo assim ficaria assim
1) Primeiro rebase fez o seu commit 001 ficar com a hash xx1
2) Depois do push o seu branch remoto ficou com a hash xx1 na árvore
3) Segundo  rebase fez o seu commit 001 ficar com um NOVO hash xx2
4) Ao tentar faz o push o Git identificou que existem hash diferentes na árvore
Solução
Existem algumas soluções:
1) Forçar –  você pode usar configurações para forçar o push, nesse caso não recomendo porque alguém pode ter baixado aquele branch e teríamos dois branchs com árvores diferentes.
2) Remover o branch remoto e re-enviar o branch local novamente para o change request. Esse ne parece o melhor cenário porque mantém a separação das informações.




Já conhece o modelo cultural Spotfy?

16 02 2018

Pra quem não viu ainda, segue um link bem interessante sobre a cultura do Spotfy, baseado em confiança e liberdade; gerando motivação, inovação e consequencialmente lucro.

Eu acredito muito nessa cultura e imagino que existe seus desafios como qualquer outra cultura, mas acredito que o ganho é para todos envolvidos e não apenas alguns.

Essa descentralização baseado em comunidades me encanta porque o bem comum não é apenas de uma célula/squad/área mas o todo.





#Resumepramim Microserviços na prática: o que aprendemos em 2 anos

5 02 2018

Da série #resumepramim segue uma apresentação do Felipe Silvestre postada no InfoQ

Objetivo

Mudar uma solução Monólito centralizada para uma solução descentralizada com microserviços.

Características

  1. A aplicação usava JSF 1.2, JBoss Seam 2.2 e Java 6 e eles migraram para uma plataforma multisserviços
  2. Deixaram a interface gráfica na frente e criaram alguns serviços backend desacoplados por trás
  3. Fizeram uma aplicação paralela e foram migrando aos poucos os usuários e soluções, analisado caso a caso
    1. Para isso utilizaram um banco central até a migração final por um tempo
  4. Dividiram a execução em 4 partes
  5. Primeira parte: definições e estruturação
    1. A definição da API com Restful estudando muito bem o padrão
    2. A definição dos testes, onde criaram uma boa camada de testes de integração de API com diferentes tecnologias como (REST-assured, Mocha etc..)
    3. A definição da documentação com Suwagger
    4. A definição do versionamento para não quebrar a API
    5. A definição da segurança (utilizando sistema de Token)
    6. A definição  da integração continua (com multi serviços a complexidade aumenta e precisa ser melhor analisada)
    7. A definição do monitoramento de todos os serviços (Utilizaram o newrelic)
  6. Segunda parte: Ajustando engrenagem
    1. Tinham problemas de logs distribuídos e centralizaram os logs usando o Graylog
    2. Começaram a utilizara mensageria com filas de mensagem
    3. Feature toggle: padronizaram as configurações de funcionalidades com o Togglz
    4. DB-MIGRATION: versionamento do banco com liquibase para os diferentes serviços
    5. SpringBoot: Utilizaram o spring boot para a criação dos microserviços com os padrões recomendados
  7. Terceira parte: Otimizando recursos
    1. Container docker: para resolver problemas de dependências com outros microserviços para desenvolvimento
    2. Kubernates: para organizar os containers do Docker
    3. Melhorando indisponibilidade de ambientes com Kubernates
    4. Utilizaram o Configserver para centralização de toda a configuração
    5. Pensaram no conceito de redundância e Fallback para os microserviços
    6. Utilizaram o Netflix OSS para API de e-mails
      1. API Gaeway (Gerencia de recurso)
      2. SeviceDiscovery (Discovery de recursos e serviços)
      3. Ristricts (Fallback e desvio de fluxos)
    7. Ao infinito em além
      1. Tracing (rastreamento)
      2. Serverless (versionamento)
      3. Eventsourcercing (mudanças de estado)
      4. DDD (pensar mais em serviços independentes)
  8. Resumo da estratégia
    1. Planeje, Prepare e Execute
    2. Progressivamente
    3. Executando e colhendo experiências em cada fatia
    4. Cuidar das pessoas (treinamento, incentivar, e processos)
    5. São muitas tecnologias envolvidas e precisa de treinamento

 

Conclusões

Achei a apresentação muito boa, bem planejada e executada, em um cenário muito comum.

Fica a sugestão de ver, acho bem interessante avaliarmos o feedback de outras empresas nessas trajetórias.

 





Stop Gain vs Stop Loss

2 10 2017

Stop Gain

Pra que serve?

  • Estabelecer um limite de ganho com maior garantia de venda

Como funciona?

  • Quando a cotação da ação chegar a um topo é enviada uma ordem automática com um valor um pouco menor garantindo assim a venda.
  • É necessário configurar dois valores principais
    • Preço de disparo: preço quando será criado a ordem automáticamente pelo sistema
    • Preço de Venda: preço que a ordem será enviada

Exemplo

  • Comprei a WEGE3 á R$ 22,45 quero fazer um Swing Trade a médio prazo vendendo a R$ 24,05 então configuro da seguinte maneira
    • Compra: R$ 22,45
    • Preço de disparo: R$ 24,10
      • quando chegar nesse preço será disparado uma ordem de venda de R$ 24,05
    • Preço de venda: R$ 24,05

Mas porque tenho que configurar uma ordem de venda menor do que o disparo?

Porque a ação pode oscilar bastante então se você configurar uma venda no topo pode ser que ação caia e não suba mais fazendo com que você não garanta a venda.

Esse é o verdadeiro valor do stop porque se configura uma bolha que garante a venda.

Stop Loss

Pra que serve?

Estabelecer um limite de perda com maior garantia de venda

Como funciona?

Quando a cotação da ação chegar a um vale é enviada uma ordem automática com um valor um pouco menor garantindo assim a venda.

É necessário configurar dois valores principais

  • Preço de disparo: preço quando será criado a ordem automáticamente pelo sistema
  • Preço de Venda: preço que a ordem será enviada

Exemplo

Comprei a WEGE3 á R$ 22,45 e quero perder no máximo 10% a médio prazo, vendendo a R$ 20,20, então configuro da seguinte maneira

  • Compra: R$ 22,45
  • Preço de disparo: R$ 22,25 (quando chegar nesse preço será disparado uma ordem de venda de R$ 22,20)
  • Preço de venda: R$ 22,20

Mas porque tenho que configurar uma ordem de venda menor do que o disparo?

Porque a ação pode oscilar bastante entre a ordem ser disparada e a venda, então é necessário configurar ela um pouco abaixo que o valor atual para que aumente a garantia de venda.

Esse é o verdadeiro valor do stop, porque se configura uma bolha que garante a venda.