As ações de conversa serão descontinuadas em 13 de junho de 2023. Para mais informações, consulte Desativação do Ações de conversa.

Criar fulfillment com a biblioteca de cliente do Node.js do Actions on Google (Dialogflow)

Mantenha tudo organizado com as coleções Salve e categorize o conteúdo com base nas suas preferências.

A biblioteca de cliente Node.js para Actions on Google é a maneira recomendada de acessar e interagir com a plataforma Actions on Google se você estiver criando um webhook de fulfillment em JavaScript.

Introdução

A biblioteca de cliente do Node.js é uma biblioteca de fulfillment para o Actions on Google que oferece estes recursos:

  • Oferece suporte a todos os recursos do Actions on Google, incluindo texto e respostas multimídia avançadas, login na conta, armazenamento de dados, transações e muito mais.
  • Fornece uma camada idiomática de abstração no JavaScript que envolve a API de webhook HTTP/JSON da conversa.
  • Lida com os detalhes de baixo nível de comunicação entre seu fulfillment e a plataforma Actions on Google.
  • Pode ser instalado usando ferramentas de gerenciamento de pacotes conhecidas, como npm ou yarn.
  • Permite implantar facilmente o webhook de fulfillment em plataformas de computação sem servidor, como o Cloud Functions para Firebase ou o AWS Lambda. Também é possível hospedar seu webhook de fulfillment em um provedor de serviços de nuvem ou em um ambiente auto-hospedado e autogerenciado.
  • É compatível com o Node.js versão 6.0.0 e mais recente.

É possível usar a biblioteca de cliente em conjunto com a integração do Dialogflow para o Actions on Google ou o SDK do Actions.

Para ver exemplos completos de código sobre como usar a biblioteca de cliente, acesse a página de amostras.

Ver a referência da API

A referência da API está hospedada na página Biblioteca de cliente do Node.js do Actions on Google no GitHub.

Também é possível gerar uma cópia local da referência executando o seguinte comando no diretório em que você fez o download do código da biblioteca de cliente:

yarn docs

Os documentos gerados estarão disponíveis na pasta docs do diretório em que você fez o download do código da biblioteca de cliente.

Entenda como funciona

Antes de usar a biblioteca de cliente, é útil entender como o webhook de fulfillment usa a biblioteca de cliente para processar solicitações de usuários que o Actions on Google envia para seu fulfillment.

Ao criar um webhook de fulfillment em JavaScript, é possível implantar e hospedar seu código em um ambiente de computação sem servidor, como o Cloud Functions para Firebase ou o AWS Lambda do Google. Também é possível hospedar o código sem trabalho extra usando o framework da Web Express.

No ambiente de execução, o webhook de fulfillment pode chamar funções na biblioteca de cliente para processar solicitações de usuários e enviar respostas de volta ao Actions on Google para renderização na saída do usuário.

As principais tarefas que seu webhook de fulfillment processa com a ajuda da biblioteca de cliente são resumidas rapidamente abaixo:

