Integrar a API Vision ao Dialogflow

1. Antes de começar

Neste codelab, você vai integrar a API Vision ao Dialogflow para fornecer respostas avançadas e dinâmicas baseadas em machine learning a entradas de imagem fornecidas pelo usuário. Você vai criar um app de chatbot que usa uma imagem como entrada, a processa na API Vision e retorna um ponto de referência identificado ao usuário. Por exemplo, se o usuário enviar uma imagem do Taj Mahal, o chatbot retornará Taj Mahal como resposta.

Isso é útil porque é possível fazer uma análise dos itens na imagem e tomar medidas com base nas informações recebidas. Também é possível criar um sistema de processamento de reembolsos para ajudar os usuários a fazer upload de comprovantes, extrair a data de compra no recibo e processar o reembolso se a data estiver adequada.

Confira a seguinte caixa de diálogo de exemplo:

Usuário: Olá

Bot de bate-papo: Olá! Você pode enviar uma foto para explorar pontos turísticos

Usuário: Faça upload de uma imagem que mostre o Taj Mahal.

Bot de bate-papo: o arquivo está sendo processado. Aqui estão os resultados: Taj Mahal, Taj Mahal Garden, Taj Mahal.

15a4243e453415ca.png

Pré-requisitos

Antes de continuar, você precisa concluir os seguintes codelabs:

  1. Criar um programador de horários com o Dialogflow
  2. Integrar um chatbot do Dialogflow com o Actions on Google
  3. Entenda as entidades no Dialogflow
  4. Criar um cliente Django de front-end para um aplicativo do Dialogflow

Você também precisa entender os conceitos e construções básicos do Dialogflow, extraídos dos vídeos a seguir no programa Criar um bot de bate-papo com o Dialogflow:

O que você vai aprender

  • Como criar um agente do Dialogflow
  • Como atualizar um agente do Dialogflow para fazer upload de arquivos
  • Como configurar a conexão da API Vision com o fulfillment do Dialogflow
  • Como configurar e executar um app de front-end do Django para o Dialogflow
  • Como implantar o app de front-end do Django no Google Cloud no App Engine
  • Como testar o app Dialogflow em um front-end personalizado

O que você vai criar

  • Crie um agente do Dialogflow
  • Implementar um front-end do Django para fazer upload de um arquivo
  • Implementar o fulfillment do Dialogflow para invocar a API Vision na imagem enviada

O que é necessário

  • Conhecimento básico de Python.
  • Noções básicas do Dialogflow
  • Noções básicas da API Vision

2. Visão geral da arquitetura

Você criará uma nova experiência de conversa com um front-end personalizado do Django e o estenderá para integração com a API Vision. Você vai criar o front-end com a estrutura Django, executá-la e testá-la localmente e implantá-la no App Engine. O front-end ficará assim:

5b07e09dc4b84646.png

O fluxo de solicitação funcionará assim, conforme ilustrado na imagem a seguir:

  1. O usuário enviará uma solicitação pelo front-end.
  2. Isso acionará uma chamada para a API detectIntent do Dialogflow para mapear o enunciado do usuário para a intent correta.
  3. Depois que a intent de ponto de referência de exploração for detectada, o fulfillment do Dialogflow enviará uma solicitação à API Vision, receberá uma resposta e a enviará ao usuário.

153725eb50e008d4.png

A arquitetura geral será assim.

a2fcea32222a9cb4.png

3. O que é a API Vision?

A API Vision é um modelo de ML pré-treinado que extrai insights de imagens. Ele pode gerar vários insights, incluindo rotulagem de imagens, detecção facial e de pontos de referência, reconhecimento óptico de caracteres e marcação de conteúdo explícito. Para saber mais, consulte a Vision AI.

4. Crie um agente do Dialogflow

  1. Acesse o console do Dialogflow.
  2. Faça login. (Se você for um usuário iniciante, use seu e-mail para se inscrever.)
  3. Aceite os termos e condições para acessar o console.
  4. Clique em d9e90c93fc779808.png, role até a parte inferior e clique em Criar novo agente. 3b3f9677e2a26d93.png
  5. Digite "VisionAPI". como Agent name (nome do agente).
  6. Clique em Criar.

O Dialogflow cria as duas intents padrão a seguir como parte do agente:

  1. A intent de boas-vindas padrão dá as boas-vindas aos usuários.
  2. A intent de fallback padrão coleta todas as perguntas que o bot não entende.

