Integrar a API Vision ao Dialogflow

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 imagens fornecidas pelo usuário. Você vai criar um app de chatbot que recebe 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 vai retornar Taj Mahal como resposta.

Isso é útil porque você pode analisar os itens na imagem e tomar medidas com base nas informações obtidas. Você também pode criar um sistema de processamento de reembolsos para ajudar os usuários a fazer upload de recibos, extrair a data de compra do recibo e processar o reembolso se a data for adequada.

Confira este exemplo de diálogo:

Usuário: Oi

Chatbot: Olá! Você pode fazer upload de uma foto para conhecer pontos de referência

Usuário: faça upload de uma imagem com o Taj Mahal.

Chatbot: O arquivo está sendo processado. Aqui estão os resultados: Taj Mahal, Jardim do Taj Mahal, Taj Mahal.

Pré-requisitos

Antes de continuar, conclua os seguintes codelabs:

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

Você também precisa entender os conceitos e construções básicos do Dialogflow, que podem ser aprendidos nos seguintes vídeos do programa Criar um chatbot 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 do 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
  • Conhecimentos básicos do Dialogflow
  • Conhecimentos básicos sobre a API Vision

Você vai criar uma nova experiência de conversa com um front-end Django personalizado e estender para integrar à API Vision. Você vai criar o front-end com a estrutura Django, executá-lo e testá-lo localmente e, em seguida, implantá-lo no App Engine. O front-end vai ficar assim:

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

  1. O usuário vai enviar uma solicitação pelo front-end.
  2. Isso vai acionar uma chamada à API detectIntent do Dialogflow para mapear a expressão do usuário à intent certa.
  3. Depois que a intent de explorar o ponto de referência é detectada, o fulfillment do Dialogflow envia uma solicitação para a API Vision, recebe uma resposta e a envia para o usuário.

Esta é a aparência da arquitetura geral.

A API Vision é um modelo de ML pré-treinado que extrai insights de imagens. Ele pode fornecer 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 Vision AI.

  1. Acesse o console do Dialogflow.
  2. Faça login. Se você estiver usando o app pela primeira vez, use seu e-mail para se inscrever.
  3. Aceite os Termos e Condições para acessar o console.
  4. Clique em , role até a parte de baixo e clique em Criar novo agente.

5. Insira "VisionAPI" como o Nome do agente.

  1. 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 é uma saudação aos usuários.
  2. A intent de fallback padrão captura 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 informar que eles podem enviar uma imagem para conhecer pontos de referência.

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

  1. Clique em Intent de boas-vindas padrão.
  2. Navegue até Respostas > Padrão > Resposta de texto ou SSML e digite "Olá! Você pode fazer upload de uma foto para conhecer os pontos de referência."

Criar entidade

  1. Clique em Entidades.

  1. Clique em Criar entidade, nomeie como "nome do arquivo" e clique em Salvar.