Figura 1. Arquitetura de alto nível da biblioteca de cliente do Node.js
  1. Receber solicitações de usuários: quando um usuário faz uma consulta no Google Assistente, a plataforma Actions on Google envia uma solicitação HTTP para o webhook de fulfillment. A solicitação inclui um payload JSON que contém a intent e outros dados, como o texto bruto da entrada do usuário e os recursos de superfície do dispositivo. Para mais exemplos do conteúdo de payload JSON, consulte os guias de formato de webhook do Dialogflow e formato de webhook de conversa.
  2. Detecção de formato de chamada do framework: para bibliotecas com suporte, a biblioteca de cliente detecta automaticamente o formato de chamada do framework (por exemplo, se a solicitação veio do framework da Web Express ou do AWS Lambda) e sabe como lidar perfeitamente com a comunicação com a plataforma Actions on Google.
  3. Processamento do gerenciador de serviços: a biblioteca de cliente representa a API de webhook HTTP/JSON da conversa para o Dialogflow e o SDK do Actions como uma função de serviço. O webhook de fulfillment usa o serviço apropriado para criar uma instância app global. A instância app atua como um gerenciador de solicitações HTTP e entende o protocolo específico do serviço.
  4. Processamento de conversas:a biblioteca de cliente representa as informações por conversa como um objeto Conversation anexado à instância app. O webhook de fulfillment pode usar o objeto Conversation para recuperar dados armazenados em conversas ou informações de estado, enviar respostas aos usuários ou fechar o microfone.
  5. Processamento de middleware: a biblioteca de cliente permite criar seu próprio middleware de serviços de conversa, que consiste em uma ou mais funções definidas que a biblioteca de cliente é executada automaticamente antes de chamar o gerenciador de intent. O webhook de fulfillment pode usar seu middleware para adicionar propriedades ou classes auxiliares ao objeto Conversation.
  6. Processamento do gerenciador de intents: a biblioteca de cliente permite definir gerenciadores para intents que o webhook de fulfillment entende. Para o Dialogflow, a biblioteca de cliente encaminha a solicitação para o gerenciador de intent correto. Para isso, ele é mapeado para a string exata do nome da intent definida no console do Dialogflow. Para o SDK do Actions, ele é roteado com base na propriedade intent enviada do Actions on Google.
  7. Enviar respostas aos usuários: para criar respostas, o webhook de fulfillment chama a função Conversation#ask(). A função ask() pode ser chamada várias vezes para criar a resposta de forma incremental. A biblioteca de cliente serializa a resposta em uma solicitação HTTP com um payload JSON e a envia para o Actions on Google. A função close() tem um comportamento semelhante ao de ask(), mas fecha a conversa.

Configurar o ambiente de desenvolvimento local

Antes de implementar o webhook de fulfillment, instale a biblioteca de cliente.

Instale a biblioteca de cliente

A maneira mais fácil de instalar a biblioteca de cliente no ambiente para desenvolvedores é usar um gerenciador de pacotes, como npm ou yarn.

Para instalar, execute um destes comandos no terminal:

  • Se estiver usando o npm: npm install actions-on-google
  • Se você estiver usando o fio: yarn add actions-on-google

Configurar as pastas do projeto

Dependendo de onde você planeja implantar o webhook de fulfillment (Cloud Functions do Google para Firebase, AWS Lambda ou Express auto-hospedado), talvez seja necessário criar uma estrutura de pasta de projeto específica para salvar seus arquivos.

Por exemplo, se você estiver usando o Cloud Functions para Firebase, poderá configurar as pastas de projetos necessárias seguindo as etapas descritas em Configurar o Node.js e a CLI do Firebase e Inicializar o Firebase para o Cloud Functions. Para o Cloud Functions para Firebase, você geralmente grava o webhook de fulfillment no arquivo /functions/index.js.

Criar uma instância de app

O Actions on Google usa formatos de mensagens específicos para trocar solicitações e respostas com o webhook de fulfillment, dependendo se você está criando uma ação de conversa usando o Dialogflow ou o SDK do Actions ou criando uma ação de casa inteligente.

Para representar esses diferentes protocolos de solicitação e resposta, a biblioteca de cliente fornece três funções de serviço:

O protocolo de webhook de conversa é usado pelos dois serviços de conversa, como Dialogflow e SDK do Actions. No entanto, cada serviço encapsula as mensagens de maneira diferente.

Use um serviço para criar uma instância de app. A instância app encapsula o estado global e a lógica de fulfillment do webhook e processa a comunicação entre o Actions on Google e o fulfillment usando o protocolo específico do serviço.

É possível configurar as propriedades da instância app e chamar os métodos dela para direcionar o comportamento do webhook de fulfillment. Também é possível conectar facilmente a instância app a um ambiente de computação sem servidor, como o Cloud Functions para Firebase, que aceita funções JavaScript como gerenciadores de solicitações HTTP.