Neste ponto, você tem um bot funcional que cumprimenta os usuários, mas precisa atualizá-lo para que eles saibam que podem fazer upload de uma imagem para explorar pontos de referência.

Atualizar a intent de boas-vindas padrão para notificar o usuário sobre o upload de uma imagem

  1. Clique em Intent de boas-vindas padrão.
  2. Acesse Respostas > Padrão > Text or SSML Response e insira "Hi! Faça upload de uma foto para explorar pontos de referência."

f9cd9ba6917a7aa9.png

Criar entidade

  1. Clique em Entities.

432fff294b666c93.png

  1. Clique em Criar entidade e dê o nome "nome do arquivo" e clique em Salvar.

602d001d684485de.png

Criar nova intent

  1. Clique em Intents >. Criar intent.
  2. Insira "Explorar imagem enviada" como o Intent name.
  3. Clique em Frases de treinamento > Adicione frases de treinamento e digite "o arquivo é demo.jpg". e "o arquivo é taj.jpeg" como expressões de usuário com @filename como a entidade.

dd54ebda59c6b896.png

  1. Clique em Respostas > Adicionar resposta > Padrão > Resposta de texto ou SSML. Insira "Avaliação do arquivo" e clique em Adicionar respostas.
  2. Clique em Fulfillment > Ative o fulfillment e ative a opção Enable webhook call for this intent (Ativar chamada de webhook para esta intent).

b32b7ac054fcc938.png

5. Configurar o fulfillment para integração com a API Vision

  1. Clique em Fulfillment.
  2. Ative o Editor in-line.

c8574c6ef899393f.png

  1. Atualize index.js com o código a seguir e atualize YOUR-BUCKET-NAME com o nome do bucket do Cloud Storage.
'use strict';

const functions = require('firebase-functions');
const {google} = require('googleapis');
const {WebhookClient} = require('dialogflow-fulfillment');
const vision = require('@google-cloud/vision');
  /**
   * TODO(developer): Uncomment the following lines before running the sample.
   */
const bucketName = 'YOUR-BUCKET-NAME';
const timeZone = 'America/Los_Angeles';
const timeZoneOffset = '-07:00';

exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request, response) => {
  const agent = new WebhookClient({ request, response });
  console.log("Parameters", agent.parameters);

  function applyML(agent){
    const filename = agent.parameters.filename;
    console.log("filename is: ", filename);

    // call vision API to detect text
    return callVisionApi(agent, bucketName, filename).then(result => {
                      console.log(`result is ${result}`);
                      agent.add(`file is being processed, here are the results:  ${result}`);
            //agent.add(`file is being processed ${result}`);
        }).catch((error)=> {
            agent.add(`error occurred at apply ml function`  + error);
        });
  }

  let intentMap = new Map();
  intentMap.set('Explore uploaded image', applyML);
  agent.handleRequest(intentMap);
});


async function callVisionApi(agent, bucketName, fileName){
    // [START vision_text_detection_gcs]
  // Imports the Google Cloud client libraries
  // Creates a client
  
  const client = new vision.ImageAnnotatorClient();
    try {
        // Performs text detection on the gcs file
        const [result] = await client.landmarkDetection(`gs://${bucketName}/${fileName}`);
        const detections = result.landmarkAnnotations;
        var detected = [];
        detections.forEach(text => {
            console.log(text.description);
            detected.push(text.description);
        });
        return detected;
    }
    catch(error) {
        console.log('fetch failed', error);
        return [];
    }
}
  1. Cole o seguinte em package.json para substituir o conteúdo dele.
{
  "name": "dialogflowFirebaseFulfillment",
  "description": "Dialogflow fulfillment for the bike shop sample",
  "version": "0.0.1",
  "private": true,
  "license": "Apache Version 2.0",
  "author": "Google Inc.",
  "engines": {
    "node": "6"
  },
  "scripts": {
    "lint": "semistandard --fix \"**/*.js\"",
    "start": "firebase deploy --only functions",
    "deploy": "firebase deploy --only functions"
  },
  "dependencies": {
    "firebase-functions": "2.0.2",
    "firebase-admin": "^5.13.1",
    "actions-on-google": "2.2.0", 
    "googleapis": "^27.0.0",
    "dialogflow-fulfillment": "^0.6.1",
    "@google-cloud/bigquery": "^1.3.0",
    "@google-cloud/storage": "^2.0.0",
    "@google-cloud/vision": "^0.25.0"
  }
}
  1. Clique em Salvar.