Criar intent

  1. Clique em Intents > Create Intent.
  2. Insira "Analisar imagem enviada" como o Nome da intent.
  3. Clique em Frases de treinamento > Adicionar frases de treinamento e insira "o arquivo é demo.jpg" e "o arquivo é taj.jpeg" como expressões do usuário com @filename como a entidade.

  1. Clique em Respostas > Adicionar resposta > Padrão > Resposta de texto ou SSML. Insira "Analisando arquivo" e clique em Adicionar respostas.
  1. Clique em Fulfillment > Enable fulfillment e ative a opção Enable webhook call for this intent.

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

  1. Atualize index.js com o código a seguir e YOUR-BUCKET-NAME com o nome do seu 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.
{
  "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 .
  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

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 app localmente, é necessário instalar e usar uma cópia local do Cloud SQL Proxy no ambiente de desenvolvimento. Para saber mais, consulte Sobre o Cloud SQL Proxy.

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

Instalar o Cloud SQL Proxy

Faça o download e instale o Cloud SQL Proxy com o seguinte comando. O proxy do Cloud SQL é 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. Insira "polls-instance" ou algo semelhante como nome. Pode levar alguns minutos para a instância ficar pronta. Depois disso, ela vai aparecer na lista de instâncias.
  2. Agora, use a ferramenta de linha de comando gcloud para executar o seguinte comando, em que [YOUR_INSTANCE_NAME] representa o nome da sua instância do Cloud SQL. Anote o valor mostrado em connectionName para usá-lo na próxima etapa. Ele aparece no formato [PROJECT_NAME]:[REGION_NAME]:[INSTANCE_NAME].
gcloud sql instances describe [YOUR_INSTANCE_NAME]

Como alternativa, clique na instância no console para acessar o Nome da conexão da instância.

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 que você registrou na seção anterior. Isso estabelece uma conexão do 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 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 nome.
  2. Crie um usuário usando o Cloud Console para a instância do Cloud SQL chamada polls-instance.

Definir as configurações do banco de dados

  1. Abra mysite/settings-changeme.py para edição.
  2. Renomeie o arquivo para 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 escolhido 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.
  1. No console do Dialogflow, clique em . Na guia Geral, acesse Projeto do Google > ID do projeto e clique em Google Cloud para abrir o console do Cloud.
  2. Clique em Menu de navegação ☰ > IAM e administrador > Contas de serviço. Em seguida, clique em ao lado de Integrações do Dialogflow e em Criar chave.

  1. Um arquivo JSON será baixado no seu computador, e você vai precisar dele nas próximas seções de configuração.
  1. Na pasta de chat, substitua key-sample.json pelo arquivo JSON de credenciais e nomeie-o como key.json.
  2. Em views.py na pasta de chat, mude GOOGLE_PROJECT_ID = "<YOUR_PROJECT_ID>" para o ID do seu projeto.

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

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

  1. Clique em Criar bucket.
  2. Insira um nome exclusivo globalmente.

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

  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.

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

  1. Clique em ao lado do bucket correspondente e em Editar permissões do bucket.

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

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

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

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>' pelo seu 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>'

Configurar o bucket do Cloud Storage em home.html

  • Abra a pasta de chat, depois templates e renomeie home-changeme.html para 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 buscar o arquivo e fazer a previsão.

Para executar o app Django no computador local, é necessário configurar um ambiente de desenvolvimento 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 seus 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/. Uma página da Web simples vai aparecer assim:

As páginas do app de exemplo são fornecidas pelo servidor da Web do Django em execução no seu computador. Quando estiver pronto para avançar, pressione Control+C (Command+C no Macintosh) para interromper 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 navegador da Web. Para fazer login no site de administração, digite o nome de usuário e a senha criados ao executar createsuperuser.

Reúna todo o conteúdo estático em uma pasta executando o seguinte comando, 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 o upload do app executando o seguinte comando no diretório em que o arquivo app.yaml está localizado:

gcloud app deploy

Aguarde a mensagem que informa sobre a conclusão da atualização.

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

Desta vez, sua solicitação é veiculada 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 tráfego novo.

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

Você pode testar o chatbot no simulador ou usar a integração com a Web ou o Google Home que você criou antes.

  1. Usuário: "oi"
  2. Chatbot: "Olá! Você pode fazer upload de uma foto para conhecer os pontos de referência."
  3. O usuário faz o upload de uma imagem.

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

  1. Chatbot: "O arquivo está sendo processado. Aqui estão os resultados: Ponte Golden Gate, Área Recreativa Nacional Golden Gate, Ponte Golden Gate, Ponte Golden Gate, Ponte Golden Gate".

No geral, ele vai ficar assim:

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

Excluir o agente do Dialogflow

  1. Clique em ao lado do agente.

  1. Na guia Geral, role para baixo e clique em Excluir este agente.
  2. Digite Excluir na janela que aparece e clique em Excluir.

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.