Para criar uma instância de app no webhook de fulfillment, siga estas etapas:

  1. Chame a função require() para importar o módulo "actions-on-google" e carregar o serviço desejado. Por exemplo, o snippet a seguir mostra como carregar o serviço dialogflow e alguns elementos usados para criar respostas e o atribuir a uma constante chamada dialogflow:

    // Import the service function and various response classes
    const {
      dialogflow,
      actionssdk,
      Image,
      Table,
      Carousel,
    } = require('actions-on-google');

    Aqui, actions-on-google se refere a uma dependência especificada em um arquivo package.json na pasta do projeto. Para ver mais exemplos, consulte este arquivo package.json.

    Ao receber uma instância de app, é possível especificar classes que representam respostas detalhadas, intents de ajuda e outras funcionalidades do Actions on Google que você quer usar. Para ver a lista completa de classes válidas que podem ser carregadas, consulte a documentação de referência dos módulos de resposta de conversa e intent auxiliar.

  2. Crie uma instância app chamando o serviço carregado. Por exemplo:

    const app = dialogflow();

  3. Para configurar a instância app na inicialização, forneça um objeto options como o primeiro argumento ao chamar o serviço. Consulte DialogflowOptions para ver mais detalhes. Por exemplo, o snippet a seguir mostra como registrar o payload JSON bruto da solicitação ou resposta do usuário definindo a sinalização { debug: true }:

const app = dialogflow({
  debug: true
});

Definir manipuladores para eventos

Para processar eventos relacionados ao Actions on Google criados pela biblioteca de cliente durante o ciclo de vida da interação do usuário com a ação, use essa biblioteca para criar gerenciadores que processam solicitações de usuários e enviam respostas.

É possível criar funções que agem como gerenciadores destes tipos principais de eventos que a biblioteca de cliente reconhece:

  • Eventos de intent: intents são identificadores exclusivos que o Actions on Google envia para o fulfillment sempre que um usuário solicita alguma funcionalidade específica. Se você estiver usando o Dialogflow, isso significa que o Dialogflow corresponde uma consulta do usuário a uma intent no agente do Dialogflow.
  • Eventos de erro: quando ocorre um erro de JavaScript ou da biblioteca de cliente, use a função catch da instância app para processar a exceção de erros adequadamente. Implemente uma única função catch para lidar com todos os erros importantes para o fulfillment.
  • Eventos substitutos: um evento substituto ocorre quando o usuário envia uma consulta que o Actions on Google não reconhece. É possível usar a função fallback da instância app para registrar um gerenciador de fallback genérico que será acionado se nenhum gerenciador de intent corresponder à solicitação de fulfillment recebida. Implemente uma única função fallback para processar todos os eventos substitutos. Se você estiver usando o Dialogflow, ele poderá acionar uma intent de fallback específica quando nenhuma outra intent for atendida. Crie um gerenciador de intent correspondente para essa intent substituta.

Sempre que o usuário envia uma solicitação para a ação, a instância app cria um objeto Conversation que representa essa sessão de conversa. Esse objeto é acessado pelo nome da variável conv transmitida na função do gerenciador de intent como o primeiro argumento de função. Normalmente, o objeto conv é usado nos gerenciadores para enviar uma resposta ao usuário.

As consultas do usuário também podem incluir parâmetros que sua ação pode extrair e usar para refinar as respostas.

  • Se você estiver usando o SDK do Actions, defina os parâmetros no pacote de ações. Para ver um exemplo de como extrair parâmetros de intents, consulte a amostra de código Eliza.
  • Se você estiver usando o Dialogflow, poderá acessar os valores de parâmetro usando a variável params. Para ver exemplos de como processar intents com parâmetros no Dialogflow, consulte Acessar parâmetros e contextos.

Definir gerenciadores para intents

Para definir o gerenciador de uma intent, chame a função intent() da instância app. Por exemplo, se você estiver usando o Dialogflow, esta será a função DialogflowApp#intent(). Nos argumentos, especifique o nome da intent e forneça uma função de gerenciador.

Se você estiver usando o Dialogflow, não precisará definir gerenciadores para cada intent no agente. Em vez disso, você pode aproveitar o gerenciador de resposta integrado do Dialogflow para processar intents automaticamente sem implementar suas próprias funções. Por exemplo, a intent de boas-vindas padrão pode ser delegada ao Dialogflow dessa maneira.