6. Fazer o download e executar o aplicativo de front-end

  1. Clone este repositório na sua máquina local:
https://github.com/priyankavergadia/visionapi-dialogflow.git
  1. Acesse o diretório que contém o código. Outra opção é fazer o download da amostra como um arquivo zip e extraí-la.
cd visionapi-dialogflow

7. Configurar seu ambiente local

Quando implantado, o app usa o Cloud SQL Proxy integrado ao ambiente padrão do App Engine para se comunicar com a instância do Cloud SQL. No entanto, para testar o aplicativo localmente, é necessário instalar e usar uma cópia local do Cloud SQL Proxy em seu ambiente de desenvolvimento. Para saber mais, consulte Sobre o Cloud SQL Proxy.

Para executar tarefas administrativas básicas na sua instância do Cloud SQL, use o cliente Cloud SQL para MySQL.

Instalar o Cloud SQL Proxy

Faça o download e instale o Cloud SQL Proxy com o comando a seguir. O Cloud SQL Proxy é usado para se conectar à instância do Cloud SQL durante a execução local.

Faça o download do proxy:

curl -o cloud_sql_proxy https://dl.google.com/cloudsql/cloud_sql_proxy.darwin.amd64

Torne o proxy executável.

chmod +x cloud_sql_proxy

crie uma instância do Cloud SQL

  1. Crie uma instância de segunda geração do Cloud SQL para MySQL. Digite "polls-instance" ou algo semelhante ao nome. Pode levar alguns minutos para a instância ficar pronta. Quando estiver pronta, ela vai aparecer na lista de instâncias.
  2. Agora, use a ferramenta de linha de comando gcloud para executar o comando a seguir, em que [YOUR_INSTANCE_NAME] representa o nome da sua instância do Cloud SQL. Anote o valor mostrado para connectionName para a próxima etapa. Ele é exibido no formato [PROJECT_NAME]:[REGION_NAME]:[INSTANCE_NAME].
gcloud sql instances describe [YOUR_INSTANCE_NAME]

Se preferir, clique na instância no console para ver o Nome da conexão da instância.

c11e94464bf4fcf8.png

Inicializar a instância do Cloud SQL

Inicie o Cloud SQL Proxy usando o connectionName da seção anterior.

./cloud_sql_proxy -instances="[YOUR_INSTANCE_CONNECTION_NAME]"=tcp:3306

Substitua [YOUR_INSTANCE_CONNECTION_NAME] pelo valor registrado na seção anterior. Isso estabelece uma conexão do seu computador local com a instância do Cloud SQL para testes locais. Mantenha o Cloud SQL Proxy em execução durante todo o teste local do aplicativo.

Em seguida, crie um novo usuário e um banco de dados do Cloud SQL.

  1. Crie um novo banco de dados usando o console do Google Cloud para a instância do Cloud SQL chamada polls-instance. Por exemplo, você pode inserir "enquetes" como o nome. a3707ec9bc38d412.png
  2. Crie um novo usuário com o Console do Cloud para a instância do Cloud SQL chamada polls-instance. f4d098fca49cccff.png

Definir as configurações do banco de dados

  1. Abra mysite/settings-changeme.py para edição.
  2. Renomeie o arquivo como setting.py.
  3. Em dois lugares, substitua [YOUR-USERNAME] e [YOUR-PASSWORD] pelo nome de usuário e senha do banco de dados que você criou na seção anterior. Isso ajuda a configurar a conexão com o banco de dados para implantação do App Engine e testes locais.
  4. Na linha ‘HOST': ‘cloudsql/ [PROJECT_NAME]:[REGION_NAME]:[INSTANCE_NAME] substitua [PROJECT_NAME]:[REGION_NAME]:[INSTANCE_NAME] pelo nome da instância adquirido na seção anterior.
  5. Execute o comando a seguir e copie o valor connectionName gerado para a próxima etapa.
gcloud sql instances describe [YOUR_INSTANCE_NAME]
  1. Substitua [YOUR-CONNECTION-NAME] pelo valor registrado na etapa anterior.
  2. Substitua [YOUR-DATABASE] pelo nome que você escolheu na seção anterior.
# [START db_setup]
if os.getenv('GAE_APPLICATION', None):
    # Running on production App Engine, so connect to Google Cloud SQL using
    # the unix socket at /cloudsql/<your-cloudsql-connection string>
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'HOST': '/cloudsql/[PROJECT_NAME]:[REGION_NAME]:[INSTANCE_NAME]',
            'USER': '[YOUR-USERNAME]',
            'PASSWORD': '[YOUR-PASSWORD]',
            'NAME': '[YOUR-DATABASE]',
        }
    }
