Webviews

Sua habilidade pode permitir que seus respectivos clientes insiram dados estruturados usando um aplicativo Webview.

As conversas em linguagem natural são, em sua essência, livres de fluxo. Mas nem sempre podem ser a melhor maneira de sua habilidade coletar informações dos usuários. Por exemplo, ao informar detalhes do cartão de crédito ou do passaporte, os usuários precisam digitar informações específicas (e digitá-las com precisão). Para ajudar com esses tipos de tarefas, a habilidade pode chamar um aplicativo webview.

Esses aplicativos não só permitem a entrada de dados estruturados por meio de elementos da IU, como formulários, seletores de data, campos e LOVs, como também podem validar a entrada do usuário e coletar informações de várias maneiras, como fazer upload de imagens, capturar assinaturas do usuário ou digitalizar códigos de barras. Os aplicativos Webview também protegem dados confidenciais do usuário, como números de cartão de crédito, porque esses dados não aparecem no histórico de chat quando são informados no aplicativo.
Veja a seguir a descrição da ilustração webview_webapp.png

Como Integrar um Webview em uma Habilidade?

Você precisa do seguinte para integrar um aplicativo Web na sua habilidade:
  • Um Serviço de Webview que conecta a habilidade ao aplicativo Web, que pode ser hospedado em um servidor Web externo ou no Digital Assistant.
  • Um Componente de Webview no fluxo de caixas de diálogo. Esse componente atua como um gateway para o aplicativo Web nomeando o Serviço de Webview, listando as variáveis do fluxo de caixas de diálogo que se baseiam no aplicativo Web e armazenando quaisquer valores retornados pelo aplicativo Web.

    No runtime, o componente renderiza um botão que inicia o aplicativo Web. O componente Webview inicia o aplicativo como webview na habilidade, ou em outra guia do navegador, quando a habilidade é executada em um canal Web.

  • O próprio aplicativo Web, que é hospedado no Digital Assistant ou em um servidor web remoto.

    Dica:

    Consulte a amostra do iniciador do webhook descrita na documentação do SDK em https://oracle.github.io/bots-node-sdk/.

Webviews Hospedados pelo Digital Assistant

Os aplicativos Web hospedados no Digital Assistant devem ser aplicativos de página única (SPAs), aplicativos Web do cliente com uma única página HTML (index.html) que inicia o aplicativo Web e é atualizado em resposta à entrada do usuário da habilidade. Quando o componente Webview chama o SPA:
  1. O index.html é carregado e inicia o aplicativo Web como webview ou em outra guia do browser.
  2. O componente Webview então transmite os valores de parâmetro coletados no fluxo de caixas de diálogo com o URL de callback. Ativar o SPA para Acessar os Parâmetros de Entrada e o URL de Callback descreve as diferentes abordagens para transmitir esses valores.
  3. O aplicativo Web faz uma solicitação POST para o URL de callback que foi gerado pelo componente Webview. Essa solicitação sinaliza que o aplicativo concluiu seu processamento. Se o aplicativo retornar dados, eles serão incluídos nessa solicitação como objeto JSON que é armazenado na propriedade variable. Você pode mencionar esses dados em seu fluxo de caixas de diálogo usando ${variable_property_name.value.Param}.

Você pode gravar o SPA usando diferentes frameworks, como Oracle Visual Builder, Angular, Oracle JavaScript Extension Toolkit (JET) ou React.js.

Observação

O backend do Oracle Visual Builder gerencia conexões REST, usuários (por meio do Oracle Identity Cloud Service) e executa objetos de negócios, de modo que qualquer aplicativo Oracle Visual Builder hospedado no Digital Assistant terá as seguintes limitações:
  • Ele não pode usar objetos de negócios.
  • Ele não pode ter integração com o Oracle Identity Cloud Service
  • Ele não pode acessar um serviço REST usando o proxy de autenticação do Oracle Visual Builder.
Portanto, o suporte de qualquer um desses recursos significa que você deve hospedar o aplicativo Oracle Visual Builder em um servidor externo.

Para hospedar o aplicativo no Digital Assistant, compacte-o em um arquivo compactado TAR (um arquivo TGZ). Como se trata de um SPA, o arquivo index.html deve estar na raiz desse pacote.

Ativar o SPA para Acessar os Parâmetros de Entrada e o URL de Callback