O exemplo a seguir mostra gerenciadores de intent para as intents "saudação" e "tchau". As funções de gerenciador anônimas recebem um argumento conv e enviam uma resposta de string simples ao usuário usando a função conv.ask():

app.intent('Default Welcome Intent', (conv) => {
  conv.ask('How are you?');
});

app.intent('bye', (conv) => {
  conv.close('See you later!');
});

Observe que a função close() é semelhante a ask(), mas fecha o microfone e a conversa acabou.

Para saber mais sobre como criar gerenciadores para intents, consulte Criar o gerenciador de intent.

Definir gerenciadores para eventos de erro

Para definir os gerenciadores em busca de erros, chame a função catch() da instância app. Por exemplo, se você estiver usando o Dialogflow, essa será a função DialogflowApp#catch().

O exemplo a seguir mostra um gerenciador de erros de captura simples que envia o erro para a saída do console e retorna uma resposta de string simples para solicitar o usuário usando a função conv.ask():

app.catch((conv, error) => {
  console.error(error);
  conv.ask('I encountered a glitch. Can you say that again?');
});

Definir manipuladores para eventos substitutos

Para definir um gerenciador substituto substituto quando nenhuma intent for correspondente à solicitação de fulfillment de entrada, chame a função fallback() da instância de app. Por exemplo, se você estiver usando o Dialogflow, essa será a função DialogflowApp#fallback().

O exemplo a seguir mostra um gerenciador substituto simples que envia uma resposta de string simples para solicitar o usuário usando a função conv.ask():

app.fallback((conv) => {
  conv.ask(`I couldn't understand. Can you say that again?`);
});

Criar o gerenciador de intent

Esta seção aborda alguns casos de uso comuns ao implementar gerenciadores de intent com a biblioteca de cliente. Para ver como a biblioteca de cliente corresponde à intent, consulte a seção "Processamento do gerenciador de intents" em Entender como funciona.

Acessar parâmetros e contextos

Se você estiver usando o Dialogflow, poderá definir parâmetros e contextos no agente do Dialogflow para manter as informações de estado e controlar o fluxo da conversa.

Os parâmetros são úteis para capturar palavras, frases ou valores importantes nas consultas do usuário. O Dialogflow extrai os parâmetros correspondentes das consultas do usuário no tempo de execução, e é possível processar esses valores de parâmetro no webhook de fulfillment para determinar como responder aos usuários.

Sempre que o usuário envia uma solicitação para a ação, a instância DialogflowApp cria um objeto parameters que representa os valores de parâmetro que o Dialogflow extraiu dessa solicitação. Esse objeto é acessado pelo nome da variável params.

O snippet a seguir mostra como acessar a propriedade name no objeto params quando o usuário envia uma solicitação:

app.intent('Default Welcome Intent', (conv, params) => {
  conv.ask(`How are you, ${params.name}?`);
});

Veja um snippet alternativo que faz o mesmo. As chaves ({}) executam a desestruturação do JavaScript para usar a propriedade name do objeto parameters e usá-la como uma variável local:

app.intent('Default Welcome Intent', (conv, {name}) => {
  conv.ask(`How are you, ${name}?`);
});

No snippet a seguir, o nome do parâmetro é full-name, mas é desestruturado e atribuído a uma variável local chamada name:

app.intent('Default Welcome Intent', (conv, {'full-name': name}) => {
  conv.ask(`How are you, ${name}?`);
});

Os contextos são um recurso avançado do Dialogflow. É possível usar contextos para gerenciar o estado, o fluxo e a ramificação da conversa. A biblioteca de cliente fornece acesso a um contexto pelo objeto DialogflowConversation#contexts. O snippet a seguir mostra como definir um contexto de maneira programática no webhook de fulfillment e como recuperar o objeto de contexto:

app.intent('intent1', (conv) => {
  const lifespan = 5;
  const contextParameters = {
    color: 'red',
  };
  conv.contexts.set('context1', lifespan, contextParameters);
  // ...
  conv.ask('...');
});

app.intent('intent2', (conv) => {
  const context1 = conv.contexts.get('context1');
  const contextParameters = context1.parameters;
  // ...
  conv.ask('...');
});