else:
    # Running locally so connect to either a local MySQL instance or connect to
    # Cloud SQL via the proxy. To start the proxy via command line:
    #     $ cloud_sql_proxy -instances=[INSTANCE_CONNECTION_NAME]=tcp:3306
    # See https://cloud.google.com/sql/docs/mysql-connect-proxy
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'HOST': '127.0.0.1',
            'PORT': '3306',
            'NAME': '[YOUR-DATABASE]',
            'USER': '[YOUR-USERNAME]',
            'PASSWORD': '[YOUR-PASSWORD]'
        }
    }
# [END db_setup]
  1. Feche e salve settings.py.

8. Configurar conta de serviço

  1. No console do Dialogflow, clique em 21a21c1104f5fdf3.png. Na guia Geral, acesse Projeto do Google > ID do projeto e clique em Google Cloud 7b2236f5627c37a0.png para abrir o console do Cloud. a4cfb880b3c8e789.png
  2. Clique em Menu de navegação ☰ > IAM e Administrador > Contas de serviço, depois clique em 796e7c9e65ae751f.png ao lado de Integrações do Dialogflow e, depois, em Criar chave.

3d72abc0c184d281.png

  1. Um arquivo JSON será salvo no seu computador e será necessário nas próximas seções de configuração.

9. Configurar o endpoint detectIntent do Dialogflow para ser chamado pelo app

  1. Na pasta de chat, substitua key-sample.json pelo arquivo JSON das suas credenciais e dê o nome key.json a ele.
  2. Em views.py na pasta do chat, mude GOOGLE_PROJECT_ID = "<YOUR_PROJECT_ID>" para o ID do projeto.

10. Criar buckets do Cloud Storage

Criar um bucket do Cloud Storage para objetos estáticos de front-end

  1. No console do Cloud, clique em Menu de navegação ☰ > Armazenamento.

87ff9469db4eb77f.png

  1. Clique em Criar bucket.
  2. Forneça um nome globalmente exclusivo.

a15a6612e92a39d3.png

  1. Escolha onde armazenar os dados Escolha Região e selecione o local que melhor atende às suas necessidades.
  2. Escolha Padrão como a classe de armazenamento padrão.

9c56abe632cf61db.png

  1. Escolha Definir permissões de maneira uniforme no nível do bucket (Somente a política do bucket) e clique em Continuar para criar o bucket.

f175ac794049df04.png

  1. Depois que o bucket for criado, clique em Menu de navegação ☰ > Armazenamento > Navegador e localize o bucket que você criou.

9500ee19b427158c.png

  1. Clique em 796e7c9e65ae751f.png ao lado do bucket correspondente e clique em Editar permissões do bucket.

fd0a310bc3656edd.png

  1. Clique em Adicionar membros, clique em Novos membros e digite "allUsers" Clique em Selecionar papel > Leitor de objetos do Storage Isso fornece acesso de visualização aos arquivos estáticos de front-end para allUsers. Essa não é a configuração de segurança ideal para os arquivos, mas funciona para a finalidade deste codelab específico.

7519116abd56d5a3.png

Criar um bucket do Cloud Storage para imagens carregadas pelo usuário

Siga as mesmas instruções para criar um bucket separado e fazer upload das imagens de usuários. Definir permissões para "allUsers" novamente, mas selecione Criador de objetos do Storage e Leitor de objetos do Storage como papéis.

11. Configurar os buckets do Cloud Storage no app de front-end

Configurar o bucket do Cloud Storage em settings.py

  1. Abra mysite/setting.py.
  2. Localize a variável GCS_BUCKET e substitua ‘<YOUR-GCS-BUCKET-NAME>" com o bucket estático do Cloud Storage.
  3. Localize a variável GS_MEDIA_BUCKET_NAME e substitua ‘<YOUR-GCS-BUCKET-NAME-MEDIA>". pelo nome do bucket do Cloud Storage para as imagens.
  4. Localize a variável GS_STATIC_BUCKET_NAME e substitua ‘<YOUR-GCS-BUCKET-NAME-STATIC>". pelo nome do bucket do Cloud Storage para os arquivos estáticos.
  5. Salve o arquivo.