Quando você hospeda um SPA no Digital Assistant, o componente do Webview injeta a variável window.webViewParameters ( mostrada no trecho de código a seguir) no elemento <head> do arquivo index.html no runtime. Os pares de chave/valores no payload informam o SPA dos valores de entrada informados pela habilidade.
window.webviewParameters = {
    parameters: [
         {"key": "variableA", "value": "jsonObjA"},
         {"key": "variableB", "value": "jsonObjB"},
         ...
         {"key": "webview.onDone",
          "value": "https://host:port/patch"},
    ]
};
Para permitir que seu aplicativo acesse esses objetos, declare uma variável window.webviewParameters['parameters']:
let webviewParameters = window.webviewParameters !=null?window.webviewParameters['parameters']:null;
O objeto retornado é armazenado na propriedade Saída do Serviço da Webview por causa do callback.
No trecho de código a seguir do arquivo app.js de um aplicativo React, a função retorna o valor de uma chave nomeada. Se não for possível encontrá-lo, ele definirá um valor padrão.

Dica:

Você pode usar esse trecho de código no seu próprio código. Você pode usar var getParam em vez de this.getParam.
class App extends Component {
    constructor(props) {
        super(props);

        let wvParams = window.webviewParameters['parameters'];

        this.getParam = (arrParams, key, defaultValue) => {
            if (arrParams) {
                let param = arrParams.find(e => {
                    return e.key === key;
                });
                return param ? param.value : defaultValue;
            }
            return defaultValue;
        };

Definindo Placeholders no Arquivo index.html

Ao hospedar o SPA no Digital Assistant, você não precisa definir placeholders para valores de variáveis no arquivo index.html. Desde que o arquivo index.html tenha um elemento <head>, o aplicativo web saberá quais valores deverão ser esperados e o callback.

Adicionar um Placeholder Único no Elemento <head>

No elemento <head>, insira um bloco <script> com o placeholder webview.sourceVariableList. O aplicativo web substitui isso por uma string codificada em JSON que possui os dados do parâmetro de entrada e o URL de callback.

No exemplo a seguir, a chave é window.wvParams. Você pode usar qualquer nome para essa chave, desde que o anexe com window. Defina sempre o valor como "webview.sourceVariableList".

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <meta name="theme-color" content="#000000">
    <link rel="manifest" href="%PUBLIC_URL%/manifest.json">
    <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">

    <title>React App</title>
    <script>
        window.wvParams="webview.sourceVariableList";
    </script>
  </head>

No exemplo de código do aplicativo abaixo:

  • A instrução let designa webview.sourceVariableList a wvParams.
  • Os valores de saída são analisados como objeto JSON.
  • fullname extrai o nome da variável definida para a propriedade sourceVariableList no componente da webview (em que name é o nome da variável definida).
class App extends Component {
    constructor(props) {
        super(props);

        let wvParams = (window.wvParams === "webview.sourceVariableList" ?
            [] : JSON.parse(window.wvParams)['parameters']);

        this.getParam = (arrParams, key, defaultValue) => {
            if (arrParams) {
                let param = arrParams.find(e => {
                    return e.key === key;
                });
                return param ? param.value : defaultValue;
            }
            return defaultValue;
        };

        fullname = getParam(wvParams, 'name', null);
        callbackurl = getParam(wvParams, 'webview.onDone', null);
    ...
   

Adicionar Vários Placehoders no Elemento <head>

Adicione um bloco <script> que tenha placeholders para cada valor definido para o componente SourceVariable e o URL de callback. O aplicativo Web retorna o URL de callback e os dados para parâmetros de entrada como string codificada em JSON. Como você adicionou placeholders, não precisa declarar uma variável window.webviewParameters['parameters'].

Conforme ilustrado pelo trecho de código a seguir, os placeholders são definidos por pares de chave/valor. Cada valor deve:
  • Corresponder aos valores de entrada definidos para a propriedade SourceVariable.
  • Ser anexado por webview. (webview.keyword, por exemplo).
Além disso, o valor de callback deve ser webview.onDone. No trecho de código a seguir, por exemplo, webview.keyword, webview.assignee, webview.inventor correspondem todos a sourceVariableList: "assignee, keyword, inventor". O URL de callback é definido com webview.onDone. Você pode dar qualquer nome para a chave de callback, mas defina sempre o valor como webview.onDone.

Você tem a opção de definir variáveis globais anexando as chaves à janela. (window.Keyword no trecho de código a seguir, por exemplo).

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <meta name="theme-color" content="#000000">
    <link rel="manifest" href="%PUBLIC_URL%/manifest.json">
    <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">

<title>React App</title>
    <script>
        window.Keyword="webview.keyword";
        window.Assignee="webview.assignee";
        window.Inventor="webview.inventor";
        window.CALLBACK_URL="webview.onDone";
    </script>
</head>

Ligar o URL de Callback a um Botão Concluído no Aplicativo Web

O URL de callback gerado pelo componente Webview é essencialmente um callback de uso único por causa de seu token de estado (https://...?state=<callback-state-token>). Embora tenha a vida útil padrão de uma hora, ele é limpo após o componente Webview tratar a solicitação de callback no aplicativo web. Como os usuários não poderão consultar o aplicativo Web após esse ponto, ele deverá fazer a transição para uma página Final com um botão Fechar que esteja conectado ao URL de callback.

Webviews Hospedados Externamente

Você hospedará um aplicativo no servidor externo se ele tiver requisitos de segurança, aproveitar a infraestrutura do servidor ou exigir integração de dados ou administração central. Os aplicativos Web hospedados remotamente podem ser SPAs, mas não necessariamente. Você pode modificar um aplicativo Web existente para ser renderizado como webview ou criar um aplicativo Web especificamente para uma habilidade.

Para aplicativos web hospedados externamente, hospede o próprio aplicativo e um serviço intermediário. O aplicativo Web espera uma solicitação GET da habilidade, enquanto o serviço intermediário recebe as solicitações POST da habilidade e formula o URL de redirecionamento para o aplicativo Web. Os dois podem residir no mesmo servidor Web ou podem ser hospedados em servidores Web distintos. Independentemente da implementação, este é o fluxo de solicitações:
  1. No runtime, o componente Webview envia ao serviço intermediário uma solicitação POST que inclui o URL de callback da habilidade e os parâmetros de entrada do usuário como array de pares de chave-valor. O componente adiciona a variável webview.onDone como chave de URL de callback. As chaves são os nomes de parâmetros que são referenciados pela propriedade Entradas para Serviço da Webview e pela propriedade webview.onDone.
    {
     "parameters": [{
      "value": "CDG",
      "key": "origin"
    }, {
     "value": "MUC",
     "key": "destination"
    }, {
      "value": "https://<url>:443/connectors/v2/callback?state=cb5443. ..2c"
      "key": "webview.onDone" 
    }]
    
  2. O serviço intermediário retorna um objeto JSON para a habilidade que tem uma única propriedade, webview.url. Sua string define o URL de redirecionamento para o aplicativo Web, que é usado pela solicitação GET subsequente da habilidade. Este URL também contém os valores-chave transmitidos da solicitação POST (a menos que o payload da solicitação POST seja salvo em um armazenamento acessível ao aplicativo Web). Pode ser semelhante a:
    {
    "webview.url":
            "https://<app url>?callbackURL=https://example.com:443/connectors/v2/callback?state=cb55435552c&origin=CDG&destination=MUC
    }
    O aplicativo Web usa o URL de callback em uma chamada para transmitir o controle de volta à habilidade e, opcionalmente, para transmitir um payload de resposta.
    self.buttonClick = function (event) {
            if (event.currentTarget.id === 'Submit') {
    
    
              let data = {};
              data.origin = self.origin();
              data.destination = self.destination();
    
              //return date in milliseconds
              data.departureDate = (new Date(self.departureDate())).getTime();
              data.returnDate = (new Date(self.returnDate())).getTime();
              data.status = "success"
              
              /*
              function jqueryPost(url, data) {
                return $.ajax({
                  contentType: "text/plain",
                  url: url,
                  data: data || {},
                  type: "POST",
                  dataType: "text/plain"
                });
              };
    
              jqueryPost(webViewCallback, JSON.stringify(data));
    
              */
    
              //JQuery post call
              $.post(webViewCallback,JSON.stringify(data));
            }
            else {
              //if user pressed "cancel" pass no data but a status informing the bot designer
              let data = {};
              data.status = "cancel"
    
              $.post(webViewCallback, JSON.stringify(data));          
            }
    Isso ilustra o uso do método JQuery $.post para retornar o objeto JSON à habilidade com pares de valores de chave origin, destination, departureDate e returnDate:
    {
    "origin":"CDC"
    "destination":"MUC"
    "departureDate":"15689736000000"
    "returnDate":"15689736000000"
    }

    Dica:

    Esse trecho de código tem uma propriedade "status" definida como "success" ou "cancel" para indicar que um usuário concluiu o trabalho no aplicativo Web ou o cancelou. Os usuários podem fechar o navegador antes que a solicitação de callback seja concluída; portanto, inclua um listener para o fechamento que emita um callback se ainda não tiver ocorrido. A chamada pode usar um status de "cancel" para indicar que o formulário não foi concluído com sucesso. Se o usuário fechar a janela e você não perceber isso, a habilidade aguardará até que ela expire.
  3. A habilidade inicia o aplicativo Web enviando uma solicitação GET para o URL definido pela propriedade webview.url.
  4. Depois que o webview processar a entrada, ele enviará um callback de conclusão, que é uma solicitação POST, para o URL de callback que o componente do Webview gerou e forneceu ao serviço intermediário. Essa solicitação não só indica que o aplicativo foi finalizado (e que a habilidade deverá retomar o controle da sessão), como também pode retornar um payload de dados, que são armazenados na propriedade Saída do Serviço do Webview.
    Dependendo da sua estratégia de hospedagem, existem algumas questões a serem consideradas:
    • Se você hospedar o aplicativo Web e o serviço intermediário no mesmo servidor Web, os parâmetros de solicitação da habilidade poderão ser salvos em uma sessão, eliminando assim a necessidade de uma string de URL longa.
    • Se você hospedar o aplicativo Web e o serviço intermediário em servidores distintos, todos os parâmetros de solicitação do aplicativo Web no URL de redirecionamento que forem enviados à habilidade deverão ser codificados como parâmetros de consulta.

Criando um Serviço de Webview

A configuração de um Serviço de Webview conecta sua habilidade ao serviço que hospeda o aplicativo webview.

Você cria Serviços Webview na página do Webview, que é acessada clicando primeiro em Componentes (Esta é uma imagem do ícone Componentes.) na barra de navegação esquerda e depois clicando em Webview. Essa página lista os diversos Serviços Webview que você pode mencionar na propriedade Serviço do Componente Webview do Webview.

Observação

Você não precisa reconfigurar um serviço hospedado pelo Digital Assistant quando cria a versão ou clona a habilidade. No entanto, se você hospedar o aplicativo Web externamente, reconfigure o serviço quando criar a versão ou clonar sua habilidade.

Criar um Serviço de Webview Hospedados pelo Digital Assistant

Embora seja necessário fornecer credenciais de autenticação como parte da configuração de um Serviço de Webview hospedado externamente, basta você compactar o aplicativo Web em um arquivo compactado TAR (um arquivo TGZ) e depois fazer upload dele. O arquivo index.html deve estar no nível raiz desse arquivo.

Você pode compactar o aplicativo usando o comando tar GNU:
tar -zcvf   webapp.tgz *
Neste exemplo, o comando -zcvf cria um arquivo chamado webapp.tgz. Conforme indicado em Definindo Placeholders no Arquivo index.html, você pode criar o aplicativo Web usando a estrutura de sua escolha, desde que o arquivo index.html esteja na raiz do arquivo TGZ. Na verdade, o arquivo index.html pode até mesmo ser o único no nível raiz.
Para criar o serviço:
  1. Digite o nome dos serviços no arquivo Nome e uma descrição (que é opcional). O nome informado aqui deve corresponder ao valor da propriedade Serviço de Componente de Webview do componente de Webview.
  2. Ative a opção Serviço Hospedado.
  3. Solte o TGZ no campo Arquivo de Pacote ou navegue até ele e selecione-o.
  4. Clique em Criar.

Empacotar Aplicativos Oracle Visual Builder

Crie e otimize seus aplicativos Oracle Visual Builder para o Digital Assistant usando a tarefa vb-build Grunt. Você pode executar essa tarefa localmente ou como parte de um build no Oracle Developer Cloud Service (DevCS).

Antes de criar o aplicativo Oracle Visual Builder:
  • Certifique-se de ter configurado a conexão de serviço para atender às limitações descritas em Como Integrar um Webview em uma Habilidade? escolhendo Direto (Ignorar o proxy) e Permitir Acesso Anônimo no Oracle Visual Builder.
  • Se você estiver usando o Oracle Visual Builder para otimizar o binário, selecione Enviar para Git. Caso contrário, poderá ignorar esta etapa.

    Consulte a Documentação do Oracle Visual Builder para saber mais sobre como proteger o aplicativo Oracle Visual Builder e integrá-lo em um repositório Git.

Empacotar o Aplicativo Oracle Visual Builder Localmente

Para otimizar e empacotar seu aplicativo Oracle Visual Builder localmente:

  1. Na home page do Oracle Visual Builder, selecione seu aplicativo e clique em Exportar sem Dados.
  2. Descompacte o aplicativo.
  3. Execute npm install na pasta raiz (em que os arquivos package.json e Gruntfile.js estão localizados).

    A execução de npm install recupera o pacote grunt-vb-build npm definido no arquivo package.json.

  4. Digite os seguintes parâmetros:
    ./node_modules/.bin/grunt vb-build \
    --url=${serviceURL} \
    --username=${username} \
    --password=${password} \
    --id=${id} --ver=${ver} \
    --ver=<your visual app ID>\
    --git-source=<local directory for sources>
    Parâmetro Descrição
    url O URL da instância do Visual Builder.
    username Seu nome de usuário para a instância do Visual Builder.
    password A senha da instância do Visual Builder.
    id O ID do aplicativo. O ID do aplicativo pode ser igual ao nome, mas deve ser exclusivo no domínio de identidade.
    ver A versão do aplicativo.
    git Especifica o local das origens (se elas não estiverem na pasta atual).
  5. Ao término da criação, navegue até o diretório do aplicativo (localizado no diretório WebApps). Por exemplo, build/optimized/webApps/financialDispute.
  6. Execute o comando tar GNU (tar -zcvf webapp.tgz *, por exemplo).
    tar -zcvf   webapp.tgz *

Empacotar o Aplicativo Usando o Oracle Developer Cloud Service

Para criar e otimizar o aplicativo no Oracle Developer Cloud Service (DevCS):
  1. Configure um job de build no Oracle Cloud para o aplicativo Web:
    • Associe o job ao Git adicionando o Git como controle de origem (o aplicativo Web também precisa ser integrada a um repositório Git).
    • Selecione um modelo de criação.
    • Adicione os parâmetros de string que são transmitidos à criação. Esses parâmetros incluem:
      • O URL, o ID e a versão do serviço do aplicativo (que você pode obter na sua instância do Oracle Visual Builder)
      • O usuário e a senha (um Parâmetro de Senha)
      • A otimização, como Uglify2.
    • Para as etapas de criação, adicione um script shell que comece com npm install e transmita os parâmetros padrão para as Tarefas Grunt do Visual Builder, como vb-build.
      npm install
      ./node_modules/.bin/grunt vb-build \
      --url=${URL} \
      --username=${username} \
      --password=${password} \
      --id=${id} --ver=${ver} \
      --optimize=${optimize} \
      --schema=dev \
      
    • Para a configuração Após a Criação, configure o arquivamento escolhendo Arquivador de Artefato (selecionado no meu Adicionar Após a Ação de Criação) e, em seguida, digite build*zip no campo Arquivos a Serem Arquivados.
  2. Ao término da criação, faça download do arquivo ZIP e depois extraia-o. O arquivo index.html está localizado na pasta webapp (que fica no diretório webapps).
  3. Compacte o aplicativo em um arquivo TGZ (tar -zcvf webapp.tgz *, por exemplo).

Criar um Serviço de Webview Hospedado Externamente

Para aplicativos webview hospedados em servidores de aplicativos web externos, forneça o seguinte:
  • Nome — O nome do serviço remoto.
    Observação

    O nome informado aqui deve corresponder ao valor da propriedade Serviço de Componente de Webview do componente de Webview.
  • Desative a opção Serviço Hospedado.
  • URL do Aplicativo Web — O ponto final base fornecido por um servidor Web que aceita os parâmetros de origem como payload em uma solicitação POST HTTP. Por exemplo, https://example.oracle.com:3001/webviewParams. Digite o URL para o serviço intermediário quando o aplicativo web e o serviço intermediário forem hospedados separadamente.
  • Token de Autenticação — Um token de autorização que é enviado com solicitações para o URL especificado pela propriedade Url do Aplicativo Web. Essa propriedade tem o formato Basic <token> ou Bearer <token>. Essa propriedade é opcional
  • Parâmetros de Consulta — Um objeto JSON em formato de string cujos pares de chave/valor são os parâmetros de consulta anexados à solicitação POST. Essa propriedade é opcional.

Referenciar os Dados Retornados no Fluxo de Caixas de Diálogo

Como os valores retornados no payload não atualizam valores de variáveis, os nomes das propriedades no payload de resposta não precisam corresponder aos definidos na propriedade Entradas para Serviço.

Você pode acessar o payload retornado usando ${variable_property_name.value.Param}.

Após criar o Serviço de Webview e configurar o componente de Webview, você poderá descobrir os dados retornados pelo aplicativo Web usando o Testador de Habilidades (Ícone O Testador.). Depois que sua conversa tiver passado pelo estado da Webview, use a janela Conversa para examinar os valores retornados para as variáveis.
Veja a seguir a descrição da ilustração tester_variables.png

Dica:

Os desenvolvedores de aplicativos Web devem garantir que o payload retornado inclua nomes de propriedades descritivos.