app.intent('intent3', (conv) => {
  conv.contexts.delete('context1');
  // ...
  conv.ask('...');
});

Acessar resultados de intent auxiliar

Por conveniência, a biblioteca de cliente fornece classes de intent úteis que envolvem tipos comuns de dados de usuários que as ações solicitam com frequência. Isso inclui classes que representam os resultados das várias intents de ajuda do Actions on Google. Use intents auxiliares quando quiser que o Google Assistente processe partes da conversa em que o usuário precisa fornecer entradas para continuar a conversa.

Exemplo: resultados do assistente de confirmação

A intent auxiliar de confirmação permite pedir uma confirmação sim/não do usuário e receber a resposta resultante. O snippet a seguir mostra como o webhook pode personalizar a resposta com base nos resultados retornados pela intent auxiliar de confirmação. Para ver um exemplo mais completo, consulte a documentação de referência da classe Confirmation.

// Create Dialogflow intent with `actions_intent_CONFIRMATION` event
app.intent('get_confirmation', (conv, input, confirmation) => {
  if (confirmation) {
    conv.close(`Great! I'm glad you want to do it!`);
  } else {
    conv.close(`That's okay. Let's not do it now.`);
  }
});

O snippet a seguir mostra como o webhook de fulfillment pode personalizar a resposta com base na entrada do usuário em um carrossel. O componente de carrossel permite que sua ação apresente uma seleção de opções para os usuários escolherem. Para ver um exemplo mais completo, consulte a documentação de referência da classe Carousel.

app.intent('carousel', (conv) => {
  conv.ask('Which of these looks good?');
  conv.ask(new Carousel({
    items: {
      car: {
        title: 'Car',
        description: 'A four wheel vehicle',
        synonyms: ['automobile', 'vehicle'],
      },
      plane: {
        title: 'Plane',
        description: 'A flying machine',
        synonyms: ['aeroplane', 'jet'],
      }
    }
  }));
});

// Create Dialogflow intent with `actions_intent_OPTION` event
app.intent('get_carousel_option', (conv, input, option) => {
  if (option === 'one') {
    conv.close(`Number one is a great choice!`);
  } else {
    conv.close(`Number ${option} is a great choice!`);
  }
});

Configurar objetos de resposta da conversa

A biblioteca de cliente fornece classes de resposta de conversa que representam respostas avançadas ou elementos multimídia que sua ação pode enviar. Geralmente, você envia essas respostas ou elementos quando os usuários não precisam fornecer entradas para continuar a conversa.

Exemplo: imagem

O snippet a seguir mostra como o webhook de fulfillment pode enviar um Image em uma resposta que será anexada automaticamente a uma resposta BasicCard pela biblioteca:

app.intent('Default Welcome Intent', (conv) => {
  conv.ask('Hi, how is it going?');
  conv.ask(`Here's a picture of a cat`);
  conv.ask(new Image({
    url: '/web/fundamentals/accessibility/semantics-builtin/imgs/160204193356-01-cat-500.jpg',
    alt: 'A cat',
  }));
});

Fazer chamadas de função assíncronas

A biblioteca de cliente Node.js do Actions on Google foi projetada para programação assíncrona. O gerenciador de intents pode retornar uma promessa que seja resolvida quando o webhook de fulfillment terminar de gerar uma resposta.

O snippet a seguir mostra como fazer uma chamada de função assíncrona para retornar um objeto de promessa e responder com uma mensagem se o webhook de fulfillment receber a intent de "saudação". Neste snippet, a promessa garante que seu webhook de fulfillment retorne uma resposta de conversa somente depois que a promessa da chamada de API externa for resolvida.

Neste exemplo, usamos uma API falsa para acessar os dados meteorológicos.

/**
 * Make an external API call to get weather data.
 * @return {Promise<string>}
 */
const forecast = () => {
  // ...
};

app.intent('Default Welcome Intent', (conv) => {
  return forecast().then((weather) => {
    conv.ask('How are you?');
    conv.ask(`Today's weather is ${weather}.`);
  });
});