GCS_BUCKET = '<YOUR-GCS-BUCKET-NAME>'
GS_MEDIA_BUCKET_NAME = '<YOUR-GCS-BUCKET-NAME-MEDIA>'
GS_STATIC_BUCKET_NAME = '<YOUR-GCS-BUCKET-NAME-STATIC>'

Configure o bucket do Cloud Storage em home.html

  • Abra a pasta do chat, depois abra templates e renomeie home-changeme.html como home.html.
  • Procure <YOUR-GCS-BUCKET-NAME-MEDIA> e substitua pelo nome do bucket em que você quer salvar o arquivo enviado pelo usuário. Isso impede que você armazene o arquivo enviado pelo usuário no front-end e mantenha os recursos estáticos no bucket do Cloud Storage. A API Vision chama o bucket do Cloud Storage para selecionar o arquivo e fazer a previsão.

12. Criar e executar o app localmente

Para executar o app Django no seu computador local, é necessário configurar um ambiente de desenvolvimento em Python, incluindo Python, pip e virtualenv. Para instruções, consulte Como configurar um ambiente de desenvolvimento em Python.

  1. Crie um ambiente Python isolado e instale as dependências.
virtualenv env
source env/bin/activate
pip install -r requirements.txt
  1. Execute as migrações do Django para configurar os modelos.
python3 manage.py makemigrations
python3 manage.py makemigrations polls
python3 manage.py migrate
  1. Inicie um servidor da Web local.
python3 manage.py runserver
  1. No navegador da Web, acesse http://localhost:8000/. Vai aparecer uma página da Web simples como esta:

8f986b8981f80f7b.png

As páginas do app de exemplo são fornecidas pelo servidor da Web Django executado no seu computador. Quando estiver pronto para avançar, pressione Control+C (Command+C no Macintosh) para parar o servidor da Web local.

Como usar o console de administração do Django

  1. Crie um superusuário.
python3 manage.py createsuperuser
  1. Inicie um servidor da Web local.
python3 manage.py runserver
  1. Acesse http://localhost:8000/admin/ no seu navegador da Web. Para fazer login no site de administração, digite o nome de usuário e a senha que você criou quando executou createsuperuser.

13. Como implantar o aplicativo no ambiente padrão do App Engine

Reúna todo o conteúdo estático em uma pasta executando o comando abaixo, que move todos os arquivos estáticos do app para a pasta especificada por STATIC_ROOT em settings.py:

python3 manage.py collectstatic

Faça upload do app executando o seguinte comando no diretório do app em que o arquivo app.yaml está localizado:

gcloud app deploy

Aguarde a mensagem notificando que a atualização foi concluída.

14. Testar o aplicativo de front-end

No navegador da Web, acesse https://<your_project_id>.appspot.com

Desta vez, sua solicitação é atendida por um servidor da Web em execução no ambiente padrão do App Engine.

O comando app deploy implanta o app conforme descrito em app.yaml e define a versão recém-implantada como padrão. Com isso, ela veicula todo o novo tráfego.

15. Produção

Quando estiver tudo pronto para veicular seu conteúdo na produção, mude a variável DEBUG para False em mysite/settings.py.

16. Teste o chatbot

É possível testar o chatbot no simulador ou usar a integração com a Web ou com o Google Home que você criou.

  1. Usuário: "Oi"
  2. Bot de bate-papo: "Olá! Faça upload de uma foto para explorar pontos de referência."
  3. O usuário faz upload de uma imagem.

Baixe esta imagem, nomeie-a como demo.jpg e use-a.

c3aff843c9f132e4.jpeg

  1. Bot de bate-papo: "O arquivo está sendo processado. Aqui estão os resultados: Ponte Golden Gate, Área de Recreação Nacional do Portão Dourado, Ponte do Portão Dourado, Ponte Golden Gate".

De modo geral, a aparência será semelhante a esta:

228df9993bfc001d.png

17. Limpar

Se você quiser concluir outros codelabs do Dialogflow, pule esta seção e volte mais tarde.

Exclua o agente do Dialogflow

  1. Clique no ca4337eeb5565bcb.png ao lado do agente.

520c1c6bb9f46ea6.png

  1. Na guia General, role para baixo e clique em Delete This Agent.
  2. Digite Excluir na janela que aparece e clique em Excluir.

18. Parabéns

Você criou um chatbot no Dialogflow e o integrou à API Vision. Você já sabe como desenvolver um chatbot.

Saiba mais

Para saber mais, confira os exemplos de código na página do Dialogflow no GitHub.