O snippet de código simplificado a seguir tem o mesmo efeito, mas usa o recurso async await introduzido no ECMA 2017 (Node.js versão 8). Para usar esse código com o Cloud Functions para Firebase, verifique se você está usando a versão correta do firebase-tools e se está com a configuração correta.

app.intent('Default Welcome Intent', async (conv) => {
  const weather = await forecast();
  conv.ask('How are you?');
  conv.ask(`Today's weather is ${weather}.`);
});

Armazenar dados de conversa

A biblioteca de cliente permite que o webhook de fulfillment salve dados em conversas para uso futuro. Os principais objetos que podem ser usados para armazenamento de dados incluem:

O snippet a seguir mostra como o webhook de fulfillment pode armazenar dados em uma propriedade arbitrária definida por você (someProperty) e anexá-lo ao objeto Conversation#user.storage. Para ver um exemplo mais completo, consulte a documentação de referência da classe Conversation#user.storage.

app.intent('Default Welcome Intent', (conv) => {
  conv.user.storage.someProperty = 'someValue';
  conv.ask('...');
});

Você pode usar o objeto Conversation#user para receber informações sobre o usuário, incluindo um identificador de string e informações pessoais. Alguns campos, como conv.user.name.display e conv.user.email, exigem a solicitação de conv.ask(new Permission) para NAME e conv.ask(new SignIn) para o Login do Google, respectivamente.

const {Permission} = require('actions-on-google');
app.intent('Default Welcome Intent', (conv) => {
  if (conv.user.last.seen) {
    conv.ask('Welcome back! How are you?');
  } else {
    conv.ask('Nice to meet you! How are you doing?');
  }
});

app.intent('permission', (conv) => {
  conv.ask(new Permission({
    context: 'To greet you personally',
    permissions: 'NAME',
  }));
});

// Create Dialogflow intent with `actions_intent_PERMISSION` event
app.intent('get_permission', (conv, input, granted) => {
  if (granted) {
    conv.close(`Hi ${conv.user.name.display}!`);
  } else {
    // User did not grant permission
    conv.close(`Hello!`);
  }
});

Escalonamento com middleware

É possível estender a biblioteca de cliente por meio de um middleware.

A camada middleware consiste em uma ou mais funções que você define, que a biblioteca de cliente executa automaticamente antes de chamar o gerenciador de intents. Usar uma camada de middleware permite modificar a instância Conversation e adicionar outras funcionalidades.

Os serviços do Dialogflow e do SDK do Actions expõem uma função app.middleware() que permite adicionar propriedades ou classes auxiliares à instância Conversation.

O snippet a seguir mostra um exemplo de como usar o middleware:

class Helper {
  constructor(conv) {
    this.conv = conv;
  }

  func1() {
    this.conv.ask(`What's up?`);
  }
}

app.middleware((conv) => {
  conv.helper = new Helper(conv);
});

app.intent('Default Welcome Intent', (conv) => {
  conv.helper.func1();
});

Exporte o app

Para expor o webhook de fulfillment de um framework da Web ou plataforma de computação sem servidor, exporte o objeto app como um webhook acessível publicamente. A biblioteca de cliente oferece suporte à implantação em diversos ambientes prontos para uso.

Os snippets a seguir mostram como exportar app em diferentes ambientes de execução:

Exemplo: Cloud Functions para Firebase

const functions = require('firebase-functions');
// ... app code here
exports.fulfillment = functions.https.onRequest(app);

Exemplo: editor in-line do Dialogflow

const functions = require('firebase-functions');

// ... app code here

// Exported function name must be 'dialogflowFirebaseFulfillment'
exports.dialogflowFirebaseFulfillment = functions.https.onRequest(app);

Exemplo: servidor Express auto-hospedado (simples)

const express = require('express');
const bodyParser = require('body-parser');  

// ... app code here

express().use(bodyParser.json(), app).listen(3000);

Exemplo: servidor Express auto-hospedado (várias rotas)

const express = require('express');
const bodyParser = require('body-parser');

// ... app code here

const expressApp = express().use(bodyParser.json());

expressApp.post('/fulfillment', app);

expressApp.listen(3000);

Exemplo: gateway da API AWS Lambda

// ... app code here

exports.fulfillment = app;